diff --git a/.travis.yml b/.travis.yml index 5d07d5a..e47af6c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ dist: trusty env: global: - DEVKITPRO=/opt/devkitpro + - WUT_ROOT=/opt/devkitpro/wut - DEVKITPPC=/opt/devkitpro/devkitPPC - DEVKITARM=/opt/devkitpro/devkitARM - PORTLIBREPOS=$HOME/portlibrepos @@ -31,8 +32,10 @@ before_install: - yes | sudo dkp-pacman -Syu devkitPPC --needed - yes | sudo dkp-pacman -Syu devkitARM --needed - yes | sudo dkp-pacman -Syu general-tools --needed + - wget $(curl -s https://api.github.com/repos/decaf-emu/wut/releases/latest | grep 'browser_' | grep 'linux' | cut -d\" -f4) install: + - 7z x -y $(ls | grep "linux") -o${WUT_ROOT} - cd $PORTLIBREPOS - ((git clone https://github.com/Maschell/dynamic_libs.git -b lib && (7z x -y ./dynamic_libs/libs/portlibs.zip -o${DEVKITPRO})) || (cd dynamic_libs && git pull)) - (git clone https://github.com/dimok789/libiosuhax.git || (cd libiosuhax && git pull)) diff --git a/Makefile b/Makefile index c693c55..4027a67 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,10 @@ ifeq ($(strip $(DEVKITPPC)),) $(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC) endif +ifeq ($(strip $(WUT_ROOT)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC) +endif + export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) export PORTLIBS := $(DEVKITPRO)/portlibs/ppc @@ -60,7 +64,7 @@ LIBS := # list of directories containing libraries, this must be the top level containing # include and lib #--------------------------------------------------------------------------------- -LIBDIRS := +LIBDIRS := $(WUT_ROOT) #--------------------------------------------------------------------------------- # no real need to edit anything past this point unless you need to add additional diff --git a/README.MD b/README.MD index 73a8bbd..17f5f16 100644 --- a/README.MD +++ b/README.MD @@ -46,6 +46,7 @@ For building the loader you need: - [dynamic_libs](https://github.com/Maschell/dynamic_libs/tree/lib) for access to the functions. - [libutils](https://github.com/Maschell/libutils) for common functions. - [libgui](https://github.com/Maschell/libgui) for the gui elements. +- [wut] (https://github.com/decaf-emu/wut) for the wut support. Install the according to their readmes. Don't forget to install their dependencies. diff --git a/ide_templates/codeblocks/Makefile b/ide_templates/codeblocks/Makefile index 335d161..f52cd9e 100644 --- a/ide_templates/codeblocks/Makefile +++ b/ide_templates/codeblocks/Makefile @@ -12,6 +12,10 @@ endif ifeq ($(strip $(DEVKITPRO)),) $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") endif +ifeq ($(strip $(WUT_ROOT)),) +$(error "Please set WUT_ROOT in your environment. export WUT_ROOT=wut) +endif + export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) export PORTLIBS := $(DEVKITPRO)/portlibs/ppc export WUPSDIR := $(DEVKITPRO)/wups @@ -57,13 +61,12 @@ include $(WUPSDIR)/plugin_makefile.mk # -mcpu=750: enable processor specific compilation # -meabi: enable eabi specific compilation # -mhard-float: enable hardware floating point instructions -# -fshort-wchar: use 16 bit whcar_t type in keeping with Wii executables # -fno-common: stop common variables which the loader can't understand # -msdata-none: do not use r2 or r13 as small data areas # -memb: enable embedded application specific compilation # -ffunction-sections: split up functions so linker can garbage collect # -fdata-sections: split up data so linker can garbage collect -COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar -fno-common -msdata=none -memb -ffunction-sections -fdata-sections +COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fno-common -msdata=none -memb -ffunction-sections -fdata-sections # -x c: compile as c code @@ -81,7 +84,12 @@ endif ASFLAGS += -LDFLAG_COMMON += +LDFLAG_COMMON += + +ifeq ($(WRAP_MALLOC), 1) + LDFLAG_COMMON += -Wl,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r +endif + LDFLAGS_MOD += $(LD_FLAGS_MOD) LDFLAGS_ELF += $(LD_FLAGS_ELF) @@ -98,7 +106,7 @@ ALL_LIBS := $(LIBS) # list of directories containing libraries, this must be the top level containing # include and lib #--------------------------------------------------------------------------------- -LIBDIRS += +LIBDIRS += $(WUT_ROOT) #--------------------------------------------------------------------------------- # no real need to edit anything past this point unless you need to add additional @@ -183,7 +191,7 @@ $(OUTPUT) : output.elf @echo "checking for missing symbols ..." @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LD_FLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o check_linking.elf @echo "linking ..." $@ - @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ + @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ # Rule to make the module file. output.elf : $(OFILES) diff --git a/ide_templates/codeblocks/makefile.mk b/ide_templates/codeblocks/makefile.mk index c1d5cfd..f2e0000 100644 --- a/ide_templates/codeblocks/makefile.mk +++ b/ide_templates/codeblocks/makefile.mk @@ -1,6 +1,9 @@ # Compiling the projects with libutils logging code? DO_LOGGING := 1 +# Non WUT plugins need to wrap the malloc functions. +WRAP_MALLOC := 1 + # Target filename TARGET := $(notdir $(CURDIR)).mod diff --git a/loader/Makefile b/loader/Makefile index 1f990ec..ec80834 100644 --- a/loader/Makefile +++ b/loader/Makefile @@ -11,6 +11,10 @@ endif ifeq ($(strip $(DEVKITPRO)),) $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") endif +ifeq ($(strip $(WUT_ROOT)),) +$(error "Please set WUT_ROOT in your environment. export WUT_ROOT=wut) +endif + export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH):$(DEVKITPRO)/tools/bin export PORTLIBS := $(DEVKITPRO)/portlibs/ppc @@ -84,7 +88,7 @@ LIBS := -lgui -lm -lgcc -lfat -lntfs -liosuhax -lutils -ldynamiclibs -lfreetype LIBDIRS := $(CURDIR) \ $(DEVKITPPC)/lib \ $(DEVKITPRO)/wups \ - $(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2 + $(WUT_ROOT) \ #--------------------------------------------------------------------------------- diff --git a/loader/src/common/retain_vars.cpp b/loader/src/common/retain_vars.cpp index 658922e..3541a88 100644 --- a/loader/src/common/retain_vars.cpp +++ b/loader/src/common/retain_vars.cpp @@ -1,6 +1,8 @@ #include "retain_vars.h" #include "myutils/overlay_helper.h" replacement_data_t gbl_replacement_data __attribute__((section(".data"))); +dyn_linking_relocation_data_t gbl_dyn_linking_data __attribute__((section(".data"))); + u8 gAppStatus __attribute__((section(".data"))) = 0; u64 gGameTitleID __attribute__((section(".data"))) = 0; volatile u8 gSDInitDone __attribute__((section(".data"))) = 0; diff --git a/loader/src/common/retain_vars.h b/loader/src/common/retain_vars.h index 47d1f90..cf71dc9 100644 --- a/loader/src/common/retain_vars.h +++ b/loader/src/common/retain_vars.h @@ -1,8 +1,11 @@ #ifndef RETAINS_VARS_H_ #define RETAINS_VARS_H_ #include "patcher/function_patcher.h" +#include "plugin/dynamic_linking_defines.h" extern replacement_data_t gbl_replacement_data; +extern dyn_linking_relocation_data_t gbl_dyn_linking_data; + extern u8 gAppStatus; extern u64 gGameTitleID; extern volatile u8 gSDInitDone; diff --git a/loader/src/main.cpp b/loader/src/main.cpp index abe94eb..0375cd4 100644 --- a/loader/src/main.cpp +++ b/loader/src/main.cpp @@ -40,6 +40,7 @@ #include "common/common.h" #include "plugin/PluginLoader.h" #include "plugin/PluginInformation.h" +#include "plugin/DynamicLinkingHelper.h" #include #include @@ -51,6 +52,7 @@ #include "Application.h" #include "patcher/function_patcher.h" #include "patcher/hooks_patcher.h" +#include "plugin/dynamic_linking_defines.h" #include "myutils/mocha.h" #include "myutils/libntfs.h" #include "myutils/libfat.h" @@ -87,6 +89,7 @@ extern "C" int Menu_Main(int argc, char **argv) { setup_os_exceptions(); DEBUG_FUNCTION_LINE("Wii U Plugin System Loader %s\n",APP_VERSION); + DEBUG_FUNCTION_LINE("Sizeof dyn_linking_relocation_data_t %d\n",sizeof(dyn_linking_relocation_data_t)); Init(); init_kernel_syscalls(); @@ -101,6 +104,9 @@ extern "C" int Menu_Main(int argc, char **argv) { CallHook(WUPS_LOADER_HOOK_DEINIT_PLUGIN); // Restore patches as the patched functions could change. RestorePatches(); + + DynamicLinkingHelper::getInstance()->clearAll(); + PluginLoader * pluginLoader = PluginLoader::getInstance(); std::vector pluginList = pluginLoader->getPluginInformation("sd:/wiiu/plugins/"); pluginLoader->loadAndLinkPlugins(pluginList); @@ -130,11 +136,18 @@ extern "C" int Menu_Main(int argc, char **argv) { } } + DEBUG_FUNCTION_LINE("Do relocations\n"); + + std::vector relocations = DynamicLinkingHelper::getInstance()->getAllValidDynamicLinkingRelocations(); + DEBUG_FUNCTION_LINE("Found relocation information for %d functions\n",relocations.size()) ; + DynamicLinkingHelper::getInstance()->fillRelocations(relocations); + if(!isInMiiMakerHBL()) { DEBUG_FUNCTION_LINE("Apply patches.\n"); ApplyPatchesAndCallHookStartingApp(); + if(MemoryMapping::isMemoryMapped()) { DEBUG_FUNCTION_LINE("Mapping was already done. Running %016llX\n",gGameTitleID); readAndPrintSegmentRegister(NULL,NULL); diff --git a/loader/src/patcher/hooks_patcher.cpp b/loader/src/patcher/hooks_patcher.cpp index 15bb357..78adce8 100644 --- a/loader/src/patcher/hooks_patcher.cpp +++ b/loader/src/patcher/hooks_patcher.cpp @@ -10,11 +10,11 @@ DECL(void, __PPCExit, void) { // Only continue if we are in the "right" application. - if(OSGetTitleID() == gGameTitleID) { - DEBUG_FUNCTION_LINE("__PPCExit\n"); - CallHook(WUPS_LOADER_HOOK_ENDING_APPLICATION); - DeInit(); - } + //if(OSGetTitleID() == gGameTitleID) { + //DEBUG_FUNCTION_LINE("__PPCExit\n"); + //CallHook(WUPS_LOADER_HOOK_ENDING_APPLICATION); + //DeInit(); + //} real___PPCExit(); } @@ -26,6 +26,10 @@ DECL(u32, ProcUIProcessMessages, u32 u) { DEBUG_FUNCTION_LINE("App status changed from %d to %d \n",gAppStatus,res); gAppStatus = res; CallHook(WUPS_LOADER_HOOK_APP_STATUS_CHANGED); + if(gAppStatus == WUPS_APP_STATUS_CLOSED) { + CallHook(WUPS_LOADER_HOOK_ENDING_APPLICATION); + DeInit(); + } } return res; @@ -63,7 +67,7 @@ DECL(int, VPADRead, int chan, VPADData *buffer, u32 buffer_size, s32 *error) { if(result > 0 && (buffer[0].btns_h == (VPAD_BUTTON_PLUS | VPAD_BUTTON_R | VPAD_BUTTON_L)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) { if(MemoryMapping::isMemoryMapped()) { MemoryMapping::readTestValuesFromMemory(); - }else{ + } else { DEBUG_FUNCTION_LINE("Memory was not mapped. To test the memory please exit the plugin loader by pressing MINUS\n"); } vpadPressCooldown = 0x3C; diff --git a/loader/src/plugin/DynamicLinkingHelper.cpp b/loader/src/plugin/DynamicLinkingHelper.cpp new file mode 100644 index 0000000..f31015a --- /dev/null +++ b/loader/src/plugin/DynamicLinkingHelper.cpp @@ -0,0 +1,170 @@ +#include "DynamicLinkingHelper.h" +#include +#include +#include +#include "utils/logger.h" +#include "ElfTools.h" +#include "PluginLoader.h" + +DynamicLinkingHelper * DynamicLinkingHelper::instance = NULL; + +dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(const char* functionName) { + if(functionName == NULL) { + return NULL; + } + dyn_linking_function_t * result = NULL; + for(int i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) { + dyn_linking_function_t * curEntry = &gbl_dyn_linking_data.functions[i]; + if(strlen(curEntry->functionName) == 0) { + strncpy(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH); + result = curEntry; + break; + } + if(strncmp(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH) == 0) { + result = curEntry; + break; + } + } + return result; +} + +dyn_linking_import_t * DynamicLinkingHelper::getOrAddFunctionImportByName(const char* importName) { + return getOrAddImport(importName, false); + +} + +dyn_linking_import_t * DynamicLinkingHelper::getOrAddDataImportByName(const char* importName) { + return getOrAddImport(importName, true); + +} + +dyn_linking_import_t * DynamicLinkingHelper::getOrAddImport(const char* importName, bool isData) { + if(importName == NULL) { + return NULL; + } + dyn_linking_import_t * result = NULL; + for(int i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) { + dyn_linking_import_t * curEntry = &gbl_dyn_linking_data.imports[i]; + if(strlen(curEntry->importName) == 0) { + strncpy(curEntry->importName,importName,DYN_LINK_IMPORT_NAME_LENGTH); + curEntry->isData = isData; + result = curEntry; + break; + } + if(strncmp(curEntry->importName,importName,DYN_LINK_IMPORT_NAME_LENGTH) == 0 && (curEntry->isData == isData)) { + return curEntry; + } + } + return result; +} + +bool DynamicLinkingHelper::addReloationEntry(RelocationData * relocationData){ + return addReloationEntry(relocationData->getType(), relocationData->getOffset(), relocationData->getAddend(), relocationData->getDestination(), relocationData->getName(), relocationData->getImportRPLInformation()); +} + +bool DynamicLinkingHelper::addReloationEntry(char type, size_t offset, int addend, void *destination, std::string name, ImportRPLInformation * rplInfo){ + dyn_linking_import_t * importInfoGbl = DynamicLinkingHelper::getOrAddImport(rplInfo->getName().c_str(),rplInfo->isData()); + if(importInfoGbl == NULL){ + DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d rpl files to import reached.\n",DYN_LINK_IMPORT_LIST_LENGTH); + return false; + } + + dyn_linking_function_t * functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(name.c_str()); + if(functionInfo == NULL){ + DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d function to be relocated reached.\n",DYN_LINK_FUNCTION_LIST_LENGTH); + return false; + } + + return addReloationEntry(type, offset, addend, destination, functionInfo, importInfoGbl); +} + +bool DynamicLinkingHelper::addReloationEntry(char type, size_t offset, int addend, void *destination, dyn_linking_function_t * functionName, dyn_linking_import_t * importInfo){ + for(int i = 0; i < DYN_LINK_RELOCATION_LIST_LENGTH; i++) { + dyn_linking_relocation_entry_t * curEntry = &gbl_dyn_linking_data.entries[i]; + if(curEntry->functionEntry != NULL) { + continue; + } + curEntry->type = type; + curEntry->offset = offset; + curEntry->addend = addend; + curEntry->destination = destination; + curEntry->functionEntry = functionName; + curEntry->importEntry = importInfo; + + return true; + } + return false; +} + +std::vector DynamicLinkingHelper::getAllValidDynamicLinkingRelocations() { + std::vector result; + for(int i = 0; i < DYN_LINK_RELOCATION_LIST_LENGTH; i++) { + if(gbl_dyn_linking_data.entries[i].functionEntry == NULL) { + break; + } + result.push_back(&gbl_dyn_linking_data.entries[i]); + } + return result; +} + +bool DynamicLinkingHelper::fillRelocations(std::vector entries ) { + for(size_t i = 0; i < entries.size(); i++) { + dyn_linking_relocation_entry_t * curEntry = entries[i]; + dyn_linking_function_t * functionEntry = curEntry->functionEntry; + void * destination = curEntry->destination; + if(functionEntry == NULL) { + DEBUG_FUNCTION_LINE("FunctionEntry was NULL\n"); + return false; + } + if(destination == NULL) { + DEBUG_FUNCTION_LINE("destination was NULL\n"); + return false; + } + if(functionEntry->address == NULL) { + dyn_linking_import_t * importEntry = curEntry->importEntry; + + if(importEntry == NULL) { + DEBUG_FUNCTION_LINE("importEntry was NULL\n"); + return false; + } + + if(importEntry->handle != 0) { + //DEBUG_FUNCTION_LINE("We cached import handle for %s\n",importEntry->importName); + } else { + OSDynLoad_Acquire(importEntry->importName, &importEntry->handle); + } + int isData = 0; + if(importEntry->isData) { + isData = 1; + //DEBUG_FUNCTION_LINE("isData\n"); + } + OSDynLoad_FindExport(importEntry->handle, isData, functionEntry->functionName, &functionEntry->address); + + if(!functionEntry->address) { + DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s on import %s\n", functionEntry->functionName,importEntry->importName); + return false; + }else{ + //DEBUG_FUNCTION_LINE("OSDynLoad_FindExport successful for %s on import %s: %08X\n",functionEntry->functionName,importEntry->importName,functionEntry->address); + } + } else { + //DEBUG_FUNCTION_LINE("We cached the address of function %s :%08X\n",functionEntry->functionName,functionEntry->address); + } + //DEBUG_FUNCTION_LINE("We would link now: type: %02X offset: %08X addend: %d destination: %08X target: %08X for %s\n",curEntry->type, curEntry->offset, curEntry->addend, curEntry->destination, functionEntry->address,functionEntry->functionName); + DEBUG_FUNCTION_LINE("Resolving relocation to %s\n",functionEntry->functionName); + ElfTools::elfLinkOne(curEntry->type, curEntry->offset, curEntry->addend, curEntry->destination, (u32) functionEntry->address); + } + + PluginLoader::flushCache(); + + DEBUG_FUNCTION_LINE("Clearing cache.\n"); + for(size_t i = 0; i < entries.size(); i++) { + dyn_linking_relocation_entry_t * curEntry = entries[i]; + curEntry->functionEntry->address = 0; + curEntry->importEntry->handle = 0; + } + return true; +} + +void DynamicLinkingHelper::clearAll() { + memset((void*)&gbl_dyn_linking_data,0,sizeof(gbl_dyn_linking_data)); +} diff --git a/loader/src/plugin/DynamicLinkingHelper.h b/loader/src/plugin/DynamicLinkingHelper.h new file mode 100644 index 0000000..0cf485b --- /dev/null +++ b/loader/src/plugin/DynamicLinkingHelper.h @@ -0,0 +1,94 @@ +#ifndef DYNAMICLINKINGHELPER_H +#define DYNAMICLINKINGHELPER_H + +#include "common/retain_vars.h" +#include "dynamic_linking_defines.h" +#include "utils/logger.h" +#include +#include +#include "RelocationData.h" + +class DynamicLinkingHelper { +public: + static DynamicLinkingHelper *getInstance() { + if(!instance) { + instance = new DynamicLinkingHelper(); + } + return instance; + } + + static void destroyInstance() { + if(instance) { + delete instance; + instance = NULL; + } + } + + + /** + Gets the function entry for a given function name. If the function name is not present in the list, it will be added. + + \param functionName Name of the function + \return Returns a pointer to the entry which contains the functionName. Null on error or if the list full. + **/ + dyn_linking_function_t * getOrAddFunctionEntryByName(const char * functionName); + + /** + Gets the function import entry for a given function name. If the import is not present in the list, it will be added. + This will return entries for _function_ imports. + + \param importName Name of the function + \return Returns a pointer to the function import entry which contains the importName. Null on error or if the list full. + **/ + dyn_linking_import_t * getOrAddFunctionImportByName(const char * importName); + + + /** + Gets the data import entry for a given data name. If the import is not present in the list, it will be added. + This will return entries for _data_ imports. + + \param importName Name of the data + \return Returns a pointer to the data import entry which contains the importName. Null on error or if the list full. + **/ + dyn_linking_import_t * getOrAddDataImportByName(const char * importName); + + + /** + Gets the import entry for a given data name and type. If the import is not present in the list, it will be added. + This will return entries for _data_ and _function_ imports, depending on the isData parameter. + + \param importName Name of the data + \param isData Set this to true to return a data import + + \return Returns a pointer to the data import entry which contains the importName. Null on error or if the list full. + **/ + dyn_linking_import_t * getOrAddImport(const char * importName, bool isData); + + + bool addReloationEntry(RelocationData * relocationData); + + bool addReloationEntry(char type, size_t offset, int addend, void *destination, std::string name, ImportRPLInformation * rplInfo); + + bool addReloationEntry(char type, size_t offset, int addend, void *destination, dyn_linking_function_t * functionName, dyn_linking_import_t * importInfo); + + std::vector getAllValidDynamicLinkingRelocations(); + + bool fillRelocations(std::vector entries ); + + void clearAll(); + + +protected: +private: + + DynamicLinkingHelper() { + } + + ~DynamicLinkingHelper() { + + } + + static DynamicLinkingHelper *instance; + }; + +#endif // DYNAMICLINKINGHELPER_H diff --git a/loader/src/plugin/ElfTools.cpp b/loader/src/plugin/ElfTools.cpp index 91c9ffe..dbd65de 100644 --- a/loader/src/plugin/ElfTools.cpp +++ b/loader/src/plugin/ElfTools.cpp @@ -24,6 +24,8 @@ */ #include "ElfTools.h" +#include "RelocationData.h" +#include "ImportRPLInformation.h" #include #include #include @@ -122,7 +124,7 @@ void ElfTools::elfLoadSymbols(size_t shndx, const void *destination, Elf32_Sym * } -bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *symtab, size_t symtab_count, size_t symtab_strndx, bool allow_globals) { +bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *symtab, size_t symtab_count, size_t symtab_strndx, bool allow_globals, PluginData * pluginData) { Elf_Scn *scn; for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) { @@ -155,8 +157,10 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym symbol = ELF32_R_SYM(rel[i].r_info); - if (symbol > symtab_count) + if (symbol > symtab_count) { + DEBUG_FUNCTION_LINE("symbol > symtab_count\n"); return false; + } switch (symtab[symbol].st_shndx) { case SHN_ABS: { @@ -164,6 +168,7 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym break; } case SHN_COMMON: { + DEBUG_FUNCTION_LINE("case SHN_COMMON\n"); return false; } case SHN_UNDEF: { @@ -209,11 +214,14 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym */ return false; } else { + DEBUG_FUNCTION_LINE("case SHN_UNDEF with !allow_globals\n"); return false; } } default: { if (symtab[symbol].st_other != 1) { + + DEBUG_FUNCTION_LINE("symtab[symbol].st_other != 1. it's %d %08X\n",symtab[symbol].st_other,symtab[symbol].st_other); return false; } @@ -223,6 +231,7 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym } if (!ElfTools::elfLinkOne(ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, *(int *)((char *)destination + rel[i].r_offset), destination, symbol_addr)) { + DEBUG_FUNCTION_LINE("elfLinkOne failed\n"); return false; } } @@ -248,8 +257,10 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym symbol = ELF32_R_SYM(rela[i].r_info); - if (symbol > symtab_count) + if (symbol > symtab_count) { + DEBUG_FUNCTION_LINE("symbol > symtab_count\n"); return false; + } switch (symtab[symbol].st_shndx) { case SHN_ABS: { @@ -257,12 +268,19 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym break; } case SHN_COMMON: { + DEBUG_FUNCTION_LINE("case SHN_COMMON\n"); return false; } case SHN_UNDEF: { if (allow_globals) { - DEBUG_FUNCTION_LINE("The elf still have unresolved relocations. This is not supported."); + char *name = elf_strptr(elf, symtab_strndx, symtab[symbol].st_name); + DEBUG_FUNCTION_LINE("The elf still have unresolved relocations. This is not supported: %s \n",name); + /* + + char *name = elf_strptr(elf, symtab_strndx, symtab[symbol].st_name); + DEBUG_FUNCTION_LINE("%s %08X\n",name,symtab[symbol].st_value); + Not support and not needed. module_unresolved_relocation_t *reloc; char *name; @@ -299,14 +317,29 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym reloc->addend = rela[i].r_addend; continue;*/ + continue; + } else { + DEBUG_FUNCTION_LINE("case SHN_UNDEF with !allow_global\n"); return false; - } else - return false; + } } default: { - if (symtab[symbol].st_other != 1) { - return false; + char *name = elf_strptr(elf, symtab_strndx, symtab[symbol].st_name); + if(pluginData == NULL) { + DEBUG_FUNCTION_LINE("No plugin data provided, but we (probably) need it.\n"); + return false; + } + + ImportRPLInformation * rplInfo = pluginData->getImportRPLInformationBySectionHeaderIndex(symtab[symbol].st_shndx); + if(rplInfo == NULL) { + DEBUG_FUNCTION_LINE("Couldn't find ImportRPLInformation for section header index %d \n", symtab[symbol].st_shndx); + return false; + } + RelocationData * relocationData = new RelocationData(ELF32_R_TYPE(rela[i].r_info), rela[i].r_offset,rela[i].r_addend, destination, name, rplInfo); + pluginData->addRelocationData(relocationData); + + continue; } symbol_addr = symtab[symbol].st_value; break; @@ -314,6 +347,7 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym } if (!ElfTools::elfLinkOne(ELF32_R_TYPE(rela[i].r_info), rela[i].r_offset,rela[i].r_addend, destination, symbol_addr)) { + DEBUG_FUNCTION_LINE("elfLinkOne failed\n"); return false; } } diff --git a/loader/src/plugin/ElfTools.h b/loader/src/plugin/ElfTools.h index fcdd880..c844547 100644 --- a/loader/src/plugin/ElfTools.h +++ b/loader/src/plugin/ElfTools.h @@ -36,13 +36,16 @@ extern "C" { } #endif + +#include "PluginData.h" + class ElfTools { public: static bool elfLoadSection(const Elf *elf, Elf_Scn *scn, const Elf32_Shdr *shdr,void *destination); static bool loadElfSymtab(Elf *elf, Elf32_Sym **symtab, size_t *symtab_count, size_t *symtab_strndx); static void elfLoadSymbols(size_t shndx, const void *destination, Elf32_Sym *symtab, size_t symtab_count); - static bool elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *symtab, size_t symtab_count, size_t symtab_strndx, bool allow_globals); + static bool elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *symtab, size_t symtab_count, size_t symtab_strndx, bool allow_globals, PluginData * pluginData = NULL); static bool elfLinkOne(char type, size_t offset, int addend, void *destination, uint32_t symbol_addr); }; diff --git a/loader/src/plugin/ImportRPLInformation.h b/loader/src/plugin/ImportRPLInformation.h new file mode 100644 index 0000000..7add1a7 --- /dev/null +++ b/loader/src/plugin/ImportRPLInformation.h @@ -0,0 +1,79 @@ +/**************************************************************************** + * Copyright (C) 2018 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ + +#ifndef _IMPORT_RPL_INFORMATION_H_ +#define _IMPORT_RPL_INFORMATION_H_ + +#include +#include + +class ImportRPLInformation { + +public: + ImportRPLInformation(int section_header_index, std::string name, bool isData = false) { + this->name = name; + this->section_header_index = section_header_index; + this->_isData = isData; + } + + ~ImportRPLInformation() { + + } + + static ImportRPLInformation * createImportRPLInformation(int section_header_index, std::string rawSectionName) { + std::string fimport = ".fimport_"; + std::string dimport = ".dimport_"; + + bool data = false; + + std::string rplName = ""; + + if(rawSectionName.size() < fimport.size()) { + return NULL; + } else if (std::equal(fimport.begin(), fimport.end(), rawSectionName.begin())) { + rplName = rawSectionName.substr(fimport.size()); + } else if (std::equal(dimport.begin(), dimport.end(), rawSectionName.begin())) { + rplName = rawSectionName.substr(dimport.size()); + data = true; + } else { + DEBUG_FUNCTION_LINE("invalid section name\n"); + return NULL; + } + DEBUG_FUNCTION_LINE("Adding %s of section index %02X. %d\n",rplName.c_str(),section_header_index,data); + return new ImportRPLInformation(section_header_index, rplName, data); + } + + std::string getName() { + return name; + } + + int getSectionHeaderIndex() { + return section_header_index; + } + + bool isData() { + return _isData; + } + +private: + std::string name; + bool _isData = false; + int section_header_index = 0; +}; + + +#endif diff --git a/loader/src/plugin/PluginData.h b/loader/src/plugin/PluginData.h index c4459a6..ede5015 100644 --- a/loader/src/plugin/PluginData.h +++ b/loader/src/plugin/PluginData.h @@ -23,6 +23,8 @@ #include "FunctionData.h" #include "HookData.h" #include "PluginInformation.h" +#include "RelocationData.h" +#include "ImportRPLInformation.h" #include #ifdef __cplusplus @@ -53,6 +55,18 @@ public: delete hook_data_list[i]; } } + + for(size_t i = 0; i< relocation_data_list.size(); i++) { + if(relocation_data_list[i] != NULL) { + delete relocation_data_list[i]; + } + } + + for(size_t i = 0; i< importRPLInformation_list.size(); i++) { + if(importRPLInformation_list[i] != NULL) { + delete importRPLInformation_list[i]; + } + } } void addFunctionData(FunctionData * function_data) { @@ -71,6 +85,38 @@ public: return hook_data_list; } + void addRelocationData(RelocationData * relocation_data) { + relocation_data_list.push_back(relocation_data); + } + + std::vector getRelocationDataList() { + return relocation_data_list; + } + + void addImportRPLInformation(ImportRPLInformation * importRPLInformation) { + importRPLInformation_list.push_back(importRPLInformation); + } + + std::vector getImportRPLInformationList() { + return importRPLInformation_list; + } + + /** + Returns a ImportRPLInformation for a given section header index. + + \param section_header_index: ID of section in elf, started counting at 1. + + \return A pointer to the corresponding ImportRPLInformation, return NULL if no corresponding information was found. + **/ + ImportRPLInformation * getImportRPLInformationBySectionHeaderIndex(int section_header_index) { + for(size_t i = 0; i< importRPLInformation_list.size(); i++) { + if(importRPLInformation_list[i] != NULL && importRPLInformation_list[i]->getSectionHeaderIndex() == section_header_index) { + return importRPLInformation_list[i]; + } + } + return NULL; + } + PluginInformation * getPluginInformation() { return pluginInformation; } @@ -81,6 +127,8 @@ private: std::vector function_data_list; std::vector hook_data_list; + std::vector relocation_data_list; + std::vector importRPLInformation_list; }; diff --git a/loader/src/plugin/PluginLoader.cpp b/loader/src/plugin/PluginLoader.cpp index 60015fa..f7e1f34 100644 --- a/loader/src/plugin/PluginLoader.cpp +++ b/loader/src/plugin/PluginLoader.cpp @@ -31,6 +31,7 @@ #include "ElfTools.h" #include "PluginData.h" #include "PluginLoader.h" +#include "DynamicLinkingHelper.h" #include "utils/StringTools.h" #include "common/retain_vars.h" @@ -105,11 +106,11 @@ bool PluginLoader::loadAndLinkPlugins(std::vector pluginInf } } + PluginLoader::flushCache(); + copyPluginDataIntoGlobalStruct(loadedPlugins); clearPluginData(loadedPlugins); - DCFlushRange((void*)this->startAddress,(u32)this->endAddress - (u32)this->startAddress); - ICInvalidateRange((void*)this->startAddress,(u32)this->endAddress - (u32)this->startAddress); return success; } @@ -141,8 +142,8 @@ PluginData * PluginLoader::loadAndLinkPlugin(PluginInformation * pluginInformati goto exit_error; } - if(pluginInformation->getSize() > ((u32) this->getCurrentStoreAddress() - (u32) this->startAddress)) { - DEBUG_FUNCTION_LINE("Not enough space left to loader the plugin into memory\n"); + if(pluginInformation->getSize() > ((u32) getAvailableSpace())) { + DEBUG_FUNCTION_LINE("Not enough space left to loader the plugin into memory %08X %08X\n",pluginInformation->getSize(),getAvailableSpace()); goto exit_error; } @@ -201,6 +202,8 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA wups_loader_hook_t *hooks = NULL; bool result = false; + int i = 1; + std::vector entry_t_list; std::vector hook_t_list; @@ -241,6 +244,7 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA name = elf_strptr(elf, shstrndx, shdr->sh_name); if (name == NULL) { + DEBUG_FUNCTION_LINE("name is null\n"); continue; } @@ -248,6 +252,7 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA continue; } else if (strcmp(name, ".wups.load") == 0) { if (entries != NULL) { + DEBUG_FUNCTION_LINE("entries != NULL\n"); goto exit_error; } @@ -255,11 +260,13 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA entries = (wups_loader_entry_t *) malloc(sizeof(wups_loader_entry_t) * entries_count); if (entries == NULL) { + DEBUG_FUNCTION_LINE("entries == NULL\n"); goto exit_error; } destinations[elf_ndxscn(scn)] = (uint8_t *)entries; if (!ElfTools::elfLoadSection(elf, scn, shdr, entries)) { + DEBUG_FUNCTION_LINE("elfLoadSection failed\n"); goto exit_error; } @@ -270,6 +277,7 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA } } else if (strcmp(name, ".wups.hooks") == 0) { if (hooks != NULL) { + DEBUG_FUNCTION_LINE("hooks != NULL\n"); goto exit_error; } @@ -277,11 +285,13 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA hooks = (wups_loader_hook_t *) malloc(sizeof(wups_loader_hook_t) * hooks_count); if (hooks == NULL) { + DEBUG_FUNCTION_LINE("hooks == NULL\n"); goto exit_error; } destinations[elf_ndxscn(scn)] = (uint8_t *)hooks; if (!ElfTools::elfLoadSection(elf, scn, shdr, hooks)) { + DEBUG_FUNCTION_LINE("elfLoadSection failed\n"); goto exit_error; } ElfTools::elfLoadSymbols(elf_ndxscn(scn), hooks, symtab, symtab_count); @@ -305,13 +315,39 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA goto exit_error; } + DEBUG_FUNCTION_LINE("Copy section %s to %08X\n",name,curAddress); if (!ElfTools::elfLoadSection(elf, scn, shdr, (void*) curAddress)) { + DEBUG_FUNCTION_LINE("elfLoadSection failed\n"); goto exit_error; } ElfTools::elfLoadSymbols(elf_ndxscn(scn), (void*) curAddress, symtab, symtab_count); } } } + for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) { + Elf32_Shdr *shdr; + + shdr = elf32_getshdr(scn); + if (shdr == NULL) { + continue; + } + const char *name; + + name = elf_strptr(elf, shstrndx, shdr->sh_name); + if (name == NULL) { + DEBUG_FUNCTION_LINE("name is null\n"); + continue; + } + if(shdr->sh_type == 0x80000002) { + ImportRPLInformation * info = ImportRPLInformation::createImportRPLInformation(i,name); + if(info != NULL) { + pluginData->addImportRPLInformation(info); + } + } + i++; + } + i = 0; + for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) { Elf32_Shdr *shdr; @@ -324,8 +360,8 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) && (shdr->sh_flags & SHF_ALLOC) && destinations[elf_ndxscn(scn)] != NULL) { - - if (!ElfTools::elfLink(elf, elf_ndxscn(scn), destinations[elf_ndxscn(scn)], symtab, symtab_count, symtab_strndx, true)) { + if (!ElfTools::elfLink(elf, elf_ndxscn(scn), destinations[elf_ndxscn(scn)], symtab, symtab_count, symtab_strndx, true, pluginData)) { + DEBUG_FUNCTION_LINE("elfLink failed\n"); goto exit_error; } } @@ -348,8 +384,6 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA this->setCurrentStoreAddress((void *) curAddress); - DEBUG_FUNCTION_LINE("Copied plugin %s to %08X\n",pluginData->getPluginInformation()->getName().c_str(),curAddress); - result = true; exit_error: if (!result) DEBUG_FUNCTION_LINE("exit_error\n"); @@ -371,12 +405,27 @@ exit_error: void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector plugins) { // Reset data memset((void*)&gbl_replacement_data,0,sizeof(gbl_replacement_data)); + DynamicLinkingHelper::getInstance()->clearAll(); int plugin_index = 0; // Copy data to global struct. for(size_t i = 0; i< plugins.size(); i++) { PluginData * cur_plugin = plugins.at(i); PluginInformation * cur_pluginInformation = cur_plugin->getPluginInformation(); + // Relocation + std::vector relocationData = cur_plugin->getRelocationDataList(); + for(size_t j = 0; j < relocationData.size(); j++) { + if(!DynamicLinkingHelper::getInstance()->addReloationEntry(relocationData[j])) { + DEBUG_FUNCTION_LINE("Adding relocation for %s failed. It won't be loaded.\n",cur_pluginInformation->getName().c_str()); + continue; + } else { + //relocationData[j]->printInformation(); + } + } + + // Other + + std::vector function_data_list = cur_plugin->getFunctionDataList(); std::vector hook_data_list = cur_plugin->getHookDataList(); if(plugin_index >= MAXIMUM_PLUGINS ) { diff --git a/loader/src/plugin/PluginLoader.h b/loader/src/plugin/PluginLoader.h index 936a515..edc23af 100644 --- a/loader/src/plugin/PluginLoader.h +++ b/loader/src/plugin/PluginLoader.h @@ -30,6 +30,7 @@ #include "PluginInformation.h" #include "PluginData.h" #include "dynamic_libs/os_types.h" +#include "dynamic_libs/os_functions.h" #ifdef __cplusplus extern "C" { @@ -49,7 +50,7 @@ class PluginLoader { public: static PluginLoader *getInstance() { if(!instance) { - instance = new PluginLoader((void*)getApplicationEndAddr(),(void *)PLUGIN_LOCATION_END_ADDRESS); + instance = new PluginLoader((void*)getApplicationEndAddr(),(void *)PLUGIN_LOCATION_END_ADDRESS); } return instance; } @@ -90,6 +91,15 @@ public: **/ bool loadAndLinkPlugins(std::vector pluginInformation); + + static void flushCache() { + u32 startAddress = getApplicationEndAddr(); + u32 endAddress = PLUGIN_LOCATION_END_ADDRESS; + + DCFlushRange((void*)startAddress,(u32)endAddress - (u32)startAddress); + ICInvalidateRange((void*)startAddress,(u32)endAddress - (u32)startAddress); + } + /** \brief Iterates through the vector and delete all it's elements diff --git a/loader/src/plugin/RelocationData.h b/loader/src/plugin/RelocationData.h new file mode 100644 index 0000000..19a8d3f --- /dev/null +++ b/loader/src/plugin/RelocationData.h @@ -0,0 +1,79 @@ +/**************************************************************************** + * Copyright (C) 2018 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ + +#ifndef _RELOCATION_DATA_H_ +#define _RELOCATION_DATA_H_ + +#include +#include +#include "ImportRPLInformation.h" + +class RelocationData { + +public: + RelocationData(char type, size_t offset, int addend, void *destination, std::string name, ImportRPLInformation * rplInfo) { + this->type = type; + this->offset = offset; + this->addend = addend; + this->destination = destination; + this->name = name; + this->rplInfo = rplInfo; + } + + ~RelocationData() { + + } + + char getType() { + return type; + } + + size_t getOffset() { + return offset; + } + + int getAddend() { + return addend; + } + + void * getDestination() { + return destination; + } + + std::string getName() { + return name; + } + + ImportRPLInformation * getImportRPLInformation() { + return rplInfo; + } + + void printInformation() { + DEBUG_FUNCTION_LINE("%s destination: %08X offset: %08X type: %02X addend: %d rplName: %s isData: %d \n",name.c_str(), destination, offset, type, addend, rplInfo->getName().c_str(), rplInfo->isData() ); + } + +private: + char type; + size_t offset; + int addend; + void *destination; + std::string name; + ImportRPLInformation * rplInfo; +}; + + +#endif diff --git a/loader/src/plugin/dynamic_linking_defines.h b/loader/src/plugin/dynamic_linking_defines.h new file mode 100644 index 0000000..15f40a2 --- /dev/null +++ b/loader/src/plugin/dynamic_linking_defines.h @@ -0,0 +1,65 @@ +/**************************************************************************** + * Copyright (C) 2018 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ + +#ifndef _DYNAMIC_LINKING_DEFINES_H_ +#define _DYNAMIC_LINKING_DEFINES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#define DYN_LINK_FUNCTION_NAME_LENGTH 255 +#define DYN_LINK_IMPORT_NAME_LENGTH 150 + +#define DYN_LINK_FUNCTION_LIST_LENGTH 500 +#define DYN_LINK_IMPORT_LIST_LENGTH 50 +#define DYN_LINK_RELOCATION_LIST_LENGTH 50000 + +typedef struct _dyn_linking_function_t { + char functionName[DYN_LINK_FUNCTION_NAME_LENGTH+1]; + void * address; +} dyn_linking_function_t; + +typedef struct _dyn_linking_import_t { + char importName[DYN_LINK_IMPORT_NAME_LENGTH+1]; + bool isData = false; + u32 handle = 0; +} dyn_linking_import_t; + +typedef struct _dyn_linking_relocation_entry_t { + dyn_linking_function_t* functionEntry = NULL; + dyn_linking_import_t* importEntry = NULL; + void * destination = NULL; + char type; + size_t offset; + int addend; +} dyn_linking_relocation_entry_t; + +typedef struct _dyn_linking_relocation_data_t { + dyn_linking_relocation_entry_t entries[DYN_LINK_RELOCATION_LIST_LENGTH]; + dyn_linking_function_t functions[DYN_LINK_FUNCTION_LIST_LENGTH]; + dyn_linking_import_t imports[DYN_LINK_IMPORT_LIST_LENGTH]; +} dyn_linking_relocation_data_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _DYNAMIC_LINKING_DEFINES_H_ */ diff --git a/plugin_makefile.mk b/plugin_makefile.mk index de2ae3f..061a647 100644 --- a/plugin_makefile.mk +++ b/plugin_makefile.mk @@ -7,10 +7,10 @@ ASFLAGS := -mregnames # --gc-sections: remove unneeded symbols # -T: use the linker script specified (to force certain wups sections together) # -Map: generate a map file - + LDFLAG_COMMON := -u wups_load -u wups_meta -u wups_hooks -T $(WUPSDIR)/wups.ld \ -Wl,-wrap,open,-wrap,close,-wrap,write,-wrap,read,-wrap,lseek,-wrap,stat,-wrap,fstat,-wrap,opendir,-wrap,closedir,-wrap,readdir,-wrap,mkdir \ - -Wl,-Map,$(notdir $@).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r,--gc-sections + -Wl,-Map,$(notdir $@).map,--gc-sections -LDFLAGS_MOD := $(LDFLAG_COMMON),--relocatable +LDFLAGS_MOD := -Wl,--relocatable LDFLAGS_ELF := --relocatable -s -T $(WUPSDIR)/wups_elf.ld \ No newline at end of file diff --git a/plugins/example_plugin/Makefile b/plugins/example_plugin/Makefile index 335d161..f52cd9e 100644 --- a/plugins/example_plugin/Makefile +++ b/plugins/example_plugin/Makefile @@ -12,6 +12,10 @@ endif ifeq ($(strip $(DEVKITPRO)),) $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") endif +ifeq ($(strip $(WUT_ROOT)),) +$(error "Please set WUT_ROOT in your environment. export WUT_ROOT=wut) +endif + export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) export PORTLIBS := $(DEVKITPRO)/portlibs/ppc export WUPSDIR := $(DEVKITPRO)/wups @@ -57,13 +61,12 @@ include $(WUPSDIR)/plugin_makefile.mk # -mcpu=750: enable processor specific compilation # -meabi: enable eabi specific compilation # -mhard-float: enable hardware floating point instructions -# -fshort-wchar: use 16 bit whcar_t type in keeping with Wii executables # -fno-common: stop common variables which the loader can't understand # -msdata-none: do not use r2 or r13 as small data areas # -memb: enable embedded application specific compilation # -ffunction-sections: split up functions so linker can garbage collect # -fdata-sections: split up data so linker can garbage collect -COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar -fno-common -msdata=none -memb -ffunction-sections -fdata-sections +COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fno-common -msdata=none -memb -ffunction-sections -fdata-sections # -x c: compile as c code @@ -81,7 +84,12 @@ endif ASFLAGS += -LDFLAG_COMMON += +LDFLAG_COMMON += + +ifeq ($(WRAP_MALLOC), 1) + LDFLAG_COMMON += -Wl,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r +endif + LDFLAGS_MOD += $(LD_FLAGS_MOD) LDFLAGS_ELF += $(LD_FLAGS_ELF) @@ -98,7 +106,7 @@ ALL_LIBS := $(LIBS) # list of directories containing libraries, this must be the top level containing # include and lib #--------------------------------------------------------------------------------- -LIBDIRS += +LIBDIRS += $(WUT_ROOT) #--------------------------------------------------------------------------------- # no real need to edit anything past this point unless you need to add additional @@ -183,7 +191,7 @@ $(OUTPUT) : output.elf @echo "checking for missing symbols ..." @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LD_FLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o check_linking.elf @echo "linking ..." $@ - @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ + @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ # Rule to make the module file. output.elf : $(OFILES) diff --git a/plugins/example_plugin/makefile.mk b/plugins/example_plugin/makefile.mk index c1d5cfd..f2e0000 100644 --- a/plugins/example_plugin/makefile.mk +++ b/plugins/example_plugin/makefile.mk @@ -1,6 +1,9 @@ # Compiling the projects with libutils logging code? DO_LOGGING := 1 +# Non WUT plugins need to wrap the malloc functions. +WRAP_MALLOC := 1 + # Target filename TARGET := $(notdir $(CURDIR)).mod diff --git a/plugins/example_plugin_wut/Makefile b/plugins/example_plugin_wut/Makefile new file mode 100644 index 0000000..f52cd9e --- /dev/null +++ b/plugins/example_plugin_wut/Makefile @@ -0,0 +1,290 @@ +# You probably never need to adjust this Makefile. +# All changes can be done in the makefile.mk + +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") +endif +ifeq ($(strip $(WUT_ROOT)),) +$(error "Please set WUT_ROOT in your environment. export WUT_ROOT=wut) +endif + +export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) +export PORTLIBS := $(DEVKITPRO)/portlibs/ppc +export WUPSDIR := $(DEVKITPRO)/wups +export GCC_VER := $(shell $(DEVKITPPC)/bin/powerpc-eabi-gcc -dumpversion) + +PREFIX := powerpc-eabi- + +export AS := $(PREFIX)as +export CC := $(PREFIX)gcc +export CXX := $(PREFIX)g++ +export LD := $(PREFIX)ld +export AR := $(PREFIX)ar +export OBJCOPY := $(PREFIX)objcopy + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +#--------------------------------------------------------------------------------- +TARGET := $(notdir $(CURDIR)).mod +BUILD := build + +ifeq ($(notdir $(CURDIR)),$(BUILD)) +include ../makefile.mk +else +include makefile.mk +endif + +include $(WUPSDIR)/plugin_makefile.mk + +#MAP ?= $(TARGET:.mod=.map) + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- + +# -Os: optimise size +# -Wall: generate lots of warnings +# -DGEKKO_U: define the symbol GEKKO (used in some headers) +# -D__wiiu__: define the symbol __wii__ (used in some headers) +# -mrvl: enable wii/gamecube compilation +# -mcpu=750: enable processor specific compilation +# -meabi: enable eabi specific compilation +# -mhard-float: enable hardware floating point instructions +# -fno-common: stop common variables which the loader can't understand +# -msdata-none: do not use r2 or r13 as small data areas +# -memb: enable embedded application specific compilation +# -ffunction-sections: split up functions so linker can garbage collect +# -fdata-sections: split up data so linker can garbage collect +COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fno-common -msdata=none -memb -ffunction-sections -fdata-sections + + +# -x c: compile as c code +# -std=c11: use the c11 standard +CFLAGS += $(COMMON_CFLAGS) -x c -std=gnu11 + +# -x c: compile as c++ code +# -std=gnu++11: use the c++11 standard +CXXFLAGS += $(COMMON_CFLAGS) -x c++ -std=gnu++11 + +ifeq ($(DO_LOGGING), 1) + CFLAGS += -D__LOGGING__ + CXXFLAGS += -D__LOGGING__ +endif + +ASFLAGS += + +LDFLAG_COMMON += + +ifeq ($(WRAP_MALLOC), 1) + LDFLAG_COMMON += -Wl,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r +endif + +LDFLAGS_MOD += $(LD_FLAGS_MOD) +LDFLAGS_ELF += $(LD_FLAGS_ELF) + +#--------------------------------------------------------------------------------- +Q := @ +MAKEFLAGS += --no-print-directory +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +ALL_LIBS := $(LIBS) +# + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS += $(WUT_ROOT) + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- +export PROJECTDIR := $(CURDIR) +export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET) +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) +export DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# automatically build a list of object files for our project +#--------------------------------------------------------------------------------- +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) +TTFFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.ttf))) +PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) + export LD_MOD := $(CC) +else + export LD_MOD := $(CXX) +endif + +export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ + $(sFILES:.s=.o) $(SFILES:.S=.o) \ + $(PNGFILES:.png=.png.o) $(addsuffix .o,$(BINFILES)) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE_FULL += $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + $(EXTERNAL_INCLUDE) + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS_FULL += $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + $(EXTERNAL_LIBPATHS) + + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean install + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf $(OUTPUT) + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) + +############################################################################### +# Rule to make everything. +PHONY += all + +all : $(OUTPUT) +############################################################################### +# Special build rules + +# Rule to make the module file. +$(OUTPUT) : output.elf + @echo "checking for missing symbols ..." + @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LD_FLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o check_linking.elf + @echo "linking ..." $@ + @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ + +# Rule to make the module file. +output.elf : $(OFILES) + @echo "linking ... output.elf" + @$(LD) $(OFILES) $(LDFLAGS_ELF) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ + +############################################################################### +# Standard build rules +#--------------------------------------------------------------------------------- +%.a: +#--------------------------------------------------------------------------------- + @echo $(notdir $@) + @rm -f $@ + @$(AR) -rc $@ $^ + +#--------------------------------------------------------------------------------- +%.o: %.cpp + @echo $(notdir $<) + @$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) $(INCLUDE_FULL) -c $< -o $@ $(ERROR_FILTER) + +#--------------------------------------------------------------------------------- +%.o: %.c + @echo $(notdir $<) + @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) $(INCLUDE_FULL) -c $< -o $@ $(ERROR_FILTER) + +#--------------------------------------------------------------------------------- +%.o: %.S + @echo $(notdir $<) + @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(INCLUDE_FULL) -c $< -o $@ $(ERROR_FILTER) + +#--------------------------------------------------------------------------------- +%.png.o : %.png + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.jpg.o : %.jpg + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.ttf.o : %.ttf + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.bin.o : %.bin + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.wav.o : %.wav + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.mp3.o : %.mp3 + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.ogg.o : %.ogg + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +############################################################################### +# Assembly listing rules + +# Rule to make assembly listing. +PHONY += list +list : $(LIST) + +# Rule to make the listing file. +%.list : $(TARGET) + $(LOG) + -$Qmkdir -p $(dir $@) + $Q$(OBJDUMP) -d $< > $@ + +############################################################################### +# Clean rule + +# Rule to clean files. +PHONY += clean +clean : + $Qrm -rf $(wildcard $(BUILD) $(BIN)) + +############################################################################### +# Phony targets + +.PHONY : $(PHONY) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/plugins/example_plugin_wut/README.md b/plugins/example_plugin_wut/README.md new file mode 100644 index 0000000..df01f44 --- /dev/null +++ b/plugins/example_plugin_wut/README.md @@ -0,0 +1,11 @@ +# Example plugin + +This is just a simple example plugin which can be used as a template. + +## Building + +For building you need: +- [wups](https://github.com/Maschell/WiiUPluginSystem) +- [wut](https://github.com/decaf-emu/wut) + +Install them (in this order) according to their README's. Don't forget the dependencies of the libs itself. \ No newline at end of file diff --git a/plugins/example_plugin_wut/makefile.mk b/plugins/example_plugin_wut/makefile.mk new file mode 100644 index 0000000..6b70fc0 --- /dev/null +++ b/plugins/example_plugin_wut/makefile.mk @@ -0,0 +1,55 @@ +# Compiling the projects with libutils logging code? +DO_LOGGING := 1 + +# Non WUT plugins need to wrap the malloc functions. +WRAP_MALLOC := 0 + +# Target filename +TARGET := $(notdir $(CURDIR)).mod + +# Source directories +SOURCES := src + +# Data directories +DATA := + +# Include directories +INCLUDES := src + +#--------------------------------------------------------------------------------- +# options for code generation and linking +#--------------------------------------------------------------------------------- +# Extra C compiler flags +CFLAGS := +# Extra C++ compiler flags +CXXFLAGS := +# Extra linking flags for all linking steps +LD_FLAGS := +# extra linking flags for linking the temporarily elf file (using ld) +LD_FLAGS_ELF := +# extra linking flags for linking the final mod file (using gcc/g++) +LD_FLAGS_MOD := + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(WUPSDIR) $(PORTLIBS) + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lwups -lwhb -lwutstdc++ -lwutnewlib -lwutmalloc -lcoreinit -lnsysnet -lnn_ac + +#--------------------------------------------------------------------------------- +# Will be added to the final lib paths +# example: +# -L$C:/library1/lib +#--------------------------------------------------------------------------------- +EXTERNAL_LIBPATHS := + +#--------------------------------------------------------------------------------- +# Will be added to the final include paths +# -IC:/library1/include +#--------------------------------------------------------------------------------- +EXTERNAL_INCLUDE := diff --git a/plugins/example_plugin_wut/src/main.cpp b/plugins/example_plugin_wut/src/main.cpp new file mode 100644 index 0000000..808bf55 --- /dev/null +++ b/plugins/example_plugin_wut/src/main.cpp @@ -0,0 +1,136 @@ +#include +#include +#include +#include +/** + Mandatory plugin information. + If not set correctly, the loader will refuse to use the plugin. +**/ +WUPS_PLUGIN_NAME("Example plugin"); +WUPS_PLUGIN_DESCRIPTION("This is just an example plugin and will log the FSOpenFile function."); +WUPS_PLUGIN_VERSION("v1.0"); +WUPS_PLUGIN_AUTHOR("Maschell"); +WUPS_PLUGIN_LICENSE("BSD"); + +/** + Add this to one of your projects file to have access to SD/USB. +**/ +WUPS_FS_ACCESS() +/** + Add this to one of your projects file to be able to create overlays. +**/ +WUPS_ALLOW_OVERLAY() + +/** + All of this defines can be used in ANY file. + It's possible to split it up into multiple files. + +**/ + +/** + Get's called ONCE when the loader exits, but BEFORE the ON_APPLICATION_START gets called or functions are overridden. +**/ +INITIALIZE_PLUGIN(){ + WHBLogUdpInit(); + WHBLogPrintf("INITIALIZE_PLUGIN"); + WHBLogUdpDeinit(); +} + + +/** + Gets called when the plugin loader is re-entered => when the plugin is unloaded. + The overridden functions are restored before this is getting called. +**/ +DEINITIALIZE_PLUGIN(){ + WHBLogPrintf("DEINITIALIZE_PLUGIN"); + WHBLogUdpDeinit(); +} + +/** + Gets called when an application starts. + This is called BEFORE the functions are overridden. + Make sure to initialize all functions you're using in the overridden functions! +**/ +ON_APPLICATION_START(){ + WHBLogUdpInit(); + WHBLogPrintf("ON_APPLICATION_START of example_plugin!"); + +} + +/** + Gets called when an application ends. A good place for freeing memory. +**/ +ON_APPLICATION_ENDING(){ + WHBLogPrintf("ON_APPLICATION_ENDING of example_plugin!"); + WHBLogUdpDeinit(); +} + +/** + Gets called on each frame. +**/ +ON_VYSNC(){ + WHBLogPrintf("ON_VYSNC of example_plugin!\n"); +} + +/** +Gets called whenever the application status changes. + +Possible values of "status": + WUPS_APP_STATUS_FOREGROUND, App is now running in foreground + WUPS_APP_STATUS_BACKGROUND App is now running in background + WUPS_APP_STATUS_CLOSED App is going to be closed +**/ +ON_APP_STATUS_CHANGED(status){ + if(status == WUPS_APP_STATUS_FOREGROUND){ + WHBLogPrintf("ON_APP_STATUS_CHANGED of example_plugin! App is now in foreground"); + } else if(status == WUPS_APP_STATUS_BACKGROUND){ + WHBLogPrintf("ON_APP_STATUS_CHANGED of example_plugin! App is now in background"); + } else if(status == WUPS_APP_STATUS_CLOSED){ + WHBLogPrintf("ON_APP_STATUS_CHANGED of example_plugin! App is now going to be closed"); + } +} + +/** + This defines a function replacement. + It allows to replace the system function with an own function. + So whenever a game / application calles an overridden function, your function gets called instead. + + Currently it's only possible to override functions that are loaded from .rpl files of OSv10 (00050010-1000400A). + + Signature of this macro: + DECL_FUNCTION( RETURN_TYPE, ARBITRARY_NAME_OF_FUNCTION , ARGS_SEPERATED_BY_COMMA){ + //Your code goes here. + } + + Within this macro, two more function get declare you can use. + my_ARBITRARY_NAME_OF_FUNCTION and real_FSOpenFile + + RETURN_TYPE my_ARBITRARY_NAME_OF_FUNCTION(ARGS_SEPERATED_BY_COMMA): + is just name of the function that gets declared in this macro. + It has the same effect as calling the overridden function directly. + + RETURN_TYPE real_ARBITRARY_NAME_OF_FUNCTION(ARGS_SEPERATED_BY_COMMA): + is the name of the function, that leads to function that was overridden. + Use this to call the original function that will be overridden. + CAUTION: Other plugins may already have manipulated the the return value or arguments. + + + Use this macro for each function you want to override + +**/ +DECL_FUNCTION(int, FSOpenFile, FSClient *pClient, FSCmdBlock *pCmd, const char *path, const char *mode, int *handle, int error) { + int result = real_FSOpenFile(pClient, pCmd, path, mode, handle, error); + + WHBLogPrintf("FSOpenFile called for folder %s! Result %d",path,result); + return result; +} + +/** +This tells the loader which functions from which library (.rpl) should be replaced with which function from this file. +The list of possible libraries can be found in the wiki. (In general it's WUPS_LOADER_LIBRARY_ + the name of the RPL in caps lock) + +WUPS_MUST_REPLACE(FUNCTION_NAME_IN_THIS_FILE, NAME_OF_LIB_WHICH_CONTAINS_THIS_FUNCTION, NAME_OF_FUNCTION_TO_OVERRIDE) + +Define this for each function you want to override. +**/ +WUPS_MUST_REPLACE(FSOpenFile, WUPS_LOADER_LIBRARY_COREINIT, FSOpenFile); diff --git a/plugins/hid_to_vpad/Makefile b/plugins/hid_to_vpad/Makefile index d593ba2..f52cd9e 100644 --- a/plugins/hid_to_vpad/Makefile +++ b/plugins/hid_to_vpad/Makefile @@ -12,6 +12,10 @@ endif ifeq ($(strip $(DEVKITPRO)),) $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") endif +ifeq ($(strip $(WUT_ROOT)),) +$(error "Please set WUT_ROOT in your environment. export WUT_ROOT=wut) +endif + export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) export PORTLIBS := $(DEVKITPRO)/portlibs/ppc export WUPSDIR := $(DEVKITPRO)/wups @@ -57,17 +61,16 @@ include $(WUPSDIR)/plugin_makefile.mk # -mcpu=750: enable processor specific compilation # -meabi: enable eabi specific compilation # -mhard-float: enable hardware floating point instructions -# -fshort-wchar: use 16 bit whcar_t type in keeping with Wii executables # -fno-common: stop common variables which the loader can't understand # -msdata-none: do not use r2 or r13 as small data areas # -memb: enable embedded application specific compilation # -ffunction-sections: split up functions so linker can garbage collect # -fdata-sections: split up data so linker can garbage collect -COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar -fno-common -msdata=none -memb -ffunction-sections -fdata-sections +COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fno-common -msdata=none -memb -ffunction-sections -fdata-sections # -x c: compile as c code -# -std=gnu11: use the gnu11 standard +# -std=c11: use the c11 standard CFLAGS += $(COMMON_CFLAGS) -x c -std=gnu11 # -x c: compile as c++ code @@ -81,7 +84,12 @@ endif ASFLAGS += -LDFLAG_COMMON += +LDFLAG_COMMON += + +ifeq ($(WRAP_MALLOC), 1) + LDFLAG_COMMON += -Wl,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r +endif + LDFLAGS_MOD += $(LD_FLAGS_MOD) LDFLAGS_ELF += $(LD_FLAGS_ELF) @@ -98,7 +106,7 @@ ALL_LIBS := $(LIBS) # list of directories containing libraries, this must be the top level containing # include and lib #--------------------------------------------------------------------------------- -LIBDIRS += +LIBDIRS += $(WUT_ROOT) #--------------------------------------------------------------------------------- # no real need to edit anything past this point unless you need to add additional @@ -183,7 +191,7 @@ $(OUTPUT) : output.elf @echo "checking for missing symbols ..." @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LD_FLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o check_linking.elf @echo "linking ..." $@ - @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ + @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ # Rule to make the module file. output.elf : $(OFILES) diff --git a/plugins/hid_to_vpad/makefile.mk b/plugins/hid_to_vpad/makefile.mk index 83c15fc..c760764 100644 --- a/plugins/hid_to_vpad/makefile.mk +++ b/plugins/hid_to_vpad/makefile.mk @@ -1,6 +1,9 @@ # Compiling the projects with libutils logging code? DO_LOGGING := 1 +# Non WUT plugins need to wrap the malloc functions. +WRAP_MALLOC := 1 + # Target filename TARGET := $(notdir $(CURDIR)).mod diff --git a/plugins/memory_info/Makefile b/plugins/memory_info/Makefile index 335d161..f52cd9e 100644 --- a/plugins/memory_info/Makefile +++ b/plugins/memory_info/Makefile @@ -12,6 +12,10 @@ endif ifeq ($(strip $(DEVKITPRO)),) $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") endif +ifeq ($(strip $(WUT_ROOT)),) +$(error "Please set WUT_ROOT in your environment. export WUT_ROOT=wut) +endif + export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) export PORTLIBS := $(DEVKITPRO)/portlibs/ppc export WUPSDIR := $(DEVKITPRO)/wups @@ -57,13 +61,12 @@ include $(WUPSDIR)/plugin_makefile.mk # -mcpu=750: enable processor specific compilation # -meabi: enable eabi specific compilation # -mhard-float: enable hardware floating point instructions -# -fshort-wchar: use 16 bit whcar_t type in keeping with Wii executables # -fno-common: stop common variables which the loader can't understand # -msdata-none: do not use r2 or r13 as small data areas # -memb: enable embedded application specific compilation # -ffunction-sections: split up functions so linker can garbage collect # -fdata-sections: split up data so linker can garbage collect -COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar -fno-common -msdata=none -memb -ffunction-sections -fdata-sections +COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fno-common -msdata=none -memb -ffunction-sections -fdata-sections # -x c: compile as c code @@ -81,7 +84,12 @@ endif ASFLAGS += -LDFLAG_COMMON += +LDFLAG_COMMON += + +ifeq ($(WRAP_MALLOC), 1) + LDFLAG_COMMON += -Wl,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r +endif + LDFLAGS_MOD += $(LD_FLAGS_MOD) LDFLAGS_ELF += $(LD_FLAGS_ELF) @@ -98,7 +106,7 @@ ALL_LIBS := $(LIBS) # list of directories containing libraries, this must be the top level containing # include and lib #--------------------------------------------------------------------------------- -LIBDIRS += +LIBDIRS += $(WUT_ROOT) #--------------------------------------------------------------------------------- # no real need to edit anything past this point unless you need to add additional @@ -183,7 +191,7 @@ $(OUTPUT) : output.elf @echo "checking for missing symbols ..." @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LD_FLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o check_linking.elf @echo "linking ..." $@ - @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ + @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ # Rule to make the module file. output.elf : $(OFILES) diff --git a/plugins/memory_info/makefile.mk b/plugins/memory_info/makefile.mk index c1d5cfd..f2e0000 100644 --- a/plugins/memory_info/makefile.mk +++ b/plugins/memory_info/makefile.mk @@ -1,6 +1,9 @@ # Compiling the projects with libutils logging code? DO_LOGGING := 1 +# Non WUT plugins need to wrap the malloc functions. +WRAP_MALLOC := 1 + # Target filename TARGET := $(notdir $(CURDIR)).mod diff --git a/plugins/nnu_patcher/Makefile b/plugins/nnu_patcher/Makefile index 335d161..f52cd9e 100644 --- a/plugins/nnu_patcher/Makefile +++ b/plugins/nnu_patcher/Makefile @@ -12,6 +12,10 @@ endif ifeq ($(strip $(DEVKITPRO)),) $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") endif +ifeq ($(strip $(WUT_ROOT)),) +$(error "Please set WUT_ROOT in your environment. export WUT_ROOT=wut) +endif + export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) export PORTLIBS := $(DEVKITPRO)/portlibs/ppc export WUPSDIR := $(DEVKITPRO)/wups @@ -57,13 +61,12 @@ include $(WUPSDIR)/plugin_makefile.mk # -mcpu=750: enable processor specific compilation # -meabi: enable eabi specific compilation # -mhard-float: enable hardware floating point instructions -# -fshort-wchar: use 16 bit whcar_t type in keeping with Wii executables # -fno-common: stop common variables which the loader can't understand # -msdata-none: do not use r2 or r13 as small data areas # -memb: enable embedded application specific compilation # -ffunction-sections: split up functions so linker can garbage collect # -fdata-sections: split up data so linker can garbage collect -COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar -fno-common -msdata=none -memb -ffunction-sections -fdata-sections +COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fno-common -msdata=none -memb -ffunction-sections -fdata-sections # -x c: compile as c code @@ -81,7 +84,12 @@ endif ASFLAGS += -LDFLAG_COMMON += +LDFLAG_COMMON += + +ifeq ($(WRAP_MALLOC), 1) + LDFLAG_COMMON += -Wl,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r +endif + LDFLAGS_MOD += $(LD_FLAGS_MOD) LDFLAGS_ELF += $(LD_FLAGS_ELF) @@ -98,7 +106,7 @@ ALL_LIBS := $(LIBS) # list of directories containing libraries, this must be the top level containing # include and lib #--------------------------------------------------------------------------------- -LIBDIRS += +LIBDIRS += $(WUT_ROOT) #--------------------------------------------------------------------------------- # no real need to edit anything past this point unless you need to add additional @@ -183,7 +191,7 @@ $(OUTPUT) : output.elf @echo "checking for missing symbols ..." @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LD_FLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o check_linking.elf @echo "linking ..." $@ - @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ + @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ # Rule to make the module file. output.elf : $(OFILES) diff --git a/plugins/nnu_patcher/makefile.mk b/plugins/nnu_patcher/makefile.mk index c1d5cfd..f2e0000 100644 --- a/plugins/nnu_patcher/makefile.mk +++ b/plugins/nnu_patcher/makefile.mk @@ -1,6 +1,9 @@ # Compiling the projects with libutils logging code? DO_LOGGING := 1 +# Non WUT plugins need to wrap the malloc functions. +WRAP_MALLOC := 1 + # Target filename TARGET := $(notdir $(CURDIR)).mod diff --git a/plugins/overlay/Makefile b/plugins/overlay/Makefile index 335d161..f52cd9e 100644 --- a/plugins/overlay/Makefile +++ b/plugins/overlay/Makefile @@ -12,6 +12,10 @@ endif ifeq ($(strip $(DEVKITPRO)),) $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") endif +ifeq ($(strip $(WUT_ROOT)),) +$(error "Please set WUT_ROOT in your environment. export WUT_ROOT=wut) +endif + export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) export PORTLIBS := $(DEVKITPRO)/portlibs/ppc export WUPSDIR := $(DEVKITPRO)/wups @@ -57,13 +61,12 @@ include $(WUPSDIR)/plugin_makefile.mk # -mcpu=750: enable processor specific compilation # -meabi: enable eabi specific compilation # -mhard-float: enable hardware floating point instructions -# -fshort-wchar: use 16 bit whcar_t type in keeping with Wii executables # -fno-common: stop common variables which the loader can't understand # -msdata-none: do not use r2 or r13 as small data areas # -memb: enable embedded application specific compilation # -ffunction-sections: split up functions so linker can garbage collect # -fdata-sections: split up data so linker can garbage collect -COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar -fno-common -msdata=none -memb -ffunction-sections -fdata-sections +COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fno-common -msdata=none -memb -ffunction-sections -fdata-sections # -x c: compile as c code @@ -81,7 +84,12 @@ endif ASFLAGS += -LDFLAG_COMMON += +LDFLAG_COMMON += + +ifeq ($(WRAP_MALLOC), 1) + LDFLAG_COMMON += -Wl,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r +endif + LDFLAGS_MOD += $(LD_FLAGS_MOD) LDFLAGS_ELF += $(LD_FLAGS_ELF) @@ -98,7 +106,7 @@ ALL_LIBS := $(LIBS) # list of directories containing libraries, this must be the top level containing # include and lib #--------------------------------------------------------------------------------- -LIBDIRS += +LIBDIRS += $(WUT_ROOT) #--------------------------------------------------------------------------------- # no real need to edit anything past this point unless you need to add additional @@ -183,7 +191,7 @@ $(OUTPUT) : output.elf @echo "checking for missing symbols ..." @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LD_FLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o check_linking.elf @echo "linking ..." $@ - @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ + @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ # Rule to make the module file. output.elf : $(OFILES) diff --git a/plugins/overlay/makefile.mk b/plugins/overlay/makefile.mk index c1d5cfd..f2e0000 100644 --- a/plugins/overlay/makefile.mk +++ b/plugins/overlay/makefile.mk @@ -1,6 +1,9 @@ # Compiling the projects with libutils logging code? DO_LOGGING := 1 +# Non WUT plugins need to wrap the malloc functions. +WRAP_MALLOC := 1 + # Target filename TARGET := $(notdir $(CURDIR)).mod diff --git a/plugins/padcon/Makefile b/plugins/padcon/Makefile index 335d161..f52cd9e 100644 --- a/plugins/padcon/Makefile +++ b/plugins/padcon/Makefile @@ -12,6 +12,10 @@ endif ifeq ($(strip $(DEVKITPRO)),) $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") endif +ifeq ($(strip $(WUT_ROOT)),) +$(error "Please set WUT_ROOT in your environment. export WUT_ROOT=wut) +endif + export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) export PORTLIBS := $(DEVKITPRO)/portlibs/ppc export WUPSDIR := $(DEVKITPRO)/wups @@ -57,13 +61,12 @@ include $(WUPSDIR)/plugin_makefile.mk # -mcpu=750: enable processor specific compilation # -meabi: enable eabi specific compilation # -mhard-float: enable hardware floating point instructions -# -fshort-wchar: use 16 bit whcar_t type in keeping with Wii executables # -fno-common: stop common variables which the loader can't understand # -msdata-none: do not use r2 or r13 as small data areas # -memb: enable embedded application specific compilation # -ffunction-sections: split up functions so linker can garbage collect # -fdata-sections: split up data so linker can garbage collect -COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar -fno-common -msdata=none -memb -ffunction-sections -fdata-sections +COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fno-common -msdata=none -memb -ffunction-sections -fdata-sections # -x c: compile as c code @@ -81,7 +84,12 @@ endif ASFLAGS += -LDFLAG_COMMON += +LDFLAG_COMMON += + +ifeq ($(WRAP_MALLOC), 1) + LDFLAG_COMMON += -Wl,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r +endif + LDFLAGS_MOD += $(LD_FLAGS_MOD) LDFLAGS_ELF += $(LD_FLAGS_ELF) @@ -98,7 +106,7 @@ ALL_LIBS := $(LIBS) # list of directories containing libraries, this must be the top level containing # include and lib #--------------------------------------------------------------------------------- -LIBDIRS += +LIBDIRS += $(WUT_ROOT) #--------------------------------------------------------------------------------- # no real need to edit anything past this point unless you need to add additional @@ -183,7 +191,7 @@ $(OUTPUT) : output.elf @echo "checking for missing symbols ..." @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LD_FLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o check_linking.elf @echo "linking ..." $@ - @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ + @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ # Rule to make the module file. output.elf : $(OFILES) diff --git a/plugins/padcon/makefile.mk b/plugins/padcon/makefile.mk index 2c2ee84..dd90dbc 100644 --- a/plugins/padcon/makefile.mk +++ b/plugins/padcon/makefile.mk @@ -1,6 +1,9 @@ # Compiling the projects with libutils logging code? DO_LOGGING := 1 +# Non WUT plugins need to wrap the malloc functions. +WRAP_MALLOC := 1 + # Target filename TARGET := $(notdir $(CURDIR)).mod diff --git a/plugins/screenshot/Makefile b/plugins/screenshot/Makefile index 335d161..f52cd9e 100644 --- a/plugins/screenshot/Makefile +++ b/plugins/screenshot/Makefile @@ -12,6 +12,10 @@ endif ifeq ($(strip $(DEVKITPRO)),) $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") endif +ifeq ($(strip $(WUT_ROOT)),) +$(error "Please set WUT_ROOT in your environment. export WUT_ROOT=wut) +endif + export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) export PORTLIBS := $(DEVKITPRO)/portlibs/ppc export WUPSDIR := $(DEVKITPRO)/wups @@ -57,13 +61,12 @@ include $(WUPSDIR)/plugin_makefile.mk # -mcpu=750: enable processor specific compilation # -meabi: enable eabi specific compilation # -mhard-float: enable hardware floating point instructions -# -fshort-wchar: use 16 bit whcar_t type in keeping with Wii executables # -fno-common: stop common variables which the loader can't understand # -msdata-none: do not use r2 or r13 as small data areas # -memb: enable embedded application specific compilation # -ffunction-sections: split up functions so linker can garbage collect # -fdata-sections: split up data so linker can garbage collect -COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar -fno-common -msdata=none -memb -ffunction-sections -fdata-sections +COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fno-common -msdata=none -memb -ffunction-sections -fdata-sections # -x c: compile as c code @@ -81,7 +84,12 @@ endif ASFLAGS += -LDFLAG_COMMON += +LDFLAG_COMMON += + +ifeq ($(WRAP_MALLOC), 1) + LDFLAG_COMMON += -Wl,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r +endif + LDFLAGS_MOD += $(LD_FLAGS_MOD) LDFLAGS_ELF += $(LD_FLAGS_ELF) @@ -98,7 +106,7 @@ ALL_LIBS := $(LIBS) # list of directories containing libraries, this must be the top level containing # include and lib #--------------------------------------------------------------------------------- -LIBDIRS += +LIBDIRS += $(WUT_ROOT) #--------------------------------------------------------------------------------- # no real need to edit anything past this point unless you need to add additional @@ -183,7 +191,7 @@ $(OUTPUT) : output.elf @echo "checking for missing symbols ..." @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LD_FLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o check_linking.elf @echo "linking ..." $@ - @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ + @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ # Rule to make the module file. output.elf : $(OFILES) diff --git a/plugins/screenshot/makefile.mk b/plugins/screenshot/makefile.mk index d681650..473e84b 100644 --- a/plugins/screenshot/makefile.mk +++ b/plugins/screenshot/makefile.mk @@ -1,6 +1,9 @@ # Compiling the projects with libutils logging code? DO_LOGGING := 1 +# Non WUT plugins need to wrap the malloc functions. +WRAP_MALLOC := 1 + # Target filename TARGET := $(notdir $(CURDIR)).mod diff --git a/plugins/sdcafiine/Makefile b/plugins/sdcafiine/Makefile index 335d161..f52cd9e 100644 --- a/plugins/sdcafiine/Makefile +++ b/plugins/sdcafiine/Makefile @@ -12,6 +12,10 @@ endif ifeq ($(strip $(DEVKITPRO)),) $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") endif +ifeq ($(strip $(WUT_ROOT)),) +$(error "Please set WUT_ROOT in your environment. export WUT_ROOT=wut) +endif + export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) export PORTLIBS := $(DEVKITPRO)/portlibs/ppc export WUPSDIR := $(DEVKITPRO)/wups @@ -57,13 +61,12 @@ include $(WUPSDIR)/plugin_makefile.mk # -mcpu=750: enable processor specific compilation # -meabi: enable eabi specific compilation # -mhard-float: enable hardware floating point instructions -# -fshort-wchar: use 16 bit whcar_t type in keeping with Wii executables # -fno-common: stop common variables which the loader can't understand # -msdata-none: do not use r2 or r13 as small data areas # -memb: enable embedded application specific compilation # -ffunction-sections: split up functions so linker can garbage collect # -fdata-sections: split up data so linker can garbage collect -COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar -fno-common -msdata=none -memb -ffunction-sections -fdata-sections +COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fno-common -msdata=none -memb -ffunction-sections -fdata-sections # -x c: compile as c code @@ -81,7 +84,12 @@ endif ASFLAGS += -LDFLAG_COMMON += +LDFLAG_COMMON += + +ifeq ($(WRAP_MALLOC), 1) + LDFLAG_COMMON += -Wl,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r +endif + LDFLAGS_MOD += $(LD_FLAGS_MOD) LDFLAGS_ELF += $(LD_FLAGS_ELF) @@ -98,7 +106,7 @@ ALL_LIBS := $(LIBS) # list of directories containing libraries, this must be the top level containing # include and lib #--------------------------------------------------------------------------------- -LIBDIRS += +LIBDIRS += $(WUT_ROOT) #--------------------------------------------------------------------------------- # no real need to edit anything past this point unless you need to add additional @@ -183,7 +191,7 @@ $(OUTPUT) : output.elf @echo "checking for missing symbols ..." @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LD_FLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o check_linking.elf @echo "linking ..." $@ - @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ + @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ # Rule to make the module file. output.elf : $(OFILES) diff --git a/plugins/sdcafiine/makefile.mk b/plugins/sdcafiine/makefile.mk index e7648c7..1d85cd5 100644 --- a/plugins/sdcafiine/makefile.mk +++ b/plugins/sdcafiine/makefile.mk @@ -1,6 +1,9 @@ # Compiling the projects with libutils logging code? DO_LOGGING := 1 +# Non WUT plugins need to wrap the malloc functions. +WRAP_MALLOC := 1 + # Target filename TARGET := $(notdir $(CURDIR)).mod diff --git a/plugins/swipswapme/Makefile b/plugins/swipswapme/Makefile index 335d161..f52cd9e 100644 --- a/plugins/swipswapme/Makefile +++ b/plugins/swipswapme/Makefile @@ -12,6 +12,10 @@ endif ifeq ($(strip $(DEVKITPRO)),) $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") endif +ifeq ($(strip $(WUT_ROOT)),) +$(error "Please set WUT_ROOT in your environment. export WUT_ROOT=wut) +endif + export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) export PORTLIBS := $(DEVKITPRO)/portlibs/ppc export WUPSDIR := $(DEVKITPRO)/wups @@ -57,13 +61,12 @@ include $(WUPSDIR)/plugin_makefile.mk # -mcpu=750: enable processor specific compilation # -meabi: enable eabi specific compilation # -mhard-float: enable hardware floating point instructions -# -fshort-wchar: use 16 bit whcar_t type in keeping with Wii executables # -fno-common: stop common variables which the loader can't understand # -msdata-none: do not use r2 or r13 as small data areas # -memb: enable embedded application specific compilation # -ffunction-sections: split up functions so linker can garbage collect # -fdata-sections: split up data so linker can garbage collect -COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar -fno-common -msdata=none -memb -ffunction-sections -fdata-sections +COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fno-common -msdata=none -memb -ffunction-sections -fdata-sections # -x c: compile as c code @@ -81,7 +84,12 @@ endif ASFLAGS += -LDFLAG_COMMON += +LDFLAG_COMMON += + +ifeq ($(WRAP_MALLOC), 1) + LDFLAG_COMMON += -Wl,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r +endif + LDFLAGS_MOD += $(LD_FLAGS_MOD) LDFLAGS_ELF += $(LD_FLAGS_ELF) @@ -98,7 +106,7 @@ ALL_LIBS := $(LIBS) # list of directories containing libraries, this must be the top level containing # include and lib #--------------------------------------------------------------------------------- -LIBDIRS += +LIBDIRS += $(WUT_ROOT) #--------------------------------------------------------------------------------- # no real need to edit anything past this point unless you need to add additional @@ -183,7 +191,7 @@ $(OUTPUT) : output.elf @echo "checking for missing symbols ..." @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LD_FLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o check_linking.elf @echo "linking ..." $@ - @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ + @$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LDFLAGS_MOD) $(ALL_LIBS) $(LIBPATHS_FULL) -o $@ # Rule to make the module file. output.elf : $(OFILES) diff --git a/plugins/swipswapme/makefile.mk b/plugins/swipswapme/makefile.mk index 1908f69..eadc504 100644 --- a/plugins/swipswapme/makefile.mk +++ b/plugins/swipswapme/makefile.mk @@ -1,6 +1,9 @@ # Compiling the projects with libutils logging code? DO_LOGGING := 1 +# Non WUT plugins need to wrap the malloc functions. +WRAP_MALLOC := 1 + # Target filename TARGET := $(notdir $(CURDIR)).mod diff --git a/src/overlay.c b/src/overlay.c index 0296e4e..0e28a39 100644 --- a/src/overlay.c +++ b/src/overlay.c @@ -10,7 +10,16 @@ #include #include #include -#include + +extern void (*OSScreenInit)(void); +extern void (*OSScreenShutdown)(void); +extern u32 (*OSScreenGetBufferSizeEx)(u32 bufferNum); +extern s32 (*OSScreenSetBufferEx)(u32 bufferNum, void * addr); +extern s32 (*OSScreenClearBufferEx)(u32 bufferNum, u32 temp); +extern s32 (*OSScreenFlipBuffersEx)(u32 bufferNum); +extern s32 (*OSScreenPutFontEx)(u32 bufferNum, u32 posX, u32 posY, const char * buffer); +extern s32 (*OSScreenEnableEx)(u32 bufferNum, s32 enable); +extern u32 (*OSScreenPutPixelEx)(u32 bufferNum, u32 posX, u32 posY, u32 color); static void * overlayfunction_ptr __attribute__((section(".data"))) = NULL; @@ -18,7 +27,6 @@ static void * overlayfunction_ptr __attribute__((section(".data"))) = NULL; extern "C" { #endif void WUPS_InitOverlay(wups_loader_init_overlay_args_t args) { - InitOSFunctionPointers(); overlayfunction_ptr = (void*) args.overlayfunction_ptr; } diff --git a/wups_include/hooks.h b/wups_include/hooks.h index d645c9c..6e04dfe 100644 --- a/wups_include/hooks.h +++ b/wups_include/hooks.h @@ -18,7 +18,7 @@ #ifndef WUPS_HOOKS_DEF_H_ #define WUPS_HOOKS_DEF_H_ -#include +#include #include "common.h" #ifdef __cplusplus