Add support for the new plugin format to the loader!

ALL EXISTING PLUGINS ARE STILL BROKEN AND NEED TO BE BUILT AGAIN
This commit is contained in:
Maschell 2018-06-28 22:25:04 +02:00
parent f3e0eaa176
commit 0882634c11
4 changed files with 48 additions and 29 deletions

View File

@ -139,8 +139,12 @@ extern "C" int32_t Menu_Main(int32_t argc, char **argv) {
DEBUG_FUNCTION_LINE("Do relocations\n");
std::vector<dyn_linking_relocation_entry_t *> 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()) {

View File

@ -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;

View File

@ -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; j<hook_t_list.size(); j++) {
wups_loader_hook_t * hook = hook_t_list[j];
@ -386,7 +399,9 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
result = true;
exit_error:
if (!result) DEBUG_FUNCTION_LINE("exit_error\n");
if (!result) {
DEBUG_FUNCTION_LINE("exit_error\n");
}
if (destinations != NULL) {
free(destinations);
}

View File

@ -114,7 +114,7 @@ public:
}
size_t getAvailableSpace() {
return ((uint32_t) this->currentStoreAddress - (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() {