From 0882634c119ef39cbb9d7358f22969b2948ce4e2 Mon Sep 17 00:00:00 2001 From: Maschell Date: Thu, 28 Jun 2018 22:25:04 +0200 Subject: [PATCH] Add support for the new plugin format to the loader! ALL EXISTING PLUGINS ARE STILL BROKEN AND NEED TO BE BUILT AGAIN --- loader/src/main.cpp | 8 +++- loader/src/plugin/PluginInformation.cpp | 4 +- loader/src/plugin/PluginLoader.cpp | 59 ++++++++++++++++--------- loader/src/plugin/PluginLoader.h | 6 +-- 4 files changed, 48 insertions(+), 29 deletions(-) diff --git a/loader/src/main.cpp b/loader/src/main.cpp index 45e497a..6502fb1 100644 --- a/loader/src/main.cpp +++ b/loader/src/main.cpp @@ -139,8 +139,12 @@ extern "C" int32_t Menu_Main(int32_t 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); + DEBUG_FUNCTION_LINE("Found relocation information for %d functions\n",relocations.size()); + + if(!DynamicLinkingHelper::getInstance()->fillRelocations(relocations)){ + OSFatal("fillRelocations failed."); + } + if(!isInMiiMakerHBL()) { diff --git a/loader/src/plugin/PluginInformation.cpp b/loader/src/plugin/PluginInformation.cpp index 615cd25..06b6d3b 100644 --- a/loader/src/plugin/PluginInformation.cpp +++ b/loader/src/plugin/PluginInformation.cpp @@ -158,10 +158,10 @@ bool PluginInformation::parseElf( Elf *elf) { DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Invalid ELF header\n", path_c); goto exit_error; } - if (ehdr->e_type != ET_REL) { + /*if (ehdr->e_type != ET_REL) { DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Not relocatable ELF.\n", path_c); goto exit_error; - } + }*/ if (ehdr->e_machine != EM_PPC) { DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Architecture not EM_PPC.\n", path_c); goto exit_error; diff --git a/loader/src/plugin/PluginLoader.cpp b/loader/src/plugin/PluginLoader.cpp index 3f39de4..e4c410e 100644 --- a/loader/src/plugin/PluginLoader.cpp +++ b/loader/src/plugin/PluginLoader.cpp @@ -187,12 +187,13 @@ exit_error: return result; } -bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endAddress) { - if(pluginData == NULL || elf == NULL || endAddress == NULL) { +bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * startAddress) { + if(pluginData == NULL || elf == NULL || startAddress == NULL) { return false; } - uint32_t curAddress = (uint32_t) endAddress; + uint32_t curAddress = (uint32_t) startAddress; + uint32_t firstCurAddress = (uint32_t) startAddress; Elf_Scn *scn; size_t symtab_count, section_count, shstrndx, symtab_strndx, entries_count, hooks_count; @@ -227,6 +228,8 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA destinations = (uint8_t **) malloc(sizeof(uint8_t *) * section_count); + DEBUG_FUNCTION_LINE("Copy sections\n"); + for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) { Elf32_Shdr *shdr; @@ -264,13 +267,15 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA goto exit_error; } - destinations[elf_ndxscn(scn)] = (uint8_t *)entries; + // We need to subtract the sh_addr because it will be added later in the relocations. + destinations[elf_ndxscn(scn)] = (uint8_t *)entries - (shdr->sh_addr); + if (!ElfTools::elfLoadSection(elf, scn, shdr, entries)) { DEBUG_FUNCTION_LINE("elfLoadSection failed\n"); goto exit_error; } - ElfTools::elfLoadSymbols(elf_ndxscn(scn), entries, symtab, symtab_count); + ElfTools::elfLoadSymbols(elf_ndxscn(scn), entries- (shdr->sh_addr), symtab, symtab_count); for(size_t i = 0; i< entries_count; i++) { entry_t_list.push_back(&entries[i]); @@ -289,41 +294,40 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA goto exit_error; } - destinations[elf_ndxscn(scn)] = (uint8_t *)hooks; + // We need to subtract the sh_addr because it will be added later in the relocations. + uint32_t destination = (uint32_t)hooks - (shdr->sh_addr); + destinations[elf_ndxscn(scn)] = (uint8_t *)destination; 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); + ElfTools::elfLoadSymbols(elf_ndxscn(scn), (void *) destination, symtab, symtab_count); for(size_t i = 0; i< hooks_count; i++) { hook_t_list.push_back(&hooks[i]); } } else { - curAddress -= shdr->sh_size; + uint32_t destination = firstCurAddress + shdr->sh_addr; + destinations[elf_ndxscn(scn)] = (uint8_t *) firstCurAddress; - if (shdr->sh_addralign > 3) { - curAddress = (uint32_t)((int32_t)curAddress & ~(shdr->sh_addralign - 1)); - } else { - curAddress = (uint32_t)((int32_t)curAddress & ~3); - } - destinations[elf_ndxscn(scn)] = (uint8_t *) curAddress; - - if((uint32_t) curAddress < (uint32_t) this->startAddress) { - DEBUG_FUNCTION_LINE("Not enough space to load function %s into memory at %08X.\n",name,curAddress); + if((uint32_t) destination + shdr->sh_size > (uint32_t) this->endAddress) { + DEBUG_FUNCTION_LINE("Not enough space to load function %s into memory at %08X.\n",name,destination); 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("Copy section %s to %08X\n",name,destination); + if (!ElfTools::elfLoadSection(elf, scn, shdr, (void*) destination)) { DEBUG_FUNCTION_LINE("elfLoadSection failed\n"); goto exit_error; } - ElfTools::elfLoadSymbols(elf_ndxscn(scn), (void*) curAddress, symtab, symtab_count); + ElfTools::elfLoadSymbols(elf_ndxscn(scn), (void*) firstCurAddress, symtab, symtab_count); + + curAddress = destination + shdr->sh_size; } } } + for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) { Elf32_Shdr *shdr; @@ -348,7 +352,6 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA } i = 0; - for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) { Elf32_Shdr *shdr; @@ -357,15 +360,25 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA 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 == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) && (shdr->sh_flags & SHF_ALLOC) && destinations[elf_ndxscn(scn)] != NULL) { + + DEBUG_FUNCTION_LINE("Linking (%d)... %s\n",i++,name); 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; } } } + DEBUG_FUNCTION_LINE("Linking done \n"); for(size_t j=0; jcurrentStoreAddress - (uint32_t) this->startAddress); + return ((uint32_t) this->endAddress - (uint32_t) this->currentStoreAddress); } size_t getUsedSpace() { @@ -122,7 +122,7 @@ public: } void resetPluginLoader() { - this->currentStoreAddress = endAddress; + this->currentStoreAddress = (void*) ROUNDUP((uint32_t)startAddress, 0x100); } uint32_t getMemoryFromDataSection(size_t align, size_t size); @@ -132,7 +132,7 @@ private: // TODO: Check if endAddress > startAddress. this->startAddress = startAddress; this->endAddress = endAddress; - this->currentStoreAddress = endAddress; + this->currentStoreAddress = (void*) ROUNDUP((uint32_t)startAddress, 0x100); } ~PluginLoader() {