diff --git a/source/main.cpp b/source/main.cpp index 578a1cf..f8903d7 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -30,8 +30,6 @@ #define MEMORY_REGION_SIZE 0x00700000 #define MEMORY_REGION_END (MEMORY_REGION_START + MEMORY_REGION_SIZE) -#define gModuleData ((module_information_t *) (MEMORY_REGION_START)) - bool CheckRunning() { switch (ProcUIProcessMessages(true)) { case PROCUI_STATUS_EXITING: { @@ -77,9 +75,10 @@ int main(int argc, char **argv) { IOS_Close(handle); } - // 0x100 because before the .text section is a .init section - // Currently the size of the .init is ~ 0x24 bytes. We substract 0x100 to be safe. - uint32_t textSectionStart = textStart() - 0x1000; + // We substract 0x100 to be safe. + uint32_t textSectionStart = textStart() - 0x100; + + auto gModuleData = (module_information_t *) (textSectionStart - sizeof(module_information_t)); std::string environment_path = std::string(environmentPath); if (strncmp(environmentPath, "fs:/vol/external01/wiiu/environments/", strlen("fs:/vol/external01/wiiu/environments/")) != 0) { @@ -113,10 +112,10 @@ int main(int argc, char **argv) { RevertMainHook(); for (int i = 0; i < setupModules.GetFilecount(); i++) { - uint32_t destination_address = ((uint32_t) gModuleData + (sizeof(module_information_t) + 0x0000FFFF)) & 0xFFFF0000; + uint32_t destination_address_end = ((uint32_t) gModuleData) & 0xFFFF0000; memset((void *) gModuleData, 0, sizeof(module_information_t)); - DEBUG_FUNCTION_LINE("Trying to run %s", setupModules.GetFilepath(i)); - auto moduleData = ModuleDataFactory::load(setupModules.GetFilepath(i), &destination_address, textSectionStart - destination_address, gModuleData->trampolines, + DEBUG_FUNCTION_LINE("Trying to run %s.", setupModules.GetFilepath(i), destination_address_end, ((uint32_t) gModuleData) - MEMORY_REGION_START); + auto moduleData = ModuleDataFactory::load(setupModules.GetFilepath(i), destination_address_end, ((uint32_t) gModuleData) - MEMORY_REGION_START, gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH); if (!moduleData) { DEBUG_FUNCTION_LINE("Failed to load %s", setupModules.GetFilepath(i)); diff --git a/source/module/ModuleDataFactory.cpp b/source/module/ModuleDataFactory.cpp index 9e237db..5436d81 100644 --- a/source/module/ModuleDataFactory.cpp +++ b/source/module/ModuleDataFactory.cpp @@ -25,7 +25,7 @@ using namespace ELFIO; std::optional> -ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_ptr, uint32_t maximum_size, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length) { +ModuleDataFactory::load(const std::string &path, uint32_t destination_address_end, uint32_t maximum_size, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length) { elfio reader; std::shared_ptr moduleData = std::make_shared(); @@ -36,10 +36,26 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p } uint32_t sec_num = reader.sections.size(); - auto **destinations = (uint8_t **) malloc(sizeof(uint8_t *) * sec_num); - uint32_t baseOffset = *destination_address_ptr; + uint32_t sizeOfModule = 0; + for (uint32_t i = 0; i < sec_num; ++i) { + section *psec = reader.sections[i]; + if (psec->get_type() == 0x80000002) { + continue; + } + + if ((psec->get_type() == SHT_PROGBITS || psec->get_type() == SHT_NOBITS) && (psec->get_flags() & SHF_ALLOC)) { + sizeOfModule += psec->get_size() + 1; + } + } + + if (sizeOfModule > maximum_size) { + DEBUG_FUNCTION_LINE("Module is too big."); + return {}; + } + + uint32_t baseOffset = (destination_address_end - sizeOfModule) & 0xFFFFFF00; uint32_t offset_text = baseOffset; uint32_t offset_data = offset_text; @@ -131,18 +147,16 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p moduleData->addRelocationData(reloc); } - DCFlushRange((void *) *destination_address_ptr, totalSize); - ICInvalidateRange((void *) *destination_address_ptr, totalSize); + DCFlushRange((void *) baseOffset, totalSize); + ICInvalidateRange((void *) baseOffset, totalSize); free(destinations); - moduleData->setStartAddress(*destination_address_ptr); + moduleData->setStartAddress(baseOffset); moduleData->setEndAddress(endAddress); moduleData->setEntrypoint(entrypoint); DEBUG_FUNCTION_LINE("Saved entrypoint as %08X", entrypoint); - *destination_address_ptr = (*destination_address_ptr + totalSize + 0x100) & 0xFFFFFF00; - return moduleData; } diff --git a/source/module/ModuleDataFactory.h b/source/module/ModuleDataFactory.h index 330cade..fc8dd2d 100644 --- a/source/module/ModuleDataFactory.h +++ b/source/module/ModuleDataFactory.h @@ -27,7 +27,7 @@ class ModuleDataFactory { public: static std::optional> - load(const std::string &path, uint32_t *destination_address_ptr, uint32_t maximum_size, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length); + load(const std::string &path, uint32_t destination_address_end, uint32_t maximum_size, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length); static bool linkSection(ELFIO::elfio &reader, uint32_t section_index, uint32_t destination, uint32_t base_text, uint32_t base_data, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length); diff --git a/source/pc.s b/source/pc.s index 1a8a70f..baa1a0f 100644 --- a/source/pc.s +++ b/source/pc.s @@ -1,4 +1,4 @@ -.section ".text" +.section ".crt0" .global textStart textStart: mflr 4;