diff --git a/.gitignore b/.gitignore index 7f4bdcc..bccf1cb 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ payload.bin .idea/ cmake-build-debug/ CMakeLists.txt +payload.elf.bin diff --git a/Makefile b/Makefile index c03a24b..e5ce696 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,8 @@ export CXX := $(PREFIX)g++ export AR := $(PREFIX)ar export OBJCOPY := $(PREFIX)objcopy +GCC_VER := $(shell $(DEVKITPPC)/bin/powerpc-eabi-gcc -dumpversion) + #--------------------------------------------------------------------------------- # TARGET is the name of the output # BUILD is the directory where object files & intermediate files will be placed @@ -39,14 +41,14 @@ CFLAGS := -std=gnu11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math -fno-built CXXFLAGS := -std=gnu++11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ -O0 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) ASFLAGS := -mregnames -LDFLAGS := -nostartfiles -Wl,--gc-sections +LDFLAGS := -nostartfiles -Wl,--gc-sections,--allow-multiple-definition Q := @ MAKEFLAGS += --no-print-directory #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := +LIBS := -lwut #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing @@ -54,7 +56,8 @@ LIBS := #--------------------------------------------------------------------------------- LIBDIRS := $(CURDIR) \ $(DEVKITPPC)/lib \ - $(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2 + $(DEVKITPRO)/wut \ + $(DEVKITPPC)/lib/gcc/powerpc-eabi/$(GCC_VER) #--------------------------------------------------------------------------------- diff --git a/sd_loader/src/entry.c b/sd_loader/src/entry.c index 4ec1876..1b350f5 100644 --- a/sd_loader/src/entry.c +++ b/sd_loader/src/entry.c @@ -10,28 +10,46 @@ #define OS_FIND_EXPORT(handle, funcName, func) OSDynLoad_FindExport(handle, 0, funcName, &func) typedef struct _private_data_t { - EXPORT_DECL(void *, MEMAllocFromDefaultHeapEx,int size, int align); - EXPORT_DECL(void, MEMFreeToDefaultHeap,void *ptr); + EXPORT_DECL(void *, MEMAllocFromDefaultHeapEx, int size, int align); + + EXPORT_DECL(void, MEMFreeToDefaultHeap, void *ptr); + + EXPORT_DECL(uint64_t, OSGetTitleID); EXPORT_DECL(void*, memcpy, void *p1, const void *p2, unsigned int s); + EXPORT_DECL(void*, memset, void *p1, int val, unsigned int s); - EXPORT_DECL(void, OSFatal, const char* msg); + + EXPORT_DECL(void, OSFatal, const char *msg); + EXPORT_DECL(unsigned int, OSEffectiveToPhysical, const void*); + EXPORT_DECL(void, exit, int); EXPORT_DECL(int, FSInit, void); + EXPORT_DECL(int, FSAddClientEx, void *pClient, int unk_zero_param, int errHandling); + EXPORT_DECL(int, FSDelClient, void *pClient); + EXPORT_DECL(void, FSInitCmdBlock, void *pCmd); + EXPORT_DECL(int, FSGetMountSource, void *pClient, void *pCmd, int type, void *source, int errHandling); + EXPORT_DECL(int, FSMount, void *pClient, void *pCmd, void *source, const char *target, uint32_t bytes, int errHandling); + EXPORT_DECL(int, FSUnmount, void *pClient, void *pCmd, const char *target, int errHandling); + EXPORT_DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling); + EXPORT_DECL(int, FSGetStatFile, void *pClient, void *pCmd, int fd, void *buffer, int error); + EXPORT_DECL(int, FSReadFile, void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling); + EXPORT_DECL(int, FSCloseFile, void *pClient, void *pCmd, int fd, int errHandling); - EXPORT_DECL(int, SYSRelaunchTitle, int argc, char** argv); + EXPORT_DECL(int, SYSRelaunchTitle, int argc, char **argv); + } private_data_t; static void (*DCFlushRange)(void *addr, unsigned int size); @@ -356,16 +374,16 @@ static int LoadFileToMem(private_data_t *private_data, const char *filepath, uns int status = private_data->FSGetMountSource(pClient, pCmd, 0, tempPath, -1); if (status != 0) { - private_data->OSFatal("FSGetMountSource failed."); + private_data->OSFatal("-13"); } status = private_data->FSMount(pClient, pCmd, tempPath, mountPath, FS_MAX_MOUNTPATH_SIZE, -1); if(status != 0) { - private_data->OSFatal("SD mount failed."); + private_data->OSFatal("-12"); } status = private_data->FSOpenFile(pClient, pCmd, filepath, "r", &iFd, -1); if(status != 0) { - private_data->OSFatal("FSOpenFile failed."); + private_data->OSFatal("-11"); } FSStat stat; @@ -375,10 +393,11 @@ static int LoadFileToMem(private_data_t *private_data, const char *filepath, uns private_data->FSGetStatFile(pClient, pCmd, iFd, &stat, -1); - if(stat.size > 0) + if (stat.size > 0) { pBuffer = private_data->MEMAllocFromDefaultHeapEx((stat.size + 0x3F) & ~0x3F, 0x40); - else - private_data->OSFatal("ELF file empty."); + } else { + private_data->OSFatal("-10"); + } unsigned int done = 0; @@ -493,10 +512,11 @@ static void loadFunctionPointers(private_data_t * private_data) { unsigned int *functionPtr = 0; OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPtr); - private_data->MEMAllocFromDefaultHeapEx = (void * (*)(int, int))*functionPtr; + private_data->MEMAllocFromDefaultHeapEx = (void *(*)(int, int)) *functionPtr; OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPtr); - private_data->MEMFreeToDefaultHeap = (void (*)(void *))*functionPtr; + private_data->MEMFreeToDefaultHeap = (void (*)(void *)) *functionPtr; + OS_FIND_EXPORT(coreinit_handle, "OSGetTitleID", private_data->OSGetTitleID); OS_FIND_EXPORT(coreinit_handle, "memcpy", private_data->memcpy); OS_FIND_EXPORT(coreinit_handle, "memset", private_data->memset); OS_FIND_EXPORT(coreinit_handle, "OSFatal", private_data->OSFatal); @@ -529,12 +549,12 @@ int _start(int argc, char **argv) { if(MAIN_ENTRY_ADDR != 0xC001C0DE) { loadFunctionPointers(&private_data); - while(1) { - if(ELF_DATA_ADDR != 0xDEADC0DE && ELF_DATA_SIZE > 0) { + while (1) { + if (ELF_DATA_ADDR != 0xDEADC0DE && ELF_DATA_SIZE > 0) { //! copy data to safe area before processing it - unsigned char * pElfBuffer = (unsigned char *)private_data.MEMAllocFromDefaultHeapEx(ELF_DATA_SIZE, 4); - if(pElfBuffer) { - private_data.memcpy(pElfBuffer, (unsigned char*)ELF_DATA_ADDR, ELF_DATA_SIZE); + unsigned char *pElfBuffer = (unsigned char *) private_data.MEMAllocFromDefaultHeapEx(ELF_DATA_SIZE, 4); + if (pElfBuffer) { + private_data.memcpy(pElfBuffer, (unsigned char *) ELF_DATA_ADDR, ELF_DATA_SIZE); MAIN_ENTRY_ADDR = load_elf_image(&private_data, pElfBuffer); private_data.MEMFreeToDefaultHeap(pElfBuffer); @@ -543,23 +563,29 @@ int _start(int argc, char **argv) { ELF_DATA_SIZE = 0; } - if(MAIN_ENTRY_ADDR == 0xDEADC0DE || MAIN_ENTRY_ADDR == 0) { + if (MAIN_ENTRY_ADDR == 0xDEADC0DE || MAIN_ENTRY_ADDR == 0) { //! setup necessary syscalls and hooks for HBL before launching it setup_patches(&private_data); - if(HBL_CHANNEL) { + if (HBL_CHANNEL) { break; } else { unsigned char *pElfBuffer = NULL; unsigned int uiElfSize = 0; + if (private_data.OSGetTitleID() == 0x000500101004A200L || // mii maker eur + private_data.OSGetTitleID() == 0x000500101004A100L || // mii maker usa + private_data.OSGetTitleID() == 0x000500101004A000L) { // mii maker jpn - LoadFileToMem(&private_data, CAFE_OS_SD_PATH WIIU_PATH "/apps/homebrew_launcher/homebrew_launcher.elf", &pElfBuffer, &uiElfSize); + LoadFileToMem(&private_data, CAFE_OS_SD_PATH WIIU_PATH "/apps/homebrew_launcher/homebrew_launcher.elf", &pElfBuffer, &uiElfSize); + }else{ + break; + } - if(!pElfBuffer) { + if (!pElfBuffer) { private_data.OSFatal("Failed to load homebrew_launcher.elf"); } else { MAIN_ENTRY_ADDR = load_elf_image(&private_data, pElfBuffer); - if(MAIN_ENTRY_ADDR == 0) { + if (MAIN_ENTRY_ADDR == 0) { private_data.OSFatal("Failed to load homebrew_launcher.elf"); } else { private_data.MEMFreeToDefaultHeap(pElfBuffer); @@ -567,12 +593,12 @@ int _start(int argc, char **argv) { } } } else { - int returnVal = ((int (*)(int, char **))MAIN_ENTRY_ADDR)(argc, argv); + int returnVal = ((int (*)(int, char **)) MAIN_ENTRY_ADDR)(argc, argv); //! exit to miimaker and restart application on re-enter of another application - if(returnVal == (int)EXIT_RELAUNCH_ON_LOAD) { + if (returnVal == (int) EXIT_RELAUNCH_ON_LOAD) { break; } - //! exit to homebrew launcher in all other cases + //! exit to homebrew launcher in all other cases else { MAIN_ENTRY_ADDR = 0xDEADC0DE; private_data.SYSRelaunchTitle(0, 0); diff --git a/src/dynamic.c b/src/dynamic.c new file mode 100644 index 0000000..901352e --- /dev/null +++ b/src/dynamic.c @@ -0,0 +1,44 @@ +#include +#include + +#define IMPORT(name) void* addr_##name +#define IMPORT_BEGIN(lib) +#define IMPORT_END() + +#include "imports.h" + +#undef IMPORT +#undef IMPORT_BEGIN +#undef IMPORT_END + +#define IMPORT(name) do{if(OSDynLoad_FindExport(handle, 0, #name, &addr_##name) < 0)OSFatal("Function " # name " is NULL");} while(0) +#define IMPORT_BEGIN(lib) OSDynLoad_Acquire(#lib ".rpl", &handle) +/* #define IMPORT_END() OSDynLoad_Release(handle) */ +#define IMPORT_END() + +#define EXPORT_VAR(type, var) type var __attribute__((section(".data"))); + +EXPORT_VAR(uint32_t *, MEMAllocFromDefaultHeap); +EXPORT_VAR(uint32_t *, MEMAllocFromDefaultHeapEx); +EXPORT_VAR(uint32_t *, MEMFreeToDefaultHeap); + +void InitFunctionPointers(void) { + OSDynLoad_Module handle; + addr_OSDynLoad_Acquire = (void *) 0x0102A3B4; + addr_OSDynLoad_FindExport = (void *) 0x0102B828; + + OSDynLoad_Acquire("coreinit.rpl", &handle); + + uint32_t **value = 0; + OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeap", (void **) &value); + MEMAllocFromDefaultHeap = *value; + OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeapEx", (void **) &value); + MEMAllocFromDefaultHeapEx = *value; + OSDynLoad_FindExport(handle, 1, "MEMFreeToDefaultHeap", (void **) &value); + MEMFreeToDefaultHeap = *value; + +#include "imports.h" + + // override failed __rplwrap_exit find export + OSDynLoad_FindExport(handle, 0, "exit", (void **) &addr___rplwrap_exit); +} diff --git a/src/dynamic.h b/src/dynamic.h new file mode 100644 index 0000000..be625d1 --- /dev/null +++ b/src/dynamic.h @@ -0,0 +1,11 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +void InitFunctionPointers(void); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/entry.c b/src/entry.c index 6d85954..075cd1e 100644 --- a/src/entry.c +++ b/src/entry.c @@ -2,6 +2,16 @@ #include "../sd_loader/src/common.h" #include "../sd_loader/sd_loader.h" #include +#include "dynamic.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include #define OSDynLoad_Acquire ((void (*)(char* rpl, unsigned int *handle))0x0102A3B4) #define OSDynLoad_FindExport ((void (*)(unsigned int handle, int isdata, char *symbol, void *address))0x0102B828) @@ -52,16 +62,30 @@ typedef struct _private_data_t { EXPORT_DECL(int, FSInit, void); EXPORT_DECL(int, FSAddClientEx, void *pClient, int unk_zero_param, int errHandling); EXPORT_DECL(int, FSDelClient, void *pClient); + EXPORT_DECL(void, FSInitCmdBlock, void *pCmd); + EXPORT_DECL(int, FSGetMountSource, void *pClient, void *pCmd, int type, void *source, int errHandling); + EXPORT_DECL(int, FSMount, void *pClient, void *pCmd, void *source, const char *target, uint32_t bytes, int errHandling); + EXPORT_DECL(int, FSUnmount, void *pClient, void *pCmd, const char *target, int errHandling); + EXPORT_DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling); + EXPORT_DECL(int, FSGetStatFile, void *pClient, void *pCmd, int fd, void *buffer, int error); + EXPORT_DECL(int, FSReadFile, void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling); + EXPORT_DECL(int, FSCloseFile, void *pClient, void *pCmd, int fd, int errHandling); - EXPORT_DECL(int, SYSRelaunchTitle, int argc, char** argv); + EXPORT_DECL(int, SYSRelaunchTitle, int argc, char **argv); + + EXPORT_DECL(int, _SYSLaunchMiiStudio); + + EXPORT_DECL(int, SYSLaunchMenu); + + EXPORT_DECL(uint64_t, OSGetTitleID); } private_data_t; static void InstallPatches(private_data_t *private_data); @@ -75,10 +99,11 @@ static void loadFunctionPointers(private_data_t * private_data) { unsigned int *functionPtr = 0; OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPtr); - private_data->MEMAllocFromDefaultHeapEx = (void * (*)(int, int))*functionPtr; + private_data->MEMAllocFromDefaultHeapEx = (void *(*)(int, int)) *functionPtr; OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPtr); - private_data->MEMFreeToDefaultHeap = (void (*)(void *))*functionPtr; + private_data->MEMFreeToDefaultHeap = (void (*)(void *)) *functionPtr; + OS_FIND_EXPORT(coreinit_handle, "OSGetTitleID", private_data->OSGetTitleID); OS_FIND_EXPORT(coreinit_handle, "memcpy", private_data->memcpy); OS_FIND_EXPORT(coreinit_handle, "memset", private_data->memset); OS_FIND_EXPORT(coreinit_handle, "DCFlushRange", private_data->DCFlushRange); @@ -102,6 +127,8 @@ static void loadFunctionPointers(private_data_t * private_data) { unsigned int sysapp_handle; OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle); OS_FIND_EXPORT(sysapp_handle, "SYSRelaunchTitle", private_data->SYSRelaunchTitle); + OS_FIND_EXPORT(sysapp_handle, "_SYSLaunchMiiStudio", private_data->_SYSLaunchMiiStudio); + OS_FIND_EXPORT(sysapp_handle, "SYSLaunchMenu", private_data->SYSLaunchMenu); } static unsigned int load_elf_image (private_data_t *private_data, unsigned char *elfstart) { @@ -156,32 +183,50 @@ static unsigned int load_elf_image (private_data_t *private_data, unsigned char return ehdr->e_entry; } - void KernelWriteU32(uint32_t addr, uint32_t value, private_data_t * pdata) { pdata->ICInvalidateRange(&value, 4); pdata->DCFlushRange(&value, 4); - uint32_t dst = (uint32_t) pdata->OSEffectiveToPhysical((void *)addr); - uint32_t src = (uint32_t) pdata->OSEffectiveToPhysical((void *)&value); + uint32_t dst = (uint32_t) pdata->OSEffectiveToPhysical((void *) addr); + uint32_t src = (uint32_t) pdata->OSEffectiveToPhysical((void *) &value); SC_0x25_KernelCopyData(dst, src, 4); - pdata->DCFlushRange((void *)addr, 4); - pdata->ICInvalidateRange((void *)addr, 4); + pdata->DCFlushRange((void *) addr, 4); + pdata->ICInvalidateRange((void *) addr, 4); +} + +bool CheckRunning() { + switch (ProcUIProcessMessages(true)) { + case PROCUI_STATUS_EXITING: { + return false; + } + case PROCUI_STATUS_RELEASE_FOREGROUND: { + ProcUIDrawDoneRelease(); + break; + } + case PROCUI_STATUS_IN_FOREGROUND: { + break; + } + case PROCUI_STATUS_IN_BACKGROUND: + default: + break; + } + return true; } int _start(int argc, char **argv) { - kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x25 * 4)), (unsigned int)SCKernelCopyData); - kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x25 * 4)), (unsigned int)SCKernelCopyData); - kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x25 * 4)), (unsigned int)SCKernelCopyData); - kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x25 * 4)), (unsigned int)SCKernelCopyData); - kern_write((void*)(KERN_SYSCALL_TBL_5 + (0x25 * 4)), (unsigned int)SCKernelCopyData); + kern_write((void *) (KERN_SYSCALL_TBL_1 + (0x25 * 4)), (unsigned int) SCKernelCopyData); + kern_write((void *) (KERN_SYSCALL_TBL_2 + (0x25 * 4)), (unsigned int) SCKernelCopyData); + kern_write((void *) (KERN_SYSCALL_TBL_3 + (0x25 * 4)), (unsigned int) SCKernelCopyData); + kern_write((void *) (KERN_SYSCALL_TBL_4 + (0x25 * 4)), (unsigned int) SCKernelCopyData); + kern_write((void *) (KERN_SYSCALL_TBL_5 + (0x25 * 4)), (unsigned int) SCKernelCopyData); - kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x36 * 4)), (unsigned int)KernelPatches); - kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x36 * 4)), (unsigned int)KernelPatches); - kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x36 * 4)), (unsigned int)KernelPatches); - kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x36 * 4)), (unsigned int)KernelPatches); - kern_write((void*)(KERN_SYSCALL_TBL_5 + (0x36 * 4)), (unsigned int)KernelPatches); + kern_write((void *) (KERN_SYSCALL_TBL_1 + (0x36 * 4)), (unsigned int) KernelPatches); + kern_write((void *) (KERN_SYSCALL_TBL_2 + (0x36 * 4)), (unsigned int) KernelPatches); + kern_write((void *) (KERN_SYSCALL_TBL_3 + (0x36 * 4)), (unsigned int) KernelPatches); + kern_write((void *) (KERN_SYSCALL_TBL_4 + (0x36 * 4)), (unsigned int) KernelPatches); + kern_write((void *) (KERN_SYSCALL_TBL_5 + (0x36 * 4)), (unsigned int) KernelPatches); Syscall_0x36(); @@ -190,11 +235,11 @@ int _start(int argc, char **argv) { InstallPatches(&private_data); - unsigned char * pElfBuffer = (unsigned char *) sd_loader; // use this address as temporary to load the elf + unsigned char *pElfBuffer = (unsigned char *) sd_loader; // use this address as temporary to load the elf unsigned int mainEntryPoint = load_elf_image(&private_data, pElfBuffer); - if(mainEntryPoint == 0) { + if (mainEntryPoint == 0) { OSFatal("failed to load elf"); } @@ -203,14 +248,41 @@ int _start(int argc, char **argv) { unsigned int jump_addr = mainEntryPoint & 0x03fffffc; unsigned int bufferU32 = 0x48000003 | jump_addr; - KernelWriteU32(repl_addr,bufferU32,&private_data); + KernelWriteU32(repl_addr, bufferU32, &private_data); + + InitFunctionPointers(); + + if ( + OSGetTitleID() == 0x000500101004A200L || // mii maker eur + OSGetTitleID() == 0x000500101004A100L || // mii maker usa + OSGetTitleID() == 0x000500101004A000L) { // mii maker jpn + + // restart mii maker. + private_data.SYSRelaunchTitle(0, 0); + private_data.exit(0); + } else { + ProcUIInit(OSSavesDone_ReadyToRelease); + for (int i = 0; i < argc; i++) { + if(strcmp(argv[i], "void forceDefaultTitleIDToWiiUMenu(void)") == 0){ + if((i + 1) < argc){ + i++; + void (*forceDefaultTitleIDToWiiUMenu)(void) = (void (*)(void)) argv[i]; + forceDefaultTitleIDToWiiUMenu(); + } + } + } + SYSLaunchMenu(); + + while (CheckRunning()) { + // wait. + OSSleepTicks(OSMillisecondsToTicks(100)); + } + ProcUIShutdown(); + + return 0; + } - // restart mii maker. - private_data.SYSRelaunchTitle(0, 0); - private_data.exit(0); return 0; - - //return ((int (*)(int, char **))mainEntryPoint)(argc, argv); } /* Write a 32-bit word with kernel permissions */ diff --git a/src/import_stub.S b/src/import_stub.S new file mode 100644 index 0000000..7bf8dc7 --- /dev/null +++ b/src/import_stub.S @@ -0,0 +1,24 @@ +/*#define IMPORT(name) \ + .global name; \ + name: \ + lis %r11, addr_##name@h; \ + lwz %r11, addr_##name@l(%r11); \ + mtctr %r11; \ + bctr*/ + +#define IMPORT(name) \ + .global name; \ + name: \ + lis %r11, addr_##name@h; \ + ori %r11, %r11, addr_##name@l; \ + lwz %r11, 0(%r11); \ + mtctr %r11; \ + bctr + +#define IMPORT_BEGIN(lib) +#define IMPORT_END() + +.align 2; +.section ".text"; + +#include "imports.h" \ No newline at end of file diff --git a/src/imports.h b/src/imports.h new file mode 100644 index 0000000..dc392a5 --- /dev/null +++ b/src/imports.h @@ -0,0 +1,294 @@ +/* coreinit */ +IMPORT_BEGIN(coreinit); + +IMPORT(OSScreenInit); +IMPORT(OSScreenGetBufferSizeEx); +IMPORT(OSScreenSetBufferEx); +IMPORT(OSScreenEnableEx); +IMPORT(OSScreenFlipBuffersEx); +IMPORT(OSScreenClearBufferEx); +IMPORT(OSScreenPutFontEx); +IMPORT(OSFatal); +IMPORT(OSDynLoad_Acquire); +IMPORT(OSDynLoad_FindExport); +IMPORT(OSDynLoad_Release); +IMPORT(OSSetExceptionCallback); +IMPORT(OSSavesDone_ReadyToRelease); +IMPORT(OSInitMutex); +IMPORT(OSLockMutex); +IMPORT(OSUnlockMutex); +IMPORT(OSInitCond); +IMPORT(OSWaitCond); +IMPORT(OSSignalCond); +IMPORT(OSInitSpinLock); +IMPORT(OSUninterruptibleSpinLock_Acquire); +IMPORT(OSUninterruptibleSpinLock_Release); +IMPORT(OSFastMutex_Init); +IMPORT(OSFastMutex_Lock); +IMPORT(OSFastMutex_Unlock); +IMPORT(OSSleepTicks); +IMPORT(OSGetTitleID); +IMPORT(OSIsThreadTerminated); +IMPORT(OSSetThreadPriority); +IMPORT(OSCreateThread); +IMPORT(OSSetThreadCleanupCallback); +IMPORT(OSResumeThread); +IMPORT(OSIsThreadSuspended); +IMPORT(OSSuspendThread); +IMPORT(OSGetCurrentThread); +IMPORT(OSExitThread); +IMPORT(OSJoinThread); +IMPORT(OSYieldThread); +IMPORT(OSGetCoreId); +IMPORT(OSIsMainCore); +IMPORT(OSGetSystemTime); +IMPORT(OSGetSystemTick); +IMPORT(OSGetTime); +IMPORT(OSGetSymbolName); +IMPORT(OSGetSharedData); +IMPORT(OSEffectiveToPhysical); +IMPORT(OSInitSemaphore); +IMPORT(OSInitSemaphoreEx); +IMPORT(OSGetSemaphoreCount); +IMPORT(OSSignalSemaphore); +IMPORT(OSWaitSemaphore); +IMPORT(OSTryWaitSemaphore); +IMPORT(OSCompareAndSwapAtomicEx); +IMPORT(OSCompareAndSwapAtomic); +IMPORT(OSGetThreadSpecific); +IMPORT(OSSetThreadSpecific); + +IMPORT(exit); +IMPORT(_Exit); +IMPORT(__os_snprintf); +IMPORT(DisassemblePPCRange); + +IMPORT(ICInvalidateRange); +IMPORT(DCInvalidateRange); +IMPORT(DCFlushRange); +IMPORT(DCStoreRange); +IMPORT(DCStoreRangeNoSync); + +IMPORT(__gh_errno_ptr); + +IMPORT(MEMGetBaseHeapHandle); +IMPORT(MEMCreateExpHeapEx); +IMPORT(MEMDestroyExpHeap); +IMPORT(MEMAllocFromExpHeapEx); +IMPORT(MEMFreeToExpHeap); +IMPORT(MEMGetSizeForMBlockExpHeap); +IMPORT(MEMAllocFromFrmHeapEx); +IMPORT(MEMFreeToFrmHeap); +IMPORT(MEMGetAllocatableSizeForFrmHeapEx); + +IMPORT(FSInit); +IMPORT(FSShutdown); +IMPORT(FSAddClient); +IMPORT(FSAddClientEx); +IMPORT(FSDelClient); +IMPORT(FSInitCmdBlock); +IMPORT(FSChangeDir); +IMPORT(FSGetFreeSpaceSize); +IMPORT(FSGetStat); +IMPORT(FSRemove); +IMPORT(FSOpenFile); +IMPORT(FSCloseFile); +IMPORT(FSOpenDir); +IMPORT(FSMakeDir); +IMPORT(FSReadDir); +IMPORT(FSRewindDir); +IMPORT(FSCloseDir); +IMPORT(FSGetStatFile); +IMPORT(FSReadFile); +IMPORT(FSWriteFile); +IMPORT(FSSetPosFile); +IMPORT(FSFlushFile); +IMPORT(FSTruncateFile); +IMPORT(FSRename); +IMPORT(FSGetMountSource); +IMPORT(FSMount); +IMPORT(FSUnmount); +IMPORT(FSChangeMode); +IMPORT(FSGetPosFile); +IMPORT(OSTicksToCalendarTime); +IMPORT(__rplwrap_exit); + +IMPORT(IOS_Open); +IMPORT(IOS_Close); +IMPORT(IOS_Ioctl); +IMPORT(IOS_IoctlAsync); + +IMPORT(IMIsAPDEnabled); +IMPORT(IMIsDimEnabled); +IMPORT(IMEnableAPD); +IMPORT(IMEnableDim); +IMPORT(IMDisableAPD); +IMPORT(IMDisableDim); + +IMPORT(OSGetSystemInfo); + +IMPORT_END(); + +/* nsysnet */ +IMPORT_BEGIN(nsysnet); + +IMPORT(socket_lib_init); +IMPORT(getaddrinfo); +IMPORT(freeaddrinfo); +IMPORT(getnameinfo); +IMPORT(inet_ntoa); +IMPORT(inet_ntop); +IMPORT(inet_aton); +IMPORT(inet_pton); +IMPORT(ntohl); +IMPORT(ntohs); +IMPORT(htonl); +IMPORT(htons); +IMPORT(accept); +IMPORT(bind); +IMPORT(socketclose); +IMPORT(connect); +IMPORT(getpeername); +IMPORT(getsockname); +IMPORT(getsockopt); +IMPORT(listen); +IMPORT(recv); +IMPORT(recvfrom); +IMPORT(send); +IMPORT(sendto); +IMPORT(setsockopt); +IMPORT(shutdown); +IMPORT(socket); +IMPORT(select); +IMPORT(socketlasterr); + +IMPORT_END(); + +/* gx2 */ +IMPORT_BEGIN(gx2); + +IMPORT(GX2Invalidate); +IMPORT(GX2Init); +IMPORT(GX2GetSystemTVScanMode); +IMPORT(GX2CalcTVSize); +IMPORT(GX2SetTVBuffer); +IMPORT(GX2CalcDRCSize); +IMPORT(GX2SetDRCBuffer); +IMPORT(GX2CalcSurfaceSizeAndAlignment); +IMPORT(GX2InitColorBufferRegs); +IMPORT(GX2SetupContextStateEx); +IMPORT(GX2SetContextState); +IMPORT(GX2SetColorBuffer); +IMPORT(GX2SetViewport); +IMPORT(GX2SetScissor); +IMPORT(GX2SetDepthOnlyControl); +IMPORT(GX2SetColorControl); +IMPORT(GX2SetBlendControl); +IMPORT(GX2SetBlendConstantColor); +IMPORT(GX2SetCullOnlyControl); +IMPORT(GX2CalcFetchShaderSizeEx); +IMPORT(GX2InitFetchShaderEx); +IMPORT(GX2SetFetchShader); +IMPORT(GX2SetVertexShader); +IMPORT(GX2SetPixelShader); +IMPORT(GX2SetGeometryShader); +IMPORT(GX2SetGeometryUniformBlock); +IMPORT(GX2SetVertexUniformBlock); +IMPORT(GX2SetPixelUniformBlock); +IMPORT(GX2CalcGeometryShaderInputRingBufferSize); +IMPORT(GX2CalcGeometryShaderOutputRingBufferSize); +IMPORT(GX2SetGeometryShaderInputRingBuffer); +IMPORT(GX2SetGeometryShaderOutputRingBuffer); +IMPORT(GX2SetShaderModeEx); +IMPORT(GX2SetAttribBuffer); +IMPORT(GX2InitTextureRegs); +IMPORT(GX2InitSampler); +IMPORT(GX2SetPixelTexture); +IMPORT(GX2SetPixelSampler); +IMPORT(GX2ClearColor); +IMPORT(GX2CopyColorBufferToScanBuffer); +IMPORT(GX2SwapScanBuffers); +IMPORT(GX2Flush); +IMPORT(GX2WaitForVsync); +IMPORT(GX2SetTVEnable); +IMPORT(GX2SetDRCEnable); +IMPORT(GX2SetSwapInterval); +IMPORT(GX2DrawDone); +IMPORT(GX2Shutdown); +IMPORT(GX2DrawEx); +IMPORT(GX2WaitForFlip); +IMPORT(GX2GetSwapStatus); + +IMPORT_END(); + +/* nn_ac */ +IMPORT_BEGIN(nn_ac); +IMPORT(ACInitialize); +IMPORT(ACFinalize); +IMPORT(ACConnect); +IMPORT(ACClose); +IMPORT(ACGetAssignedAddress); +IMPORT(ACGetAssignedSubnet); +IMPORT(Initialize__Q2_2nn3actFv); +IMPORT(GetSlotNo__Q2_2nn3actFv); +IMPORT(GetDefaultAccount__Q2_2nn3actFv); +IMPORT(Finalize__Q2_2nn3actFv); +IMPORT_END(); + +/* proc_ui */ +IMPORT_BEGIN(proc_ui); + +IMPORT(ProcUIInit); +IMPORT(ProcUIShutdown); +IMPORT(ProcUIDrawDoneRelease); +IMPORT(ProcUIProcessMessages); + +IMPORT_END(); + +/* sndcore2 */ +IMPORT_BEGIN(sndcore2); + +IMPORT(AXInitWithParams); +IMPORT(AXQuit); +IMPORT(AXRegisterFrameCallback); +IMPORT(AXAcquireMultiVoice); +IMPORT(AXSetMultiVoiceDeviceMix); +IMPORT(AXSetMultiVoiceOffsets); +IMPORT(AXSetMultiVoiceCurrentOffset); +IMPORT(AXSetMultiVoiceState); +IMPORT(AXSetMultiVoiceVe); +IMPORT(AXSetMultiVoiceSrcType); +IMPORT(AXSetMultiVoiceSrcRatio); +IMPORT(AXIsMultiVoiceRunning); +IMPORT(AXFreeMultiVoice); + +IMPORT_END(); + +/* sysapp */ +IMPORT_BEGIN(sysapp); + +IMPORT(SYSRelaunchTitle); +IMPORT(_SYSGetSystemApplicationTitleId); +IMPORT(SYSLaunchMenu); +IMPORT(_SYSLaunchMenuWithCheckingAccount); + +IMPORT_END(); + +/* vpad */ +IMPORT_BEGIN(vpad); + +IMPORT(VPADRead); +IMPORT(VPADInit); +IMPORT(VPADGetTPCalibratedPoint); + +IMPORT_END(); + + +/* nsyskbd */ +IMPORT_BEGIN(zlib125); + +IMPORT(inflateInit_); +IMPORT(inflate); +IMPORT(inflateEnd); + +IMPORT_END(); diff --git a/src/link.ld b/src/link.ld index 385a69d..32dafd5 100644 --- a/src/link.ld +++ b/src/link.ld @@ -4,14 +4,20 @@ ENTRY(_start); SECTIONS { . = 0x00840000; - .text : { + .text : { + *(.kernel_code*); *(.text*); - } + /* Tell linker to not garbage collect this section as it is not referenced anywhere */ + KEEP(*(.kernel_code*)); + } .data : { *(.rodata*); *(.data*); + *(.sdata*); *(.bss*); + *(.sbss*); } + __CODE_END = .; /DISCARD/ : { *(*); }