mirror of
https://github.com/wiiu-env/WiiUPluginSystem.git
synced 2024-11-16 15:49:23 +01:00
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:
parent
f3e0eaa176
commit
0882634c11
@ -140,7 +140,11 @@ extern "C" int32_t Menu_Main(int32_t argc, char **argv) {
|
|||||||
|
|
||||||
std::vector<dyn_linking_relocation_entry_t *> relocations = DynamicLinkingHelper::getInstance()->getAllValidDynamicLinkingRelocations();
|
std::vector<dyn_linking_relocation_entry_t *> relocations = DynamicLinkingHelper::getInstance()->getAllValidDynamicLinkingRelocations();
|
||||||
DEBUG_FUNCTION_LINE("Found relocation information for %d functions\n",relocations.size());
|
DEBUG_FUNCTION_LINE("Found relocation information for %d functions\n",relocations.size());
|
||||||
DynamicLinkingHelper::getInstance()->fillRelocations(relocations);
|
|
||||||
|
if(!DynamicLinkingHelper::getInstance()->fillRelocations(relocations)){
|
||||||
|
OSFatal("fillRelocations failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(!isInMiiMakerHBL()) {
|
if(!isInMiiMakerHBL()) {
|
||||||
|
@ -158,10 +158,10 @@ bool PluginInformation::parseElf( Elf *elf) {
|
|||||||
DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Invalid ELF header\n", path_c);
|
DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Invalid ELF header\n", path_c);
|
||||||
goto exit_error;
|
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);
|
DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Not relocatable ELF.\n", path_c);
|
||||||
goto exit_error;
|
goto exit_error;
|
||||||
}
|
}*/
|
||||||
if (ehdr->e_machine != EM_PPC) {
|
if (ehdr->e_machine != EM_PPC) {
|
||||||
DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Architecture not EM_PPC.\n", path_c);
|
DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Architecture not EM_PPC.\n", path_c);
|
||||||
goto exit_error;
|
goto exit_error;
|
||||||
|
@ -187,12 +187,13 @@ exit_error:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endAddress) {
|
bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * startAddress) {
|
||||||
if(pluginData == NULL || elf == NULL || endAddress == NULL) {
|
if(pluginData == NULL || elf == NULL || startAddress == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t curAddress = (uint32_t) endAddress;
|
uint32_t curAddress = (uint32_t) startAddress;
|
||||||
|
uint32_t firstCurAddress = (uint32_t) startAddress;
|
||||||
|
|
||||||
Elf_Scn *scn;
|
Elf_Scn *scn;
|
||||||
size_t symtab_count, section_count, shstrndx, symtab_strndx, entries_count, hooks_count;
|
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);
|
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)) {
|
for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) {
|
||||||
Elf32_Shdr *shdr;
|
Elf32_Shdr *shdr;
|
||||||
|
|
||||||
@ -264,13 +267,15 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
|
|||||||
goto exit_error;
|
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)) {
|
if (!ElfTools::elfLoadSection(elf, scn, shdr, entries)) {
|
||||||
DEBUG_FUNCTION_LINE("elfLoadSection failed\n");
|
DEBUG_FUNCTION_LINE("elfLoadSection failed\n");
|
||||||
goto exit_error;
|
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++) {
|
for(size_t i = 0; i< entries_count; i++) {
|
||||||
entry_t_list.push_back(&entries[i]);
|
entry_t_list.push_back(&entries[i]);
|
||||||
@ -289,41 +294,40 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
|
|||||||
goto exit_error;
|
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)) {
|
if (!ElfTools::elfLoadSection(elf, scn, shdr, hooks)) {
|
||||||
DEBUG_FUNCTION_LINE("elfLoadSection failed\n");
|
DEBUG_FUNCTION_LINE("elfLoadSection failed\n");
|
||||||
goto exit_error;
|
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++) {
|
for(size_t i = 0; i< hooks_count; i++) {
|
||||||
hook_t_list.push_back(&hooks[i]);
|
hook_t_list.push_back(&hooks[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
curAddress -= shdr->sh_size;
|
uint32_t destination = firstCurAddress + shdr->sh_addr;
|
||||||
|
destinations[elf_ndxscn(scn)] = (uint8_t *) firstCurAddress;
|
||||||
|
|
||||||
if (shdr->sh_addralign > 3) {
|
if((uint32_t) destination + shdr->sh_size > (uint32_t) this->endAddress) {
|
||||||
curAddress = (uint32_t)((int32_t)curAddress & ~(shdr->sh_addralign - 1));
|
DEBUG_FUNCTION_LINE("Not enough space to load function %s into memory at %08X.\n",name,destination);
|
||||||
} 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);
|
|
||||||
goto exit_error;
|
goto exit_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_FUNCTION_LINE("Copy section %s to %08X\n",name,curAddress);
|
DEBUG_FUNCTION_LINE("Copy section %s to %08X\n",name,destination);
|
||||||
if (!ElfTools::elfLoadSection(elf, scn, shdr, (void*) curAddress)) {
|
if (!ElfTools::elfLoadSection(elf, scn, shdr, (void*) destination)) {
|
||||||
DEBUG_FUNCTION_LINE("elfLoadSection failed\n");
|
DEBUG_FUNCTION_LINE("elfLoadSection failed\n");
|
||||||
goto exit_error;
|
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)) {
|
for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) {
|
||||||
Elf32_Shdr *shdr;
|
Elf32_Shdr *shdr;
|
||||||
|
|
||||||
@ -348,7 +352,6 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
|
|||||||
}
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
|
|
||||||
for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) {
|
for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) {
|
||||||
Elf32_Shdr *shdr;
|
Elf32_Shdr *shdr;
|
||||||
|
|
||||||
@ -357,15 +360,25 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
|
|||||||
continue;
|
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) &&
|
if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) &&
|
||||||
(shdr->sh_flags & SHF_ALLOC) &&
|
(shdr->sh_flags & SHF_ALLOC) &&
|
||||||
destinations[elf_ndxscn(scn)] != NULL) {
|
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)) {
|
if (!ElfTools::elfLink(elf, elf_ndxscn(scn), destinations[elf_ndxscn(scn)], symtab, symtab_count, symtab_strndx, true, pluginData)) {
|
||||||
DEBUG_FUNCTION_LINE("elfLink failed\n");
|
DEBUG_FUNCTION_LINE("elfLink failed\n");
|
||||||
goto exit_error;
|
goto exit_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DEBUG_FUNCTION_LINE("Linking done \n");
|
||||||
|
|
||||||
for(size_t j=0; j<hook_t_list.size(); j++) {
|
for(size_t j=0; j<hook_t_list.size(); j++) {
|
||||||
wups_loader_hook_t * hook = hook_t_list[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;
|
result = true;
|
||||||
exit_error:
|
exit_error:
|
||||||
if (!result) DEBUG_FUNCTION_LINE("exit_error\n");
|
if (!result) {
|
||||||
|
DEBUG_FUNCTION_LINE("exit_error\n");
|
||||||
|
}
|
||||||
if (destinations != NULL) {
|
if (destinations != NULL) {
|
||||||
free(destinations);
|
free(destinations);
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t getAvailableSpace() {
|
size_t getAvailableSpace() {
|
||||||
return ((uint32_t) this->currentStoreAddress - (uint32_t) this->startAddress);
|
return ((uint32_t) this->endAddress - (uint32_t) this->currentStoreAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getUsedSpace() {
|
size_t getUsedSpace() {
|
||||||
@ -122,7 +122,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void resetPluginLoader() {
|
void resetPluginLoader() {
|
||||||
this->currentStoreAddress = endAddress;
|
this->currentStoreAddress = (void*) ROUNDUP((uint32_t)startAddress, 0x100);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t getMemoryFromDataSection(size_t align, size_t size);
|
uint32_t getMemoryFromDataSection(size_t align, size_t size);
|
||||||
@ -132,7 +132,7 @@ private:
|
|||||||
// TODO: Check if endAddress > startAddress.
|
// TODO: Check if endAddress > startAddress.
|
||||||
this->startAddress = startAddress;
|
this->startAddress = startAddress;
|
||||||
this->endAddress = endAddress;
|
this->endAddress = endAddress;
|
||||||
this->currentStoreAddress = endAddress;
|
this->currentStoreAddress = (void*) ROUNDUP((uint32_t)startAddress, 0x100);
|
||||||
}
|
}
|
||||||
|
|
||||||
~PluginLoader() {
|
~PluginLoader() {
|
||||||
|
Loading…
Reference in New Issue
Block a user