diff --git a/relocator/src/DynamicLinkingHelper.cpp b/relocator/src/DynamicLinkingHelper.cpp index d71f695..1b5dc9c 100644 --- a/relocator/src/DynamicLinkingHelper.cpp +++ b/relocator/src/DynamicLinkingHelper.cpp @@ -5,26 +5,26 @@ #include "utils/logger.h" #include "../../source/common/module_defines.h" -dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t * data, const char* functionName) { - if(data == NULL) { +dyn_linking_function_t *DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, const char *functionName) { + if (data == NULL) { return NULL; } - if(functionName == NULL) { + if (functionName == NULL) { return NULL; } - dyn_linking_function_t * result = NULL; - for(int32_t i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) { - dyn_linking_function_t * curEntry = &(data->functions[i]); - if(strlen(curEntry->functionName) == 0) { - if(strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) { + dyn_linking_function_t *result = NULL; + for (int32_t i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) { + dyn_linking_function_t *curEntry = &(data->functions[i]); + if (strlen(curEntry->functionName) == 0) { + if (strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) { DEBUG_FUNCTION_LINE("Failed to add function name, it's too long.\n"); return NULL; } - strncpy(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH); + strncpy(curEntry->functionName, functionName, DYN_LINK_FUNCTION_NAME_LENGTH); result = curEntry; break; } - if(strncmp(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH) == 0) { + if (strncmp(curEntry->functionName, functionName, DYN_LINK_FUNCTION_NAME_LENGTH) == 0) { result = curEntry; break; } @@ -32,62 +32,65 @@ dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_l return result; } -dyn_linking_import_t * DynamicLinkingHelper::getOrAddFunctionImportByName(dyn_linking_relocation_data_t * data, const char* importName) { +dyn_linking_import_t *DynamicLinkingHelper::getOrAddFunctionImportByName(dyn_linking_relocation_data_t *data, const char *importName) { return getOrAddImport(data, importName, false); } -dyn_linking_import_t * DynamicLinkingHelper::getOrAddDataImportByName(dyn_linking_relocation_data_t * data, const char* importName) { +dyn_linking_import_t *DynamicLinkingHelper::getOrAddDataImportByName(dyn_linking_relocation_data_t *data, const char *importName) { return getOrAddImport(data, importName, true); } -dyn_linking_import_t * DynamicLinkingHelper::getOrAddImport(dyn_linking_relocation_data_t * data, const char* importName, bool isData) { - if(importName == NULL || data == NULL) { +dyn_linking_import_t *DynamicLinkingHelper::getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData) { + if (importName == NULL || data == NULL) { return NULL; } - dyn_linking_import_t * result = NULL; - for(int32_t i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) { - dyn_linking_import_t * curEntry = &(data->imports[i]); - if(strlen(curEntry->importName) == 0) { - if(strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) { + dyn_linking_import_t *result = NULL; + for (int32_t i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) { + dyn_linking_import_t *curEntry = &(data->imports[i]); + if (strlen(curEntry->importName) == 0) { + if (strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) { DEBUG_FUNCTION_LINE("Failed to add Import, it's too long.\n"); return NULL; } - strncpy(curEntry->importName,importName,DYN_LINK_IMPORT_NAME_LENGTH); + 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)) { + if (strncmp(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH) == 0 && (curEntry->isData == isData)) { return curEntry; } } return result; } -bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, const RelocationData& relocationData) { - return addReloationEntry(linking_data, linking_entries, linking_entry_length, relocationData.getType(), relocationData.getOffset(), relocationData.getAddend(), relocationData.getDestination(), relocationData.getName(), relocationData.getImportRPLInformation()); +bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, const RelocationData &relocationData) { + return addReloationEntry(linking_data, linking_entries, linking_entry_length, relocationData.getType(), relocationData.getOffset(), relocationData.getAddend(), relocationData.getDestination(), relocationData.getName(), + relocationData.getImportRPLInformation()); } -bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, std::string name, const ImportRPLInformation& rplInfo) { - dyn_linking_import_t * importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, 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); +bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, + std::string name, const ImportRPLInformation &rplInfo) { + dyn_linking_import_t *importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, 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(linking_data, 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); + dyn_linking_function_t *functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(linking_data, 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(linking_entries, linking_entry_length, type, offset, addend, destination, functionInfo, importInfoGbl); } -bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, dyn_linking_function_t * functionName, dyn_linking_import_t * importInfo) { - for(uint32_t i = 0; i < linking_entry_length; i++) { - dyn_linking_relocation_entry_t * curEntry = &(linking_entries[i]); - if(curEntry->functionEntry != NULL) { +bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, dyn_linking_function_t *functionName, + dyn_linking_import_t *importInfo) { + for (uint32_t i = 0; i < linking_entry_length; i++) { + dyn_linking_relocation_entry_t *curEntry = &(linking_entries[i]); + if (curEntry->functionEntry != NULL) { continue; } curEntry->type = type; diff --git a/relocator/src/DynamicLinkingHelper.h b/relocator/src/DynamicLinkingHelper.h index ef97ccd..ce08c4f 100644 --- a/relocator/src/DynamicLinkingHelper.h +++ b/relocator/src/DynamicLinkingHelper.h @@ -1,4 +1,5 @@ #pragma once + #include "../../source/common/dynamic_linking_defines.h" #include "utils/logger.h" #include @@ -13,7 +14,7 @@ public: \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. **/ - static dyn_linking_function_t * getOrAddFunctionEntryByName(dyn_linking_relocation_data_t * data, const char * functionName); + static dyn_linking_function_t *getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, 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. @@ -22,7 +23,7 @@ public: \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. **/ - static dyn_linking_import_t * getOrAddFunctionImportByName(dyn_linking_relocation_data_t * data, const char * importName); + static dyn_linking_import_t *getOrAddFunctionImportByName(dyn_linking_relocation_data_t *data, const char *importName); /** @@ -32,7 +33,7 @@ public: \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. **/ - static dyn_linking_import_t * getOrAddDataImportByName(dyn_linking_relocation_data_t * data, const char * importName); + static dyn_linking_import_t *getOrAddDataImportByName(dyn_linking_relocation_data_t *data, const char *importName); /** @@ -44,13 +45,16 @@ public: \return Returns a pointer to the data import entry which contains the importName. Null on error or if the list full. **/ - static dyn_linking_import_t * getOrAddImport(dyn_linking_relocation_data_t * data, const char * importName, bool isData); + static dyn_linking_import_t *getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData); - static bool addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, const RelocationData& relocationData); + static bool addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, const RelocationData &relocationData); - static bool addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, std::string name, const ImportRPLInformation& rplInfo); + static bool addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, std::string name, + const ImportRPLInformation &rplInfo); + + static bool + addReloationEntry(dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, dyn_linking_function_t *functionName, dyn_linking_import_t *importInfo); - static bool addReloationEntry(dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, dyn_linking_function_t * functionName, dyn_linking_import_t * importInfo); private: DynamicLinkingHelper() { } diff --git a/relocator/src/ElfUtils.cpp b/relocator/src/ElfUtils.cpp index f2b301c..ea47783 100644 --- a/relocator/src/ElfUtils.cpp +++ b/relocator/src/ElfUtils.cpp @@ -6,145 +6,145 @@ #include "ElfUtils.h" // See https://github.com/decaf-emu/decaf-emu/blob/43366a34e7b55ab9d19b2444aeb0ccd46ac77dea/src/libdecaf/src/cafe/loader/cafe_loader_reloc.cpp#L144 -bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type) { - if(type == R_PPC_NONE) { +bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type) { + if (type == R_PPC_NONE) { return true; } - auto target = destination + offset; + auto target = destination + offset; auto value = symbol_addr + addend; auto relValue = value - static_cast(target); switch (type) { - case R_PPC_NONE: - break; - case R_PPC_ADDR32: - *((uint32_t *)(target)) = value; - break; - case R_PPC_ADDR16_LO: - *((uint16_t *)(target)) = static_cast(value & 0xFFFF); - break; - case R_PPC_ADDR16_HI: - *((uint16_t *)(target)) = static_cast(value >> 16); - break; - case R_PPC_ADDR16_HA: - *((uint16_t *)(target)) = static_cast((value + 0x8000) >> 16); - break; - case R_PPC_DTPMOD32: - DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n"); - //*((int32_t *)(target)) = tlsModuleIndex; - break; - case R_PPC_DTPREL32: - *((uint32_t *)(target)) = value; - break; - case R_PPC_GHS_REL16_HA: - *((uint16_t *)(target)) = static_cast((relValue + 0x8000) >> 16); - break; - case R_PPC_GHS_REL16_HI: - *((uint16_t *)(target)) = static_cast(relValue >> 16); - break; - case R_PPC_GHS_REL16_LO: - *((uint16_t *)(target)) = static_cast(relValue & 0xFFFF); - break; - case R_PPC_REL14: { - auto distance = static_cast(value) - static_cast(target); - if (distance > 0x7FFC || distance < -0x7FFC) { - DEBUG_FUNCTION_LINE("***14-bit relative branch cannot hit target."); - return false; - } - - if (distance & 3) { - DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470040); - return false; - } - - if ((distance >= 0 && (distance & 0xFFFF8000)) || - (distance < 0 && ((distance & 0xFFFF8000) != 0xFFFF8000))) { - DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 17 bits before shift must all be the same.", -470040); - return false; - } - - *(int32_t *)target = (*(int32_t *)target & 0xFFBF0003) | (distance & 0x0000fffc); - break; - } - case R_PPC_REL24: { - // if (isWeakSymbol && !symbolValue) { - // symbolValue = static_cast(target); - // value = symbolValue + addend; - // } - auto distance = static_cast(value) - static_cast(target); - if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) { - if(trampolin_data == NULL) { - DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin isn't provided\n"); - DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); + case R_PPC_NONE: + break; + case R_PPC_ADDR32: + *((uint32_t *) (target)) = value; + break; + case R_PPC_ADDR16_LO: + *((uint16_t *) (target)) = static_cast(value & 0xFFFF); + break; + case R_PPC_ADDR16_HI: + *((uint16_t *) (target)) = static_cast(value >> 16); + break; + case R_PPC_ADDR16_HA: + *((uint16_t *) (target)) = static_cast((value + 0x8000) >> 16); + break; + case R_PPC_DTPMOD32: + DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n"); + //*((int32_t *)(target)) = tlsModuleIndex; + break; + case R_PPC_DTPREL32: + *((uint32_t *) (target)) = value; + break; + case R_PPC_GHS_REL16_HA: + *((uint16_t *) (target)) = static_cast((relValue + 0x8000) >> 16); + break; + case R_PPC_GHS_REL16_HI: + *((uint16_t *) (target)) = static_cast(relValue >> 16); + break; + case R_PPC_GHS_REL16_LO: + *((uint16_t *) (target)) = static_cast(relValue & 0xFFFF); + break; + case R_PPC_REL14: { + auto distance = static_cast(value) - static_cast(target); + if (distance > 0x7FFC || distance < -0x7FFC) { + DEBUG_FUNCTION_LINE("***14-bit relative branch cannot hit target."); return false; - } else { - relocation_trampolin_entry_t * freeSlot = NULL; - for(uint32_t i = 0; i < trampolin_data_length; i++) { - // We want to override "old" relocations of imports - // Pending relocations have the status RELOC_TRAMP_IMPORT_IN_PROGRESS. - // When all relocations are done successfully, they will be turned into RELOC_TRAMP_IMPORT_DONE - // so they can be overridden/updated/reused on the next application launch. - // - // Relocations that won't change will have the status RELOC_TRAMP_FIXED and are set to free when the module is unloaded. - if(trampolin_data[i].status == RELOC_TRAMP_FREE || - trampolin_data[i].status == RELOC_TRAMP_IMPORT_DONE) { - freeSlot = &(trampolin_data[i]); - break; - } - } - if(freeSlot != NULL) { - DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin data list is full\n"); - DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); - return false; - } - if(target - (uint32_t)&(freeSlot->trampolin[0]) > 0x1FFFFFC) { - DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer)."); - DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); - return false; - } - - freeSlot->trampolin[0] = 0x3D600000 | ((((uint32_t) value) >> 16) & 0x0000FFFF); // lis r11, real_addr@h - freeSlot->trampolin[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l - freeSlot->trampolin[2] = 0x7D6903A6; // mtctr r11 - freeSlot->trampolin[3] = 0x4E800420; // bctr - DCFlushRange((void*)freeSlot->trampolin, sizeof(freeSlot->trampolin)); - ICInvalidateRange((unsigned char*)freeSlot->trampolin, sizeof(freeSlot->trampolin)); - - if(reloc_type == RELOC_TYPE_FIXED) { - freeSlot->status = RELOC_TRAMP_FIXED; - } else { - // Relocations for the imports may be overridden - freeSlot->status = RELOC_TRAMP_IMPORT_IN_PROGRESS; - } - uint32_t symbolValue = (uint32_t)&(freeSlot->trampolin[0]); - value = symbolValue + addend; - distance = static_cast(value) - static_cast(target); - DEBUG_FUNCTION_LINE("Created tramp\n"); } - } - if (distance & 3) { - DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470022); + if (distance & 3) { + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470040); + return false; + } + + if ((distance >= 0 && (distance & 0xFFFF8000)) || + (distance < 0 && ((distance & 0xFFFF8000) != 0xFFFF8000))) { + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 17 bits before shift must all be the same.", -470040); + return false; + } + + *(int32_t *) target = (*(int32_t *) target & 0xFFBF0003) | (distance & 0x0000fffc); + break; + } + case R_PPC_REL24: { + // if (isWeakSymbol && !symbolValue) { + // symbolValue = static_cast(target); + // value = symbolValue + addend; + // } + auto distance = static_cast(value) - static_cast(target); + if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) { + if (trampolin_data == NULL) { + DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin isn't provided\n"); + DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); + return false; + } else { + relocation_trampolin_entry_t *freeSlot = NULL; + for (uint32_t i = 0; i < trampolin_data_length; i++) { + // We want to override "old" relocations of imports + // Pending relocations have the status RELOC_TRAMP_IMPORT_IN_PROGRESS. + // When all relocations are done successfully, they will be turned into RELOC_TRAMP_IMPORT_DONE + // so they can be overridden/updated/reused on the next application launch. + // + // Relocations that won't change will have the status RELOC_TRAMP_FIXED and are set to free when the module is unloaded. + if (trampolin_data[i].status == RELOC_TRAMP_FREE || + trampolin_data[i].status == RELOC_TRAMP_IMPORT_DONE) { + freeSlot = &(trampolin_data[i]); + break; + } + } + if (freeSlot != NULL) { + DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin data list is full\n"); + DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); + return false; + } + if (target - (uint32_t) &(freeSlot->trampolin[0]) > 0x1FFFFFC) { + DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer)."); + DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); + return false; + } + + freeSlot->trampolin[0] = 0x3D600000 | ((((uint32_t) value) >> 16) & 0x0000FFFF); // lis r11, real_addr@h + freeSlot->trampolin[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l + freeSlot->trampolin[2] = 0x7D6903A6; // mtctr r11 + freeSlot->trampolin[3] = 0x4E800420; // bctr + DCFlushRange((void *) freeSlot->trampolin, sizeof(freeSlot->trampolin)); + ICInvalidateRange((unsigned char *) freeSlot->trampolin, sizeof(freeSlot->trampolin)); + + if (reloc_type == RELOC_TYPE_FIXED) { + freeSlot->status = RELOC_TRAMP_FIXED; + } else { + // Relocations for the imports may be overridden + freeSlot->status = RELOC_TRAMP_IMPORT_IN_PROGRESS; + } + uint32_t symbolValue = (uint32_t) &(freeSlot->trampolin[0]); + value = symbolValue + addend; + distance = static_cast(value) - static_cast(target); + DEBUG_FUNCTION_LINE("Created tramp\n"); + } + } + + if (distance & 3) { + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470022); + return false; + } + + if (distance < 0 && (distance & 0xFE000000) != 0xFE000000) { + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (1).", -470040); + return false; + } + + if (distance >= 0 && (distance & 0xFE000000)) { + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (0).", -470040); + return false; + } + + *(int32_t *) target = (*(int32_t *) target & 0xfc000003) | (distance & 0x03fffffc); + break; + } + default: + DEBUG_FUNCTION_LINE("***ERROR: Unsupported Relocation_Add Type (%08X):", type); return false; - } - - if (distance < 0 && (distance & 0xFE000000) != 0xFE000000) { - DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (1).", -470040); - return false; - } - - if (distance >= 0 && (distance & 0xFE000000)) { - DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (0).", -470040); - return false; - } - - *(int32_t *)target = (*(int32_t *)target & 0xfc000003) | (distance & 0x03fffffc); - break; - } - default: - DEBUG_FUNCTION_LINE("***ERROR: Unsupported Relocation_Add Type (%08X):", type); - return false; } return true; } diff --git a/relocator/src/ElfUtils.h b/relocator/src/ElfUtils.h index 5f8bec6..044701e 100644 --- a/relocator/src/ElfUtils.h +++ b/relocator/src/ElfUtils.h @@ -42,5 +42,5 @@ extern "C" { class ElfUtils { public: - static bool elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type); + static bool elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type); }; diff --git a/relocator/src/ModuleDataPersistence.cpp b/relocator/src/ModuleDataPersistence.cpp index 85c36c5..de9520c 100644 --- a/relocator/src/ModuleDataPersistence.cpp +++ b/relocator/src/ModuleDataPersistence.cpp @@ -5,19 +5,19 @@ #include "../../source/module/RelocationData.h" #include -bool ModuleDataPersistence::saveModuleData(module_information_t * moduleInformation, const ModuleData& module) { +bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformation, const ModuleData &module) { int32_t module_count = moduleInformation->number_used_modules; - if(module_count >= MAXIMUM_MODULES) { + if (module_count >= MAXIMUM_MODULES) { return false; } // Copy data to global struct. - module_information_single_t * module_data = &(moduleInformation->module_data[module_count]); + module_information_single_t *module_data = &(moduleInformation->module_data[module_count]); // Relocation std::vector relocationData = module.getRelocationDataList(); - for (auto const& reloc : relocationData) { - if(!DynamicLinkingHelper::addReloationEntry(&(moduleInformation->linking_data), module_data->linking_entries, DYN_LINK_RELOCATION_LIST_LENGTH, reloc)) { + for (auto const &reloc : relocationData) { + if (!DynamicLinkingHelper::addReloationEntry(&(moduleInformation->linking_data), module_data->linking_entries, DYN_LINK_RELOCATION_LIST_LENGTH, reloc)) { return false; } } @@ -33,30 +33,30 @@ bool ModuleDataPersistence::saveModuleData(module_information_t * moduleInformat moduleInformation->number_used_modules++; - DCFlushRange((void*)moduleInformation,sizeof(module_information_t)); - ICInvalidateRange((void*)moduleInformation,sizeof(module_information_t)); + DCFlushRange((void *) moduleInformation, sizeof(module_information_t)); + ICInvalidateRange((void *) moduleInformation, sizeof(module_information_t)); return true; } -std::vector ModuleDataPersistence::loadModuleData(module_information_t * moduleInformation) { +std::vector ModuleDataPersistence::loadModuleData(module_information_t *moduleInformation) { std::vector result; - if(moduleInformation == NULL) { + if (moduleInformation == NULL) { DEBUG_FUNCTION_LINE("moduleInformation == NULL\n"); return result; } - DCFlushRange((void*)moduleInformation,sizeof(module_information_t)); - ICInvalidateRange((void*)moduleInformation,sizeof(module_information_t)); + DCFlushRange((void *) moduleInformation, sizeof(module_information_t)); + ICInvalidateRange((void *) moduleInformation, sizeof(module_information_t)); int32_t module_count = moduleInformation->number_used_modules; - if(module_count > MAXIMUM_MODULES) { - DEBUG_FUNCTION_LINE("moduleInformation->module_count was bigger then allowed. %d > %d. Limiting to %d\n",module_count, MAXIMUM_MODULES, MAXIMUM_MODULES); + if (module_count > MAXIMUM_MODULES) { + DEBUG_FUNCTION_LINE("moduleInformation->module_count was bigger then allowed. %d > %d. Limiting to %d\n", module_count, MAXIMUM_MODULES, MAXIMUM_MODULES); module_count = MAXIMUM_MODULES; } - for(int32_t i = 0; i < module_count; i++) { + for (int32_t i = 0; i < module_count; i++) { // Copy data from struct. - module_information_single_t * module_data = &(moduleInformation->module_data[i]); + module_information_single_t *module_data = &(moduleInformation->module_data[i]); ModuleData moduleData; moduleData.setBSSLocation(module_data->bssAddr, module_data->bssSize); @@ -65,27 +65,27 @@ std::vector ModuleDataPersistence::loadModuleData(module_information moduleData.setStartAddress(module_data->startAddress); moduleData.setEndAddress(module_data->endAddress); - for(uint32_t j = 0; j < DYN_LINK_RELOCATION_LIST_LENGTH; j++) { - dyn_linking_relocation_entry_t * linking_entry = &(module_data->linking_entries[j]); - if(linking_entry->destination == NULL){ + for (uint32_t j = 0; j < DYN_LINK_RELOCATION_LIST_LENGTH; j++) { + dyn_linking_relocation_entry_t *linking_entry = &(module_data->linking_entries[j]); + if (linking_entry->destination == NULL) { break; } - dyn_linking_import_t* importEntry = linking_entry->importEntry; - if(importEntry == NULL){ + dyn_linking_import_t *importEntry = linking_entry->importEntry; + if (importEntry == NULL) { DEBUG_FUNCTION_LINE("importEntry was NULL, skipping relocation entry\n"); continue; } - if(importEntry->importName == NULL){ + if (importEntry->importName == NULL) { DEBUG_FUNCTION_LINE("importEntry->importName was NULL, skipping relocation entry\n"); continue; } - dyn_linking_function_t* functionEntry = linking_entry->functionEntry; + dyn_linking_function_t *functionEntry = linking_entry->functionEntry; - if(functionEntry == NULL){ + if (functionEntry == NULL) { DEBUG_FUNCTION_LINE("functionEntry was NULL, skipping relocation entry\n"); continue; } - if(functionEntry->functionName == NULL){ + if (functionEntry->functionName == NULL) { DEBUG_FUNCTION_LINE("functionEntry->functionName was NULL, skipping relocation entry\n"); continue; } diff --git a/relocator/src/ModuleDataPersistence.h b/relocator/src/ModuleDataPersistence.h index 98242bc..bba9337 100644 --- a/relocator/src/ModuleDataPersistence.h +++ b/relocator/src/ModuleDataPersistence.h @@ -5,6 +5,7 @@ class ModuleDataPersistence { public: - static bool saveModuleData(module_information_t * moduleInformation, const ModuleData& module); - static std::vector loadModuleData(module_information_t * moduleInformation); + static bool saveModuleData(module_information_t *moduleInformation, const ModuleData &module); + + static std::vector loadModuleData(module_information_t *moduleInformation); }; diff --git a/relocator/src/entry.cpp b/relocator/src/entry.cpp index f104592..07fe8d9 100644 --- a/relocator/src/entry.cpp +++ b/relocator/src/entry.cpp @@ -32,31 +32,31 @@ extern "C" int _start(int argc, char **argv) { socket_lib_init(); log_init(); - doStart(argc,argv); + doStart(argc, argv); DEBUG_FUNCTION_LINE("Call real one\n"); - return ( (int (*)(int, char **))(*(unsigned int*)0x1005E040) )(argc, argv); + return ((int (*)(int, char **)) (*(unsigned int *) 0x1005E040))(argc, argv); } -bool doRelocation(std::vector &relocData, relocation_trampolin_entry_t * tramp_data, uint32_t tramp_length) { - std::map moduleCache; - for (auto const& curReloc : relocData) { +bool doRelocation(std::vector &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length) { + std::map moduleCache; + for (auto const &curReloc : relocData) { std::string functionName = curReloc.getName(); std::string rplName = curReloc.getImportRPLInformation().getName(); int32_t isData = curReloc.getImportRPLInformation().isData(); OSDynLoad_Module rplHandle = 0; - if(moduleCache.count(rplName) == 0){ + if (moduleCache.count(rplName) == 0) { OSDynLoad_Acquire(rplName.c_str(), &rplHandle); moduleCache[rplName] = rplHandle; } rplHandle = moduleCache.at(rplName); uint32_t functionAddress = 0; - OSDynLoad_FindExport(rplHandle, isData, functionName.c_str(), (void**) &functionAddress); - if(functionAddress == 0) { + OSDynLoad_FindExport(rplHandle, isData, functionName.c_str(), (void **) &functionAddress); + if (functionAddress == 0) { DEBUG_FUNCTION_LINE("Failed to find function\n"); return false; } - if(!ElfUtils::elfLinkOne(curReloc.getType(), curReloc.getOffset(), curReloc.getAddend(), (uint32_t) curReloc.getDestination(), functionAddress, tramp_data, tramp_length, RELOC_TYPE_IMPORT)) { + if (!ElfUtils::elfLinkOne(curReloc.getType(), curReloc.getOffset(), curReloc.getAddend(), (uint32_t) curReloc.getDestination(), functionAddress, tramp_data, tramp_length, RELOC_TYPE_IMPORT)) { DEBUG_FUNCTION_LINE("Relocation failed\n"); return false; } @@ -66,36 +66,37 @@ bool doRelocation(std::vector &relocData, relocation_trampolin_e ICInvalidateRange(tramp_data, tramp_length * sizeof(relocation_trampolin_entry_t)); return true; } + bool ResolveRelocations() { std::vector loadedModules = ModuleDataPersistence::loadModuleData(gModuleData); bool wasSuccessful = true; uint32_t count = 0; - for (auto const& curModule : loadedModules) { - if(wasSuccessful) { + for (auto const &curModule : loadedModules) { + if (wasSuccessful) { std::vector relocData = curModule.getRelocationDataList(); - if(!doRelocation(relocData, gModuleData->trampolines,DYN_LINK_TRAMPOLIN_LIST_LENGTH)) { + if (!doRelocation(relocData, gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH)) { DEBUG_FUNCTION_LINE("FAIL\n"); wasSuccessful = false; } } - if(curModule.getBSSAddr() != 0){ + if (curModule.getBSSAddr() != 0) { DEBUG_FUNCTION_LINE("memset .bss %08X (%d)\n", curModule.getBSSAddr(), curModule.getBSSSize()); - memset((void*)curModule.getBSSAddr(), 0, curModule.getBSSSize()); + memset((void *) curModule.getBSSAddr(), 0, curModule.getBSSSize()); } - if(curModule.getSBSSAddr() != 0){ + if (curModule.getSBSSAddr() != 0) { DEBUG_FUNCTION_LINE("memset .sbss %08X (%d)\n", curModule.getSBSSAddr(), curModule.getSBSSSize()); - memset((void*)curModule.getSBSSAddr(), 0, curModule.getSBSSSize()); + memset((void *) curModule.getSBSSAddr(), 0, curModule.getSBSSSize()); } } - if(count > 0) { - DCFlushRange((void*) 0x00800000, 0x00800000); - ICInvalidateRange((void*) 0x00800000, 0x00800000); + if (count > 0) { + DCFlushRange((void *) 0x00800000, 0x00800000); + ICInvalidateRange((void *) 0x00800000, 0x00800000); } return wasSuccessful; } extern "C" void doStart(int argc, char **argv) { - if(!gFunctionsPatched){ + if (!gFunctionsPatched) { gFunctionsPatched = 1; kernelInitialize(); PatchInvidualMethodHooks(method_hooks_hooks_static, method_hooks_size_hooks_static, method_calls_hooks_static); @@ -103,9 +104,9 @@ extern "C" void doStart(int argc, char **argv) { DEBUG_FUNCTION_LINE("Resolve relocations\n"); DEBUG_FUNCTION_LINE("Number of modules %d\n", gModuleData->number_used_modules); ResolveRelocations(); - for(int i = 0; inumber_used_modules; i++) { - DEBUG_FUNCTION_LINE("About to call %08X\n",gModuleData->module_data[i].entrypoint); - int ret = ( (int (*)(int, char **))(gModuleData->module_data[i].entrypoint) )(argc, argv); + for (int i = 0; i < gModuleData->number_used_modules; i++) { + DEBUG_FUNCTION_LINE("About to call %08X\n", gModuleData->module_data[i].entrypoint); + int ret = ((int (*)(int, char **)) (gModuleData->module_data[i].entrypoint))(argc, argv); DEBUG_FUNCTION_LINE("return code was %d\n", ret); } } diff --git a/relocator/src/hooks_patcher_static.cpp b/relocator/src/hooks_patcher_static.cpp index becd749..c6e83c2 100644 --- a/relocator/src/hooks_patcher_static.cpp +++ b/relocator/src/hooks_patcher_static.cpp @@ -10,12 +10,12 @@ DECL(OSDynLoad_Error, OSDynLoad_Acquire, char const *name, OSDynLoad_Module *out DECL(OSDynLoad_Error, OSDynLoad_FindExport, OSDynLoad_Module module, BOOL isData, char const *name, void **outAddr) { DEBUG_FUNCTION_LINE("%s\n", name); - return real_OSDynLoad_FindExport(module,isData, name, outAddr); + return real_OSDynLoad_FindExport(module, isData, name, outAddr); } hooks_magic_t method_hooks_hooks_static[] __attribute__((section(".data"))) = { - MAKE_MAGIC(OSDynLoad_Acquire, LIB_CORE_INIT, STATIC_FUNCTION), - MAKE_MAGIC(OSDynLoad_FindExport, LIB_CORE_INIT, STATIC_FUNCTION) + MAKE_MAGIC(OSDynLoad_Acquire, LIB_CORE_INIT, STATIC_FUNCTION), + MAKE_MAGIC(OSDynLoad_FindExport, LIB_CORE_INIT, STATIC_FUNCTION) }; uint32_t method_hooks_size_hooks_static __attribute__((section(".data"))) = sizeof(method_hooks_hooks_static) / sizeof(hooks_magic_t); diff --git a/relocator/src/kernel/kernel_utils.c b/relocator/src/kernel/kernel_utils.c index 058902c..94d8a5a 100644 --- a/relocator/src/kernel/kernel_utils.c +++ b/relocator/src/kernel/kernel_utils.c @@ -81,7 +81,7 @@ void PatchSyscall(int index, uint32_t addr) { void kernelInitialize() { static uint8_t ucSyscallsSetupRequired = 1; - if (!ucSyscallsSetupRequired){ + if (!ucSyscallsSetupRequired) { return; } diff --git a/relocator/src/utils/dynamic.c b/relocator/src/utils/dynamic.c index 263bf73..45f5b07 100644 --- a/relocator/src/utils/dynamic.c +++ b/relocator/src/utils/dynamic.c @@ -4,6 +4,7 @@ #define IMPORT(name) void* addr_##name #define IMPORT_BEGIN(lib) #define IMPORT_END() + #include "imports.h" #undef IMPORT @@ -23,13 +24,13 @@ EXPORT_VAR(uint32_t *, pMEMFreeToDefaultHeap); void InitFunctionPointers(void) { OSDynLoad_Module handle; - addr_OSDynLoad_Acquire = (void*) 0x0102A3B4; - addr_OSDynLoad_FindExport = (void*) 0x0102B828; + addr_OSDynLoad_Acquire = (void *) 0x0102A3B4; + addr_OSDynLoad_FindExport = (void *) 0x0102B828; OSDynLoad_Acquire("coreinit.rpl", &handle); - OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeapEx", (void**) &pMEMAllocFromDefaultHeapEx); - OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeap", (void**) &pMEMAllocFromDefaultHeap); - OSDynLoad_FindExport(handle, 1, "MEMFreeToDefaultHeap", (void**) &pMEMFreeToDefaultHeap); + OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeapEx", (void **) &pMEMAllocFromDefaultHeapEx); + OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeap", (void **) &pMEMAllocFromDefaultHeap); + OSDynLoad_FindExport(handle, 1, "MEMFreeToDefaultHeap", (void **) &pMEMFreeToDefaultHeap); #include "imports.h" diff --git a/relocator/src/utils/logger.c b/relocator/src/utils/logger.c index 74cc2b3..f682284 100644 --- a/relocator/src/utils/logger.c +++ b/relocator/src/utils/logger.c @@ -10,7 +10,7 @@ #include #include -static int log_socket __attribute__((section(".data")))= -1; +static int log_socket __attribute__((section(".data"))) = -1; static struct sockaddr_in connect_addr __attribute__((section(".data"))); static volatile int log_lock __attribute__((section(".data"))) = 0; @@ -30,11 +30,11 @@ void log_init_() { void log_print_(const char *str) { // socket is always 0 initially as it is in the BSS - if(log_socket < 0) { + if (log_socket < 0) { return; } - while(log_lock) { + while (log_lock) { OSSleepTicks(OSMicrosecondsToTicks(1000)); } log_lock = 1; @@ -43,8 +43,8 @@ void log_print_(const char *str) { int ret; while (len > 0) { int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet - ret = sendto(log_socket, str, block, 0, (struct sockaddr *)&connect_addr, sizeof(struct sockaddr_in)); - if(ret < 0) + ret = sendto(log_socket, str, block, 0, (struct sockaddr *) &connect_addr, sizeof(struct sockaddr_in)); + if (ret < 0) break; len -= ret; @@ -59,14 +59,14 @@ void OSFatal_printf(const char *format, ...) { tmp[0] = 0; va_list va; va_start(va, format); - if((vsprintf(tmp, format, va) >= 0)) { + if ((vsprintf(tmp, format, va) >= 0)) { OSFatal(tmp); } va_end(va); } void log_printf_(const char *format, ...) { - if(log_socket < 0) { + if (log_socket < 0) { return; } @@ -75,7 +75,7 @@ void log_printf_(const char *format, ...) { va_list va; va_start(va, format); - if((vsprintf(tmp, format, va) >= 0)) { + if ((vsprintf(tmp, format, va) >= 0)) { log_print_(tmp); } va_end(va); diff --git a/relocator/src/utils/logger.h b/relocator/src/utils/logger.h index d026b05..b6f1040 100644 --- a/relocator/src/utils/logger.h +++ b/relocator/src/utils/logger.h @@ -8,9 +8,12 @@ extern "C" { #include void log_init_(); + //void log_deinit_(void); void log_print_(const char *str); + void log_printf_(const char *format, ...); + void OSFatal_printf(const char *format, ...); #define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) @@ -21,7 +24,6 @@ void OSFatal_printf(const char *format, ...); } while (0) - #define log_init() log_init_() //#define log_deinit() log_deinit_() #define log_print(str) log_print_(str) diff --git a/relocator/src/utils/memory.c b/relocator/src/utils/memory.c index 214726d..8aec2b0 100644 --- a/relocator/src/utils/memory.c +++ b/relocator/src/utils/memory.c @@ -21,15 +21,15 @@ #include #include -extern uint32_t * pMEMAllocFromDefaultHeapEx; -extern uint32_t * pMEMAllocFromDefaultHeap; -extern uint32_t * pMEMFreeToDefaultHeap; +extern uint32_t *pMEMAllocFromDefaultHeapEx; +extern uint32_t *pMEMAllocFromDefaultHeap; +extern uint32_t *pMEMFreeToDefaultHeap; //!------------------------------------------------------------------------------------------- //! reent versions //!------------------------------------------------------------------------------------------- void *_malloc_r(struct _reent *r, size_t size) { - void *ptr = ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(size); + void *ptr = ((void *(*)(size_t)) (*pMEMAllocFromDefaultHeap))(size); if (!ptr) { r->_errno = ENOMEM; } @@ -37,7 +37,7 @@ void *_malloc_r(struct _reent *r, size_t size) { } void *_calloc_r(struct _reent *r, size_t num, size_t size) { - void *ptr = ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(size); + void *ptr = ((void *(*)(size_t)) (*pMEMAllocFromDefaultHeap))(size); if (ptr) { memset(ptr, 0, num * size); } else { @@ -48,17 +48,17 @@ void *_calloc_r(struct _reent *r, size_t num, size_t size) { } void *_memalign_r(struct _reent *r, size_t align, size_t size) { - return ((void * (*)(size_t, size_t))(*pMEMAllocFromDefaultHeapEx))(size, align); + return ((void *(*)(size_t, size_t)) (*pMEMAllocFromDefaultHeapEx))(size, align); } void _free_r(struct _reent *r, void *ptr) { if (ptr) { - ((void (*)(void *))(*pMEMFreeToDefaultHeap))(ptr); + ((void (*)(void *)) (*pMEMFreeToDefaultHeap))(ptr); } } void *_realloc_r(struct _reent *r, void *p, size_t size) { - void *new_ptr = ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(size); + void *new_ptr = ((void *(*)(size_t)) (*pMEMAllocFromDefaultHeap))(size); if (!new_ptr) { r->_errno = ENOMEM; return new_ptr; @@ -67,13 +67,13 @@ void *_realloc_r(struct _reent *r, void *p, size_t size) { if (p) { size_t old_size = MEMGetSizeForMBlockExpHeap(p); memcpy(new_ptr, p, old_size <= size ? old_size : size); - ((void (*)(void *))(*pMEMFreeToDefaultHeap))(p); + ((void (*)(void *)) (*pMEMFreeToDefaultHeap))(p); } return new_ptr; } struct mallinfo _mallinfo_r(struct _reent *r) { - struct mallinfo info = { 0 }; + struct mallinfo info = {0}; return info; } @@ -93,12 +93,12 @@ _malloc_usable_size_r(struct _reent *r, void *ptr) { void * _valloc_r(struct _reent *r, size_t size) { - return ((void * (*)(size_t, size_t))(*pMEMAllocFromDefaultHeapEx))(size, OS_PAGE_SIZE); + return ((void *(*)(size_t, size_t)) (*pMEMAllocFromDefaultHeapEx))(size, OS_PAGE_SIZE); } void * _pvalloc_r(struct _reent *r, size_t size) { - return ((void * (*)(size_t, size_t))(*pMEMAllocFromDefaultHeapEx))((size + (OS_PAGE_SIZE - 1)) & ~(OS_PAGE_SIZE - 1), OS_PAGE_SIZE); + return ((void *(*)(size_t, size_t)) (*pMEMAllocFromDefaultHeapEx))((size + (OS_PAGE_SIZE - 1)) & ~(OS_PAGE_SIZE - 1), OS_PAGE_SIZE); } int diff --git a/relocator/src/utils/memory.h b/relocator/src/utils/memory.h index db67a05..bac713f 100644 --- a/relocator/src/utils/memory.h +++ b/relocator/src/utils/memory.h @@ -24,15 +24,19 @@ extern "C" { #include void memoryInitialize(void); + void memoryRelease(void); -void * MEM2_alloc(u32 size, u32 align); +void *MEM2_alloc(u32 size, u32 align); + void MEM2_free(void *ptr); -void * MEM1_alloc(u32 size, u32 align); +void *MEM1_alloc(u32 size, u32 align); + void MEM1_free(void *ptr); -void * MEMBucket_alloc(u32 size, u32 align); +void *MEMBucket_alloc(u32 size, u32 align); + void MEMBucket_free(void *ptr); #ifdef __cplusplus diff --git a/source/ElfUtils.cpp b/source/ElfUtils.cpp index ace159a..e772bc9 100644 --- a/source/ElfUtils.cpp +++ b/source/ElfUtils.cpp @@ -12,10 +12,10 @@ #include "elfio/elfio.hpp" #include "ElfUtils.h" -int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * sizeOut) { +int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t *sizeOut) { char path[256]; int result = 0; - char * sdRootPath = NULL; + char *sdRootPath = NULL; if (!WHBMountSdCard()) { WHBLogPrintf("Failed to mount SD Card..."); result = -1; @@ -23,9 +23,9 @@ int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * s } sdRootPath = WHBGetSdCardMountPath(); - sprintf(path, "%s/%s", sdRootPath,relativefilepath); + sprintf(path, "%s/%s", sdRootPath, relativefilepath); - WHBLogPrintf("Loading file %s.",path); + WHBLogPrintf("Loading file %s.", path); *fileOut = WHBReadWholeFile(path, sizeOut); if (!(*fileOut)) { @@ -34,25 +34,25 @@ int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * s goto exit; } -exit: + exit: WHBUnmountSdCard(); return result; } -uint32_t load_loader_elf_from_sd(unsigned char* baseAddress, const char* relativePath) { - char * elf_data = NULL; +uint32_t load_loader_elf_from_sd(unsigned char *baseAddress, const char *relativePath) { + char *elf_data = NULL; uint32_t fileSize = 0; - if(LoadFileToMem(relativePath, &elf_data, &fileSize) != 0) { + if (LoadFileToMem(relativePath, &elf_data, &fileSize) != 0) { OSFatal("Failed to load hook_payload.elf from the SD Card."); } uint32_t result = load_loader_elf(baseAddress, elf_data, fileSize); - MEMFreeToDefaultHeap((void*)elf_data); + MEMFreeToDefaultHeap((void *) elf_data); return result; } -uint32_t load_loader_elf(unsigned char* baseAddress, char * elf_data, uint32_t fileSize) { +uint32_t load_loader_elf(unsigned char *baseAddress, char *elf_data, uint32_t fileSize) { ELFIO::Elf32_Ehdr *ehdr; ELFIO::Elf32_Phdr *phdrs; uint8_t *image; @@ -60,50 +60,50 @@ uint32_t load_loader_elf(unsigned char* baseAddress, char * elf_data, uint32_t f ehdr = (ELFIO::Elf32_Ehdr *) elf_data; - if(ehdr->e_phoff == 0 || ehdr->e_phnum == 0) { + if (ehdr->e_phoff == 0 || ehdr->e_phnum == 0) { return 0; } - if(ehdr->e_phentsize != sizeof(ELFIO::Elf32_Phdr)) { + if (ehdr->e_phentsize != sizeof(ELFIO::Elf32_Phdr)) { return 0; } - phdrs = (ELFIO::Elf32_Phdr*)(elf_data + ehdr->e_phoff); + phdrs = (ELFIO::Elf32_Phdr *) (elf_data + ehdr->e_phoff); - for(i = 0; i < ehdr->e_phnum; i++) { - if(phdrs[i].p_type != PT_LOAD) { + for (i = 0; i < ehdr->e_phnum; i++) { + if (phdrs[i].p_type != PT_LOAD) { continue; } - if(phdrs[i].p_filesz > phdrs[i].p_memsz) { + if (phdrs[i].p_filesz > phdrs[i].p_memsz) { continue; } - if(!phdrs[i].p_filesz) { + if (!phdrs[i].p_filesz) { continue; } - uint32_t p_paddr = phdrs[i].p_paddr + (uint32_t)baseAddress; + uint32_t p_paddr = phdrs[i].p_paddr + (uint32_t) baseAddress; image = (uint8_t *) (elf_data + phdrs[i].p_offset); - memcpy ((void *) p_paddr, image, phdrs[i].p_filesz); - DCFlushRange((void*)p_paddr, phdrs[i].p_filesz); + memcpy((void *) p_paddr, image, phdrs[i].p_filesz); + DCFlushRange((void *) p_paddr, phdrs[i].p_filesz); - if(phdrs[i].p_flags & PF_X) { - ICInvalidateRange ((void *) p_paddr, phdrs[i].p_memsz); + if (phdrs[i].p_flags & PF_X) { + ICInvalidateRange((void *) p_paddr, phdrs[i].p_memsz); } } //! clear BSS ELFIO::Elf32_Shdr *shdr = (ELFIO::Elf32_Shdr *) (elf_data + ehdr->e_shoff); - for(i = 0; i < ehdr->e_shnum; i++) { - const char *section_name = ((const char*)elf_data) + shdr[ehdr->e_shstrndx].sh_offset + shdr[i].sh_name; - if(section_name[0] == '.' && section_name[1] == 'b' && section_name[2] == 's' && section_name[3] == 's') { - memset((void*)(shdr[i].sh_addr + baseAddress), 0, shdr[i].sh_size); - DCFlushRange((void*)(shdr[i].sh_addr + baseAddress), shdr[i].sh_size); - } else if(section_name[0] == '.' && section_name[1] == 's' && section_name[2] == 'b' && section_name[3] == 's' && section_name[4] == 's') { - memset((void*)(shdr[i].sh_addr + baseAddress), 0, shdr[i].sh_size); - DCFlushRange((void*)(shdr[i].sh_addr + baseAddress), shdr[i].sh_size); + for (i = 0; i < ehdr->e_shnum; i++) { + const char *section_name = ((const char *) elf_data) + shdr[ehdr->e_shstrndx].sh_offset + shdr[i].sh_name; + if (section_name[0] == '.' && section_name[1] == 'b' && section_name[2] == 's' && section_name[3] == 's') { + memset((void *) (shdr[i].sh_addr + baseAddress), 0, shdr[i].sh_size); + DCFlushRange((void *) (shdr[i].sh_addr + baseAddress), shdr[i].sh_size); + } else if (section_name[0] == '.' && section_name[1] == 's' && section_name[2] == 'b' && section_name[3] == 's' && section_name[4] == 's') { + memset((void *) (shdr[i].sh_addr + baseAddress), 0, shdr[i].sh_size); + DCFlushRange((void *) (shdr[i].sh_addr + baseAddress), shdr[i].sh_size); } } @@ -111,146 +111,146 @@ uint32_t load_loader_elf(unsigned char* baseAddress, char * elf_data, uint32_t f } // See https://github.com/decaf-emu/decaf-emu/blob/43366a34e7b55ab9d19b2444aeb0ccd46ac77dea/src/libdecaf/src/cafe/loader/cafe_loader_reloc.cpp#L144 -bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type) { - if(type == R_PPC_NONE) { +bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type) { + if (type == R_PPC_NONE) { return true; } - auto target = destination + offset; + auto target = destination + offset; auto value = symbol_addr + addend; auto relValue = value - static_cast(target); switch (type) { - case R_PPC_NONE: - break; - case R_PPC_ADDR32: - *((uint32_t *)(target)) = value; - break; - case R_PPC_ADDR16_LO: - *((uint16_t *)(target)) = static_cast(value & 0xFFFF); - break; - case R_PPC_ADDR16_HI: - *((uint16_t *)(target)) = static_cast(value >> 16); - break; - case R_PPC_ADDR16_HA: - *((uint16_t *)(target)) = static_cast((value + 0x8000) >> 16); - break; - case R_PPC_DTPMOD32: - DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n"); - //*((int32_t *)(target)) = tlsModuleIndex; - break; - case R_PPC_DTPREL32: - *((uint32_t *)(target)) = value; - break; - case R_PPC_GHS_REL16_HA: - *((uint16_t *)(target)) = static_cast((relValue + 0x8000) >> 16); - break; - case R_PPC_GHS_REL16_HI: - *((uint16_t *)(target)) = static_cast(relValue >> 16); - break; - case R_PPC_GHS_REL16_LO: - *((uint16_t *)(target)) = static_cast(relValue & 0xFFFF); - break; - case R_PPC_REL14: { - auto distance = static_cast(value) - static_cast(target); - if (distance > 0x7FFC || distance < -0x7FFC) { - DEBUG_FUNCTION_LINE("***14-bit relative branch cannot hit target."); - return false; - } - - if (distance & 3) { - DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470040); - return false; - } - - if ((distance >= 0 && (distance & 0xFFFF8000)) || - (distance < 0 && ((distance & 0xFFFF8000) != 0xFFFF8000))) { - DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 17 bits before shift must all be the same.", -470040); - return false; - } - - *(int32_t *)target = (*(int32_t *)target & 0xFFBF0003) | (distance & 0x0000fffc); - break; - } - case R_PPC_REL24: { - // if (isWeakSymbol && !symbolValue) { - // symbolValue = static_cast(target); - // value = symbolValue + addend; - // } - auto distance = static_cast(value) - static_cast(target); - if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) { - if(trampolin_data == NULL) { - DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin isn't provided\n"); - DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); + case R_PPC_NONE: + break; + case R_PPC_ADDR32: + *((uint32_t *) (target)) = value; + break; + case R_PPC_ADDR16_LO: + *((uint16_t *) (target)) = static_cast(value & 0xFFFF); + break; + case R_PPC_ADDR16_HI: + *((uint16_t *) (target)) = static_cast(value >> 16); + break; + case R_PPC_ADDR16_HA: + *((uint16_t *) (target)) = static_cast((value + 0x8000) >> 16); + break; + case R_PPC_DTPMOD32: + DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n"); + //*((int32_t *)(target)) = tlsModuleIndex; + break; + case R_PPC_DTPREL32: + *((uint32_t *) (target)) = value; + break; + case R_PPC_GHS_REL16_HA: + *((uint16_t *) (target)) = static_cast((relValue + 0x8000) >> 16); + break; + case R_PPC_GHS_REL16_HI: + *((uint16_t *) (target)) = static_cast(relValue >> 16); + break; + case R_PPC_GHS_REL16_LO: + *((uint16_t *) (target)) = static_cast(relValue & 0xFFFF); + break; + case R_PPC_REL14: { + auto distance = static_cast(value) - static_cast(target); + if (distance > 0x7FFC || distance < -0x7FFC) { + DEBUG_FUNCTION_LINE("***14-bit relative branch cannot hit target."); return false; - } else { - relocation_trampolin_entry_t * freeSlot = NULL; - for(uint32_t i = 0; i < trampolin_data_length; i++) { - // We want to override "old" relocations of imports - // Pending relocations have the status RELOC_TRAMP_IMPORT_IN_PROGRESS. - // When all relocations are done successfully, they will be turned into RELOC_TRAMP_IMPORT_DONE - // so they can be overridden/updated/reused on the next application launch. - // - // Relocations that won't change will have the status RELOC_TRAMP_FIXED and are set to free when the module is unloaded. - if(trampolin_data[i].status == RELOC_TRAMP_FREE || - trampolin_data[i].status == RELOC_TRAMP_IMPORT_DONE) { - freeSlot = &(trampolin_data[i]); - break; - } - } - if(freeSlot != NULL) { - DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin data list is full\n"); - DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); - return false; - } - if(target - (uint32_t)&(freeSlot->trampolin[0]) > 0x1FFFFFC) { - DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer)."); - DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); - return false; - } - - freeSlot->trampolin[0] = 0x3D600000 | ((((uint32_t) value) >> 16) & 0x0000FFFF); // lis r11, real_addr@h - freeSlot->trampolin[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l - freeSlot->trampolin[2] = 0x7D6903A6; // mtctr r11 - freeSlot->trampolin[3] = 0x4E800420; // bctr - DCFlushRange((void*)freeSlot->trampolin, sizeof(freeSlot->trampolin)); - ICInvalidateRange((unsigned char*)freeSlot->trampolin, sizeof(freeSlot->trampolin)); - - if(reloc_type == RELOC_TYPE_FIXED) { - freeSlot->status = RELOC_TRAMP_FIXED; - } else { - // Relocations for the imports may be overridden - freeSlot->status = RELOC_TRAMP_IMPORT_IN_PROGRESS; - } - uint32_t symbolValue = (uint32_t)&(freeSlot->trampolin[0]); - value = symbolValue + addend; - distance = static_cast(value) - static_cast(target); - DEBUG_FUNCTION_LINE("Created tramp\n"); } - } - if (distance & 3) { - DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470022); + if (distance & 3) { + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470040); + return false; + } + + if ((distance >= 0 && (distance & 0xFFFF8000)) || + (distance < 0 && ((distance & 0xFFFF8000) != 0xFFFF8000))) { + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 17 bits before shift must all be the same.", -470040); + return false; + } + + *(int32_t *) target = (*(int32_t *) target & 0xFFBF0003) | (distance & 0x0000fffc); + break; + } + case R_PPC_REL24: { + // if (isWeakSymbol && !symbolValue) { + // symbolValue = static_cast(target); + // value = symbolValue + addend; + // } + auto distance = static_cast(value) - static_cast(target); + if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) { + if (trampolin_data == NULL) { + DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin isn't provided\n"); + DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); + return false; + } else { + relocation_trampolin_entry_t *freeSlot = NULL; + for (uint32_t i = 0; i < trampolin_data_length; i++) { + // We want to override "old" relocations of imports + // Pending relocations have the status RELOC_TRAMP_IMPORT_IN_PROGRESS. + // When all relocations are done successfully, they will be turned into RELOC_TRAMP_IMPORT_DONE + // so they can be overridden/updated/reused on the next application launch. + // + // Relocations that won't change will have the status RELOC_TRAMP_FIXED and are set to free when the module is unloaded. + if (trampolin_data[i].status == RELOC_TRAMP_FREE || + trampolin_data[i].status == RELOC_TRAMP_IMPORT_DONE) { + freeSlot = &(trampolin_data[i]); + break; + } + } + if (freeSlot != NULL) { + DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin data list is full\n"); + DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); + return false; + } + if (target - (uint32_t) &(freeSlot->trampolin[0]) > 0x1FFFFFC) { + DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer)."); + DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance); + return false; + } + + freeSlot->trampolin[0] = 0x3D600000 | ((((uint32_t) value) >> 16) & 0x0000FFFF); // lis r11, real_addr@h + freeSlot->trampolin[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l + freeSlot->trampolin[2] = 0x7D6903A6; // mtctr r11 + freeSlot->trampolin[3] = 0x4E800420; // bctr + DCFlushRange((void *) freeSlot->trampolin, sizeof(freeSlot->trampolin)); + ICInvalidateRange((unsigned char *) freeSlot->trampolin, sizeof(freeSlot->trampolin)); + + if (reloc_type == RELOC_TYPE_FIXED) { + freeSlot->status = RELOC_TRAMP_FIXED; + } else { + // Relocations for the imports may be overridden + freeSlot->status = RELOC_TRAMP_IMPORT_IN_PROGRESS; + } + uint32_t symbolValue = (uint32_t) &(freeSlot->trampolin[0]); + value = symbolValue + addend; + distance = static_cast(value) - static_cast(target); + DEBUG_FUNCTION_LINE("Created tramp\n"); + } + } + + if (distance & 3) { + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470022); + return false; + } + + if (distance < 0 && (distance & 0xFE000000) != 0xFE000000) { + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (1).", -470040); + return false; + } + + if (distance >= 0 && (distance & 0xFE000000)) { + DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (0).", -470040); + return false; + } + + *(int32_t *) target = (*(int32_t *) target & 0xfc000003) | (distance & 0x03fffffc); + break; + } + default: + DEBUG_FUNCTION_LINE("***ERROR: Unsupported Relocation_Add Type (%08X):", type); return false; - } - - if (distance < 0 && (distance & 0xFE000000) != 0xFE000000) { - DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (1).", -470040); - return false; - } - - if (distance >= 0 && (distance & 0xFE000000)) { - DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (0).", -470040); - return false; - } - - *(int32_t *)target = (*(int32_t *)target & 0xfc000003) | (distance & 0x03fffffc); - break; - } - default: - DEBUG_FUNCTION_LINE("***ERROR: Unsupported Relocation_Add Type (%08X):", type); - return false; } return true; } diff --git a/source/ElfUtils.h b/source/ElfUtils.h index 37c8e4a..e8d6fce 100644 --- a/source/ElfUtils.h +++ b/source/ElfUtils.h @@ -8,9 +8,9 @@ extern "C" { #endif -int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * sizeOut); -uint32_t load_loader_elf_from_sd(unsigned char* baseAddress, const char* relativePath); -uint32_t load_loader_elf(unsigned char* baseAddress, char * elf_data, uint32_t fileSize); +int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t *sizeOut); +uint32_t load_loader_elf_from_sd(unsigned char *baseAddress, const char *relativePath); +uint32_t load_loader_elf(unsigned char *baseAddress, char *elf_data, uint32_t fileSize); #define R_PPC_NONE 0 #define R_PPC_ADDR32 1 @@ -47,5 +47,5 @@ uint32_t load_loader_elf(unsigned char* baseAddress, char * elf_data, uint32_t f class ElfUtils { public: - static bool elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type); + static bool elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type); }; diff --git a/source/common/dynamic_linking_defines.h b/source/common/dynamic_linking_defines.h index 2a87d80..716936a 100644 --- a/source/common/dynamic_linking_defines.h +++ b/source/common/dynamic_linking_defines.h @@ -33,19 +33,19 @@ extern "C" { #define DYN_LINK_TRAMPOLIN_LIST_LENGTH DYN_LINK_FUNCTION_LIST_LENGTH typedef struct _dyn_linking_function_t { - char functionName[DYN_LINK_FUNCTION_NAME_LENGTH+1]; - void * address; + 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]; + char importName[DYN_LINK_IMPORT_NAME_LENGTH + 1]; bool isData = false; } 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; + dyn_linking_function_t *functionEntry = NULL; + dyn_linking_import_t *importEntry = NULL; + void *destination = NULL; char type; size_t offset; int32_t addend; diff --git a/source/fs/CFile.cpp b/source/fs/CFile.cpp index c2a7ae6..c8e78d2 100644 --- a/source/fs/CFile.cpp +++ b/source/fs/CFile.cpp @@ -12,12 +12,12 @@ CFile::CFile() { pos = 0; } -CFile::CFile(const std::string & filepath, eOpenTypes mode) { +CFile::CFile(const std::string &filepath, eOpenTypes mode) { iFd = -1; this->open(filepath, mode); } -CFile::CFile(const uint8_t * mem, int32_t size) { +CFile::CFile(const uint8_t *mem, int32_t size) { iFd = -1; this->open(mem, size); } @@ -26,27 +26,27 @@ CFile::~CFile() { this->close(); } -int32_t CFile::open(const std::string & filepath, eOpenTypes mode) { +int32_t CFile::open(const std::string &filepath, eOpenTypes mode) { this->close(); int32_t openMode = 0; // This depend on the devoptab implementation. // see https://github.com/devkitPro/wut/blob/master/libraries/wutdevoptab/devoptab_fs_open.c#L21 fpr reference - switch(mode) { - default: - case ReadOnly: // file must exist - openMode = O_RDONLY; - break; - case WriteOnly: // file will be created / zerod - openMode = O_TRUNC | O_CREAT | O_WRONLY; - break; - case ReadWrite: // file must exist - openMode = O_RDWR; - break; - case Append: // append to file, file will be created if missing. write only - openMode = O_CREAT | O_APPEND | O_WRONLY; - break; + switch (mode) { + default: + case ReadOnly: // file must exist + openMode = O_RDONLY; + break; + case WriteOnly: // file will be created / zerod + openMode = O_TRUNC | O_CREAT | O_WRONLY; + break; + case ReadWrite: // file must exist + openMode = O_RDWR; + break; + case Append: // append to file, file will be created if missing. write only + openMode = O_CREAT | O_APPEND | O_WRONLY; + break; } //! Using fopen works only on the first launch as expected @@ -54,7 +54,7 @@ int32_t CFile::open(const std::string & filepath, eOpenTypes mode) { //! the .data sections which is needed for a normal application to re-init //! this will be added with launching as RPX iFd = ::open(filepath.c_str(), openMode); - if(iFd < 0) + if (iFd < 0) return iFd; @@ -64,7 +64,7 @@ int32_t CFile::open(const std::string & filepath, eOpenTypes mode) { return 0; } -int32_t CFile::open(const uint8_t * mem, int32_t size) { +int32_t CFile::open(const uint8_t *mem, int32_t size) { this->close(); mem_file = mem; @@ -74,7 +74,7 @@ int32_t CFile::open(const uint8_t * mem, int32_t size) { } void CFile::close() { - if(iFd >= 0) + if (iFd >= 0) ::close(iFd); iFd = -1; @@ -83,24 +83,24 @@ void CFile::close() { pos = 0; } -int32_t CFile::read(uint8_t * ptr, size_t size) { - if(iFd >= 0) { - int32_t ret = ::read(iFd, ptr,size); - if(ret > 0) +int32_t CFile::read(uint8_t *ptr, size_t size) { + if (iFd >= 0) { + int32_t ret = ::read(iFd, ptr, size); + if (ret > 0) pos += ret; return ret; } int32_t readsize = size; - if(readsize > (int64_t) (filesize-pos)) - readsize = filesize-pos; + if (readsize > (int64_t) (filesize - pos)) + readsize = filesize - pos; - if(readsize <= 0) + if (readsize <= 0) return readsize; - if(mem_file != NULL) { - memcpy(ptr, mem_file+pos, readsize); + if (mem_file != NULL) { + memcpy(ptr, mem_file + pos, readsize); pos += readsize; return readsize; } @@ -108,12 +108,12 @@ int32_t CFile::read(uint8_t * ptr, size_t size) { return -1; } -int32_t CFile::write(const uint8_t * ptr, size_t size) { - if(iFd >= 0) { +int32_t CFile::write(const uint8_t *ptr, size_t size) { + if (iFd >= 0) { size_t done = 0; - while(done < size) { + while (done < size) { int32_t ret = ::write(iFd, ptr, size - done); - if(ret <= 0) + if (ret <= 0) return ret; ptr += ret; @@ -130,25 +130,25 @@ int32_t CFile::seek(long int offset, int32_t origin) { int32_t ret = 0; int64_t newPos = pos; - if(origin == SEEK_SET) { + if (origin == SEEK_SET) { newPos = offset; - } else if(origin == SEEK_CUR) { + } else if (origin == SEEK_CUR) { newPos += offset; - } else if(origin == SEEK_END) { - newPos = filesize+offset; + } else if (origin == SEEK_END) { + newPos = filesize + offset; } - if(newPos < 0) { + if (newPos < 0) { pos = 0; } else { pos = newPos; } - if(iFd >= 0) + if (iFd >= 0) ret = ::lseek(iFd, pos, SEEK_SET); - if(mem_file != NULL) { - if(pos > filesize) { + if (mem_file != NULL) { + if (pos > filesize) { pos = filesize; } } @@ -163,8 +163,8 @@ int32_t CFile::fwrite(const char *format, ...) { va_list va; va_start(va, format); - if((vsprintf(tmp, format, va) >= 0)) { - result = this->write((uint8_t *)tmp, strlen(tmp)); + if ((vsprintf(tmp, format, va) >= 0)) { + result = this->write((uint8_t *) tmp, strlen(tmp)); } va_end(va); diff --git a/source/fs/CFile.hpp b/source/fs/CFile.hpp index 8816a49..6c0421b 100644 --- a/source/fs/CFile.hpp +++ b/source/fs/CFile.hpp @@ -18,18 +18,22 @@ public: }; CFile(); - CFile(const std::string & filepath, eOpenTypes mode); - CFile(const uint8_t * memory, int32_t memsize); + + CFile(const std::string &filepath, eOpenTypes mode); + + CFile(const uint8_t *memory, int32_t memsize); + virtual ~CFile(); - int32_t open(const std::string & filepath, eOpenTypes mode); - int32_t open(const uint8_t * memory, int32_t memsize); + int32_t open(const std::string &filepath, eOpenTypes mode); + + int32_t open(const uint8_t *memory, int32_t memsize); BOOL isOpen() const { - if(iFd >= 0) + if (iFd >= 0) return true; - if(mem_file) + if (mem_file) return true; return false; @@ -37,23 +41,29 @@ public: void close(); - int32_t read(uint8_t * ptr, size_t size); - int32_t write(const uint8_t * ptr, size_t size); + int32_t read(uint8_t *ptr, size_t size); + + int32_t write(const uint8_t *ptr, size_t size); + int32_t fwrite(const char *format, ...); + int32_t seek(long int offset, int32_t origin); + uint64_t tell() { return pos; }; + uint64_t size() { return filesize; }; + void rewind() { this->seek(0, SEEK_SET); }; protected: int32_t iFd; - const uint8_t * mem_file; + const uint8_t *mem_file; uint64_t filesize; uint64_t pos; }; diff --git a/source/fs/DirList.cpp b/source/fs/DirList.cpp index 450d4b6..ab2fea4 100644 --- a/source/fs/DirList.cpp +++ b/source/fs/DirList.cpp @@ -42,7 +42,7 @@ DirList::DirList() { Depth = 0; } -DirList::DirList(const std::string & path, const char *filter, uint32_t flags, uint32_t maxDepth) { +DirList::DirList(const std::string &path, const char *filter, uint32_t flags, uint32_t maxDepth) { this->LoadPath(path, filter, flags, maxDepth); this->SortList(); } @@ -51,8 +51,8 @@ DirList::~DirList() { ClearList(); } -BOOL DirList::LoadPath(const std::string & folder, const char *filter, uint32_t flags, uint32_t maxDepth) { - if(folder.empty()) +BOOL DirList::LoadPath(const std::string &folder, const char *filter, uint32_t flags, uint32_t maxDepth) { + if (folder.empty()) return false; Flags = flags; @@ -66,11 +66,11 @@ BOOL DirList::LoadPath(const std::string & folder, const char *filter, uint32_t StringTools::RemoveDoubleSlashs(folderpath); //! remove last slash if exists - if(length > 0 && folderpath[length-1] == '/') - folderpath.erase(length-1); + if (length > 0 && folderpath[length - 1] == '/') + folderpath.erase(length - 1); //! add root slash if missing - if(folderpath.find('/') == std::string::npos) { + if (folderpath.find('/') == std::string::npos) { folderpath += '/'; } @@ -78,7 +78,7 @@ BOOL DirList::LoadPath(const std::string & folder, const char *filter, uint32_t } BOOL DirList::InternalLoadPath(std::string &folderpath) { - if(folderpath.size() < 3) + if (folderpath.size() < 3) return false; struct dirent *dirent = NULL; @@ -92,13 +92,13 @@ BOOL DirList::InternalLoadPath(std::string &folderpath) { BOOL isDir = dirent->d_type & DT_DIR; const char *filename = dirent->d_name; - if(isDir) { - if(strcmp(filename,".") == 0 || strcmp(filename,"..") == 0) + if (isDir) { + if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0) continue; - if((Flags & CheckSubfolders) && (Depth > 0)) { + if ((Flags & CheckSubfolders) && (Depth > 0)) { int32_t length = folderpath.size(); - if(length > 2 && folderpath[length-1] != '/') { + if (length > 2 && folderpath[length - 1] != '/') { folderpath += '/'; } folderpath += filename; @@ -109,18 +109,18 @@ BOOL DirList::InternalLoadPath(std::string &folderpath) { Depth++; } - if(!(Flags & Dirs)) + if (!(Flags & Dirs)) continue; - } else if(!(Flags & Files)) { + } else if (!(Flags & Files)) { continue; } - if(Filter) { - char * fileext = strrchr(filename, '.'); - if(!fileext) + if (Filter) { + char *fileext = strrchr(filename, '.'); + if (!fileext) continue; - if(StringTools::strtokcmp(fileext, Filter, ",") == 0) + if (StringTools::strtokcmp(fileext, Filter, ",") == 0) AddEntrie(folderpath, filename, isDir); } else { AddEntrie(folderpath, filename, isDir); @@ -131,16 +131,16 @@ BOOL DirList::InternalLoadPath(std::string &folderpath) { return true; } -void DirList::AddEntrie(const std::string &filepath, const char * filename, BOOL isDir) { - if(!filename) +void DirList::AddEntrie(const std::string &filepath, const char *filename, BOOL isDir) { + if (!filename) return; int32_t pos = FileInfo.size(); - FileInfo.resize(pos+1); + FileInfo.resize(pos + 1); - FileInfo[pos].FilePath = (char *) malloc(filepath.size()+strlen(filename)+2); - if(!FileInfo[pos].FilePath) { + FileInfo[pos].FilePath = (char *) malloc(filepath.size() + strlen(filename) + 2); + if (!FileInfo[pos].FilePath) { FileInfo.resize(pos); return; } @@ -150,8 +150,8 @@ void DirList::AddEntrie(const std::string &filepath, const char * filename, BOOL } void DirList::ClearList() { - for(uint32_t i = 0; i < FileInfo.size(); ++i) { - if(FileInfo[i].FilePath) { + for (uint32_t i = 0; i < FileInfo.size(); ++i) { + if (FileInfo[i].FilePath) { free(FileInfo[i].FilePath); FileInfo[i].FilePath = NULL; } @@ -161,37 +161,37 @@ void DirList::ClearList() { std::vector().swap(FileInfo); } -const char * DirList::GetFilename(int32_t ind) const { +const char *DirList::GetFilename(int32_t ind) const { if (!valid(ind)) return ""; return StringTools::FullpathToFilename(FileInfo[ind].FilePath); } -static BOOL SortCallback(const DirEntry & f1, const DirEntry & f2) { - if(f1.isDir && !(f2.isDir)) +static BOOL SortCallback(const DirEntry &f1, const DirEntry &f2) { + if (f1.isDir && !(f2.isDir)) return true; - if(!(f1.isDir) && f2.isDir) + if (!(f1.isDir) && f2.isDir) return false; - if(f1.FilePath && !f2.FilePath) + if (f1.FilePath && !f2.FilePath) return true; - if(!f1.FilePath) + if (!f1.FilePath) return false; - if(strcasecmp(f1.FilePath, f2.FilePath) > 0) + if (strcasecmp(f1.FilePath, f2.FilePath) > 0) return false; return true; } void DirList::SortList() { - if(FileInfo.size() > 1) + if (FileInfo.size() > 1) std::sort(FileInfo.begin(), FileInfo.end(), SortCallback); } void DirList::SortList(BOOL (*SortFunc)(const DirEntry &a, const DirEntry &b)) { - if(FileInfo.size() > 1) + if (FileInfo.size() > 1) std::sort(FileInfo.begin(), FileInfo.end(), SortFunc); } @@ -199,14 +199,14 @@ uint64_t DirList::GetFilesize(int32_t index) const { struct stat st; const char *path = GetFilepath(index); - if(!path || stat(path, &st) != 0) + if (!path || stat(path, &st) != 0) return 0; return st.st_size; } int32_t DirList::GetFileIndex(const char *filename) const { - if(!filename) + if (!filename) return -1; for (uint32_t i = 0; i < FileInfo.size(); ++i) { diff --git a/source/fs/DirList.h b/source/fs/DirList.h index b9559aa..08b3fbc 100644 --- a/source/fs/DirList.h +++ b/source/fs/DirList.h @@ -32,7 +32,7 @@ #include typedef struct { - char * FilePath; + char *FilePath; BOOL isDir; } DirEntry; @@ -40,17 +40,22 @@ class DirList { public: //!Constructor DirList(void); + //!\param path Path from where to load the filelist of all files //!\param filter A fileext that needs to be filtered //!\param flags search/filter flags from the enum - DirList(const std::string & path, const char *filter = NULL, uint32_t flags = Files | Dirs, uint32_t maxDepth = 0xffffffff); + DirList(const std::string &path, const char *filter = NULL, uint32_t flags = Files | Dirs, uint32_t maxDepth = 0xffffffff); + //!Destructor virtual ~DirList(); + //! Load all the files from a directory - BOOL LoadPath(const std::string & path, const char *filter = NULL, uint32_t flags = Files | Dirs, uint32_t maxDepth = 0xffffffff); + BOOL LoadPath(const std::string &path, const char *filter = NULL, uint32_t flags = Files | Dirs, uint32_t maxDepth = 0xffffffff); + //! Get a filename of the list //!\param list index - const char * GetFilename(int32_t index) const; + const char *GetFilename(int32_t index) const; + //! Get the a filepath of the list //!\param list index const char *GetFilepath(int32_t index) const { @@ -59,26 +64,33 @@ public: else return FileInfo[index].FilePath; } + //! Get the a filesize of the list //!\param list index uint64_t GetFilesize(int32_t index) const; + //! Is index a dir or a file //!\param list index BOOL IsDir(int32_t index) const { - if(!valid(index)) + if (!valid(index)) return false; return FileInfo[index].isDir; }; + //! Get the filecount of the whole list int32_t GetFilecount() const { return FileInfo.size(); }; + //! Sort list by filepath void SortList(); + //! Custom sort command for custom sort functions definitions void SortList(BOOL (*SortFunc)(const DirEntry &a, const DirEntry &b)); + //! Get the index of the specified filename int32_t GetFileIndex(const char *filename) const; + //! Enum for search/filter flags enum { Files = 0x01, @@ -88,10 +100,13 @@ public: protected: // Internal parser BOOL InternalLoadPath(std::string &path); + //!Add a list entrie - void AddEntrie(const std::string &filepath, const char * filename, BOOL isDir); + void AddEntrie(const std::string &filepath, const char *filename, BOOL isDir); + //! Clear the list void ClearList(); + //! Check if valid pos is requested inline BOOL valid(uint32_t pos) const { return (pos < FileInfo.size()); diff --git a/source/kernel.cpp b/source/kernel.cpp index ebd9328..6600552 100644 --- a/source/kernel.cpp +++ b/source/kernel.cpp @@ -8,18 +8,18 @@ extern "C" void SCKernelCopyData(uint32_t addr, uint32_t src, uint32_t len); extern "C" void SC_KernelCopyData(uint32_t addr, uint32_t src, uint32_t len); void SetupRelocator() { - kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x25 * 4)), (unsigned int)SCKernelCopyData); - kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x25 * 4)), (unsigned int)SCKernelCopyData); - kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x25 * 4)), (unsigned int)SCKernelCopyData); - kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x25 * 4)), (unsigned int)SCKernelCopyData); - kern_write((void*)(KERN_SYSCALL_TBL_5 + (0x25 * 4)), (unsigned int)SCKernelCopyData); + kern_write((void *) (KERN_SYSCALL_TBL_1 + (0x25 * 4)), (unsigned int) SCKernelCopyData); + kern_write((void *) (KERN_SYSCALL_TBL_2 + (0x25 * 4)), (unsigned int) SCKernelCopyData); + kern_write((void *) (KERN_SYSCALL_TBL_3 + (0x25 * 4)), (unsigned int) SCKernelCopyData); + kern_write((void *) (KERN_SYSCALL_TBL_4 + (0x25 * 4)), (unsigned int) SCKernelCopyData); + kern_write((void *) (KERN_SYSCALL_TBL_5 + (0x25 * 4)), (unsigned int) SCKernelCopyData); - uint32_t entryPoint = load_loader_elf(0, (char*) ___relocator_relocator_elf, ___relocator_relocator_elf_len); + uint32_t entryPoint = load_loader_elf(0, (char *) ___relocator_relocator_elf, ___relocator_relocator_elf_len); unsigned int repl_addr = ADDRESS_main_entry_hook; - KernelWriteU32(repl_addr,0x48000003 | entryPoint); - DCFlushRange((void*) repl_addr, 4); - ICInvalidateRange((void*)(repl_addr), 4); + KernelWriteU32(repl_addr, 0x48000003 | entryPoint); + DCFlushRange((void *) repl_addr, 4); + ICInvalidateRange((void *) (repl_addr), 4); } void KernelWriteU32(uint32_t addr, uint32_t value) { @@ -32,28 +32,28 @@ void KernelWriteU32(uint32_t addr, uint32_t value) { SC_KernelCopyData(dst, src, 4); - DCFlushRange((void *)addr, 4); - ICInvalidateRange((void *)addr, 4); + DCFlushRange((void *) addr, 4); + ICInvalidateRange((void *) addr, 4); } /* Write a 32-bit word with kernel permissions */ void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value) { asm volatile ( - "li 3,1\n" - "li 4,0\n" - "mr 5,%1\n" - "li 6,0\n" - "li 7,0\n" - "lis 8,1\n" - "mr 9,%0\n" - "mr %1,1\n" - "li 0,0x3500\n" - "sc\n" - "nop\n" - "mr 1,%1\n" - : - : "r"(addr), "r"(value) - : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", - "11", "12" + "li 3,1\n" + "li 4,0\n" + "mr 5,%1\n" + "li 6,0\n" + "li 7,0\n" + "lis 8,1\n" + "mr 9,%0\n" + "mr %1,1\n" + "li 0,0x3500\n" + "sc\n" + "nop\n" + "mr 1,%1\n" + : + : "r"(addr), "r"(value) + : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", + "11", "12" ); } diff --git a/source/kernel.h b/source/kernel.h index 7870842..d5e0478 100644 --- a/source/kernel.h +++ b/source/kernel.h @@ -1,4 +1,5 @@ #pragma once + #include #define ADDRESS_main_entry_hook 0x0101C56C @@ -10,5 +11,7 @@ #define KERN_SYSCALL_TBL_5 0xFFEAAE60 // works with browser (previously KERN_SYSCALL_TBL) void SetupRelocator(); + void KernelWriteU32(uint32_t addr, uint32_t value); + void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value); diff --git a/source/main.cpp b/source/main.cpp index e8e9469..4b70a67 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -26,20 +26,20 @@ bool CheckRunning() { - switch(ProcUIProcessMessages(true)) { - case PROCUI_STATUS_EXITING: { - return false; - } - case PROCUI_STATUS_RELEASE_FOREGROUND: { - ProcUIDrawDoneRelease(); - break; - } - case PROCUI_STATUS_IN_FOREGROUND: { - break; - } - case PROCUI_STATUS_IN_BACKGROUND: - default: - break; + switch (ProcUIProcessMessages(true)) { + case PROCUI_STATUS_EXITING: { + return false; + } + case PROCUI_STATUS_RELEASE_FOREGROUND: { + ProcUIDrawDoneRelease(); + break; + } + case PROCUI_STATUS_IN_FOREGROUND: { + break; + } + case PROCUI_STATUS_IN_BACKGROUND: + default: + break; } return true; } @@ -50,8 +50,8 @@ static_assert(sizeof(module_information_t) <= 0x80000); extern "C" uint32_t textStart(); -bool doRelocation(std::vector &relocData, relocation_trampolin_entry_t * tramp_data, uint32_t tramp_length) { - for (auto const& curReloc : relocData) { +bool doRelocation(std::vector &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length) { + for (auto const &curReloc : relocData) { std::string functionName = curReloc.getName(); std::string rplName = curReloc.getImportRPLInformation().getName(); int32_t isData = curReloc.getImportRPLInformation().isData(); @@ -59,11 +59,11 @@ bool doRelocation(std::vector &relocData, relocation_trampolin_e OSDynLoad_Acquire(rplName.c_str(), &rplHandle); uint32_t functionAddress = 0; - OSDynLoad_FindExport(rplHandle, isData, functionName.c_str(), (void**) &functionAddress); - if(functionAddress == 0) { + OSDynLoad_FindExport(rplHandle, isData, functionName.c_str(), (void **) &functionAddress); + if (functionAddress == 0) { return false; } - if(!ElfUtils::elfLinkOne(curReloc.getType(), curReloc.getOffset(), curReloc.getAddend(), (uint32_t) curReloc.getDestination(), functionAddress, tramp_data, tramp_length, RELOC_TYPE_IMPORT)) { + if (!ElfUtils::elfLinkOne(curReloc.getType(), curReloc.getOffset(), curReloc.getAddend(), (uint32_t) curReloc.getDestination(), functionAddress, tramp_data, tramp_length, RELOC_TYPE_IMPORT)) { DEBUG_FUNCTION_LINE("Relocation failed\n"); return false; } @@ -74,7 +74,7 @@ bool doRelocation(std::vector &relocData, relocation_trampolin_e return true; } -int main(int argc, char **argv) { +int main(int argc, char **argv) { WHBLogUdpInit(); // 0x100 because before the .text section is a .init section @@ -84,45 +84,45 @@ int main(int argc, char **argv) { DirList setupModules("fs:/vol/external01/wiiu/modules/setup", ".rpx", DirList::Files, 1); setupModules.SortList(); - for(int i = 0; i < setupModules.GetFilecount(); i++) { - memset((void*)gModuleData, 0, sizeof(module_information_t)); - DEBUG_FUNCTION_LINE("Trying to run %s",setupModules.GetFilepath(i)); + for (int i = 0; i < setupModules.GetFilecount(); i++) { + memset((void *) gModuleData, 0, sizeof(module_information_t)); + DEBUG_FUNCTION_LINE("Trying to run %s", setupModules.GetFilepath(i)); std::optional moduleData = ModuleDataFactory::load(setupModules.GetFilepath(i), 0x00900000, 0x01000000 - textSectionStart, gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH); - if(!moduleData) { + if (!moduleData) { DEBUG_FUNCTION_LINE("Failed to load %s", setupModules.GetFilepath(i)); continue; } DEBUG_FUNCTION_LINE("Loaded module data"); std::vector relocData = moduleData->getRelocationDataList(); - if(!doRelocation(relocData, gModuleData->trampolines,DYN_LINK_TRAMPOLIN_LIST_LENGTH)) { + if (!doRelocation(relocData, gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH)) { DEBUG_FUNCTION_LINE("relocations failed\n"); } - if(moduleData->getBSSAddr() != 0) { + if (moduleData->getBSSAddr() != 0) { DEBUG_FUNCTION_LINE("memset .bss %08X (%d)", moduleData->getBSSAddr(), moduleData->getBSSSize()); - memset((void*)moduleData->getBSSAddr(), 0, moduleData->getBSSSize()); + memset((void *) moduleData->getBSSAddr(), 0, moduleData->getBSSSize()); } - if(moduleData->getSBSSAddr() != 0) { + if (moduleData->getSBSSAddr() != 0) { DEBUG_FUNCTION_LINE("memset .sbss %08X (%d)", moduleData->getSBSSAddr(), moduleData->getSBSSSize()); - memset((void*)moduleData->getSBSSAddr(), 0, moduleData->getSBSSSize()); + memset((void *) moduleData->getSBSSAddr(), 0, moduleData->getSBSSSize()); } - DCFlushRange((void*)0x00800000, 0x00800000); - ICInvalidateRange((void*)0x00800000, 0x00800000); + DCFlushRange((void *) 0x00800000, 0x00800000); + ICInvalidateRange((void *) 0x00800000, 0x00800000); DEBUG_FUNCTION_LINE("Calling %08X", moduleData->getEntrypoint()); - ((int (*)(int, char **))moduleData->getEntrypoint())(argc, argv); + ((int (*)(int, char **)) moduleData->getEntrypoint())(argc, argv); DEBUG_FUNCTION_LINE("Back from module"); } - memset((void*)gModuleData, 0, sizeof(module_information_t)); + memset((void *) gModuleData, 0, sizeof(module_information_t)); DirList modules("fs:/vol/external01/wiiu/modules", ".rpx", DirList::Files, 1); modules.SortList(); - for(int i = 0; i < modules.GetFilecount(); i++) { - DEBUG_FUNCTION_LINE("Loading module %s",modules.GetFilepath(i)); + for (int i = 0; i < modules.GetFilecount(); i++) { + DEBUG_FUNCTION_LINE("Loading module %s", modules.GetFilepath(i)); std::optional moduleData = ModuleDataFactory::load(modules.GetFilepath(i), 0x00900000, 0x01000000 - textSectionStart, gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH); - if(moduleData) { + if (moduleData) { DEBUG_FUNCTION_LINE("Successfully loaded %s", modules.GetFilepath(i)); ModuleDataPersistence::saveModuleData(gModuleData, moduleData.value()); } else { @@ -136,7 +136,7 @@ int main(int argc, char **argv) { ProcUIInit(OSSavesDone_ReadyToRelease); SYSLaunchMenu(); - while(CheckRunning()) { + while (CheckRunning()) { // wait. OSSleepTicks(OSMillisecondsToTicks(100)); } diff --git a/source/module/DynamicLinkingHelper.cpp b/source/module/DynamicLinkingHelper.cpp index b98f27b..501cca2 100644 --- a/source/module/DynamicLinkingHelper.cpp +++ b/source/module/DynamicLinkingHelper.cpp @@ -6,26 +6,26 @@ #include "utils/logger.h" #include "common/module_defines.h" -dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t * data, const char* functionName) { - if(data == NULL) { +dyn_linking_function_t *DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, const char *functionName) { + if (data == NULL) { return NULL; } - if(functionName == NULL) { + if (functionName == NULL) { return NULL; } - dyn_linking_function_t * result = NULL; - for(int32_t i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) { - dyn_linking_function_t * curEntry = &(data->functions[i]); - if(strlen(curEntry->functionName) == 0) { - if(strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) { + dyn_linking_function_t *result = NULL; + for (int32_t i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) { + dyn_linking_function_t *curEntry = &(data->functions[i]); + if (strlen(curEntry->functionName) == 0) { + if (strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) { DEBUG_FUNCTION_LINE("Failed to add function name, it's too long.\n"); return NULL; } - strncpy(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH); + strncpy(curEntry->functionName, functionName, DYN_LINK_FUNCTION_NAME_LENGTH); result = curEntry; break; } - if(strncmp(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH) == 0) { + if (strncmp(curEntry->functionName, functionName, DYN_LINK_FUNCTION_NAME_LENGTH) == 0) { result = curEntry; break; } @@ -33,62 +33,65 @@ dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_l return result; } -dyn_linking_import_t * DynamicLinkingHelper::getOrAddFunctionImportByName(dyn_linking_relocation_data_t * data, const char* importName) { +dyn_linking_import_t *DynamicLinkingHelper::getOrAddFunctionImportByName(dyn_linking_relocation_data_t *data, const char *importName) { return getOrAddImport(data, importName, false); } -dyn_linking_import_t * DynamicLinkingHelper::getOrAddDataImportByName(dyn_linking_relocation_data_t * data, const char* importName) { +dyn_linking_import_t *DynamicLinkingHelper::getOrAddDataImportByName(dyn_linking_relocation_data_t *data, const char *importName) { return getOrAddImport(data, importName, true); } -dyn_linking_import_t * DynamicLinkingHelper::getOrAddImport(dyn_linking_relocation_data_t * data, const char* importName, bool isData) { - if(importName == NULL || data == NULL) { +dyn_linking_import_t *DynamicLinkingHelper::getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData) { + if (importName == NULL || data == NULL) { return NULL; } - dyn_linking_import_t * result = NULL; - for(int32_t i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) { - dyn_linking_import_t * curEntry = &(data->imports[i]); - if(strlen(curEntry->importName) == 0) { - if(strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) { + dyn_linking_import_t *result = NULL; + for (int32_t i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) { + dyn_linking_import_t *curEntry = &(data->imports[i]); + if (strlen(curEntry->importName) == 0) { + if (strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) { DEBUG_FUNCTION_LINE("Failed to add Import, it's too long.\n"); return NULL; } - strncpy(curEntry->importName,importName,DYN_LINK_IMPORT_NAME_LENGTH); + 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)) { + if (strncmp(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH) == 0 && (curEntry->isData == isData)) { return curEntry; } } return result; } -bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, const RelocationData& relocationData) { - return addReloationEntry(linking_data, linking_entries, linking_entry_length, relocationData.getType(), relocationData.getOffset(), relocationData.getAddend(), relocationData.getDestination(), relocationData.getName(), relocationData.getImportRPLInformation()); +bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, const RelocationData &relocationData) { + return addReloationEntry(linking_data, linking_entries, linking_entry_length, relocationData.getType(), relocationData.getOffset(), relocationData.getAddend(), relocationData.getDestination(), relocationData.getName(), + relocationData.getImportRPLInformation()); } -bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, std::string name, const ImportRPLInformation& rplInfo) { - dyn_linking_import_t * importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, 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); +bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, + std::string name, const ImportRPLInformation &rplInfo) { + dyn_linking_import_t *importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, 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(linking_data, 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); + dyn_linking_function_t *functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(linking_data, 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(linking_entries, linking_entry_length, type, offset, addend, destination, functionInfo, importInfoGbl); } -bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, dyn_linking_function_t * functionName, dyn_linking_import_t * importInfo) { - for(uint32_t i = 0; i < linking_entry_length; i++) { - dyn_linking_relocation_entry_t * curEntry = &(linking_entries[i]); - if(curEntry->functionEntry != NULL) { +bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, dyn_linking_function_t *functionName, + dyn_linking_import_t *importInfo) { + for (uint32_t i = 0; i < linking_entry_length; i++) { + dyn_linking_relocation_entry_t *curEntry = &(linking_entries[i]); + if (curEntry->functionEntry != NULL) { continue; } curEntry->type = type; diff --git a/source/module/DynamicLinkingHelper.h b/source/module/DynamicLinkingHelper.h index 0ed97ee..4dfa5eb 100644 --- a/source/module/DynamicLinkingHelper.h +++ b/source/module/DynamicLinkingHelper.h @@ -1,4 +1,5 @@ #pragma once + #include "common/dynamic_linking_defines.h" #include "utils/logger.h" #include @@ -13,7 +14,7 @@ public: \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. **/ - static dyn_linking_function_t * getOrAddFunctionEntryByName(dyn_linking_relocation_data_t * data, const char * functionName); + static dyn_linking_function_t *getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, 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. @@ -22,7 +23,7 @@ public: \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. **/ - static dyn_linking_import_t * getOrAddFunctionImportByName(dyn_linking_relocation_data_t * data, const char * importName); + static dyn_linking_import_t *getOrAddFunctionImportByName(dyn_linking_relocation_data_t *data, const char *importName); /** @@ -32,7 +33,7 @@ public: \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. **/ - static dyn_linking_import_t * getOrAddDataImportByName(dyn_linking_relocation_data_t * data, const char * importName); + static dyn_linking_import_t *getOrAddDataImportByName(dyn_linking_relocation_data_t *data, const char *importName); /** @@ -44,13 +45,16 @@ public: \return Returns a pointer to the data import entry which contains the importName. Null on error or if the list full. **/ - static dyn_linking_import_t * getOrAddImport(dyn_linking_relocation_data_t * data, const char * importName, bool isData); + static dyn_linking_import_t *getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData); - static bool addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, const RelocationData& relocationData); + static bool addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, const RelocationData &relocationData); - static bool addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, std::string name, const ImportRPLInformation& rplInfo); + static bool addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, std::string name, + const ImportRPLInformation &rplInfo); + + static bool + addReloationEntry(dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, dyn_linking_function_t *functionName, dyn_linking_import_t *importInfo); - static bool addReloationEntry(dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, dyn_linking_function_t * functionName, dyn_linking_import_t * importInfo); private: DynamicLinkingHelper() { } diff --git a/source/module/ImportRPLInformation.h b/source/module/ImportRPLInformation.h index 648a732..1628c7f 100644 --- a/source/module/ImportRPLInformation.h +++ b/source/module/ImportRPLInformation.h @@ -40,7 +40,7 @@ public: std::string rplName = ""; - if(rawSectionName.size() < fimport.size()) { + if (rawSectionName.size() < fimport.size()) { return std::nullopt; } else if (std::equal(fimport.begin(), fimport.end(), rawSectionName.begin())) { rplName = rawSectionName.substr(fimport.size()); diff --git a/source/module/ModuleData.h b/source/module/ModuleData.h index 2ded0f4..9b7e117 100644 --- a/source/module/ModuleData.h +++ b/source/module/ModuleData.h @@ -53,11 +53,11 @@ public: this->endAddress = endAddress; } - void addRelocationData(const RelocationData& relocation_data) { + void addRelocationData(const RelocationData &relocation_data) { relocation_data_list.push_back(relocation_data); } - const std::vector& getRelocationDataList() const { + const std::vector &getRelocationDataList() const { return relocation_data_list; } @@ -80,31 +80,32 @@ public: return bssAddr; } - uint32_t getBSSSize() const{ + uint32_t getBSSSize() const { return bssSize; } - uint32_t getSBSSAddr() const{ + uint32_t getSBSSAddr() const { return sbssAddr; } - uint32_t getSBSSSize() const{ + uint32_t getSBSSSize() const { return sbssSize; } - uint32_t getEntrypoint() const{ + uint32_t getEntrypoint() const { return entrypoint; } - uint32_t getStartAddress() const{ + uint32_t getStartAddress() const { return startAddress; } - uint32_t getEndAddress() const{ + uint32_t getEndAddress() const { return endAddress; } std::string toString() const; + private: std::vector relocation_data_list; std::map section_info_list; diff --git a/source/module/ModuleDataFactory.cpp b/source/module/ModuleDataFactory.cpp index 4d1319b..5616698 100644 --- a/source/module/ModuleDataFactory.cpp +++ b/source/module/ModuleDataFactory.cpp @@ -27,7 +27,7 @@ using namespace ELFIO; -std::optional ModuleDataFactory::load(std::string path, uint32_t destination_address, uint32_t maximum_size, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length) { +std::optional ModuleDataFactory::load(std::string path, uint32_t destination_address, uint32_t maximum_size, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length) { elfio reader; ModuleData moduleData; @@ -52,8 +52,8 @@ std::optional ModuleDataFactory::load(std::string path, uint32_t des uint32_t endAddress = 0; - for(uint32_t i = 0; i < sec_num; ++i ) { - section* psec = reader.sections[i]; + for (uint32_t i = 0; i < sec_num; ++i) { + section *psec = reader.sections[i]; if (psec->get_type() == 0x80000002) { continue; } @@ -65,15 +65,15 @@ std::optional ModuleDataFactory::load(std::string path, uint32_t des destinations[psec->get_index()] = (uint8_t *) baseOffset; uint32_t destination = baseOffset + address; - if((address >= 0x02000000) && address < 0x10000000) { + if ((address >= 0x02000000) && address < 0x10000000) { destination -= 0x02000000; destinations[psec->get_index()] -= 0x02000000; baseOffset += sectionSize; offset_data += sectionSize; - } else if((address >= 0x10000000) && address < 0xC0000000) { + } else if ((address >= 0x10000000) && address < 0xC0000000) { destination -= 0x10000000; destinations[psec->get_index()] -= 0x10000000; - } else if(address >= 0xC0000000) { + } else if (address >= 0xC0000000) { destination -= 0xC0000000; destinations[psec->get_index()] -= 0xC0000000; } else { @@ -82,21 +82,21 @@ std::optional ModuleDataFactory::load(std::string path, uint32_t des return std::nullopt; } - const char* p = reader.sections[i]->get_data(); + const char *p = reader.sections[i]->get_data(); - if(psec->get_type() == SHT_NOBITS) { + if (psec->get_type() == SHT_NOBITS) { DEBUG_FUNCTION_LINE("memset section %s %08X to 0 (%d bytes)", psec->get_name().c_str(), destination, sectionSize); - memset((void*) destination, 0, sectionSize); - } else if(psec->get_type() == SHT_PROGBITS) { + memset((void *) destination, 0, sectionSize); + } else if (psec->get_type() == SHT_PROGBITS) { DEBUG_FUNCTION_LINE("Copy section %s %08X -> %08X (%d bytes)", psec->get_name().c_str(), p, destination, sectionSize); - memcpy((void*) destination, p, sectionSize); + memcpy((void *) destination, p, sectionSize); } //nextAddress = ROUNDUP(destination + sectionSize,0x100); - if(psec->get_name().compare(".bss") == 0) { + if (psec->get_name().compare(".bss") == 0) { moduleData.setBSSLocation(destination, sectionSize); DEBUG_FUNCTION_LINE("Saved %s section info. Location: %08X size: %08X", psec->get_name().c_str(), destination, sectionSize); - } else if(psec->get_name().compare(".sbss") == 0) { + } else if (psec->get_name().compare(".sbss") == 0) { moduleData.setSBSSLocation(destination, sectionSize); DEBUG_FUNCTION_LINE("Saved %s section info. Location: %08X size: %08X", psec->get_name().c_str(), destination, sectionSize); } @@ -107,19 +107,19 @@ std::optional ModuleDataFactory::load(std::string path, uint32_t des totalSize += sectionSize; - if(endAddress < destination + sectionSize){ + if (endAddress < destination + sectionSize) { endAddress = destination + sectionSize; } - DCFlushRange((void*)destination, sectionSize); - ICInvalidateRange((void*)destination, sectionSize); + DCFlushRange((void *) destination, sectionSize); + ICInvalidateRange((void *) destination, sectionSize); } } - for(uint32_t i = 0; i < sec_num; ++i ) { - section* psec = reader.sections[i]; + for (uint32_t i = 0; i < sec_num; ++i) { + section *psec = reader.sections[i]; if ((psec->get_type() == SHT_PROGBITS || psec->get_type() == SHT_NOBITS) && (psec->get_flags() & SHF_ALLOC)) { - DEBUG_FUNCTION_LINE("Linking (%d)... %s",i,psec->get_name().c_str()); + DEBUG_FUNCTION_LINE("Linking (%d)... %s", i, psec->get_name().c_str()); if (!linkSection(reader, psec->get_index(), (uint32_t) destinations[psec->get_index()], offset_text, offset_data, trampolin_data, trampolin_data_length)) { DEBUG_FUNCTION_LINE("elfLink failed"); free(destinations); @@ -129,12 +129,12 @@ std::optional ModuleDataFactory::load(std::string path, uint32_t des } std::vector relocationData = getImportRelocationData(reader, destinations); - for (auto const& reloc : relocationData) { + for (auto const &reloc : relocationData) { moduleData.addRelocationData(reloc); } - DCFlushRange((void*)destination_address, totalSize); - ICInvalidateRange((void*)destination_address, totalSize); + DCFlushRange((void *) destination_address, totalSize); + ICInvalidateRange((void *) destination_address, totalSize); free(destinations); @@ -148,43 +148,43 @@ std::optional ModuleDataFactory::load(std::string path, uint32_t des return moduleData; } -std::vector ModuleDataFactory::getImportRelocationData(elfio& reader, uint8_t ** destinations) { +std::vector ModuleDataFactory::getImportRelocationData(elfio &reader, uint8_t **destinations) { std::vector result; - std::map infoMap; + std::map infoMap; uint32_t sec_num = reader.sections.size(); - for ( uint32_t i = 0; i < sec_num; ++i ) { - section* psec = reader.sections[i]; + for (uint32_t i = 0; i < sec_num; ++i) { + section *psec = reader.sections[i]; if (psec->get_type() == 0x80000002) { infoMap[i] = psec->get_name(); } } - for (uint32_t i = 0; i < sec_num; ++i ) { - section* psec = reader.sections[i]; - if(psec->get_type() == SHT_RELA || psec->get_type() == SHT_REL) { - DEBUG_FUNCTION_LINE("Found relocation section %s",psec->get_name().c_str()); + for (uint32_t i = 0; i < sec_num; ++i) { + section *psec = reader.sections[i]; + if (psec->get_type() == SHT_RELA || psec->get_type() == SHT_REL) { + DEBUG_FUNCTION_LINE("Found relocation section %s", psec->get_name().c_str()); relocation_section_accessor rel(reader, psec); - for ( uint32_t j = 0; j < (uint32_t) rel.get_entries_num(); ++j ) { - Elf64_Addr offset; - Elf_Word type; - Elf_Sxword addend; - std::string sym_name; - Elf64_Addr sym_value; - Elf_Half sym_section_index; + for (uint32_t j = 0; j < (uint32_t) rel.get_entries_num(); ++j) { + Elf64_Addr offset; + Elf_Word type; + Elf_Sxword addend; + std::string sym_name; + Elf64_Addr sym_value; + Elf_Half sym_section_index; - if(!rel.get_entry(j, offset, sym_value, sym_name, type, addend, sym_section_index)) { + if (!rel.get_entry(j, offset, sym_value, sym_name, type, addend, sym_section_index)) { DEBUG_FUNCTION_LINE("Failed to get relocation"); break; } uint32_t adjusted_sym_value = (uint32_t) sym_value; - if(adjusted_sym_value < 0xC0000000) { + if (adjusted_sym_value < 0xC0000000) { continue; } std::optional rplInfo = ImportRPLInformation::createImportRPLInformation(infoMap[sym_section_index]); - if(!rplInfo) { + if (!rplInfo) { DEBUG_FUNCTION_LINE("Failed to create import information"); break; } @@ -192,7 +192,7 @@ std::vector ModuleDataFactory::getImportRelocationData(elfio& re uint32_t section_index = psec->get_info(); // When these relocations are performed, we don't need the 0xC0000000 offset anymore. - RelocationData relocationData(type, offset - 0x02000000, addend, (void*)(destinations[section_index] + 0x02000000), sym_name, rplInfo.value()); + RelocationData relocationData(type, offset - 0x02000000, addend, (void *) (destinations[section_index] + 0x02000000), sym_name, rplInfo.value()); //relocationData->printInformation(); result.push_back(relocationData); } @@ -200,52 +200,53 @@ std::vector ModuleDataFactory::getImportRelocationData(elfio& re } return result; } -bool ModuleDataFactory::linkSection(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) { + +bool ModuleDataFactory::linkSection(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) { uint32_t sec_num = reader.sections.size(); - for (uint32_t i = 0; i < sec_num; ++i ) { - section* psec = reader.sections[i]; - if(psec->get_info() == section_index) { - DEBUG_FUNCTION_LINE("Found relocation section %s",psec->get_name().c_str()); + for (uint32_t i = 0; i < sec_num; ++i) { + section *psec = reader.sections[i]; + if (psec->get_info() == section_index) { + DEBUG_FUNCTION_LINE("Found relocation section %s", psec->get_name().c_str()); relocation_section_accessor rel(reader, psec); - for ( uint32_t j = 0; j < (uint32_t) rel.get_entries_num(); ++j ) { - Elf64_Addr offset; - Elf_Word type; - Elf_Sxword addend; - std::string sym_name; - Elf64_Addr sym_value; - Elf_Half sym_section_index; + for (uint32_t j = 0; j < (uint32_t) rel.get_entries_num(); ++j) { + Elf64_Addr offset; + Elf_Word type; + Elf_Sxword addend; + std::string sym_name; + Elf64_Addr sym_value; + Elf_Half sym_section_index; - if(!rel.get_entry(j, offset, sym_value, sym_name, type, addend, sym_section_index)) { + if (!rel.get_entry(j, offset, sym_value, sym_name, type, addend, sym_section_index)) { DEBUG_FUNCTION_LINE("Failed to get relocation"); break; } uint32_t adjusted_sym_value = (uint32_t) sym_value; - if((adjusted_sym_value >= 0x02000000) && adjusted_sym_value < 0x10000000) { + if ((adjusted_sym_value >= 0x02000000) && adjusted_sym_value < 0x10000000) { adjusted_sym_value -= 0x02000000; adjusted_sym_value += base_text; - } else if((adjusted_sym_value >= 0x10000000) && adjusted_sym_value < 0xC0000000) { + } else if ((adjusted_sym_value >= 0x10000000) && adjusted_sym_value < 0xC0000000) { adjusted_sym_value -= 0x10000000; adjusted_sym_value += base_data; - } else if(adjusted_sym_value >= 0xC0000000) { + } else if (adjusted_sym_value >= 0xC0000000) { // Skip imports continue; - } else if(adjusted_sym_value == 0x0) { + } else if (adjusted_sym_value == 0x0) { // } else { - DEBUG_FUNCTION_LINE("Unhandled case %08X",adjusted_sym_value); + DEBUG_FUNCTION_LINE("Unhandled case %08X", adjusted_sym_value); return false; } - if(sym_section_index == SHN_ABS) { + if (sym_section_index == SHN_ABS) { // - } else if(sym_section_index > SHN_LORESERVE) { + } else if (sym_section_index > SHN_LORESERVE) { DEBUG_FUNCTION_LINE("NOT IMPLEMENTED: %04X", sym_section_index); return false; } - if(!ElfUtils::elfLinkOne(type, offset, addend, destination, adjusted_sym_value, trampolin_data, trampolin_data_length, RELOC_TYPE_FIXED)) { + if (!ElfUtils::elfLinkOne(type, offset, addend, destination, adjusted_sym_value, trampolin_data, trampolin_data_length, RELOC_TYPE_FIXED)) { DEBUG_FUNCTION_LINE("Link failed"); return false; } diff --git a/source/module/ModuleDataFactory.h b/source/module/ModuleDataFactory.h index 594f66c..21633c9 100644 --- a/source/module/ModuleDataFactory.h +++ b/source/module/ModuleDataFactory.h @@ -26,7 +26,9 @@ class ModuleDataFactory { public: - static std::optional load(std::string path, uint32_t destination_address, 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); - static std::vector getImportRelocationData(ELFIO::elfio& reader, uint8_t ** destinations); + static std::optional load(std::string path, uint32_t destination_address, 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); + + static std::vector getImportRelocationData(ELFIO::elfio &reader, uint8_t **destinations); }; diff --git a/source/module/ModuleDataPersistence.cpp b/source/module/ModuleDataPersistence.cpp index 05a04c5..cf44576 100644 --- a/source/module/ModuleDataPersistence.cpp +++ b/source/module/ModuleDataPersistence.cpp @@ -6,21 +6,21 @@ #include "ModuleData.h" #include "RelocationData.h" -bool ModuleDataPersistence::saveModuleData(module_information_t * moduleInformation, const ModuleData& module) { +bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformation, const ModuleData &module) { int32_t module_count = moduleInformation->number_used_modules; - if(module_count >= MAXIMUM_MODULES) { + if (module_count >= MAXIMUM_MODULES) { DEBUG_FUNCTION_LINE("Reached maximum module count of %d", MAXIMUM_MODULES); return false; } // Copy data to global struct. - module_information_single_t * module_data = &(moduleInformation->module_data[module_count]); + module_information_single_t *module_data = &(moduleInformation->module_data[module_count]); DEBUG_FUNCTION_LINE("Saving reloation data for module at %08X", module.getEntrypoint()); // Relocation std::vector relocationData = module.getRelocationDataList(); - for (auto const& reloc : relocationData) { - if(!DynamicLinkingHelper::addReloationEntry(&(moduleInformation->linking_data), module_data->linking_entries, DYN_LINK_RELOCATION_LIST_LENGTH, reloc)) { + for (auto const &reloc : relocationData) { + if (!DynamicLinkingHelper::addReloationEntry(&(moduleInformation->linking_data), module_data->linking_entries, DYN_LINK_RELOCATION_LIST_LENGTH, reloc)) { DEBUG_FUNCTION_LINE("Failed to add relocation entry\n"); return false; } @@ -37,29 +37,29 @@ bool ModuleDataPersistence::saveModuleData(module_information_t * moduleInformat moduleInformation->number_used_modules++; - DCFlushRange((void*)moduleInformation,sizeof(module_information_t)); - ICInvalidateRange((void*)moduleInformation,sizeof(module_information_t)); + DCFlushRange((void *) moduleInformation, sizeof(module_information_t)); + ICInvalidateRange((void *) moduleInformation, sizeof(module_information_t)); return true; } -std::vector ModuleDataPersistence::loadModuleData(module_information_t * moduleInformation) { +std::vector ModuleDataPersistence::loadModuleData(module_information_t *moduleInformation) { std::vector result; - if(moduleInformation == NULL) { + if (moduleInformation == NULL) { DEBUG_FUNCTION_LINE("moduleInformation == NULL\n"); return result; } - DCFlushRange((void*)moduleInformation,sizeof(module_information_t)); - ICInvalidateRange((void*)moduleInformation,sizeof(module_information_t)); + DCFlushRange((void *) moduleInformation, sizeof(module_information_t)); + ICInvalidateRange((void *) moduleInformation, sizeof(module_information_t)); int32_t module_count = moduleInformation->number_used_modules; - if(module_count > MAXIMUM_MODULES) { - DEBUG_FUNCTION_LINE("moduleInformation->module_count was bigger then allowed. %d > %d. Limiting to %d\n",module_count, MAXIMUM_MODULES, MAXIMUM_MODULES); + if (module_count > MAXIMUM_MODULES) { + DEBUG_FUNCTION_LINE("moduleInformation->module_count was bigger then allowed. %d > %d. Limiting to %d\n", module_count, MAXIMUM_MODULES, MAXIMUM_MODULES); module_count = MAXIMUM_MODULES; } - for(int32_t i = 0; i < module_count; i++) { + for (int32_t i = 0; i < module_count; i++) { // Copy data from struct. - module_information_single_t * module_data = &(moduleInformation->module_data[i]); + module_information_single_t *module_data = &(moduleInformation->module_data[i]); ModuleData moduleData; moduleData.setBSSLocation(module_data->bssAddr, module_data->bssSize); moduleData.setSBSSLocation(module_data->sbssAddr, module_data->sbssSize); @@ -67,27 +67,27 @@ std::vector ModuleDataPersistence::loadModuleData(module_information moduleData.setStartAddress(module_data->startAddress); moduleData.setEndAddress(module_data->endAddress); - for(uint32_t j = 0; j < DYN_LINK_RELOCATION_LIST_LENGTH; j++) { - dyn_linking_relocation_entry_t * linking_entry = &(module_data->linking_entries[j]); - if(linking_entry->destination == NULL){ + for (uint32_t j = 0; j < DYN_LINK_RELOCATION_LIST_LENGTH; j++) { + dyn_linking_relocation_entry_t *linking_entry = &(module_data->linking_entries[j]); + if (linking_entry->destination == NULL) { break; } - dyn_linking_import_t* importEntry = linking_entry->importEntry; - if(importEntry == NULL){ + dyn_linking_import_t *importEntry = linking_entry->importEntry; + if (importEntry == NULL) { DEBUG_FUNCTION_LINE("importEntry was NULL, skipping relocation entry\n"); continue; } - if(importEntry->importName == NULL){ + if (importEntry->importName == NULL) { DEBUG_FUNCTION_LINE("importEntry->importName was NULL, skipping relocation entry\n"); continue; } - dyn_linking_function_t* functionEntry = linking_entry->functionEntry; + dyn_linking_function_t *functionEntry = linking_entry->functionEntry; - if(functionEntry == NULL){ + if (functionEntry == NULL) { DEBUG_FUNCTION_LINE("functionEntry was NULL, skipping relocation entry\n"); continue; } - if(functionEntry->functionName == NULL){ + if (functionEntry->functionName == NULL) { DEBUG_FUNCTION_LINE("functionEntry->functionName was NULL, skipping relocation entry\n"); continue; } diff --git a/source/module/ModuleDataPersistence.h b/source/module/ModuleDataPersistence.h index 08545ba..9506c2f 100644 --- a/source/module/ModuleDataPersistence.h +++ b/source/module/ModuleDataPersistence.h @@ -5,6 +5,7 @@ class ModuleDataPersistence { public: - static bool saveModuleData(module_information_t * moduleInformation, const ModuleData& module); - static std::vector loadModuleData(module_information_t * moduleInformation); + static bool saveModuleData(module_information_t *moduleInformation, const ModuleData &module); + + static std::vector loadModuleData(module_information_t *moduleInformation); }; diff --git a/source/module/RelocationData.cpp b/source/module/RelocationData.cpp index c8b7efc..1099237 100644 --- a/source/module/RelocationData.cpp +++ b/source/module/RelocationData.cpp @@ -1,6 +1,6 @@ #include "RelocationData.h" #include "utils/StringTools.h" -std::string RelocationData::toString() const{ - return StringTools::strfmt("%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() ); +std::string RelocationData::toString() const { + return StringTools::strfmt("%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()); } diff --git a/source/module/RelocationData.h b/source/module/RelocationData.h index 7a9275d..ef18ba2 100644 --- a/source/module/RelocationData.h +++ b/source/module/RelocationData.h @@ -23,7 +23,7 @@ class RelocationData { public: - RelocationData(char type, size_t offset, int32_t addend, void *destination, std::string name, const ImportRPLInformation& rplInfo): rplInfo(rplInfo) { + RelocationData(char type, size_t offset, int32_t addend, void *destination, std::string name, const ImportRPLInformation &rplInfo) : rplInfo(rplInfo) { this->type = type; this->offset = offset; this->addend = addend; @@ -34,31 +34,32 @@ public: ~RelocationData() { } - char getType() const{ + char getType() const { return type; } - size_t getOffset() const{ + size_t getOffset() const { return offset; } - int32_t getAddend() const{ + int32_t getAddend() const { return addend; } - void * getDestination() const{ + void *getDestination() const { return destination; } - std::string getName() const{ + std::string getName() const { return name; } - ImportRPLInformation getImportRPLInformation() const{ + ImportRPLInformation getImportRPLInformation() const { return rplInfo; } std::string toString() const; + private: char type; size_t offset; diff --git a/source/utils/StringTools.cpp b/source/utils/StringTools.cpp index ec7cf68..d5c366f 100644 --- a/source/utils/StringTools.cpp +++ b/source/utils/StringTools.cpp @@ -36,13 +36,13 @@ #include -BOOL StringTools::EndsWith(const std::string& a, const std::string& b) { +BOOL StringTools::EndsWith(const std::string &a, const std::string &b) { if (b.size() > a.size()) return false; return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin()); } -const char * StringTools::byte_to_binary(int32_t x) { +const char *StringTools::byte_to_binary(int32_t x) { static char b[9]; b[0] = '\0'; @@ -54,25 +54,25 @@ const char * StringTools::byte_to_binary(int32_t x) { return b; } -std::string StringTools::removeCharFromString(std::string& input,char toBeRemoved) { +std::string StringTools::removeCharFromString(std::string &input, char toBeRemoved) { std::string output = input; size_t position; - while(1) { + while (1) { position = output.find(toBeRemoved); - if(position == std::string::npos) + if (position == std::string::npos) break; output.erase(position, 1); } return output; } -const char * StringTools::fmt(const char * format, ...) { +const char *StringTools::fmt(const char *format, ...) { static char strChar[512]; strChar[0] = 0; va_list va; va_start(va, format); - if((vsprintf(strChar, format, va) >= 0)) { + if ((vsprintf(strChar, format, va) >= 0)) { va_end(va); return (const char *) strChar; } @@ -81,26 +81,26 @@ const char * StringTools::fmt(const char * format, ...) { return NULL; } -const wchar_t * StringTools::wfmt(const char * format, ...) { +const wchar_t *StringTools::wfmt(const char *format, ...) { static char tmp[512]; static wchar_t strWChar[512]; strWChar[0] = 0; tmp[0] = 0; - if(!format) + if (!format) return (const wchar_t *) strWChar; - if(strcmp(format, "") == 0) + if (strcmp(format, "") == 0) return (const wchar_t *) strWChar; va_list va; va_start(va, format); - if((vsprintf(tmp, format, va) >= 0)) { - int bt; + if ((vsprintf(tmp, format, va) >= 0)) { + int bt; int32_t strlength = strlen(tmp); - bt = mbstowcs(strWChar, tmp, (strlength < 512) ? strlength : 512 ); + bt = mbstowcs(strWChar, tmp, (strlength < 512) ? strlength : 512); - if(bt > 0) { + if (bt > 0) { strWChar[bt] = 0; return (const wchar_t *) strWChar; } @@ -110,14 +110,14 @@ const wchar_t * StringTools::wfmt(const char * format, ...) { return NULL; } -int32_t StringTools::strprintf(std::string &str, const char * format, ...) { +int32_t StringTools::strprintf(std::string &str, const char *format, ...) { static char tmp[512]; tmp[0] = 0; int32_t result = 0; va_list va; va_start(va, format); - if((vsprintf(tmp, format, va) >= 0)) { + if ((vsprintf(tmp, format, va) >= 0)) { str = tmp; result = str.size(); } @@ -126,14 +126,14 @@ int32_t StringTools::strprintf(std::string &str, const char * format, ...) { return result; } -std::string StringTools::strfmt(const char * format, ...) { +std::string StringTools::strfmt(const char *format, ...) { std::string str; static char tmp[512]; tmp[0] = 0; va_list va; va_start(va, format); - if((vsprintf(tmp, format, va) >= 0)) { + if ((vsprintf(tmp, format, va) >= 0)) { str = tmp; } va_end(va); @@ -141,11 +141,11 @@ std::string StringTools::strfmt(const char * format, ...) { return str; } -BOOL StringTools::char2wchar_t(const char * strChar, wchar_t * dest) { - if(!strChar || !dest) +BOOL StringTools::char2wchar_t(const char *strChar, wchar_t *dest) { + if (!strChar || !dest) return false; - int bt; + int bt; bt = mbstowcs(dest, strChar, strlen(strChar)); if (bt > 0) { dest[bt] = 0; @@ -155,39 +155,39 @@ BOOL StringTools::char2wchar_t(const char * strChar, wchar_t * dest) { return false; } -int32_t StringTools::strtokcmp(const char * string, const char * compare, const char * separator) { - if(!string || !compare) +int32_t StringTools::strtokcmp(const char *string, const char *compare, const char *separator) { + if (!string || !compare) return -1; char TokCopy[512]; strncpy(TokCopy, compare, sizeof(TokCopy)); TokCopy[511] = '\0'; - char * strTok = strtok(TokCopy, separator); + char *strTok = strtok(TokCopy, separator); while (strTok != NULL) { if (strcasecmp(string, strTok) == 0) { return 0; } - strTok = strtok(NULL,separator); + strTok = strtok(NULL, separator); } return -1; } -int32_t StringTools::strextcmp(const char * string, const char * extension, char seperator) { - if(!string || !extension) +int32_t StringTools::strextcmp(const char *string, const char *extension, char seperator) { + if (!string || !extension) return -1; char *ptr = strrchr(string, seperator); - if(!ptr) + if (!ptr) return -1; return strcasecmp(ptr + 1, extension); } -std::vector StringTools::stringSplit(const std::string & inValue, const std::string & splitter) { +std::vector StringTools::stringSplit(const std::string &inValue, const std::string &splitter) { std::string value = inValue; std::vector result; while (true) { @@ -202,7 +202,7 @@ std::vector StringTools::stringSplit(const std::string & inValue, c result.push_back(""); break; } - if(index + splitter.size() > value.length()) { + if (index + splitter.size() > value.length()) { break; } value = value.substr(index + splitter.size(), value.length()); @@ -211,39 +211,39 @@ std::vector StringTools::stringSplit(const std::string & inValue, c } -const char * StringTools::FullpathToFilename(const char *path) { - if(!path) - return path; +const char *StringTools::FullpathToFilename(const char *path) { + if (!path) + return path; - const char * ptr = path; - const char * Filename = ptr; + const char *ptr = path; + const char *Filename = ptr; - while(*ptr != '\0') { - if(ptr[0] == '/' && ptr[1] != '\0') - Filename = ptr+1; + while (*ptr != '\0') { + if (ptr[0] == '/' && ptr[1] != '\0') + Filename = ptr + 1; - ++ptr; - } - - return Filename; + ++ptr; } + return Filename; +} + void StringTools::RemoveDoubleSlashs(std::string &str) { - uint32_t length = str.size(); + uint32_t length = str.size(); - //! clear path of double slashes - for(uint32_t i = 1; i < length; ++i) { - if(str[i-1] == '/' && str[i] == '/') { - str.erase(i, 1); - i--; - length--; - } + //! clear path of double slashes + for (uint32_t i = 1; i < length; ++i) { + if (str[i - 1] == '/' && str[i] == '/') { + str.erase(i, 1); + i--; + length--; } } +} // You must free the result if result is non-NULL. -char * StringTools::str_replace(char *orig, char *rep, char *with) { +char *StringTools::str_replace(char *orig, char *rep, char *with) { char *result; // the return string char *ins; // the next insert point char *tmp; // varies @@ -268,7 +268,7 @@ char * StringTools::str_replace(char *orig, char *rep, char *with) { ins = tmp + len_rep; } - tmp = result = (char*)malloc(strlen(orig) + (len_with - len_rep) * count + 1); + tmp = result = (char *) malloc(strlen(orig) + (len_with - len_rep) * count + 1); if (!result) return NULL; diff --git a/source/utils/StringTools.h b/source/utils/StringTools.h index 8087a70..851aa73 100644 --- a/source/utils/StringTools.h +++ b/source/utils/StringTools.h @@ -32,20 +32,33 @@ class StringTools { public: - static BOOL EndsWith(const std::string& a, const std::string& b); - static const char * byte_to_binary(int32_t x); - static std::string removeCharFromString(std::string& input,char toBeRemoved); - static const char * fmt(const char * format, ...); - static const wchar_t * wfmt(const char * format, ...); - static int32_t strprintf(std::string &str, const char * format, ...); - static std::string strfmt(const char * format, ...); - static BOOL char2wchar_t(const char * src, wchar_t * dest); - static int32_t strtokcmp(const char * string, const char * compare, const char * separator); - static int32_t strextcmp(const char * string, const char * extension, char seperator); + static BOOL EndsWith(const std::string &a, const std::string &b); + + static const char *byte_to_binary(int32_t x); + + static std::string removeCharFromString(std::string &input, char toBeRemoved); + + static const char *fmt(const char *format, ...); + + static const wchar_t *wfmt(const char *format, ...); + + static int32_t strprintf(std::string &str, const char *format, ...); + + static std::string strfmt(const char *format, ...); + + static BOOL char2wchar_t(const char *src, wchar_t *dest); + + static int32_t strtokcmp(const char *string, const char *compare, const char *separator); + + static int32_t strextcmp(const char *string, const char *extension, char seperator); + static char *str_replace(char *orig, char *rep, char *with); - static const char * FullpathToFilename(const char *path); + + static const char *FullpathToFilename(const char *path); + static void RemoveDoubleSlashs(std::string &str); - static std::vector stringSplit(const std::string & value, const std::string & splitter); + + static std::vector stringSplit(const std::string &value, const std::string &splitter); }; #endif /* __STRING_TOOLS_H */ diff --git a/source/utils/logger.h b/source/utils/logger.h index 400a353..9b5195f 100644 --- a/source/utils/logger.h +++ b/source/utils/logger.h @@ -1,4 +1,5 @@ #pragma once + #include #include diff --git a/source/utils/utils.c b/source/utils/utils.c index ed48ced..17c597b 100644 --- a/source/utils/utils.c +++ b/source/utils/utils.c @@ -7,31 +7,31 @@ #include "utils/logger.h" // https://gist.github.com/ccbrown/9722406 -void dumpHex(const void* data, size_t size) { +void dumpHex(const void *data, size_t size) { char ascii[17]; size_t i, j; ascii[16] = '\0'; DEBUG_FUNCTION_LINE("0x%08X (0x0000): ", data); for (i = 0; i < size; ++i) { - WHBLogPrintf("%02X ", ((unsigned char*)data)[i]); - if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') { - ascii[i % 16] = ((unsigned char*)data)[i]; + WHBLogPrintf("%02X ", ((unsigned char *) data)[i]); + if (((unsigned char *) data)[i] >= ' ' && ((unsigned char *) data)[i] <= '~') { + ascii[i % 16] = ((unsigned char *) data)[i]; } else { ascii[i % 16] = '.'; } - if ((i+1) % 8 == 0 || i+1 == size) { + if ((i + 1) % 8 == 0 || i + 1 == size) { WHBLogPrintf(" "); - if ((i+1) % 16 == 0) { + if ((i + 1) % 16 == 0) { WHBLogPrintf("| %s \n", ascii); - if(i + 1 < size) { - DEBUG_FUNCTION_LINE("0x%08X (0x%04X); ", data + i + 1,i+1); + if (i + 1 < size) { + DEBUG_FUNCTION_LINE("0x%08X (0x%04X); ", data + i + 1, i + 1); } - } else if (i+1 == size) { - ascii[(i+1) % 16] = '\0'; - if ((i+1) % 16 <= 8) { + } else if (i + 1 == size) { + ascii[(i + 1) % 16] = '\0'; + if ((i + 1) % 16 <= 8) { WHBLogPrintf(" "); } - for (j = (i+1) % 16; j < 16; ++j) { + for (j = (i + 1) % 16; j < 16; ++j) { WHBLogPrintf(" "); } WHBLogPrintf("| %s \n", ascii); diff --git a/source/utils/utils.h b/source/utils/utils.h index 155015b..a502522 100644 --- a/source/utils/utils.h +++ b/source/utils/utils.h @@ -7,12 +7,12 @@ extern "C" { #endif -#define LIMIT(x, min, max) \ - ({ \ - typeof( x ) _x = x; \ - typeof( min ) _min = min; \ - typeof( max ) _max = max; \ - ( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \ +#define LIMIT(x, min, max) \ + ({ \ + typeof( x ) _x = x; \ + typeof( min ) _min = min; \ + typeof( max ) _max = max; \ + ( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \ }) #define DegToRad(a) ( (a) * 0.01745329252f ) @@ -31,7 +31,7 @@ extern "C" { #define le64(i) ((((uint64_t)le32((i) & 0xFFFFFFFFLL)) << 32) | ((uint64_t)le32(((i) & 0xFFFFFFFF00000000LL) >> 32))) //Needs to have log_init() called beforehand. -void dumpHex(const void* data, size_t size); +void dumpHex(const void *data, size_t size); #ifdef __cplusplus }