Formatting

This commit is contained in:
Maschell 2020-05-17 19:05:51 +02:00
parent 373579cd6f
commit 2ee3011ae8
39 changed files with 881 additions and 810 deletions

View File

@ -5,26 +5,26 @@
#include "utils/logger.h" #include "utils/logger.h"
#include "../../source/common/module_defines.h" #include "../../source/common/module_defines.h"
dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t * data, const char* functionName) { dyn_linking_function_t *DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, const char *functionName) {
if(data == NULL) { if (data == NULL) {
return NULL; return NULL;
} }
if(functionName == NULL) { if (functionName == NULL) {
return NULL; return NULL;
} }
dyn_linking_function_t * result = NULL; dyn_linking_function_t *result = NULL;
for(int32_t i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) { for (int32_t i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) {
dyn_linking_function_t * curEntry = &(data->functions[i]); dyn_linking_function_t *curEntry = &(data->functions[i]);
if(strlen(curEntry->functionName) == 0) { if (strlen(curEntry->functionName) == 0) {
if(strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) { if (strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) {
DEBUG_FUNCTION_LINE("Failed to add function name, it's too long.\n"); DEBUG_FUNCTION_LINE("Failed to add function name, it's too long.\n");
return NULL; return NULL;
} }
strncpy(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH); strncpy(curEntry->functionName, functionName, DYN_LINK_FUNCTION_NAME_LENGTH);
result = curEntry; result = curEntry;
break; 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; result = curEntry;
break; break;
} }
@ -32,62 +32,65 @@ dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_l
return result; 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); 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); return getOrAddImport(data, importName, true);
} }
dyn_linking_import_t * DynamicLinkingHelper::getOrAddImport(dyn_linking_relocation_data_t * data, const char* importName, bool isData) { dyn_linking_import_t *DynamicLinkingHelper::getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData) {
if(importName == NULL || data == NULL) { if (importName == NULL || data == NULL) {
return NULL; return NULL;
} }
dyn_linking_import_t * result = NULL; dyn_linking_import_t *result = NULL;
for(int32_t i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) { for (int32_t i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) {
dyn_linking_import_t * curEntry = &(data->imports[i]); dyn_linking_import_t *curEntry = &(data->imports[i]);
if(strlen(curEntry->importName) == 0) { if (strlen(curEntry->importName) == 0) {
if(strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) { if (strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) {
DEBUG_FUNCTION_LINE("Failed to add Import, it's too long.\n"); DEBUG_FUNCTION_LINE("Failed to add Import, it's too long.\n");
return NULL; return NULL;
} }
strncpy(curEntry->importName,importName,DYN_LINK_IMPORT_NAME_LENGTH); strncpy(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH);
curEntry->isData = isData; curEntry->isData = isData;
result = curEntry; result = curEntry;
break; 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 curEntry;
} }
} }
return result; 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) { 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()); 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) { 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,
dyn_linking_import_t * importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo.getName().c_str(),rplInfo.isData()); std::string name, const ImportRPLInformation &rplInfo) {
if(importInfoGbl == NULL) { dyn_linking_import_t *importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo.getName().c_str(), rplInfo.isData());
DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d rpl files to import reached.\n",DYN_LINK_IMPORT_LIST_LENGTH); 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; return false;
} }
dyn_linking_function_t * functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(linking_data, name.c_str()); dyn_linking_function_t *functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(linking_data, name.c_str());
if(functionInfo == NULL) { 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); 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 false;
} }
return addReloationEntry(linking_entries, linking_entry_length, type, offset, addend, destination, functionInfo, importInfoGbl); 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) { 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,
for(uint32_t i = 0; i < linking_entry_length; i++) { dyn_linking_import_t *importInfo) {
dyn_linking_relocation_entry_t * curEntry = &(linking_entries[i]); for (uint32_t i = 0; i < linking_entry_length; i++) {
if(curEntry->functionEntry != NULL) { dyn_linking_relocation_entry_t *curEntry = &(linking_entries[i]);
if (curEntry->functionEntry != NULL) {
continue; continue;
} }
curEntry->type = type; curEntry->type = type;

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "../../source/common/dynamic_linking_defines.h" #include "../../source/common/dynamic_linking_defines.h"
#include "utils/logger.h" #include "utils/logger.h"
#include <string> #include <string>
@ -13,7 +14,7 @@ public:
\param functionName Name of the function \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. \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. 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 \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. \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 \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. \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. \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: private:
DynamicLinkingHelper() { DynamicLinkingHelper() {
} }

View File

@ -6,8 +6,8 @@
#include "ElfUtils.h" #include "ElfUtils.h"
// See https://github.com/decaf-emu/decaf-emu/blob/43366a34e7b55ab9d19b2444aeb0ccd46ac77dea/src/libdecaf/src/cafe/loader/cafe_loader_reloc.cpp#L144 // 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) { 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) { if (type == R_PPC_NONE) {
return true; return true;
} }
auto target = destination + offset; auto target = destination + offset;
@ -19,32 +19,32 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
case R_PPC_NONE: case R_PPC_NONE:
break; break;
case R_PPC_ADDR32: case R_PPC_ADDR32:
*((uint32_t *)(target)) = value; *((uint32_t *) (target)) = value;
break; break;
case R_PPC_ADDR16_LO: case R_PPC_ADDR16_LO:
*((uint16_t *)(target)) = static_cast<uint16_t>(value & 0xFFFF); *((uint16_t *) (target)) = static_cast<uint16_t>(value & 0xFFFF);
break; break;
case R_PPC_ADDR16_HI: case R_PPC_ADDR16_HI:
*((uint16_t *)(target)) = static_cast<uint16_t>(value >> 16); *((uint16_t *) (target)) = static_cast<uint16_t>(value >> 16);
break; break;
case R_PPC_ADDR16_HA: case R_PPC_ADDR16_HA:
*((uint16_t *)(target)) = static_cast<uint16_t>((value + 0x8000) >> 16); *((uint16_t *) (target)) = static_cast<uint16_t>((value + 0x8000) >> 16);
break; break;
case R_PPC_DTPMOD32: case R_PPC_DTPMOD32:
DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n"); DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n");
//*((int32_t *)(target)) = tlsModuleIndex; //*((int32_t *)(target)) = tlsModuleIndex;
break; break;
case R_PPC_DTPREL32: case R_PPC_DTPREL32:
*((uint32_t *)(target)) = value; *((uint32_t *) (target)) = value;
break; break;
case R_PPC_GHS_REL16_HA: case R_PPC_GHS_REL16_HA:
*((uint16_t *)(target)) = static_cast<uint16_t>((relValue + 0x8000) >> 16); *((uint16_t *) (target)) = static_cast<uint16_t>((relValue + 0x8000) >> 16);
break; break;
case R_PPC_GHS_REL16_HI: case R_PPC_GHS_REL16_HI:
*((uint16_t *)(target)) = static_cast<uint16_t>(relValue >> 16); *((uint16_t *) (target)) = static_cast<uint16_t>(relValue >> 16);
break; break;
case R_PPC_GHS_REL16_LO: case R_PPC_GHS_REL16_LO:
*((uint16_t *)(target)) = static_cast<uint16_t>(relValue & 0xFFFF); *((uint16_t *) (target)) = static_cast<uint16_t>(relValue & 0xFFFF);
break; break;
case R_PPC_REL14: { case R_PPC_REL14: {
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target); auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
@ -64,7 +64,7 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
return false; return false;
} }
*(int32_t *)target = (*(int32_t *)target & 0xFFBF0003) | (distance & 0x0000fffc); *(int32_t *) target = (*(int32_t *) target & 0xFFBF0003) | (distance & 0x0000fffc);
break; break;
} }
case R_PPC_REL24: { case R_PPC_REL24: {
@ -74,31 +74,31 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
// } // }
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target); auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) { if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) {
if(trampolin_data == NULL) { if (trampolin_data == NULL) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin isn't provided\n"); 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); DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false; return false;
} else { } else {
relocation_trampolin_entry_t * freeSlot = NULL; relocation_trampolin_entry_t *freeSlot = NULL;
for(uint32_t i = 0; i < trampolin_data_length; i++) { for (uint32_t i = 0; i < trampolin_data_length; i++) {
// We want to override "old" relocations of imports // We want to override "old" relocations of imports
// Pending relocations have the status RELOC_TRAMP_IMPORT_IN_PROGRESS. // 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 // 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. // 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. // 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 || if (trampolin_data[i].status == RELOC_TRAMP_FREE ||
trampolin_data[i].status == RELOC_TRAMP_IMPORT_DONE) { trampolin_data[i].status == RELOC_TRAMP_IMPORT_DONE) {
freeSlot = &(trampolin_data[i]); freeSlot = &(trampolin_data[i]);
break; break;
} }
} }
if(freeSlot != NULL) { if (freeSlot != NULL) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin data list is full\n"); 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); DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false; return false;
} }
if(target - (uint32_t)&(freeSlot->trampolin[0]) > 0x1FFFFFC) { if (target - (uint32_t) &(freeSlot->trampolin[0]) > 0x1FFFFFC) {
DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer)."); 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); DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false; return false;
@ -108,16 +108,16 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
freeSlot->trampolin[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l freeSlot->trampolin[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l
freeSlot->trampolin[2] = 0x7D6903A6; // mtctr r11 freeSlot->trampolin[2] = 0x7D6903A6; // mtctr r11
freeSlot->trampolin[3] = 0x4E800420; // bctr freeSlot->trampolin[3] = 0x4E800420; // bctr
DCFlushRange((void*)freeSlot->trampolin, sizeof(freeSlot->trampolin)); DCFlushRange((void *) freeSlot->trampolin, sizeof(freeSlot->trampolin));
ICInvalidateRange((unsigned char*)freeSlot->trampolin, sizeof(freeSlot->trampolin)); ICInvalidateRange((unsigned char *) freeSlot->trampolin, sizeof(freeSlot->trampolin));
if(reloc_type == RELOC_TYPE_FIXED) { if (reloc_type == RELOC_TYPE_FIXED) {
freeSlot->status = RELOC_TRAMP_FIXED; freeSlot->status = RELOC_TRAMP_FIXED;
} else { } else {
// Relocations for the imports may be overridden // Relocations for the imports may be overridden
freeSlot->status = RELOC_TRAMP_IMPORT_IN_PROGRESS; freeSlot->status = RELOC_TRAMP_IMPORT_IN_PROGRESS;
} }
uint32_t symbolValue = (uint32_t)&(freeSlot->trampolin[0]); uint32_t symbolValue = (uint32_t) &(freeSlot->trampolin[0]);
value = symbolValue + addend; value = symbolValue + addend;
distance = static_cast<int32_t>(value) - static_cast<int32_t>(target); distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
DEBUG_FUNCTION_LINE("Created tramp\n"); DEBUG_FUNCTION_LINE("Created tramp\n");
@ -139,7 +139,7 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
return false; return false;
} }
*(int32_t *)target = (*(int32_t *)target & 0xfc000003) | (distance & 0x03fffffc); *(int32_t *) target = (*(int32_t *) target & 0xfc000003) | (distance & 0x03fffffc);
break; break;
} }
default: default:

View File

@ -42,5 +42,5 @@ extern "C" {
class ElfUtils { class ElfUtils {
public: 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);
}; };

View File

@ -5,19 +5,19 @@
#include "../../source/module/RelocationData.h" #include "../../source/module/RelocationData.h"
#include <coreinit/cache.h> #include <coreinit/cache.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; int32_t module_count = moduleInformation->number_used_modules;
if(module_count >= MAXIMUM_MODULES) { if (module_count >= MAXIMUM_MODULES) {
return false; return false;
} }
// Copy data to global struct. // 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 // Relocation
std::vector<RelocationData> relocationData = module.getRelocationDataList(); std::vector<RelocationData> relocationData = module.getRelocationDataList();
for (auto const& reloc : relocationData) { for (auto const &reloc : relocationData) {
if(!DynamicLinkingHelper::addReloationEntry(&(moduleInformation->linking_data), module_data->linking_entries, DYN_LINK_RELOCATION_LIST_LENGTH, reloc)) { if (!DynamicLinkingHelper::addReloationEntry(&(moduleInformation->linking_data), module_data->linking_entries, DYN_LINK_RELOCATION_LIST_LENGTH, reloc)) {
return false; return false;
} }
} }
@ -33,30 +33,30 @@ bool ModuleDataPersistence::saveModuleData(module_information_t * moduleInformat
moduleInformation->number_used_modules++; moduleInformation->number_used_modules++;
DCFlushRange((void*)moduleInformation,sizeof(module_information_t)); DCFlushRange((void *) moduleInformation, sizeof(module_information_t));
ICInvalidateRange((void*)moduleInformation,sizeof(module_information_t)); ICInvalidateRange((void *) moduleInformation, sizeof(module_information_t));
return true; return true;
} }
std::vector<ModuleData> ModuleDataPersistence::loadModuleData(module_information_t * moduleInformation) { std::vector<ModuleData> ModuleDataPersistence::loadModuleData(module_information_t *moduleInformation) {
std::vector<ModuleData> result; std::vector<ModuleData> result;
if(moduleInformation == NULL) { if (moduleInformation == NULL) {
DEBUG_FUNCTION_LINE("moduleInformation == NULL\n"); DEBUG_FUNCTION_LINE("moduleInformation == NULL\n");
return result; return result;
} }
DCFlushRange((void*)moduleInformation,sizeof(module_information_t)); DCFlushRange((void *) moduleInformation, sizeof(module_information_t));
ICInvalidateRange((void*)moduleInformation,sizeof(module_information_t)); ICInvalidateRange((void *) moduleInformation, sizeof(module_information_t));
int32_t module_count = moduleInformation->number_used_modules; int32_t module_count = moduleInformation->number_used_modules;
if(module_count > 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); 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; 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. // 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 moduleData;
moduleData.setBSSLocation(module_data->bssAddr, module_data->bssSize); moduleData.setBSSLocation(module_data->bssAddr, module_data->bssSize);
@ -65,27 +65,27 @@ std::vector<ModuleData> ModuleDataPersistence::loadModuleData(module_information
moduleData.setStartAddress(module_data->startAddress); moduleData.setStartAddress(module_data->startAddress);
moduleData.setEndAddress(module_data->endAddress); moduleData.setEndAddress(module_data->endAddress);
for(uint32_t j = 0; j < DYN_LINK_RELOCATION_LIST_LENGTH; j++) { for (uint32_t j = 0; j < DYN_LINK_RELOCATION_LIST_LENGTH; j++) {
dyn_linking_relocation_entry_t * linking_entry = &(module_data->linking_entries[j]); dyn_linking_relocation_entry_t *linking_entry = &(module_data->linking_entries[j]);
if(linking_entry->destination == NULL){ if (linking_entry->destination == NULL) {
break; break;
} }
dyn_linking_import_t* importEntry = linking_entry->importEntry; dyn_linking_import_t *importEntry = linking_entry->importEntry;
if(importEntry == NULL){ if (importEntry == NULL) {
DEBUG_FUNCTION_LINE("importEntry was NULL, skipping relocation entry\n"); DEBUG_FUNCTION_LINE("importEntry was NULL, skipping relocation entry\n");
continue; continue;
} }
if(importEntry->importName == NULL){ if (importEntry->importName == NULL) {
DEBUG_FUNCTION_LINE("importEntry->importName was NULL, skipping relocation entry\n"); DEBUG_FUNCTION_LINE("importEntry->importName was NULL, skipping relocation entry\n");
continue; 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"); DEBUG_FUNCTION_LINE("functionEntry was NULL, skipping relocation entry\n");
continue; continue;
} }
if(functionEntry->functionName == NULL){ if (functionEntry->functionName == NULL) {
DEBUG_FUNCTION_LINE("functionEntry->functionName was NULL, skipping relocation entry\n"); DEBUG_FUNCTION_LINE("functionEntry->functionName was NULL, skipping relocation entry\n");
continue; continue;
} }

View File

@ -5,6 +5,7 @@
class ModuleDataPersistence { class ModuleDataPersistence {
public: public:
static bool saveModuleData(module_information_t * moduleInformation, const ModuleData& module); static bool saveModuleData(module_information_t *moduleInformation, const ModuleData &module);
static std::vector<ModuleData> loadModuleData(module_information_t * moduleInformation);
static std::vector<ModuleData> loadModuleData(module_information_t *moduleInformation);
}; };

View File

@ -32,31 +32,31 @@ extern "C" int _start(int argc, char **argv) {
socket_lib_init(); socket_lib_init();
log_init(); log_init();
doStart(argc,argv); doStart(argc, argv);
DEBUG_FUNCTION_LINE("Call real one\n"); 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<RelocationData> &relocData, relocation_trampolin_entry_t * tramp_data, uint32_t tramp_length) { bool doRelocation(std::vector<RelocationData> &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length) {
std::map<std::string,OSDynLoad_Module> moduleCache; std::map<std::string, OSDynLoad_Module> moduleCache;
for (auto const& curReloc : relocData) { for (auto const &curReloc : relocData) {
std::string functionName = curReloc.getName(); std::string functionName = curReloc.getName();
std::string rplName = curReloc.getImportRPLInformation().getName(); std::string rplName = curReloc.getImportRPLInformation().getName();
int32_t isData = curReloc.getImportRPLInformation().isData(); int32_t isData = curReloc.getImportRPLInformation().isData();
OSDynLoad_Module rplHandle = 0; OSDynLoad_Module rplHandle = 0;
if(moduleCache.count(rplName) == 0){ if (moduleCache.count(rplName) == 0) {
OSDynLoad_Acquire(rplName.c_str(), &rplHandle); OSDynLoad_Acquire(rplName.c_str(), &rplHandle);
moduleCache[rplName] = rplHandle; moduleCache[rplName] = rplHandle;
} }
rplHandle = moduleCache.at(rplName); rplHandle = moduleCache.at(rplName);
uint32_t functionAddress = 0; uint32_t functionAddress = 0;
OSDynLoad_FindExport(rplHandle, isData, functionName.c_str(), (void**) &functionAddress); OSDynLoad_FindExport(rplHandle, isData, functionName.c_str(), (void **) &functionAddress);
if(functionAddress == 0) { if (functionAddress == 0) {
DEBUG_FUNCTION_LINE("Failed to find function\n"); DEBUG_FUNCTION_LINE("Failed to find function\n");
return false; 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"); DEBUG_FUNCTION_LINE("Relocation failed\n");
return false; return false;
} }
@ -66,36 +66,37 @@ bool doRelocation(std::vector<RelocationData> &relocData, relocation_trampolin_e
ICInvalidateRange(tramp_data, tramp_length * sizeof(relocation_trampolin_entry_t)); ICInvalidateRange(tramp_data, tramp_length * sizeof(relocation_trampolin_entry_t));
return true; return true;
} }
bool ResolveRelocations() { bool ResolveRelocations() {
std::vector<ModuleData> loadedModules = ModuleDataPersistence::loadModuleData(gModuleData); std::vector<ModuleData> loadedModules = ModuleDataPersistence::loadModuleData(gModuleData);
bool wasSuccessful = true; bool wasSuccessful = true;
uint32_t count = 0; uint32_t count = 0;
for (auto const& curModule : loadedModules) { for (auto const &curModule : loadedModules) {
if(wasSuccessful) { if (wasSuccessful) {
std::vector<RelocationData> relocData = curModule.getRelocationDataList(); std::vector<RelocationData> 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"); DEBUG_FUNCTION_LINE("FAIL\n");
wasSuccessful = false; wasSuccessful = false;
} }
} }
if(curModule.getBSSAddr() != 0){ if (curModule.getBSSAddr() != 0) {
DEBUG_FUNCTION_LINE("memset .bss %08X (%d)\n", curModule.getBSSAddr(), curModule.getBSSSize()); 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()); 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) { if (count > 0) {
DCFlushRange((void*) 0x00800000, 0x00800000); DCFlushRange((void *) 0x00800000, 0x00800000);
ICInvalidateRange((void*) 0x00800000, 0x00800000); ICInvalidateRange((void *) 0x00800000, 0x00800000);
} }
return wasSuccessful; return wasSuccessful;
} }
extern "C" void doStart(int argc, char **argv) { extern "C" void doStart(int argc, char **argv) {
if(!gFunctionsPatched){ if (!gFunctionsPatched) {
gFunctionsPatched = 1; gFunctionsPatched = 1;
kernelInitialize(); kernelInitialize();
PatchInvidualMethodHooks(method_hooks_hooks_static, method_hooks_size_hooks_static, method_calls_hooks_static); 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("Resolve relocations\n");
DEBUG_FUNCTION_LINE("Number of modules %d\n", gModuleData->number_used_modules); DEBUG_FUNCTION_LINE("Number of modules %d\n", gModuleData->number_used_modules);
ResolveRelocations(); ResolveRelocations();
for(int i = 0; i<gModuleData->number_used_modules; i++) { for (int i = 0; i < gModuleData->number_used_modules; i++) {
DEBUG_FUNCTION_LINE("About to call %08X\n",gModuleData->module_data[i].entrypoint); 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); int ret = ((int (*)(int, char **)) (gModuleData->module_data[i].entrypoint))(argc, argv);
DEBUG_FUNCTION_LINE("return code was %d\n", ret); DEBUG_FUNCTION_LINE("return code was %d\n", ret);
} }
} }

View File

@ -10,7 +10,7 @@ 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) { DECL(OSDynLoad_Error, OSDynLoad_FindExport, OSDynLoad_Module module, BOOL isData, char const *name, void **outAddr) {
DEBUG_FUNCTION_LINE("%s\n", name); 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"))) = { hooks_magic_t method_hooks_hooks_static[] __attribute__((section(".data"))) = {

View File

@ -81,7 +81,7 @@ void PatchSyscall(int index, uint32_t addr) {
void kernelInitialize() { void kernelInitialize() {
static uint8_t ucSyscallsSetupRequired = 1; static uint8_t ucSyscallsSetupRequired = 1;
if (!ucSyscallsSetupRequired){ if (!ucSyscallsSetupRequired) {
return; return;
} }

View File

@ -4,6 +4,7 @@
#define IMPORT(name) void* addr_##name #define IMPORT(name) void* addr_##name
#define IMPORT_BEGIN(lib) #define IMPORT_BEGIN(lib)
#define IMPORT_END() #define IMPORT_END()
#include "imports.h" #include "imports.h"
#undef IMPORT #undef IMPORT
@ -23,13 +24,13 @@ EXPORT_VAR(uint32_t *, pMEMFreeToDefaultHeap);
void InitFunctionPointers(void) { void InitFunctionPointers(void) {
OSDynLoad_Module handle; OSDynLoad_Module handle;
addr_OSDynLoad_Acquire = (void*) 0x0102A3B4; addr_OSDynLoad_Acquire = (void *) 0x0102A3B4;
addr_OSDynLoad_FindExport = (void*) 0x0102B828; addr_OSDynLoad_FindExport = (void *) 0x0102B828;
OSDynLoad_Acquire("coreinit.rpl", &handle); OSDynLoad_Acquire("coreinit.rpl", &handle);
OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeapEx", (void**) &pMEMAllocFromDefaultHeapEx); OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeapEx", (void **) &pMEMAllocFromDefaultHeapEx);
OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeap", (void**) &pMEMAllocFromDefaultHeap); OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeap", (void **) &pMEMAllocFromDefaultHeap);
OSDynLoad_FindExport(handle, 1, "MEMFreeToDefaultHeap", (void**) &pMEMFreeToDefaultHeap); OSDynLoad_FindExport(handle, 1, "MEMFreeToDefaultHeap", (void **) &pMEMFreeToDefaultHeap);
#include "imports.h" #include "imports.h"

View File

@ -10,7 +10,7 @@
#include <coreinit/systeminfo.h> #include <coreinit/systeminfo.h>
#include <coreinit/thread.h> #include <coreinit/thread.h>
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 struct sockaddr_in connect_addr __attribute__((section(".data")));
static volatile int log_lock __attribute__((section(".data"))) = 0; static volatile int log_lock __attribute__((section(".data"))) = 0;
@ -30,11 +30,11 @@ void log_init_() {
void log_print_(const char *str) { void log_print_(const char *str) {
// socket is always 0 initially as it is in the BSS // socket is always 0 initially as it is in the BSS
if(log_socket < 0) { if (log_socket < 0) {
return; return;
} }
while(log_lock) { while (log_lock) {
OSSleepTicks(OSMicrosecondsToTicks(1000)); OSSleepTicks(OSMicrosecondsToTicks(1000));
} }
log_lock = 1; log_lock = 1;
@ -43,8 +43,8 @@ void log_print_(const char *str) {
int ret; int ret;
while (len > 0) { while (len > 0) {
int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet 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)); ret = sendto(log_socket, str, block, 0, (struct sockaddr *) &connect_addr, sizeof(struct sockaddr_in));
if(ret < 0) if (ret < 0)
break; break;
len -= ret; len -= ret;
@ -59,14 +59,14 @@ void OSFatal_printf(const char *format, ...) {
tmp[0] = 0; tmp[0] = 0;
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) { if ((vsprintf(tmp, format, va) >= 0)) {
OSFatal(tmp); OSFatal(tmp);
} }
va_end(va); va_end(va);
} }
void log_printf_(const char *format, ...) { void log_printf_(const char *format, ...) {
if(log_socket < 0) { if (log_socket < 0) {
return; return;
} }
@ -75,7 +75,7 @@ void log_printf_(const char *format, ...) {
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) { if ((vsprintf(tmp, format, va) >= 0)) {
log_print_(tmp); log_print_(tmp);
} }
va_end(va); va_end(va);

View File

@ -8,9 +8,12 @@ extern "C" {
#include <string.h> #include <string.h>
void log_init_(); void log_init_();
//void log_deinit_(void); //void log_deinit_(void);
void log_print_(const char *str); void log_print_(const char *str);
void log_printf_(const char *format, ...); void log_printf_(const char *format, ...);
void OSFatal_printf(const char *format, ...); void OSFatal_printf(const char *format, ...);
#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) #define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
@ -21,7 +24,6 @@ void OSFatal_printf(const char *format, ...);
} while (0) } while (0)
#define log_init() log_init_() #define log_init() log_init_()
//#define log_deinit() log_deinit_() //#define log_deinit() log_deinit_()
#define log_print(str) log_print_(str) #define log_print(str) log_print_(str)

View File

@ -21,15 +21,15 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
extern uint32_t * pMEMAllocFromDefaultHeapEx; extern uint32_t *pMEMAllocFromDefaultHeapEx;
extern uint32_t * pMEMAllocFromDefaultHeap; extern uint32_t *pMEMAllocFromDefaultHeap;
extern uint32_t * pMEMFreeToDefaultHeap; extern uint32_t *pMEMFreeToDefaultHeap;
//!------------------------------------------------------------------------------------------- //!-------------------------------------------------------------------------------------------
//! reent versions //! reent versions
//!------------------------------------------------------------------------------------------- //!-------------------------------------------------------------------------------------------
void *_malloc_r(struct _reent *r, size_t size) { 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) { if (!ptr) {
r->_errno = ENOMEM; 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 *_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) { if (ptr) {
memset(ptr, 0, num * size); memset(ptr, 0, num * size);
} else { } 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) { 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) { void _free_r(struct _reent *r, void *ptr) {
if (ptr) { if (ptr) {
((void (*)(void *))(*pMEMFreeToDefaultHeap))(ptr); ((void (*)(void *)) (*pMEMFreeToDefaultHeap))(ptr);
} }
} }
void *_realloc_r(struct _reent *r, void *p, size_t size) { 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) { if (!new_ptr) {
r->_errno = ENOMEM; r->_errno = ENOMEM;
return new_ptr; return new_ptr;
@ -67,13 +67,13 @@ void *_realloc_r(struct _reent *r, void *p, size_t size) {
if (p) { if (p) {
size_t old_size = MEMGetSizeForMBlockExpHeap(p); size_t old_size = MEMGetSizeForMBlockExpHeap(p);
memcpy(new_ptr, p, old_size <= size ? old_size : size); memcpy(new_ptr, p, old_size <= size ? old_size : size);
((void (*)(void *))(*pMEMFreeToDefaultHeap))(p); ((void (*)(void *)) (*pMEMFreeToDefaultHeap))(p);
} }
return new_ptr; return new_ptr;
} }
struct mallinfo _mallinfo_r(struct _reent *r) { struct mallinfo _mallinfo_r(struct _reent *r) {
struct mallinfo info = { 0 }; struct mallinfo info = {0};
return info; return info;
} }
@ -93,12 +93,12 @@ _malloc_usable_size_r(struct _reent *r, void *ptr) {
void * void *
_valloc_r(struct _reent *r, size_t size) { _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 * void *
_pvalloc_r(struct _reent *r, size_t size) { _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 int

View File

@ -24,15 +24,19 @@ extern "C" {
#include <malloc.h> #include <malloc.h>
void memoryInitialize(void); void memoryInitialize(void);
void memoryRelease(void); void memoryRelease(void);
void * MEM2_alloc(u32 size, u32 align); void *MEM2_alloc(u32 size, u32 align);
void MEM2_free(void *ptr); 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 MEM1_free(void *ptr);
void * MEMBucket_alloc(u32 size, u32 align); void *MEMBucket_alloc(u32 size, u32 align);
void MEMBucket_free(void *ptr); void MEMBucket_free(void *ptr);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -12,10 +12,10 @@
#include "elfio/elfio.hpp" #include "elfio/elfio.hpp"
#include "ElfUtils.h" #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]; char path[256];
int result = 0; int result = 0;
char * sdRootPath = NULL; char *sdRootPath = NULL;
if (!WHBMountSdCard()) { if (!WHBMountSdCard()) {
WHBLogPrintf("Failed to mount SD Card..."); WHBLogPrintf("Failed to mount SD Card...");
result = -1; result = -1;
@ -23,9 +23,9 @@ int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * s
} }
sdRootPath = WHBGetSdCardMountPath(); 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); *fileOut = WHBReadWholeFile(path, sizeOut);
if (!(*fileOut)) { if (!(*fileOut)) {
@ -34,25 +34,25 @@ int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * s
goto exit; goto exit;
} }
exit: exit:
WHBUnmountSdCard(); WHBUnmountSdCard();
return result; return result;
} }
uint32_t load_loader_elf_from_sd(unsigned char* baseAddress, const char* relativePath) { uint32_t load_loader_elf_from_sd(unsigned char *baseAddress, const char *relativePath) {
char * elf_data = NULL; char *elf_data = NULL;
uint32_t fileSize = 0; 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."); OSFatal("Failed to load hook_payload.elf from the SD Card.");
} }
uint32_t result = load_loader_elf(baseAddress, elf_data, fileSize); uint32_t result = load_loader_elf(baseAddress, elf_data, fileSize);
MEMFreeToDefaultHeap((void*)elf_data); MEMFreeToDefaultHeap((void *) elf_data);
return result; 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_Ehdr *ehdr;
ELFIO::Elf32_Phdr *phdrs; ELFIO::Elf32_Phdr *phdrs;
uint8_t *image; 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; 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; return 0;
} }
if(ehdr->e_phentsize != sizeof(ELFIO::Elf32_Phdr)) { if (ehdr->e_phentsize != sizeof(ELFIO::Elf32_Phdr)) {
return 0; 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++) { for (i = 0; i < ehdr->e_phnum; i++) {
if(phdrs[i].p_type != PT_LOAD) { if (phdrs[i].p_type != PT_LOAD) {
continue; continue;
} }
if(phdrs[i].p_filesz > phdrs[i].p_memsz) { if (phdrs[i].p_filesz > phdrs[i].p_memsz) {
continue; continue;
} }
if(!phdrs[i].p_filesz) { if (!phdrs[i].p_filesz) {
continue; 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); image = (uint8_t *) (elf_data + phdrs[i].p_offset);
memcpy ((void *) p_paddr, image, phdrs[i].p_filesz); memcpy((void *) p_paddr, image, phdrs[i].p_filesz);
DCFlushRange((void*)p_paddr, phdrs[i].p_filesz); DCFlushRange((void *) p_paddr, phdrs[i].p_filesz);
if(phdrs[i].p_flags & PF_X) { if (phdrs[i].p_flags & PF_X) {
ICInvalidateRange ((void *) p_paddr, phdrs[i].p_memsz); ICInvalidateRange((void *) p_paddr, phdrs[i].p_memsz);
} }
} }
//! clear BSS //! clear BSS
ELFIO::Elf32_Shdr *shdr = (ELFIO::Elf32_Shdr *) (elf_data + ehdr->e_shoff); ELFIO::Elf32_Shdr *shdr = (ELFIO::Elf32_Shdr *) (elf_data + ehdr->e_shoff);
for(i = 0; i < ehdr->e_shnum; i++) { 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; 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') { 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); memset((void *) (shdr[i].sh_addr + baseAddress), 0, shdr[i].sh_size);
DCFlushRange((void*)(shdr[i].sh_addr + baseAddress), 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') { } 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); memset((void *) (shdr[i].sh_addr + baseAddress), 0, shdr[i].sh_size);
DCFlushRange((void*)(shdr[i].sh_addr + baseAddress), shdr[i].sh_size); DCFlushRange((void *) (shdr[i].sh_addr + baseAddress), shdr[i].sh_size);
} }
} }
@ -111,8 +111,8 @@ 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 // 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) { 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) { if (type == R_PPC_NONE) {
return true; return true;
} }
auto target = destination + offset; auto target = destination + offset;
@ -125,32 +125,32 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
case R_PPC_NONE: case R_PPC_NONE:
break; break;
case R_PPC_ADDR32: case R_PPC_ADDR32:
*((uint32_t *)(target)) = value; *((uint32_t *) (target)) = value;
break; break;
case R_PPC_ADDR16_LO: case R_PPC_ADDR16_LO:
*((uint16_t *)(target)) = static_cast<uint16_t>(value & 0xFFFF); *((uint16_t *) (target)) = static_cast<uint16_t>(value & 0xFFFF);
break; break;
case R_PPC_ADDR16_HI: case R_PPC_ADDR16_HI:
*((uint16_t *)(target)) = static_cast<uint16_t>(value >> 16); *((uint16_t *) (target)) = static_cast<uint16_t>(value >> 16);
break; break;
case R_PPC_ADDR16_HA: case R_PPC_ADDR16_HA:
*((uint16_t *)(target)) = static_cast<uint16_t>((value + 0x8000) >> 16); *((uint16_t *) (target)) = static_cast<uint16_t>((value + 0x8000) >> 16);
break; break;
case R_PPC_DTPMOD32: case R_PPC_DTPMOD32:
DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n"); DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n");
//*((int32_t *)(target)) = tlsModuleIndex; //*((int32_t *)(target)) = tlsModuleIndex;
break; break;
case R_PPC_DTPREL32: case R_PPC_DTPREL32:
*((uint32_t *)(target)) = value; *((uint32_t *) (target)) = value;
break; break;
case R_PPC_GHS_REL16_HA: case R_PPC_GHS_REL16_HA:
*((uint16_t *)(target)) = static_cast<uint16_t>((relValue + 0x8000) >> 16); *((uint16_t *) (target)) = static_cast<uint16_t>((relValue + 0x8000) >> 16);
break; break;
case R_PPC_GHS_REL16_HI: case R_PPC_GHS_REL16_HI:
*((uint16_t *)(target)) = static_cast<uint16_t>(relValue >> 16); *((uint16_t *) (target)) = static_cast<uint16_t>(relValue >> 16);
break; break;
case R_PPC_GHS_REL16_LO: case R_PPC_GHS_REL16_LO:
*((uint16_t *)(target)) = static_cast<uint16_t>(relValue & 0xFFFF); *((uint16_t *) (target)) = static_cast<uint16_t>(relValue & 0xFFFF);
break; break;
case R_PPC_REL14: { case R_PPC_REL14: {
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target); auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
@ -170,7 +170,7 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
return false; return false;
} }
*(int32_t *)target = (*(int32_t *)target & 0xFFBF0003) | (distance & 0x0000fffc); *(int32_t *) target = (*(int32_t *) target & 0xFFBF0003) | (distance & 0x0000fffc);
break; break;
} }
case R_PPC_REL24: { case R_PPC_REL24: {
@ -180,31 +180,31 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
// } // }
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target); auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) { if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) {
if(trampolin_data == NULL) { if (trampolin_data == NULL) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin isn't provided\n"); 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); DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false; return false;
} else { } else {
relocation_trampolin_entry_t * freeSlot = NULL; relocation_trampolin_entry_t *freeSlot = NULL;
for(uint32_t i = 0; i < trampolin_data_length; i++) { for (uint32_t i = 0; i < trampolin_data_length; i++) {
// We want to override "old" relocations of imports // We want to override "old" relocations of imports
// Pending relocations have the status RELOC_TRAMP_IMPORT_IN_PROGRESS. // 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 // 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. // 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. // 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 || if (trampolin_data[i].status == RELOC_TRAMP_FREE ||
trampolin_data[i].status == RELOC_TRAMP_IMPORT_DONE) { trampolin_data[i].status == RELOC_TRAMP_IMPORT_DONE) {
freeSlot = &(trampolin_data[i]); freeSlot = &(trampolin_data[i]);
break; break;
} }
} }
if(freeSlot != NULL) { if (freeSlot != NULL) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin data list is full\n"); 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); DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false; return false;
} }
if(target - (uint32_t)&(freeSlot->trampolin[0]) > 0x1FFFFFC) { if (target - (uint32_t) &(freeSlot->trampolin[0]) > 0x1FFFFFC) {
DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer)."); 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); DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false; return false;
@ -214,16 +214,16 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
freeSlot->trampolin[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l freeSlot->trampolin[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l
freeSlot->trampolin[2] = 0x7D6903A6; // mtctr r11 freeSlot->trampolin[2] = 0x7D6903A6; // mtctr r11
freeSlot->trampolin[3] = 0x4E800420; // bctr freeSlot->trampolin[3] = 0x4E800420; // bctr
DCFlushRange((void*)freeSlot->trampolin, sizeof(freeSlot->trampolin)); DCFlushRange((void *) freeSlot->trampolin, sizeof(freeSlot->trampolin));
ICInvalidateRange((unsigned char*)freeSlot->trampolin, sizeof(freeSlot->trampolin)); ICInvalidateRange((unsigned char *) freeSlot->trampolin, sizeof(freeSlot->trampolin));
if(reloc_type == RELOC_TYPE_FIXED) { if (reloc_type == RELOC_TYPE_FIXED) {
freeSlot->status = RELOC_TRAMP_FIXED; freeSlot->status = RELOC_TRAMP_FIXED;
} else { } else {
// Relocations for the imports may be overridden // Relocations for the imports may be overridden
freeSlot->status = RELOC_TRAMP_IMPORT_IN_PROGRESS; freeSlot->status = RELOC_TRAMP_IMPORT_IN_PROGRESS;
} }
uint32_t symbolValue = (uint32_t)&(freeSlot->trampolin[0]); uint32_t symbolValue = (uint32_t) &(freeSlot->trampolin[0]);
value = symbolValue + addend; value = symbolValue + addend;
distance = static_cast<int32_t>(value) - static_cast<int32_t>(target); distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
DEBUG_FUNCTION_LINE("Created tramp\n"); DEBUG_FUNCTION_LINE("Created tramp\n");
@ -245,7 +245,7 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
return false; return false;
} }
*(int32_t *)target = (*(int32_t *)target & 0xfc000003) | (distance & 0x03fffffc); *(int32_t *) target = (*(int32_t *) target & 0xfc000003) | (distance & 0x03fffffc);
break; break;
} }
default: default:

View File

@ -8,9 +8,9 @@
extern "C" { extern "C" {
#endif #endif
int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * sizeOut); 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_from_sd(unsigned char *baseAddress, const char *relativePath);
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);
#define R_PPC_NONE 0 #define R_PPC_NONE 0
#define R_PPC_ADDR32 1 #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 { class ElfUtils {
public: 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);
}; };

View File

@ -33,19 +33,19 @@ extern "C" {
#define DYN_LINK_TRAMPOLIN_LIST_LENGTH DYN_LINK_FUNCTION_LIST_LENGTH #define DYN_LINK_TRAMPOLIN_LIST_LENGTH DYN_LINK_FUNCTION_LIST_LENGTH
typedef struct _dyn_linking_function_t { typedef struct _dyn_linking_function_t {
char functionName[DYN_LINK_FUNCTION_NAME_LENGTH+1]; char functionName[DYN_LINK_FUNCTION_NAME_LENGTH + 1];
void * address; void *address;
} dyn_linking_function_t; } dyn_linking_function_t;
typedef struct _dyn_linking_import_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; bool isData = false;
} dyn_linking_import_t; } dyn_linking_import_t;
typedef struct _dyn_linking_relocation_entry_t { typedef struct _dyn_linking_relocation_entry_t {
dyn_linking_function_t* functionEntry = NULL; dyn_linking_function_t *functionEntry = NULL;
dyn_linking_import_t* importEntry = NULL; dyn_linking_import_t *importEntry = NULL;
void * destination = NULL; void *destination = NULL;
char type; char type;
size_t offset; size_t offset;
int32_t addend; int32_t addend;

View File

@ -12,12 +12,12 @@ CFile::CFile() {
pos = 0; pos = 0;
} }
CFile::CFile(const std::string & filepath, eOpenTypes mode) { CFile::CFile(const std::string &filepath, eOpenTypes mode) {
iFd = -1; iFd = -1;
this->open(filepath, mode); this->open(filepath, mode);
} }
CFile::CFile(const uint8_t * mem, int32_t size) { CFile::CFile(const uint8_t *mem, int32_t size) {
iFd = -1; iFd = -1;
this->open(mem, size); this->open(mem, size);
} }
@ -26,14 +26,14 @@ CFile::~CFile() {
this->close(); this->close();
} }
int32_t CFile::open(const std::string & filepath, eOpenTypes mode) { int32_t CFile::open(const std::string &filepath, eOpenTypes mode) {
this->close(); this->close();
int32_t openMode = 0; int32_t openMode = 0;
// This depend on the devoptab implementation. // This depend on the devoptab implementation.
// see https://github.com/devkitPro/wut/blob/master/libraries/wutdevoptab/devoptab_fs_open.c#L21 fpr reference // see https://github.com/devkitPro/wut/blob/master/libraries/wutdevoptab/devoptab_fs_open.c#L21 fpr reference
switch(mode) { switch (mode) {
default: default:
case ReadOnly: // file must exist case ReadOnly: // file must exist
openMode = O_RDONLY; openMode = O_RDONLY;
@ -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 //! the .data sections which is needed for a normal application to re-init
//! this will be added with launching as RPX //! this will be added with launching as RPX
iFd = ::open(filepath.c_str(), openMode); iFd = ::open(filepath.c_str(), openMode);
if(iFd < 0) if (iFd < 0)
return iFd; return iFd;
@ -64,7 +64,7 @@ int32_t CFile::open(const std::string & filepath, eOpenTypes mode) {
return 0; 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(); this->close();
mem_file = mem; mem_file = mem;
@ -74,7 +74,7 @@ int32_t CFile::open(const uint8_t * mem, int32_t size) {
} }
void CFile::close() { void CFile::close() {
if(iFd >= 0) if (iFd >= 0)
::close(iFd); ::close(iFd);
iFd = -1; iFd = -1;
@ -83,24 +83,24 @@ void CFile::close() {
pos = 0; pos = 0;
} }
int32_t CFile::read(uint8_t * ptr, size_t size) { int32_t CFile::read(uint8_t *ptr, size_t size) {
if(iFd >= 0) { if (iFd >= 0) {
int32_t ret = ::read(iFd, ptr,size); int32_t ret = ::read(iFd, ptr, size);
if(ret > 0) if (ret > 0)
pos += ret; pos += ret;
return ret; return ret;
} }
int32_t readsize = size; int32_t readsize = size;
if(readsize > (int64_t) (filesize-pos)) if (readsize > (int64_t) (filesize - pos))
readsize = filesize-pos; readsize = filesize - pos;
if(readsize <= 0) if (readsize <= 0)
return readsize; return readsize;
if(mem_file != NULL) { if (mem_file != NULL) {
memcpy(ptr, mem_file+pos, readsize); memcpy(ptr, mem_file + pos, readsize);
pos += readsize; pos += readsize;
return readsize; return readsize;
} }
@ -108,12 +108,12 @@ int32_t CFile::read(uint8_t * ptr, size_t size) {
return -1; return -1;
} }
int32_t CFile::write(const uint8_t * ptr, size_t size) { int32_t CFile::write(const uint8_t *ptr, size_t size) {
if(iFd >= 0) { if (iFd >= 0) {
size_t done = 0; size_t done = 0;
while(done < size) { while (done < size) {
int32_t ret = ::write(iFd, ptr, size - done); int32_t ret = ::write(iFd, ptr, size - done);
if(ret <= 0) if (ret <= 0)
return ret; return ret;
ptr += ret; ptr += ret;
@ -130,25 +130,25 @@ int32_t CFile::seek(long int offset, int32_t origin) {
int32_t ret = 0; int32_t ret = 0;
int64_t newPos = pos; int64_t newPos = pos;
if(origin == SEEK_SET) { if (origin == SEEK_SET) {
newPos = offset; newPos = offset;
} else if(origin == SEEK_CUR) { } else if (origin == SEEK_CUR) {
newPos += offset; newPos += offset;
} else if(origin == SEEK_END) { } else if (origin == SEEK_END) {
newPos = filesize+offset; newPos = filesize + offset;
} }
if(newPos < 0) { if (newPos < 0) {
pos = 0; pos = 0;
} else { } else {
pos = newPos; pos = newPos;
} }
if(iFd >= 0) if (iFd >= 0)
ret = ::lseek(iFd, pos, SEEK_SET); ret = ::lseek(iFd, pos, SEEK_SET);
if(mem_file != NULL) { if (mem_file != NULL) {
if(pos > filesize) { if (pos > filesize) {
pos = filesize; pos = filesize;
} }
} }
@ -163,8 +163,8 @@ int32_t CFile::fwrite(const char *format, ...) {
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) { if ((vsprintf(tmp, format, va) >= 0)) {
result = this->write((uint8_t *)tmp, strlen(tmp)); result = this->write((uint8_t *) tmp, strlen(tmp));
} }
va_end(va); va_end(va);

View File

@ -18,18 +18,22 @@ public:
}; };
CFile(); 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(); virtual ~CFile();
int32_t open(const std::string & filepath, eOpenTypes mode); int32_t open(const std::string &filepath, eOpenTypes mode);
int32_t open(const uint8_t * memory, int32_t memsize);
int32_t open(const uint8_t *memory, int32_t memsize);
BOOL isOpen() const { BOOL isOpen() const {
if(iFd >= 0) if (iFd >= 0)
return true; return true;
if(mem_file) if (mem_file)
return true; return true;
return false; return false;
@ -37,23 +41,29 @@ public:
void close(); void close();
int32_t read(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 write(const uint8_t *ptr, size_t size);
int32_t fwrite(const char *format, ...); int32_t fwrite(const char *format, ...);
int32_t seek(long int offset, int32_t origin); int32_t seek(long int offset, int32_t origin);
uint64_t tell() { uint64_t tell() {
return pos; return pos;
}; };
uint64_t size() { uint64_t size() {
return filesize; return filesize;
}; };
void rewind() { void rewind() {
this->seek(0, SEEK_SET); this->seek(0, SEEK_SET);
}; };
protected: protected:
int32_t iFd; int32_t iFd;
const uint8_t * mem_file; const uint8_t *mem_file;
uint64_t filesize; uint64_t filesize;
uint64_t pos; uint64_t pos;
}; };

View File

@ -42,7 +42,7 @@ DirList::DirList() {
Depth = 0; 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->LoadPath(path, filter, flags, maxDepth);
this->SortList(); this->SortList();
} }
@ -51,8 +51,8 @@ DirList::~DirList() {
ClearList(); ClearList();
} }
BOOL DirList::LoadPath(const std::string & folder, const char *filter, uint32_t flags, uint32_t maxDepth) { BOOL DirList::LoadPath(const std::string &folder, const char *filter, uint32_t flags, uint32_t maxDepth) {
if(folder.empty()) if (folder.empty())
return false; return false;
Flags = flags; Flags = flags;
@ -66,11 +66,11 @@ BOOL DirList::LoadPath(const std::string & folder, const char *filter, uint32_t
StringTools::RemoveDoubleSlashs(folderpath); StringTools::RemoveDoubleSlashs(folderpath);
//! remove last slash if exists //! remove last slash if exists
if(length > 0 && folderpath[length-1] == '/') if (length > 0 && folderpath[length - 1] == '/')
folderpath.erase(length-1); folderpath.erase(length - 1);
//! add root slash if missing //! add root slash if missing
if(folderpath.find('/') == std::string::npos) { if (folderpath.find('/') == std::string::npos) {
folderpath += '/'; folderpath += '/';
} }
@ -78,7 +78,7 @@ BOOL DirList::LoadPath(const std::string & folder, const char *filter, uint32_t
} }
BOOL DirList::InternalLoadPath(std::string &folderpath) { BOOL DirList::InternalLoadPath(std::string &folderpath) {
if(folderpath.size() < 3) if (folderpath.size() < 3)
return false; return false;
struct dirent *dirent = NULL; struct dirent *dirent = NULL;
@ -92,13 +92,13 @@ BOOL DirList::InternalLoadPath(std::string &folderpath) {
BOOL isDir = dirent->d_type & DT_DIR; BOOL isDir = dirent->d_type & DT_DIR;
const char *filename = dirent->d_name; const char *filename = dirent->d_name;
if(isDir) { if (isDir) {
if(strcmp(filename,".") == 0 || strcmp(filename,"..") == 0) if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0)
continue; continue;
if((Flags & CheckSubfolders) && (Depth > 0)) { if ((Flags & CheckSubfolders) && (Depth > 0)) {
int32_t length = folderpath.size(); int32_t length = folderpath.size();
if(length > 2 && folderpath[length-1] != '/') { if (length > 2 && folderpath[length - 1] != '/') {
folderpath += '/'; folderpath += '/';
} }
folderpath += filename; folderpath += filename;
@ -109,18 +109,18 @@ BOOL DirList::InternalLoadPath(std::string &folderpath) {
Depth++; Depth++;
} }
if(!(Flags & Dirs)) if (!(Flags & Dirs))
continue; continue;
} else if(!(Flags & Files)) { } else if (!(Flags & Files)) {
continue; continue;
} }
if(Filter) { if (Filter) {
char * fileext = strrchr(filename, '.'); char *fileext = strrchr(filename, '.');
if(!fileext) if (!fileext)
continue; continue;
if(StringTools::strtokcmp(fileext, Filter, ",") == 0) if (StringTools::strtokcmp(fileext, Filter, ",") == 0)
AddEntrie(folderpath, filename, isDir); AddEntrie(folderpath, filename, isDir);
} else { } else {
AddEntrie(folderpath, filename, isDir); AddEntrie(folderpath, filename, isDir);
@ -131,16 +131,16 @@ BOOL DirList::InternalLoadPath(std::string &folderpath) {
return true; return true;
} }
void DirList::AddEntrie(const std::string &filepath, const char * filename, BOOL isDir) { void DirList::AddEntrie(const std::string &filepath, const char *filename, BOOL isDir) {
if(!filename) if (!filename)
return; return;
int32_t pos = FileInfo.size(); int32_t pos = FileInfo.size();
FileInfo.resize(pos+1); FileInfo.resize(pos + 1);
FileInfo[pos].FilePath = (char *) malloc(filepath.size()+strlen(filename)+2); FileInfo[pos].FilePath = (char *) malloc(filepath.size() + strlen(filename) + 2);
if(!FileInfo[pos].FilePath) { if (!FileInfo[pos].FilePath) {
FileInfo.resize(pos); FileInfo.resize(pos);
return; return;
} }
@ -150,8 +150,8 @@ void DirList::AddEntrie(const std::string &filepath, const char * filename, BOOL
} }
void DirList::ClearList() { void DirList::ClearList() {
for(uint32_t i = 0; i < FileInfo.size(); ++i) { for (uint32_t i = 0; i < FileInfo.size(); ++i) {
if(FileInfo[i].FilePath) { if (FileInfo[i].FilePath) {
free(FileInfo[i].FilePath); free(FileInfo[i].FilePath);
FileInfo[i].FilePath = NULL; FileInfo[i].FilePath = NULL;
} }
@ -161,37 +161,37 @@ void DirList::ClearList() {
std::vector<DirEntry>().swap(FileInfo); std::vector<DirEntry>().swap(FileInfo);
} }
const char * DirList::GetFilename(int32_t ind) const { const char *DirList::GetFilename(int32_t ind) const {
if (!valid(ind)) if (!valid(ind))
return ""; return "";
return StringTools::FullpathToFilename(FileInfo[ind].FilePath); return StringTools::FullpathToFilename(FileInfo[ind].FilePath);
} }
static BOOL SortCallback(const DirEntry & f1, const DirEntry & f2) { static BOOL SortCallback(const DirEntry &f1, const DirEntry &f2) {
if(f1.isDir && !(f2.isDir)) if (f1.isDir && !(f2.isDir))
return true; return true;
if(!(f1.isDir) && f2.isDir) if (!(f1.isDir) && f2.isDir)
return false; return false;
if(f1.FilePath && !f2.FilePath) if (f1.FilePath && !f2.FilePath)
return true; return true;
if(!f1.FilePath) if (!f1.FilePath)
return false; return false;
if(strcasecmp(f1.FilePath, f2.FilePath) > 0) if (strcasecmp(f1.FilePath, f2.FilePath) > 0)
return false; return false;
return true; return true;
} }
void DirList::SortList() { void DirList::SortList() {
if(FileInfo.size() > 1) if (FileInfo.size() > 1)
std::sort(FileInfo.begin(), FileInfo.end(), SortCallback); std::sort(FileInfo.begin(), FileInfo.end(), SortCallback);
} }
void DirList::SortList(BOOL (*SortFunc)(const DirEntry &a, const DirEntry &b)) { 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); std::sort(FileInfo.begin(), FileInfo.end(), SortFunc);
} }
@ -199,14 +199,14 @@ uint64_t DirList::GetFilesize(int32_t index) const {
struct stat st; struct stat st;
const char *path = GetFilepath(index); const char *path = GetFilepath(index);
if(!path || stat(path, &st) != 0) if (!path || stat(path, &st) != 0)
return 0; return 0;
return st.st_size; return st.st_size;
} }
int32_t DirList::GetFileIndex(const char *filename) const { int32_t DirList::GetFileIndex(const char *filename) const {
if(!filename) if (!filename)
return -1; return -1;
for (uint32_t i = 0; i < FileInfo.size(); ++i) { for (uint32_t i = 0; i < FileInfo.size(); ++i) {

View File

@ -32,7 +32,7 @@
#include <wut_types.h> #include <wut_types.h>
typedef struct { typedef struct {
char * FilePath; char *FilePath;
BOOL isDir; BOOL isDir;
} DirEntry; } DirEntry;
@ -40,17 +40,22 @@ class DirList {
public: public:
//!Constructor //!Constructor
DirList(void); DirList(void);
//!\param path Path from where to load the filelist of all files //!\param path Path from where to load the filelist of all files
//!\param filter A fileext that needs to be filtered //!\param filter A fileext that needs to be filtered
//!\param flags search/filter flags from the enum //!\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 //!Destructor
virtual ~DirList(); virtual ~DirList();
//! Load all the files from a directory //! 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 //! Get a filename of the list
//!\param list index //!\param list index
const char * GetFilename(int32_t index) const; const char *GetFilename(int32_t index) const;
//! Get the a filepath of the list //! Get the a filepath of the list
//!\param list index //!\param list index
const char *GetFilepath(int32_t index) const { const char *GetFilepath(int32_t index) const {
@ -59,26 +64,33 @@ public:
else else
return FileInfo[index].FilePath; return FileInfo[index].FilePath;
} }
//! Get the a filesize of the list //! Get the a filesize of the list
//!\param list index //!\param list index
uint64_t GetFilesize(int32_t index) const; uint64_t GetFilesize(int32_t index) const;
//! Is index a dir or a file //! Is index a dir or a file
//!\param list index //!\param list index
BOOL IsDir(int32_t index) const { BOOL IsDir(int32_t index) const {
if(!valid(index)) if (!valid(index))
return false; return false;
return FileInfo[index].isDir; return FileInfo[index].isDir;
}; };
//! Get the filecount of the whole list //! Get the filecount of the whole list
int32_t GetFilecount() const { int32_t GetFilecount() const {
return FileInfo.size(); return FileInfo.size();
}; };
//! Sort list by filepath //! Sort list by filepath
void SortList(); void SortList();
//! Custom sort command for custom sort functions definitions //! Custom sort command for custom sort functions definitions
void SortList(BOOL (*SortFunc)(const DirEntry &a, const DirEntry &b)); void SortList(BOOL (*SortFunc)(const DirEntry &a, const DirEntry &b));
//! Get the index of the specified filename //! Get the index of the specified filename
int32_t GetFileIndex(const char *filename) const; int32_t GetFileIndex(const char *filename) const;
//! Enum for search/filter flags //! Enum for search/filter flags
enum { enum {
Files = 0x01, Files = 0x01,
@ -88,10 +100,13 @@ public:
protected: protected:
// Internal parser // Internal parser
BOOL InternalLoadPath(std::string &path); BOOL InternalLoadPath(std::string &path);
//!Add a list entrie //!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 //! Clear the list
void ClearList(); void ClearList();
//! Check if valid pos is requested //! Check if valid pos is requested
inline BOOL valid(uint32_t pos) const { inline BOOL valid(uint32_t pos) const {
return (pos < FileInfo.size()); return (pos < FileInfo.size());

View File

@ -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); extern "C" void SC_KernelCopyData(uint32_t addr, uint32_t src, uint32_t len);
void SetupRelocator() { void SetupRelocator() {
kern_write((void*)(KERN_SYSCALL_TBL_1 + (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_2 + (0x25 * 4)), (unsigned int) SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_3 + (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_4 + (0x25 * 4)), (unsigned int) SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_5 + (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; unsigned int repl_addr = ADDRESS_main_entry_hook;
KernelWriteU32(repl_addr,0x48000003 | entryPoint); KernelWriteU32(repl_addr, 0x48000003 | entryPoint);
DCFlushRange((void*) repl_addr, 4); DCFlushRange((void *) repl_addr, 4);
ICInvalidateRange((void*)(repl_addr), 4); ICInvalidateRange((void *) (repl_addr), 4);
} }
void KernelWriteU32(uint32_t addr, uint32_t value) { void KernelWriteU32(uint32_t addr, uint32_t value) {
@ -32,8 +32,8 @@ void KernelWriteU32(uint32_t addr, uint32_t value) {
SC_KernelCopyData(dst, src, 4); SC_KernelCopyData(dst, src, 4);
DCFlushRange((void *)addr, 4); DCFlushRange((void *) addr, 4);
ICInvalidateRange((void *)addr, 4); ICInvalidateRange((void *) addr, 4);
} }
/* Write a 32-bit word with kernel permissions */ /* Write a 32-bit word with kernel permissions */

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#define ADDRESS_main_entry_hook 0x0101C56C #define ADDRESS_main_entry_hook 0x0101C56C
@ -10,5 +11,7 @@
#define KERN_SYSCALL_TBL_5 0xFFEAAE60 // works with browser (previously KERN_SYSCALL_TBL) #define KERN_SYSCALL_TBL_5 0xFFEAAE60 // works with browser (previously KERN_SYSCALL_TBL)
void SetupRelocator(); void SetupRelocator();
void KernelWriteU32(uint32_t addr, uint32_t value); void KernelWriteU32(uint32_t addr, uint32_t value);
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value); void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value);

View File

@ -26,7 +26,7 @@
bool CheckRunning() { bool CheckRunning() {
switch(ProcUIProcessMessages(true)) { switch (ProcUIProcessMessages(true)) {
case PROCUI_STATUS_EXITING: { case PROCUI_STATUS_EXITING: {
return false; return false;
} }
@ -50,8 +50,8 @@ static_assert(sizeof(module_information_t) <= 0x80000);
extern "C" uint32_t textStart(); extern "C" uint32_t textStart();
bool doRelocation(std::vector<RelocationData> &relocData, relocation_trampolin_entry_t * tramp_data, uint32_t tramp_length) { bool doRelocation(std::vector<RelocationData> &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length) {
for (auto const& curReloc : relocData) { for (auto const &curReloc : relocData) {
std::string functionName = curReloc.getName(); std::string functionName = curReloc.getName();
std::string rplName = curReloc.getImportRPLInformation().getName(); std::string rplName = curReloc.getImportRPLInformation().getName();
int32_t isData = curReloc.getImportRPLInformation().isData(); int32_t isData = curReloc.getImportRPLInformation().isData();
@ -59,11 +59,11 @@ bool doRelocation(std::vector<RelocationData> &relocData, relocation_trampolin_e
OSDynLoad_Acquire(rplName.c_str(), &rplHandle); OSDynLoad_Acquire(rplName.c_str(), &rplHandle);
uint32_t functionAddress = 0; uint32_t functionAddress = 0;
OSDynLoad_FindExport(rplHandle, isData, functionName.c_str(), (void**) &functionAddress); OSDynLoad_FindExport(rplHandle, isData, functionName.c_str(), (void **) &functionAddress);
if(functionAddress == 0) { if (functionAddress == 0) {
return false; 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"); DEBUG_FUNCTION_LINE("Relocation failed\n");
return false; return false;
} }
@ -84,45 +84,45 @@ int main(int argc, char **argv) {
DirList setupModules("fs:/vol/external01/wiiu/modules/setup", ".rpx", DirList::Files, 1); DirList setupModules("fs:/vol/external01/wiiu/modules/setup", ".rpx", DirList::Files, 1);
setupModules.SortList(); setupModules.SortList();
for(int i = 0; i < setupModules.GetFilecount(); i++) { for (int i = 0; i < setupModules.GetFilecount(); i++) {
memset((void*)gModuleData, 0, sizeof(module_information_t)); memset((void *) gModuleData, 0, sizeof(module_information_t));
DEBUG_FUNCTION_LINE("Trying to run %s",setupModules.GetFilepath(i)); DEBUG_FUNCTION_LINE("Trying to run %s", setupModules.GetFilepath(i));
std::optional<ModuleData> moduleData = ModuleDataFactory::load(setupModules.GetFilepath(i), 0x00900000, 0x01000000 - textSectionStart, gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH); std::optional<ModuleData> 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)); DEBUG_FUNCTION_LINE("Failed to load %s", setupModules.GetFilepath(i));
continue; continue;
} }
DEBUG_FUNCTION_LINE("Loaded module data"); DEBUG_FUNCTION_LINE("Loaded module data");
std::vector<RelocationData> relocData = moduleData->getRelocationDataList(); std::vector<RelocationData> 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"); 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()); 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()); 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); DCFlushRange((void *) 0x00800000, 0x00800000);
ICInvalidateRange((void*)0x00800000, 0x00800000); ICInvalidateRange((void *) 0x00800000, 0x00800000);
DEBUG_FUNCTION_LINE("Calling %08X", moduleData->getEntrypoint()); 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"); 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); DirList modules("fs:/vol/external01/wiiu/modules", ".rpx", DirList::Files, 1);
modules.SortList(); modules.SortList();
for(int i = 0; i < modules.GetFilecount(); i++) { for (int i = 0; i < modules.GetFilecount(); i++) {
DEBUG_FUNCTION_LINE("Loading module %s",modules.GetFilepath(i)); DEBUG_FUNCTION_LINE("Loading module %s", modules.GetFilepath(i));
std::optional<ModuleData> moduleData = ModuleDataFactory::load(modules.GetFilepath(i), 0x00900000, 0x01000000 - textSectionStart, gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH); std::optional<ModuleData> 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)); DEBUG_FUNCTION_LINE("Successfully loaded %s", modules.GetFilepath(i));
ModuleDataPersistence::saveModuleData(gModuleData, moduleData.value()); ModuleDataPersistence::saveModuleData(gModuleData, moduleData.value());
} else { } else {
@ -136,7 +136,7 @@ int main(int argc, char **argv) {
ProcUIInit(OSSavesDone_ReadyToRelease); ProcUIInit(OSSavesDone_ReadyToRelease);
SYSLaunchMenu(); SYSLaunchMenu();
while(CheckRunning()) { while (CheckRunning()) {
// wait. // wait.
OSSleepTicks(OSMillisecondsToTicks(100)); OSSleepTicks(OSMillisecondsToTicks(100));
} }

View File

@ -6,26 +6,26 @@
#include "utils/logger.h" #include "utils/logger.h"
#include "common/module_defines.h" #include "common/module_defines.h"
dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t * data, const char* functionName) { dyn_linking_function_t *DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, const char *functionName) {
if(data == NULL) { if (data == NULL) {
return NULL; return NULL;
} }
if(functionName == NULL) { if (functionName == NULL) {
return NULL; return NULL;
} }
dyn_linking_function_t * result = NULL; dyn_linking_function_t *result = NULL;
for(int32_t i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) { for (int32_t i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) {
dyn_linking_function_t * curEntry = &(data->functions[i]); dyn_linking_function_t *curEntry = &(data->functions[i]);
if(strlen(curEntry->functionName) == 0) { if (strlen(curEntry->functionName) == 0) {
if(strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) { if (strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) {
DEBUG_FUNCTION_LINE("Failed to add function name, it's too long.\n"); DEBUG_FUNCTION_LINE("Failed to add function name, it's too long.\n");
return NULL; return NULL;
} }
strncpy(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH); strncpy(curEntry->functionName, functionName, DYN_LINK_FUNCTION_NAME_LENGTH);
result = curEntry; result = curEntry;
break; 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; result = curEntry;
break; break;
} }
@ -33,62 +33,65 @@ dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_l
return result; 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); 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); return getOrAddImport(data, importName, true);
} }
dyn_linking_import_t * DynamicLinkingHelper::getOrAddImport(dyn_linking_relocation_data_t * data, const char* importName, bool isData) { dyn_linking_import_t *DynamicLinkingHelper::getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData) {
if(importName == NULL || data == NULL) { if (importName == NULL || data == NULL) {
return NULL; return NULL;
} }
dyn_linking_import_t * result = NULL; dyn_linking_import_t *result = NULL;
for(int32_t i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) { for (int32_t i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) {
dyn_linking_import_t * curEntry = &(data->imports[i]); dyn_linking_import_t *curEntry = &(data->imports[i]);
if(strlen(curEntry->importName) == 0) { if (strlen(curEntry->importName) == 0) {
if(strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) { if (strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) {
DEBUG_FUNCTION_LINE("Failed to add Import, it's too long.\n"); DEBUG_FUNCTION_LINE("Failed to add Import, it's too long.\n");
return NULL; return NULL;
} }
strncpy(curEntry->importName,importName,DYN_LINK_IMPORT_NAME_LENGTH); strncpy(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH);
curEntry->isData = isData; curEntry->isData = isData;
result = curEntry; result = curEntry;
break; 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 curEntry;
} }
} }
return result; 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) { 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()); 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) { 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,
dyn_linking_import_t * importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo.getName().c_str(),rplInfo.isData()); std::string name, const ImportRPLInformation &rplInfo) {
if(importInfoGbl == NULL) { dyn_linking_import_t *importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo.getName().c_str(), rplInfo.isData());
DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d rpl files to import reached.\n",DYN_LINK_IMPORT_LIST_LENGTH); 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; return false;
} }
dyn_linking_function_t * functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(linking_data, name.c_str()); dyn_linking_function_t *functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(linking_data, name.c_str());
if(functionInfo == NULL) { 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); 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 false;
} }
return addReloationEntry(linking_entries, linking_entry_length, type, offset, addend, destination, functionInfo, importInfoGbl); 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) { 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,
for(uint32_t i = 0; i < linking_entry_length; i++) { dyn_linking_import_t *importInfo) {
dyn_linking_relocation_entry_t * curEntry = &(linking_entries[i]); for (uint32_t i = 0; i < linking_entry_length; i++) {
if(curEntry->functionEntry != NULL) { dyn_linking_relocation_entry_t *curEntry = &(linking_entries[i]);
if (curEntry->functionEntry != NULL) {
continue; continue;
} }
curEntry->type = type; curEntry->type = type;

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "common/dynamic_linking_defines.h" #include "common/dynamic_linking_defines.h"
#include "utils/logger.h" #include "utils/logger.h"
#include <string> #include <string>
@ -13,7 +14,7 @@ public:
\param functionName Name of the function \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. \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. 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 \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. \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 \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. \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. \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: private:
DynamicLinkingHelper() { DynamicLinkingHelper() {
} }

View File

@ -40,7 +40,7 @@ public:
std::string rplName = ""; std::string rplName = "";
if(rawSectionName.size() < fimport.size()) { if (rawSectionName.size() < fimport.size()) {
return std::nullopt; return std::nullopt;
} else if (std::equal(fimport.begin(), fimport.end(), rawSectionName.begin())) { } else if (std::equal(fimport.begin(), fimport.end(), rawSectionName.begin())) {
rplName = rawSectionName.substr(fimport.size()); rplName = rawSectionName.substr(fimport.size());

View File

@ -53,11 +53,11 @@ public:
this->endAddress = endAddress; this->endAddress = endAddress;
} }
void addRelocationData(const RelocationData& relocation_data) { void addRelocationData(const RelocationData &relocation_data) {
relocation_data_list.push_back(relocation_data); relocation_data_list.push_back(relocation_data);
} }
const std::vector<RelocationData>& getRelocationDataList() const { const std::vector<RelocationData> &getRelocationDataList() const {
return relocation_data_list; return relocation_data_list;
} }
@ -80,31 +80,32 @@ public:
return bssAddr; return bssAddr;
} }
uint32_t getBSSSize() const{ uint32_t getBSSSize() const {
return bssSize; return bssSize;
} }
uint32_t getSBSSAddr() const{ uint32_t getSBSSAddr() const {
return sbssAddr; return sbssAddr;
} }
uint32_t getSBSSSize() const{ uint32_t getSBSSSize() const {
return sbssSize; return sbssSize;
} }
uint32_t getEntrypoint() const{ uint32_t getEntrypoint() const {
return entrypoint; return entrypoint;
} }
uint32_t getStartAddress() const{ uint32_t getStartAddress() const {
return startAddress; return startAddress;
} }
uint32_t getEndAddress() const{ uint32_t getEndAddress() const {
return endAddress; return endAddress;
} }
std::string toString() const; std::string toString() const;
private: private:
std::vector<RelocationData> relocation_data_list; std::vector<RelocationData> relocation_data_list;
std::map<std::string, SectionInfo> section_info_list; std::map<std::string, SectionInfo> section_info_list;

View File

@ -27,7 +27,7 @@
using namespace ELFIO; using namespace ELFIO;
std::optional<ModuleData> 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<ModuleData> 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; elfio reader;
ModuleData moduleData; ModuleData moduleData;
@ -52,8 +52,8 @@ std::optional<ModuleData> ModuleDataFactory::load(std::string path, uint32_t des
uint32_t endAddress = 0; uint32_t endAddress = 0;
for(uint32_t i = 0; i < sec_num; ++i ) { for (uint32_t i = 0; i < sec_num; ++i) {
section* psec = reader.sections[i]; section *psec = reader.sections[i];
if (psec->get_type() == 0x80000002) { if (psec->get_type() == 0x80000002) {
continue; continue;
} }
@ -65,15 +65,15 @@ std::optional<ModuleData> ModuleDataFactory::load(std::string path, uint32_t des
destinations[psec->get_index()] = (uint8_t *) baseOffset; destinations[psec->get_index()] = (uint8_t *) baseOffset;
uint32_t destination = baseOffset + address; uint32_t destination = baseOffset + address;
if((address >= 0x02000000) && address < 0x10000000) { if ((address >= 0x02000000) && address < 0x10000000) {
destination -= 0x02000000; destination -= 0x02000000;
destinations[psec->get_index()] -= 0x02000000; destinations[psec->get_index()] -= 0x02000000;
baseOffset += sectionSize; baseOffset += sectionSize;
offset_data += sectionSize; offset_data += sectionSize;
} else if((address >= 0x10000000) && address < 0xC0000000) { } else if ((address >= 0x10000000) && address < 0xC0000000) {
destination -= 0x10000000; destination -= 0x10000000;
destinations[psec->get_index()] -= 0x10000000; destinations[psec->get_index()] -= 0x10000000;
} else if(address >= 0xC0000000) { } else if (address >= 0xC0000000) {
destination -= 0xC0000000; destination -= 0xC0000000;
destinations[psec->get_index()] -= 0xC0000000; destinations[psec->get_index()] -= 0xC0000000;
} else { } else {
@ -82,21 +82,21 @@ std::optional<ModuleData> ModuleDataFactory::load(std::string path, uint32_t des
return std::nullopt; 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); DEBUG_FUNCTION_LINE("memset section %s %08X to 0 (%d bytes)", psec->get_name().c_str(), destination, sectionSize);
memset((void*) destination, 0, sectionSize); memset((void *) destination, 0, sectionSize);
} else if(psec->get_type() == SHT_PROGBITS) { } 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); 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); //nextAddress = ROUNDUP(destination + sectionSize,0x100);
if(psec->get_name().compare(".bss") == 0) { if (psec->get_name().compare(".bss") == 0) {
moduleData.setBSSLocation(destination, sectionSize); moduleData.setBSSLocation(destination, sectionSize);
DEBUG_FUNCTION_LINE("Saved %s section info. Location: %08X size: %08X", psec->get_name().c_str(), 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); moduleData.setSBSSLocation(destination, sectionSize);
DEBUG_FUNCTION_LINE("Saved %s section info. Location: %08X size: %08X", psec->get_name().c_str(), 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<ModuleData> ModuleDataFactory::load(std::string path, uint32_t des
totalSize += sectionSize; totalSize += sectionSize;
if(endAddress < destination + sectionSize){ if (endAddress < destination + sectionSize) {
endAddress = destination + sectionSize; endAddress = destination + sectionSize;
} }
DCFlushRange((void*)destination, sectionSize); DCFlushRange((void *) destination, sectionSize);
ICInvalidateRange((void*)destination, sectionSize); ICInvalidateRange((void *) destination, sectionSize);
} }
} }
for(uint32_t i = 0; i < sec_num; ++i ) { for (uint32_t i = 0; i < sec_num; ++i) {
section* psec = reader.sections[i]; section *psec = reader.sections[i];
if ((psec->get_type() == SHT_PROGBITS || psec->get_type() == SHT_NOBITS) && (psec->get_flags() & SHF_ALLOC)) { 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)) { 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"); DEBUG_FUNCTION_LINE("elfLink failed");
free(destinations); free(destinations);
@ -129,12 +129,12 @@ std::optional<ModuleData> ModuleDataFactory::load(std::string path, uint32_t des
} }
std::vector<RelocationData> relocationData = getImportRelocationData(reader, destinations); std::vector<RelocationData> relocationData = getImportRelocationData(reader, destinations);
for (auto const& reloc : relocationData) { for (auto const &reloc : relocationData) {
moduleData.addRelocationData(reloc); moduleData.addRelocationData(reloc);
} }
DCFlushRange((void*)destination_address, totalSize); DCFlushRange((void *) destination_address, totalSize);
ICInvalidateRange((void*)destination_address, totalSize); ICInvalidateRange((void *) destination_address, totalSize);
free(destinations); free(destinations);
@ -148,25 +148,25 @@ std::optional<ModuleData> ModuleDataFactory::load(std::string path, uint32_t des
return moduleData; return moduleData;
} }
std::vector<RelocationData> ModuleDataFactory::getImportRelocationData(elfio& reader, uint8_t ** destinations) { std::vector<RelocationData> ModuleDataFactory::getImportRelocationData(elfio &reader, uint8_t **destinations) {
std::vector<RelocationData> result; std::vector<RelocationData> result;
std::map<uint32_t,std::string> infoMap; std::map<uint32_t, std::string> infoMap;
uint32_t sec_num = reader.sections.size(); uint32_t sec_num = reader.sections.size();
for ( uint32_t i = 0; i < sec_num; ++i ) { for (uint32_t i = 0; i < sec_num; ++i) {
section* psec = reader.sections[i]; section *psec = reader.sections[i];
if (psec->get_type() == 0x80000002) { if (psec->get_type() == 0x80000002) {
infoMap[i] = psec->get_name(); infoMap[i] = psec->get_name();
} }
} }
for (uint32_t i = 0; i < sec_num; ++i ) { for (uint32_t i = 0; i < sec_num; ++i) {
section* psec = reader.sections[i]; section *psec = reader.sections[i];
if(psec->get_type() == SHT_RELA || psec->get_type() == SHT_REL) { if (psec->get_type() == SHT_RELA || psec->get_type() == SHT_REL) {
DEBUG_FUNCTION_LINE("Found relocation section %s",psec->get_name().c_str()); DEBUG_FUNCTION_LINE("Found relocation section %s", psec->get_name().c_str());
relocation_section_accessor rel(reader, psec); relocation_section_accessor rel(reader, psec);
for ( uint32_t j = 0; j < (uint32_t) rel.get_entries_num(); ++j ) { for (uint32_t j = 0; j < (uint32_t) rel.get_entries_num(); ++j) {
Elf64_Addr offset; Elf64_Addr offset;
Elf_Word type; Elf_Word type;
Elf_Sxword addend; Elf_Sxword addend;
@ -174,17 +174,17 @@ std::vector<RelocationData> ModuleDataFactory::getImportRelocationData(elfio& re
Elf64_Addr sym_value; Elf64_Addr sym_value;
Elf_Half sym_section_index; 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"); DEBUG_FUNCTION_LINE("Failed to get relocation");
break; break;
} }
uint32_t adjusted_sym_value = (uint32_t) sym_value; uint32_t adjusted_sym_value = (uint32_t) sym_value;
if(adjusted_sym_value < 0xC0000000) { if (adjusted_sym_value < 0xC0000000) {
continue; continue;
} }
std::optional<ImportRPLInformation> rplInfo = ImportRPLInformation::createImportRPLInformation(infoMap[sym_section_index]); std::optional<ImportRPLInformation> rplInfo = ImportRPLInformation::createImportRPLInformation(infoMap[sym_section_index]);
if(!rplInfo) { if (!rplInfo) {
DEBUG_FUNCTION_LINE("Failed to create import information"); DEBUG_FUNCTION_LINE("Failed to create import information");
break; break;
} }
@ -192,7 +192,7 @@ std::vector<RelocationData> ModuleDataFactory::getImportRelocationData(elfio& re
uint32_t section_index = psec->get_info(); uint32_t section_index = psec->get_info();
// When these relocations are performed, we don't need the 0xC0000000 offset anymore. // 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(); //relocationData->printInformation();
result.push_back(relocationData); result.push_back(relocationData);
} }
@ -200,15 +200,16 @@ std::vector<RelocationData> ModuleDataFactory::getImportRelocationData(elfio& re
} }
return result; 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(); uint32_t sec_num = reader.sections.size();
for (uint32_t i = 0; i < sec_num; ++i ) { for (uint32_t i = 0; i < sec_num; ++i) {
section* psec = reader.sections[i]; section *psec = reader.sections[i];
if(psec->get_info() == section_index) { if (psec->get_info() == section_index) {
DEBUG_FUNCTION_LINE("Found relocation section %s",psec->get_name().c_str()); DEBUG_FUNCTION_LINE("Found relocation section %s", psec->get_name().c_str());
relocation_section_accessor rel(reader, psec); relocation_section_accessor rel(reader, psec);
for ( uint32_t j = 0; j < (uint32_t) rel.get_entries_num(); ++j ) { for (uint32_t j = 0; j < (uint32_t) rel.get_entries_num(); ++j) {
Elf64_Addr offset; Elf64_Addr offset;
Elf_Word type; Elf_Word type;
Elf_Sxword addend; Elf_Sxword addend;
@ -216,36 +217,36 @@ bool ModuleDataFactory::linkSection(elfio& reader, uint32_t section_index, uint3
Elf64_Addr sym_value; Elf64_Addr sym_value;
Elf_Half sym_section_index; 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"); DEBUG_FUNCTION_LINE("Failed to get relocation");
break; break;
} }
uint32_t adjusted_sym_value = (uint32_t) sym_value; 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 -= 0x02000000;
adjusted_sym_value += base_text; 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 -= 0x10000000;
adjusted_sym_value += base_data; adjusted_sym_value += base_data;
} else if(adjusted_sym_value >= 0xC0000000) { } else if (adjusted_sym_value >= 0xC0000000) {
// Skip imports // Skip imports
continue; continue;
} else if(adjusted_sym_value == 0x0) { } else if (adjusted_sym_value == 0x0) {
// //
} else { } else {
DEBUG_FUNCTION_LINE("Unhandled case %08X",adjusted_sym_value); DEBUG_FUNCTION_LINE("Unhandled case %08X", adjusted_sym_value);
return false; 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); DEBUG_FUNCTION_LINE("NOT IMPLEMENTED: %04X", sym_section_index);
return false; 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"); DEBUG_FUNCTION_LINE("Link failed");
return false; return false;
} }

View File

@ -26,7 +26,9 @@
class ModuleDataFactory { class ModuleDataFactory {
public: public:
static std::optional<ModuleData> load(std::string path, uint32_t destination_address, uint32_t maximum_size, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length); static std::optional<ModuleData> 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<RelocationData> getImportRelocationData(ELFIO::elfio& reader, uint8_t ** destinations); 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<RelocationData> getImportRelocationData(ELFIO::elfio &reader, uint8_t **destinations);
}; };

View File

@ -6,21 +6,21 @@
#include "ModuleData.h" #include "ModuleData.h"
#include "RelocationData.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; 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); DEBUG_FUNCTION_LINE("Reached maximum module count of %d", MAXIMUM_MODULES);
return false; return false;
} }
// Copy data to global struct. // 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()); DEBUG_FUNCTION_LINE("Saving reloation data for module at %08X", module.getEntrypoint());
// Relocation // Relocation
std::vector<RelocationData> relocationData = module.getRelocationDataList(); std::vector<RelocationData> relocationData = module.getRelocationDataList();
for (auto const& reloc : relocationData) { for (auto const &reloc : relocationData) {
if(!DynamicLinkingHelper::addReloationEntry(&(moduleInformation->linking_data), module_data->linking_entries, DYN_LINK_RELOCATION_LIST_LENGTH, reloc)) { 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"); DEBUG_FUNCTION_LINE("Failed to add relocation entry\n");
return false; return false;
} }
@ -37,29 +37,29 @@ bool ModuleDataPersistence::saveModuleData(module_information_t * moduleInformat
moduleInformation->number_used_modules++; moduleInformation->number_used_modules++;
DCFlushRange((void*)moduleInformation,sizeof(module_information_t)); DCFlushRange((void *) moduleInformation, sizeof(module_information_t));
ICInvalidateRange((void*)moduleInformation,sizeof(module_information_t)); ICInvalidateRange((void *) moduleInformation, sizeof(module_information_t));
return true; return true;
} }
std::vector<ModuleData> ModuleDataPersistence::loadModuleData(module_information_t * moduleInformation) { std::vector<ModuleData> ModuleDataPersistence::loadModuleData(module_information_t *moduleInformation) {
std::vector<ModuleData> result; std::vector<ModuleData> result;
if(moduleInformation == NULL) { if (moduleInformation == NULL) {
DEBUG_FUNCTION_LINE("moduleInformation == NULL\n"); DEBUG_FUNCTION_LINE("moduleInformation == NULL\n");
return result; return result;
} }
DCFlushRange((void*)moduleInformation,sizeof(module_information_t)); DCFlushRange((void *) moduleInformation, sizeof(module_information_t));
ICInvalidateRange((void*)moduleInformation,sizeof(module_information_t)); ICInvalidateRange((void *) moduleInformation, sizeof(module_information_t));
int32_t module_count = moduleInformation->number_used_modules; int32_t module_count = moduleInformation->number_used_modules;
if(module_count > 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); 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; 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. // 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 moduleData;
moduleData.setBSSLocation(module_data->bssAddr, module_data->bssSize); moduleData.setBSSLocation(module_data->bssAddr, module_data->bssSize);
moduleData.setSBSSLocation(module_data->sbssAddr, module_data->sbssSize); moduleData.setSBSSLocation(module_data->sbssAddr, module_data->sbssSize);
@ -67,27 +67,27 @@ std::vector<ModuleData> ModuleDataPersistence::loadModuleData(module_information
moduleData.setStartAddress(module_data->startAddress); moduleData.setStartAddress(module_data->startAddress);
moduleData.setEndAddress(module_data->endAddress); moduleData.setEndAddress(module_data->endAddress);
for(uint32_t j = 0; j < DYN_LINK_RELOCATION_LIST_LENGTH; j++) { for (uint32_t j = 0; j < DYN_LINK_RELOCATION_LIST_LENGTH; j++) {
dyn_linking_relocation_entry_t * linking_entry = &(module_data->linking_entries[j]); dyn_linking_relocation_entry_t *linking_entry = &(module_data->linking_entries[j]);
if(linking_entry->destination == NULL){ if (linking_entry->destination == NULL) {
break; break;
} }
dyn_linking_import_t* importEntry = linking_entry->importEntry; dyn_linking_import_t *importEntry = linking_entry->importEntry;
if(importEntry == NULL){ if (importEntry == NULL) {
DEBUG_FUNCTION_LINE("importEntry was NULL, skipping relocation entry\n"); DEBUG_FUNCTION_LINE("importEntry was NULL, skipping relocation entry\n");
continue; continue;
} }
if(importEntry->importName == NULL){ if (importEntry->importName == NULL) {
DEBUG_FUNCTION_LINE("importEntry->importName was NULL, skipping relocation entry\n"); DEBUG_FUNCTION_LINE("importEntry->importName was NULL, skipping relocation entry\n");
continue; 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"); DEBUG_FUNCTION_LINE("functionEntry was NULL, skipping relocation entry\n");
continue; continue;
} }
if(functionEntry->functionName == NULL){ if (functionEntry->functionName == NULL) {
DEBUG_FUNCTION_LINE("functionEntry->functionName was NULL, skipping relocation entry\n"); DEBUG_FUNCTION_LINE("functionEntry->functionName was NULL, skipping relocation entry\n");
continue; continue;
} }

View File

@ -5,6 +5,7 @@
class ModuleDataPersistence { class ModuleDataPersistence {
public: public:
static bool saveModuleData(module_information_t * moduleInformation, const ModuleData& module); static bool saveModuleData(module_information_t *moduleInformation, const ModuleData &module);
static std::vector<ModuleData> loadModuleData(module_information_t * moduleInformation);
static std::vector<ModuleData> loadModuleData(module_information_t *moduleInformation);
}; };

View File

@ -1,6 +1,6 @@
#include "RelocationData.h" #include "RelocationData.h"
#include "utils/StringTools.h" #include "utils/StringTools.h"
std::string RelocationData::toString() const{ 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() ); 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());
} }

View File

@ -23,7 +23,7 @@
class RelocationData { class RelocationData {
public: 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->type = type;
this->offset = offset; this->offset = offset;
this->addend = addend; this->addend = addend;
@ -34,31 +34,32 @@ public:
~RelocationData() { ~RelocationData() {
} }
char getType() const{ char getType() const {
return type; return type;
} }
size_t getOffset() const{ size_t getOffset() const {
return offset; return offset;
} }
int32_t getAddend() const{ int32_t getAddend() const {
return addend; return addend;
} }
void * getDestination() const{ void *getDestination() const {
return destination; return destination;
} }
std::string getName() const{ std::string getName() const {
return name; return name;
} }
ImportRPLInformation getImportRPLInformation() const{ ImportRPLInformation getImportRPLInformation() const {
return rplInfo; return rplInfo;
} }
std::string toString() const; std::string toString() const;
private: private:
char type; char type;
size_t offset; size_t offset;

View File

@ -36,13 +36,13 @@
#include <utils/StringTools.h> #include <utils/StringTools.h>
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()) if (b.size() > a.size())
return false; return false;
return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin()); 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]; static char b[9];
b[0] = '\0'; b[0] = '\0';
@ -54,25 +54,25 @@ const char * StringTools::byte_to_binary(int32_t x) {
return b; return b;
} }
std::string StringTools::removeCharFromString(std::string& input,char toBeRemoved) { std::string StringTools::removeCharFromString(std::string &input, char toBeRemoved) {
std::string output = input; std::string output = input;
size_t position; size_t position;
while(1) { while (1) {
position = output.find(toBeRemoved); position = output.find(toBeRemoved);
if(position == std::string::npos) if (position == std::string::npos)
break; break;
output.erase(position, 1); output.erase(position, 1);
} }
return output; return output;
} }
const char * StringTools::fmt(const char * format, ...) { const char *StringTools::fmt(const char *format, ...) {
static char strChar[512]; static char strChar[512];
strChar[0] = 0; strChar[0] = 0;
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if((vsprintf(strChar, format, va) >= 0)) { if ((vsprintf(strChar, format, va) >= 0)) {
va_end(va); va_end(va);
return (const char *) strChar; return (const char *) strChar;
} }
@ -81,26 +81,26 @@ const char * StringTools::fmt(const char * format, ...) {
return NULL; return NULL;
} }
const wchar_t * StringTools::wfmt(const char * format, ...) { const wchar_t *StringTools::wfmt(const char *format, ...) {
static char tmp[512]; static char tmp[512];
static wchar_t strWChar[512]; static wchar_t strWChar[512];
strWChar[0] = 0; strWChar[0] = 0;
tmp[0] = 0; tmp[0] = 0;
if(!format) if (!format)
return (const wchar_t *) strWChar; return (const wchar_t *) strWChar;
if(strcmp(format, "") == 0) if (strcmp(format, "") == 0)
return (const wchar_t *) strWChar; return (const wchar_t *) strWChar;
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) { if ((vsprintf(tmp, format, va) >= 0)) {
int bt; int bt;
int32_t strlength = strlen(tmp); 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; strWChar[bt] = 0;
return (const wchar_t *) strWChar; return (const wchar_t *) strWChar;
} }
@ -110,14 +110,14 @@ const wchar_t * StringTools::wfmt(const char * format, ...) {
return NULL; 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]; static char tmp[512];
tmp[0] = 0; tmp[0] = 0;
int32_t result = 0; int32_t result = 0;
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) { if ((vsprintf(tmp, format, va) >= 0)) {
str = tmp; str = tmp;
result = str.size(); result = str.size();
} }
@ -126,14 +126,14 @@ int32_t StringTools::strprintf(std::string &str, const char * format, ...) {
return result; return result;
} }
std::string StringTools::strfmt(const char * format, ...) { std::string StringTools::strfmt(const char *format, ...) {
std::string str; std::string str;
static char tmp[512]; static char tmp[512];
tmp[0] = 0; tmp[0] = 0;
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) { if ((vsprintf(tmp, format, va) >= 0)) {
str = tmp; str = tmp;
} }
va_end(va); va_end(va);
@ -141,8 +141,8 @@ std::string StringTools::strfmt(const char * format, ...) {
return str; return str;
} }
BOOL StringTools::char2wchar_t(const char * strChar, wchar_t * dest) { BOOL StringTools::char2wchar_t(const char *strChar, wchar_t *dest) {
if(!strChar || !dest) if (!strChar || !dest)
return false; return false;
int bt; int bt;
@ -155,39 +155,39 @@ BOOL StringTools::char2wchar_t(const char * strChar, wchar_t * dest) {
return false; return false;
} }
int32_t StringTools::strtokcmp(const char * string, const char * compare, const char * separator) { int32_t StringTools::strtokcmp(const char *string, const char *compare, const char *separator) {
if(!string || !compare) if (!string || !compare)
return -1; return -1;
char TokCopy[512]; char TokCopy[512];
strncpy(TokCopy, compare, sizeof(TokCopy)); strncpy(TokCopy, compare, sizeof(TokCopy));
TokCopy[511] = '\0'; TokCopy[511] = '\0';
char * strTok = strtok(TokCopy, separator); char *strTok = strtok(TokCopy, separator);
while (strTok != NULL) { while (strTok != NULL) {
if (strcasecmp(string, strTok) == 0) { if (strcasecmp(string, strTok) == 0) {
return 0; return 0;
} }
strTok = strtok(NULL,separator); strTok = strtok(NULL, separator);
} }
return -1; return -1;
} }
int32_t StringTools::strextcmp(const char * string, const char * extension, char seperator) { int32_t StringTools::strextcmp(const char *string, const char *extension, char seperator) {
if(!string || !extension) if (!string || !extension)
return -1; return -1;
char *ptr = strrchr(string, seperator); char *ptr = strrchr(string, seperator);
if(!ptr) if (!ptr)
return -1; return -1;
return strcasecmp(ptr + 1, extension); return strcasecmp(ptr + 1, extension);
} }
std::vector<std::string> StringTools::stringSplit(const std::string & inValue, const std::string & splitter) { std::vector<std::string> StringTools::stringSplit(const std::string &inValue, const std::string &splitter) {
std::string value = inValue; std::string value = inValue;
std::vector<std::string> result; std::vector<std::string> result;
while (true) { while (true) {
@ -202,7 +202,7 @@ std::vector<std::string> StringTools::stringSplit(const std::string & inValue, c
result.push_back(""); result.push_back("");
break; break;
} }
if(index + splitter.size() > value.length()) { if (index + splitter.size() > value.length()) {
break; break;
} }
value = value.substr(index + splitter.size(), value.length()); value = value.substr(index + splitter.size(), value.length());
@ -211,39 +211,39 @@ std::vector<std::string> StringTools::stringSplit(const std::string & inValue, c
} }
const char * StringTools::FullpathToFilename(const char *path) { const char *StringTools::FullpathToFilename(const char *path) {
if(!path) if (!path)
return path; return path;
const char * ptr = path; const char *ptr = path;
const char * Filename = ptr; const char *Filename = ptr;
while(*ptr != '\0') { while (*ptr != '\0') {
if(ptr[0] == '/' && ptr[1] != '\0') if (ptr[0] == '/' && ptr[1] != '\0')
Filename = ptr+1; Filename = ptr + 1;
++ptr; ++ptr;
} }
return Filename; return Filename;
} }
void StringTools::RemoveDoubleSlashs(std::string &str) { void StringTools::RemoveDoubleSlashs(std::string &str) {
uint32_t length = str.size(); uint32_t length = str.size();
//! clear path of double slashes //! clear path of double slashes
for(uint32_t i = 1; i < length; ++i) { for (uint32_t i = 1; i < length; ++i) {
if(str[i-1] == '/' && str[i] == '/') { if (str[i - 1] == '/' && str[i] == '/') {
str.erase(i, 1); str.erase(i, 1);
i--; i--;
length--; length--;
} }
} }
} }
// You must free the result if result is non-NULL. // 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 *result; // the return string
char *ins; // the next insert point char *ins; // the next insert point
char *tmp; // varies char *tmp; // varies
@ -268,7 +268,7 @@ char * StringTools::str_replace(char *orig, char *rep, char *with) {
ins = tmp + len_rep; 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) if (!result)
return NULL; return NULL;

View File

@ -32,20 +32,33 @@
class StringTools { class StringTools {
public: public:
static BOOL EndsWith(const std::string& a, const std::string& b); 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 *byte_to_binary(int32_t x);
static const char * fmt(const char * format, ...);
static const wchar_t * wfmt(const char * format, ...); static std::string removeCharFromString(std::string &input, char toBeRemoved);
static int32_t strprintf(std::string &str, const char * format, ...);
static std::string strfmt(const char * format, ...); static const char *fmt(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 const wchar_t *wfmt(const char *format, ...);
static int32_t strextcmp(const char * string, const char * extension, char seperator);
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 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 void RemoveDoubleSlashs(std::string &str);
static std::vector<std::string> stringSplit(const std::string & value, const std::string & splitter);
static std::vector<std::string> stringSplit(const std::string &value, const std::string &splitter);
}; };
#endif /* __STRING_TOOLS_H */ #endif /* __STRING_TOOLS_H */

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <whb/log.h> #include <whb/log.h>
#include <string.h> #include <string.h>

View File

@ -7,31 +7,31 @@
#include "utils/logger.h" #include "utils/logger.h"
// https://gist.github.com/ccbrown/9722406 // 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]; char ascii[17];
size_t i, j; size_t i, j;
ascii[16] = '\0'; ascii[16] = '\0';
DEBUG_FUNCTION_LINE("0x%08X (0x0000): ", data); DEBUG_FUNCTION_LINE("0x%08X (0x0000): ", data);
for (i = 0; i < size; ++i) { for (i = 0; i < size; ++i) {
WHBLogPrintf("%02X ", ((unsigned char*)data)[i]); WHBLogPrintf("%02X ", ((unsigned char *) data)[i]);
if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') { if (((unsigned char *) data)[i] >= ' ' && ((unsigned char *) data)[i] <= '~') {
ascii[i % 16] = ((unsigned char*)data)[i]; ascii[i % 16] = ((unsigned char *) data)[i];
} else { } else {
ascii[i % 16] = '.'; ascii[i % 16] = '.';
} }
if ((i+1) % 8 == 0 || i+1 == size) { if ((i + 1) % 8 == 0 || i + 1 == size) {
WHBLogPrintf(" "); WHBLogPrintf(" ");
if ((i+1) % 16 == 0) { if ((i + 1) % 16 == 0) {
WHBLogPrintf("| %s \n", ascii); WHBLogPrintf("| %s \n", ascii);
if(i + 1 < size) { if (i + 1 < size) {
DEBUG_FUNCTION_LINE("0x%08X (0x%04X); ", data + i + 1,i+1); DEBUG_FUNCTION_LINE("0x%08X (0x%04X); ", data + i + 1, i + 1);
} }
} else if (i+1 == size) { } else if (i + 1 == size) {
ascii[(i+1) % 16] = '\0'; ascii[(i + 1) % 16] = '\0';
if ((i+1) % 16 <= 8) { if ((i + 1) % 16 <= 8) {
WHBLogPrintf(" "); WHBLogPrintf(" ");
} }
for (j = (i+1) % 16; j < 16; ++j) { for (j = (i + 1) % 16; j < 16; ++j) {
WHBLogPrintf(" "); WHBLogPrintf(" ");
} }
WHBLogPrintf("| %s \n", ascii); WHBLogPrintf("| %s \n", ascii);

View File

@ -31,7 +31,7 @@ extern "C" {
#define le64(i) ((((uint64_t)le32((i) & 0xFFFFFFFFLL)) << 32) | ((uint64_t)le32(((i) & 0xFFFFFFFF00000000LL) >> 32))) #define le64(i) ((((uint64_t)le32((i) & 0xFFFFFFFFLL)) << 32) | ((uint64_t)le32(((i) & 0xFFFFFFFF00000000LL) >> 32)))
//Needs to have log_init() called beforehand. //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 #ifdef __cplusplus
} }