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

View File

@ -1,4 +1,5 @@
#pragma once
#include "../../source/common/dynamic_linking_defines.h"
#include "utils/logger.h"
#include <string>
@ -13,7 +14,7 @@ public:
\param functionName Name of the function
\return Returns a pointer to the entry which contains the functionName. Null on error or if the list full.
**/
static dyn_linking_function_t * getOrAddFunctionEntryByName(dyn_linking_relocation_data_t * data, const char * functionName);
static dyn_linking_function_t *getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, const char *functionName);
/**
Gets the function import entry for a given function name. If the import is not present in the list, it will be added.
@ -22,7 +23,7 @@ public:
\param importName Name of the function
\return Returns a pointer to the function import entry which contains the importName. Null on error or if the list full.
**/
static dyn_linking_import_t * getOrAddFunctionImportByName(dyn_linking_relocation_data_t * data, const char * importName);
static dyn_linking_import_t *getOrAddFunctionImportByName(dyn_linking_relocation_data_t *data, const char *importName);
/**
@ -32,7 +33,7 @@ public:
\param importName Name of the data
\return Returns a pointer to the data import entry which contains the importName. Null on error or if the list full.
**/
static dyn_linking_import_t * getOrAddDataImportByName(dyn_linking_relocation_data_t * data, const char * importName);
static dyn_linking_import_t *getOrAddDataImportByName(dyn_linking_relocation_data_t *data, const char *importName);
/**
@ -44,13 +45,16 @@ public:
\return Returns a pointer to the data import entry which contains the importName. Null on error or if the list full.
**/
static dyn_linking_import_t * getOrAddImport(dyn_linking_relocation_data_t * data, const char * importName, bool isData);
static dyn_linking_import_t *getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData);
static bool addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, const RelocationData& relocationData);
static bool addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, const RelocationData &relocationData);
static bool addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, std::string name, const ImportRPLInformation& rplInfo);
static bool addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, std::string name,
const ImportRPLInformation &rplInfo);
static bool
addReloationEntry(dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, dyn_linking_function_t *functionName, dyn_linking_import_t *importInfo);
static bool addReloationEntry(dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, dyn_linking_function_t * functionName, dyn_linking_import_t * importInfo);
private:
DynamicLinkingHelper() {
}

View File

@ -6,145 +6,145 @@
#include "ElfUtils.h"
// See https://github.com/decaf-emu/decaf-emu/blob/43366a34e7b55ab9d19b2444aeb0ccd46ac77dea/src/libdecaf/src/cafe/loader/cafe_loader_reloc.cpp#L144
bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type) {
if(type == R_PPC_NONE) {
bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type) {
if (type == R_PPC_NONE) {
return true;
}
auto target = destination + offset;
auto target = destination + offset;
auto value = symbol_addr + addend;
auto relValue = value - static_cast<uint32_t>(target);
switch (type) {
case R_PPC_NONE:
break;
case R_PPC_ADDR32:
*((uint32_t *)(target)) = value;
break;
case R_PPC_ADDR16_LO:
*((uint16_t *)(target)) = static_cast<uint16_t>(value & 0xFFFF);
break;
case R_PPC_ADDR16_HI:
*((uint16_t *)(target)) = static_cast<uint16_t>(value >> 16);
break;
case R_PPC_ADDR16_HA:
*((uint16_t *)(target)) = static_cast<uint16_t>((value + 0x8000) >> 16);
break;
case R_PPC_DTPMOD32:
DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n");
//*((int32_t *)(target)) = tlsModuleIndex;
break;
case R_PPC_DTPREL32:
*((uint32_t *)(target)) = value;
break;
case R_PPC_GHS_REL16_HA:
*((uint16_t *)(target)) = static_cast<uint16_t>((relValue + 0x8000) >> 16);
break;
case R_PPC_GHS_REL16_HI:
*((uint16_t *)(target)) = static_cast<uint16_t>(relValue >> 16);
break;
case R_PPC_GHS_REL16_LO:
*((uint16_t *)(target)) = static_cast<uint16_t>(relValue & 0xFFFF);
break;
case R_PPC_REL14: {
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
if (distance > 0x7FFC || distance < -0x7FFC) {
DEBUG_FUNCTION_LINE("***14-bit relative branch cannot hit target.");
return false;
}
if (distance & 3) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470040);
return false;
}
if ((distance >= 0 && (distance & 0xFFFF8000)) ||
(distance < 0 && ((distance & 0xFFFF8000) != 0xFFFF8000))) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 17 bits before shift must all be the same.", -470040);
return false;
}
*(int32_t *)target = (*(int32_t *)target & 0xFFBF0003) | (distance & 0x0000fffc);
break;
}
case R_PPC_REL24: {
// if (isWeakSymbol && !symbolValue) {
// symbolValue = static_cast<uint32_t>(target);
// value = symbolValue + addend;
// }
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) {
if(trampolin_data == NULL) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin isn't provided\n");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
case R_PPC_NONE:
break;
case R_PPC_ADDR32:
*((uint32_t *) (target)) = value;
break;
case R_PPC_ADDR16_LO:
*((uint16_t *) (target)) = static_cast<uint16_t>(value & 0xFFFF);
break;
case R_PPC_ADDR16_HI:
*((uint16_t *) (target)) = static_cast<uint16_t>(value >> 16);
break;
case R_PPC_ADDR16_HA:
*((uint16_t *) (target)) = static_cast<uint16_t>((value + 0x8000) >> 16);
break;
case R_PPC_DTPMOD32:
DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n");
//*((int32_t *)(target)) = tlsModuleIndex;
break;
case R_PPC_DTPREL32:
*((uint32_t *) (target)) = value;
break;
case R_PPC_GHS_REL16_HA:
*((uint16_t *) (target)) = static_cast<uint16_t>((relValue + 0x8000) >> 16);
break;
case R_PPC_GHS_REL16_HI:
*((uint16_t *) (target)) = static_cast<uint16_t>(relValue >> 16);
break;
case R_PPC_GHS_REL16_LO:
*((uint16_t *) (target)) = static_cast<uint16_t>(relValue & 0xFFFF);
break;
case R_PPC_REL14: {
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
if (distance > 0x7FFC || distance < -0x7FFC) {
DEBUG_FUNCTION_LINE("***14-bit relative branch cannot hit target.");
return false;
} else {
relocation_trampolin_entry_t * freeSlot = NULL;
for(uint32_t i = 0; i < trampolin_data_length; i++) {
// We want to override "old" relocations of imports
// Pending relocations have the status RELOC_TRAMP_IMPORT_IN_PROGRESS.
// When all relocations are done successfully, they will be turned into RELOC_TRAMP_IMPORT_DONE
// so they can be overridden/updated/reused on the next application launch.
//
// Relocations that won't change will have the status RELOC_TRAMP_FIXED and are set to free when the module is unloaded.
if(trampolin_data[i].status == RELOC_TRAMP_FREE ||
trampolin_data[i].status == RELOC_TRAMP_IMPORT_DONE) {
freeSlot = &(trampolin_data[i]);
break;
}
}
if(freeSlot != NULL) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin data list is full\n");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false;
}
if(target - (uint32_t)&(freeSlot->trampolin[0]) > 0x1FFFFFC) {
DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer).");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false;
}
freeSlot->trampolin[0] = 0x3D600000 | ((((uint32_t) value) >> 16) & 0x0000FFFF); // lis r11, real_addr@h
freeSlot->trampolin[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l
freeSlot->trampolin[2] = 0x7D6903A6; // mtctr r11
freeSlot->trampolin[3] = 0x4E800420; // bctr
DCFlushRange((void*)freeSlot->trampolin, sizeof(freeSlot->trampolin));
ICInvalidateRange((unsigned char*)freeSlot->trampolin, sizeof(freeSlot->trampolin));
if(reloc_type == RELOC_TYPE_FIXED) {
freeSlot->status = RELOC_TRAMP_FIXED;
} else {
// Relocations for the imports may be overridden
freeSlot->status = RELOC_TRAMP_IMPORT_IN_PROGRESS;
}
uint32_t symbolValue = (uint32_t)&(freeSlot->trampolin[0]);
value = symbolValue + addend;
distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
DEBUG_FUNCTION_LINE("Created tramp\n");
}
}
if (distance & 3) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470022);
if (distance & 3) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470040);
return false;
}
if ((distance >= 0 && (distance & 0xFFFF8000)) ||
(distance < 0 && ((distance & 0xFFFF8000) != 0xFFFF8000))) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 17 bits before shift must all be the same.", -470040);
return false;
}
*(int32_t *) target = (*(int32_t *) target & 0xFFBF0003) | (distance & 0x0000fffc);
break;
}
case R_PPC_REL24: {
// if (isWeakSymbol && !symbolValue) {
// symbolValue = static_cast<uint32_t>(target);
// value = symbolValue + addend;
// }
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) {
if (trampolin_data == NULL) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin isn't provided\n");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false;
} else {
relocation_trampolin_entry_t *freeSlot = NULL;
for (uint32_t i = 0; i < trampolin_data_length; i++) {
// We want to override "old" relocations of imports
// Pending relocations have the status RELOC_TRAMP_IMPORT_IN_PROGRESS.
// When all relocations are done successfully, they will be turned into RELOC_TRAMP_IMPORT_DONE
// so they can be overridden/updated/reused on the next application launch.
//
// Relocations that won't change will have the status RELOC_TRAMP_FIXED and are set to free when the module is unloaded.
if (trampolin_data[i].status == RELOC_TRAMP_FREE ||
trampolin_data[i].status == RELOC_TRAMP_IMPORT_DONE) {
freeSlot = &(trampolin_data[i]);
break;
}
}
if (freeSlot != NULL) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin data list is full\n");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false;
}
if (target - (uint32_t) &(freeSlot->trampolin[0]) > 0x1FFFFFC) {
DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer).");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false;
}
freeSlot->trampolin[0] = 0x3D600000 | ((((uint32_t) value) >> 16) & 0x0000FFFF); // lis r11, real_addr@h
freeSlot->trampolin[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l
freeSlot->trampolin[2] = 0x7D6903A6; // mtctr r11
freeSlot->trampolin[3] = 0x4E800420; // bctr
DCFlushRange((void *) freeSlot->trampolin, sizeof(freeSlot->trampolin));
ICInvalidateRange((unsigned char *) freeSlot->trampolin, sizeof(freeSlot->trampolin));
if (reloc_type == RELOC_TYPE_FIXED) {
freeSlot->status = RELOC_TRAMP_FIXED;
} else {
// Relocations for the imports may be overridden
freeSlot->status = RELOC_TRAMP_IMPORT_IN_PROGRESS;
}
uint32_t symbolValue = (uint32_t) &(freeSlot->trampolin[0]);
value = symbolValue + addend;
distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
DEBUG_FUNCTION_LINE("Created tramp\n");
}
}
if (distance & 3) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470022);
return false;
}
if (distance < 0 && (distance & 0xFE000000) != 0xFE000000) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (1).", -470040);
return false;
}
if (distance >= 0 && (distance & 0xFE000000)) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (0).", -470040);
return false;
}
*(int32_t *) target = (*(int32_t *) target & 0xfc000003) | (distance & 0x03fffffc);
break;
}
default:
DEBUG_FUNCTION_LINE("***ERROR: Unsupported Relocation_Add Type (%08X):", type);
return false;
}
if (distance < 0 && (distance & 0xFE000000) != 0xFE000000) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (1).", -470040);
return false;
}
if (distance >= 0 && (distance & 0xFE000000)) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (0).", -470040);
return false;
}
*(int32_t *)target = (*(int32_t *)target & 0xfc000003) | (distance & 0x03fffffc);
break;
}
default:
DEBUG_FUNCTION_LINE("***ERROR: Unsupported Relocation_Add Type (%08X):", type);
return false;
}
return true;
}

View File

@ -42,5 +42,5 @@ extern "C" {
class ElfUtils {
public:
static bool elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type);
static bool elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type);
};

View File

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

View File

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

View File

@ -10,12 +10,12 @@ DECL(OSDynLoad_Error, OSDynLoad_Acquire, char const *name, OSDynLoad_Module *out
DECL(OSDynLoad_Error, OSDynLoad_FindExport, OSDynLoad_Module module, BOOL isData, char const *name, void **outAddr) {
DEBUG_FUNCTION_LINE("%s\n", name);
return real_OSDynLoad_FindExport(module,isData, name, outAddr);
return real_OSDynLoad_FindExport(module, isData, name, outAddr);
}
hooks_magic_t method_hooks_hooks_static[] __attribute__((section(".data"))) = {
MAKE_MAGIC(OSDynLoad_Acquire, LIB_CORE_INIT, STATIC_FUNCTION),
MAKE_MAGIC(OSDynLoad_FindExport, LIB_CORE_INIT, STATIC_FUNCTION)
MAKE_MAGIC(OSDynLoad_Acquire, LIB_CORE_INIT, STATIC_FUNCTION),
MAKE_MAGIC(OSDynLoad_FindExport, LIB_CORE_INIT, STATIC_FUNCTION)
};
uint32_t method_hooks_size_hooks_static __attribute__((section(".data"))) = sizeof(method_hooks_hooks_static) / sizeof(hooks_magic_t);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -12,10 +12,10 @@
#include "elfio/elfio.hpp"
#include "ElfUtils.h"
int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * sizeOut) {
int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t *sizeOut) {
char path[256];
int result = 0;
char * sdRootPath = NULL;
char *sdRootPath = NULL;
if (!WHBMountSdCard()) {
WHBLogPrintf("Failed to mount SD Card...");
result = -1;
@ -23,9 +23,9 @@ int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * s
}
sdRootPath = WHBGetSdCardMountPath();
sprintf(path, "%s/%s", sdRootPath,relativefilepath);
sprintf(path, "%s/%s", sdRootPath, relativefilepath);
WHBLogPrintf("Loading file %s.",path);
WHBLogPrintf("Loading file %s.", path);
*fileOut = WHBReadWholeFile(path, sizeOut);
if (!(*fileOut)) {
@ -34,25 +34,25 @@ int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * s
goto exit;
}
exit:
exit:
WHBUnmountSdCard();
return result;
}
uint32_t load_loader_elf_from_sd(unsigned char* baseAddress, const char* relativePath) {
char * elf_data = NULL;
uint32_t load_loader_elf_from_sd(unsigned char *baseAddress, const char *relativePath) {
char *elf_data = NULL;
uint32_t fileSize = 0;
if(LoadFileToMem(relativePath, &elf_data, &fileSize) != 0) {
if (LoadFileToMem(relativePath, &elf_data, &fileSize) != 0) {
OSFatal("Failed to load hook_payload.elf from the SD Card.");
}
uint32_t result = load_loader_elf(baseAddress, elf_data, fileSize);
MEMFreeToDefaultHeap((void*)elf_data);
MEMFreeToDefaultHeap((void *) elf_data);
return result;
}
uint32_t load_loader_elf(unsigned char* baseAddress, char * elf_data, uint32_t fileSize) {
uint32_t load_loader_elf(unsigned char *baseAddress, char *elf_data, uint32_t fileSize) {
ELFIO::Elf32_Ehdr *ehdr;
ELFIO::Elf32_Phdr *phdrs;
uint8_t *image;
@ -60,50 +60,50 @@ uint32_t load_loader_elf(unsigned char* baseAddress, char * elf_data, uint32_t f
ehdr = (ELFIO::Elf32_Ehdr *) elf_data;
if(ehdr->e_phoff == 0 || ehdr->e_phnum == 0) {
if (ehdr->e_phoff == 0 || ehdr->e_phnum == 0) {
return 0;
}
if(ehdr->e_phentsize != sizeof(ELFIO::Elf32_Phdr)) {
if (ehdr->e_phentsize != sizeof(ELFIO::Elf32_Phdr)) {
return 0;
}
phdrs = (ELFIO::Elf32_Phdr*)(elf_data + ehdr->e_phoff);
phdrs = (ELFIO::Elf32_Phdr *) (elf_data + ehdr->e_phoff);
for(i = 0; i < ehdr->e_phnum; i++) {
if(phdrs[i].p_type != PT_LOAD) {
for (i = 0; i < ehdr->e_phnum; i++) {
if (phdrs[i].p_type != PT_LOAD) {
continue;
}
if(phdrs[i].p_filesz > phdrs[i].p_memsz) {
if (phdrs[i].p_filesz > phdrs[i].p_memsz) {
continue;
}
if(!phdrs[i].p_filesz) {
if (!phdrs[i].p_filesz) {
continue;
}
uint32_t p_paddr = phdrs[i].p_paddr + (uint32_t)baseAddress;
uint32_t p_paddr = phdrs[i].p_paddr + (uint32_t) baseAddress;
image = (uint8_t *) (elf_data + phdrs[i].p_offset);
memcpy ((void *) p_paddr, image, phdrs[i].p_filesz);
DCFlushRange((void*)p_paddr, phdrs[i].p_filesz);
memcpy((void *) p_paddr, image, phdrs[i].p_filesz);
DCFlushRange((void *) p_paddr, phdrs[i].p_filesz);
if(phdrs[i].p_flags & PF_X) {
ICInvalidateRange ((void *) p_paddr, phdrs[i].p_memsz);
if (phdrs[i].p_flags & PF_X) {
ICInvalidateRange((void *) p_paddr, phdrs[i].p_memsz);
}
}
//! clear BSS
ELFIO::Elf32_Shdr *shdr = (ELFIO::Elf32_Shdr *) (elf_data + ehdr->e_shoff);
for(i = 0; i < ehdr->e_shnum; i++) {
const char *section_name = ((const char*)elf_data) + shdr[ehdr->e_shstrndx].sh_offset + shdr[i].sh_name;
if(section_name[0] == '.' && section_name[1] == 'b' && section_name[2] == 's' && section_name[3] == 's') {
memset((void*)(shdr[i].sh_addr + baseAddress), 0, shdr[i].sh_size);
DCFlushRange((void*)(shdr[i].sh_addr + baseAddress), shdr[i].sh_size);
} else if(section_name[0] == '.' && section_name[1] == 's' && section_name[2] == 'b' && section_name[3] == 's' && section_name[4] == 's') {
memset((void*)(shdr[i].sh_addr + baseAddress), 0, shdr[i].sh_size);
DCFlushRange((void*)(shdr[i].sh_addr + baseAddress), shdr[i].sh_size);
for (i = 0; i < ehdr->e_shnum; i++) {
const char *section_name = ((const char *) elf_data) + shdr[ehdr->e_shstrndx].sh_offset + shdr[i].sh_name;
if (section_name[0] == '.' && section_name[1] == 'b' && section_name[2] == 's' && section_name[3] == 's') {
memset((void *) (shdr[i].sh_addr + baseAddress), 0, shdr[i].sh_size);
DCFlushRange((void *) (shdr[i].sh_addr + baseAddress), shdr[i].sh_size);
} else if (section_name[0] == '.' && section_name[1] == 's' && section_name[2] == 'b' && section_name[3] == 's' && section_name[4] == 's') {
memset((void *) (shdr[i].sh_addr + baseAddress), 0, shdr[i].sh_size);
DCFlushRange((void *) (shdr[i].sh_addr + baseAddress), shdr[i].sh_size);
}
}
@ -111,146 +111,146 @@ uint32_t load_loader_elf(unsigned char* baseAddress, char * elf_data, uint32_t f
}
// See https://github.com/decaf-emu/decaf-emu/blob/43366a34e7b55ab9d19b2444aeb0ccd46ac77dea/src/libdecaf/src/cafe/loader/cafe_loader_reloc.cpp#L144
bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type) {
if(type == R_PPC_NONE) {
bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type) {
if (type == R_PPC_NONE) {
return true;
}
auto target = destination + offset;
auto target = destination + offset;
auto value = symbol_addr + addend;
auto relValue = value - static_cast<uint32_t>(target);
switch (type) {
case R_PPC_NONE:
break;
case R_PPC_ADDR32:
*((uint32_t *)(target)) = value;
break;
case R_PPC_ADDR16_LO:
*((uint16_t *)(target)) = static_cast<uint16_t>(value & 0xFFFF);
break;
case R_PPC_ADDR16_HI:
*((uint16_t *)(target)) = static_cast<uint16_t>(value >> 16);
break;
case R_PPC_ADDR16_HA:
*((uint16_t *)(target)) = static_cast<uint16_t>((value + 0x8000) >> 16);
break;
case R_PPC_DTPMOD32:
DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n");
//*((int32_t *)(target)) = tlsModuleIndex;
break;
case R_PPC_DTPREL32:
*((uint32_t *)(target)) = value;
break;
case R_PPC_GHS_REL16_HA:
*((uint16_t *)(target)) = static_cast<uint16_t>((relValue + 0x8000) >> 16);
break;
case R_PPC_GHS_REL16_HI:
*((uint16_t *)(target)) = static_cast<uint16_t>(relValue >> 16);
break;
case R_PPC_GHS_REL16_LO:
*((uint16_t *)(target)) = static_cast<uint16_t>(relValue & 0xFFFF);
break;
case R_PPC_REL14: {
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
if (distance > 0x7FFC || distance < -0x7FFC) {
DEBUG_FUNCTION_LINE("***14-bit relative branch cannot hit target.");
return false;
}
if (distance & 3) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470040);
return false;
}
if ((distance >= 0 && (distance & 0xFFFF8000)) ||
(distance < 0 && ((distance & 0xFFFF8000) != 0xFFFF8000))) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 17 bits before shift must all be the same.", -470040);
return false;
}
*(int32_t *)target = (*(int32_t *)target & 0xFFBF0003) | (distance & 0x0000fffc);
break;
}
case R_PPC_REL24: {
// if (isWeakSymbol && !symbolValue) {
// symbolValue = static_cast<uint32_t>(target);
// value = symbolValue + addend;
// }
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) {
if(trampolin_data == NULL) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin isn't provided\n");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
case R_PPC_NONE:
break;
case R_PPC_ADDR32:
*((uint32_t *) (target)) = value;
break;
case R_PPC_ADDR16_LO:
*((uint16_t *) (target)) = static_cast<uint16_t>(value & 0xFFFF);
break;
case R_PPC_ADDR16_HI:
*((uint16_t *) (target)) = static_cast<uint16_t>(value >> 16);
break;
case R_PPC_ADDR16_HA:
*((uint16_t *) (target)) = static_cast<uint16_t>((value + 0x8000) >> 16);
break;
case R_PPC_DTPMOD32:
DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n");
//*((int32_t *)(target)) = tlsModuleIndex;
break;
case R_PPC_DTPREL32:
*((uint32_t *) (target)) = value;
break;
case R_PPC_GHS_REL16_HA:
*((uint16_t *) (target)) = static_cast<uint16_t>((relValue + 0x8000) >> 16);
break;
case R_PPC_GHS_REL16_HI:
*((uint16_t *) (target)) = static_cast<uint16_t>(relValue >> 16);
break;
case R_PPC_GHS_REL16_LO:
*((uint16_t *) (target)) = static_cast<uint16_t>(relValue & 0xFFFF);
break;
case R_PPC_REL14: {
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
if (distance > 0x7FFC || distance < -0x7FFC) {
DEBUG_FUNCTION_LINE("***14-bit relative branch cannot hit target.");
return false;
} else {
relocation_trampolin_entry_t * freeSlot = NULL;
for(uint32_t i = 0; i < trampolin_data_length; i++) {
// We want to override "old" relocations of imports
// Pending relocations have the status RELOC_TRAMP_IMPORT_IN_PROGRESS.
// When all relocations are done successfully, they will be turned into RELOC_TRAMP_IMPORT_DONE
// so they can be overridden/updated/reused on the next application launch.
//
// Relocations that won't change will have the status RELOC_TRAMP_FIXED and are set to free when the module is unloaded.
if(trampolin_data[i].status == RELOC_TRAMP_FREE ||
trampolin_data[i].status == RELOC_TRAMP_IMPORT_DONE) {
freeSlot = &(trampolin_data[i]);
break;
}
}
if(freeSlot != NULL) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin data list is full\n");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false;
}
if(target - (uint32_t)&(freeSlot->trampolin[0]) > 0x1FFFFFC) {
DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer).");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false;
}
freeSlot->trampolin[0] = 0x3D600000 | ((((uint32_t) value) >> 16) & 0x0000FFFF); // lis r11, real_addr@h
freeSlot->trampolin[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l
freeSlot->trampolin[2] = 0x7D6903A6; // mtctr r11
freeSlot->trampolin[3] = 0x4E800420; // bctr
DCFlushRange((void*)freeSlot->trampolin, sizeof(freeSlot->trampolin));
ICInvalidateRange((unsigned char*)freeSlot->trampolin, sizeof(freeSlot->trampolin));
if(reloc_type == RELOC_TYPE_FIXED) {
freeSlot->status = RELOC_TRAMP_FIXED;
} else {
// Relocations for the imports may be overridden
freeSlot->status = RELOC_TRAMP_IMPORT_IN_PROGRESS;
}
uint32_t symbolValue = (uint32_t)&(freeSlot->trampolin[0]);
value = symbolValue + addend;
distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
DEBUG_FUNCTION_LINE("Created tramp\n");
}
}
if (distance & 3) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470022);
if (distance & 3) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470040);
return false;
}
if ((distance >= 0 && (distance & 0xFFFF8000)) ||
(distance < 0 && ((distance & 0xFFFF8000) != 0xFFFF8000))) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 17 bits before shift must all be the same.", -470040);
return false;
}
*(int32_t *) target = (*(int32_t *) target & 0xFFBF0003) | (distance & 0x0000fffc);
break;
}
case R_PPC_REL24: {
// if (isWeakSymbol && !symbolValue) {
// symbolValue = static_cast<uint32_t>(target);
// value = symbolValue + addend;
// }
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) {
if (trampolin_data == NULL) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin isn't provided\n");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false;
} else {
relocation_trampolin_entry_t *freeSlot = NULL;
for (uint32_t i = 0; i < trampolin_data_length; i++) {
// We want to override "old" relocations of imports
// Pending relocations have the status RELOC_TRAMP_IMPORT_IN_PROGRESS.
// When all relocations are done successfully, they will be turned into RELOC_TRAMP_IMPORT_DONE
// so they can be overridden/updated/reused on the next application launch.
//
// Relocations that won't change will have the status RELOC_TRAMP_FIXED and are set to free when the module is unloaded.
if (trampolin_data[i].status == RELOC_TRAMP_FREE ||
trampolin_data[i].status == RELOC_TRAMP_IMPORT_DONE) {
freeSlot = &(trampolin_data[i]);
break;
}
}
if (freeSlot != NULL) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin data list is full\n");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false;
}
if (target - (uint32_t) &(freeSlot->trampolin[0]) > 0x1FFFFFC) {
DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer).");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false;
}
freeSlot->trampolin[0] = 0x3D600000 | ((((uint32_t) value) >> 16) & 0x0000FFFF); // lis r11, real_addr@h
freeSlot->trampolin[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l
freeSlot->trampolin[2] = 0x7D6903A6; // mtctr r11
freeSlot->trampolin[3] = 0x4E800420; // bctr
DCFlushRange((void *) freeSlot->trampolin, sizeof(freeSlot->trampolin));
ICInvalidateRange((unsigned char *) freeSlot->trampolin, sizeof(freeSlot->trampolin));
if (reloc_type == RELOC_TYPE_FIXED) {
freeSlot->status = RELOC_TRAMP_FIXED;
} else {
// Relocations for the imports may be overridden
freeSlot->status = RELOC_TRAMP_IMPORT_IN_PROGRESS;
}
uint32_t symbolValue = (uint32_t) &(freeSlot->trampolin[0]);
value = symbolValue + addend;
distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
DEBUG_FUNCTION_LINE("Created tramp\n");
}
}
if (distance & 3) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470022);
return false;
}
if (distance < 0 && (distance & 0xFE000000) != 0xFE000000) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (1).", -470040);
return false;
}
if (distance >= 0 && (distance & 0xFE000000)) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (0).", -470040);
return false;
}
*(int32_t *) target = (*(int32_t *) target & 0xfc000003) | (distance & 0x03fffffc);
break;
}
default:
DEBUG_FUNCTION_LINE("***ERROR: Unsupported Relocation_Add Type (%08X):", type);
return false;
}
if (distance < 0 && (distance & 0xFE000000) != 0xFE000000) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (1).", -470040);
return false;
}
if (distance >= 0 && (distance & 0xFE000000)) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (0).", -470040);
return false;
}
*(int32_t *)target = (*(int32_t *)target & 0xfc000003) | (distance & 0x03fffffc);
break;
}
default:
DEBUG_FUNCTION_LINE("***ERROR: Unsupported Relocation_Add Type (%08X):", type);
return false;
}
return true;
}

View File

@ -8,9 +8,9 @@
extern "C" {
#endif
int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * sizeOut);
uint32_t load_loader_elf_from_sd(unsigned char* baseAddress, const char* relativePath);
uint32_t load_loader_elf(unsigned char* baseAddress, char * elf_data, uint32_t fileSize);
int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t *sizeOut);
uint32_t load_loader_elf_from_sd(unsigned char *baseAddress, const char *relativePath);
uint32_t load_loader_elf(unsigned char *baseAddress, char *elf_data, uint32_t fileSize);
#define R_PPC_NONE 0
#define R_PPC_ADDR32 1
@ -47,5 +47,5 @@ uint32_t load_loader_elf(unsigned char* baseAddress, char * elf_data, uint32_t f
class ElfUtils {
public:
static bool elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type);
static bool elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type);
};

View File

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

View File

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

View File

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

View File

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

View File

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

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);
void SetupRelocator() {
kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_5 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
kern_write((void *) (KERN_SYSCALL_TBL_1 + (0x25 * 4)), (unsigned int) SCKernelCopyData);
kern_write((void *) (KERN_SYSCALL_TBL_2 + (0x25 * 4)), (unsigned int) SCKernelCopyData);
kern_write((void *) (KERN_SYSCALL_TBL_3 + (0x25 * 4)), (unsigned int) SCKernelCopyData);
kern_write((void *) (KERN_SYSCALL_TBL_4 + (0x25 * 4)), (unsigned int) SCKernelCopyData);
kern_write((void *) (KERN_SYSCALL_TBL_5 + (0x25 * 4)), (unsigned int) SCKernelCopyData);
uint32_t entryPoint = load_loader_elf(0, (char*) ___relocator_relocator_elf, ___relocator_relocator_elf_len);
uint32_t entryPoint = load_loader_elf(0, (char *) ___relocator_relocator_elf, ___relocator_relocator_elf_len);
unsigned int repl_addr = ADDRESS_main_entry_hook;
KernelWriteU32(repl_addr,0x48000003 | entryPoint);
DCFlushRange((void*) repl_addr, 4);
ICInvalidateRange((void*)(repl_addr), 4);
KernelWriteU32(repl_addr, 0x48000003 | entryPoint);
DCFlushRange((void *) repl_addr, 4);
ICInvalidateRange((void *) (repl_addr), 4);
}
void KernelWriteU32(uint32_t addr, uint32_t value) {
@ -32,28 +32,28 @@ void KernelWriteU32(uint32_t addr, uint32_t value) {
SC_KernelCopyData(dst, src, 4);
DCFlushRange((void *)addr, 4);
ICInvalidateRange((void *)addr, 4);
DCFlushRange((void *) addr, 4);
ICInvalidateRange((void *) addr, 4);
}
/* Write a 32-bit word with kernel permissions */
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value) {
asm volatile (
"li 3,1\n"
"li 4,0\n"
"mr 5,%1\n"
"li 6,0\n"
"li 7,0\n"
"lis 8,1\n"
"mr 9,%0\n"
"mr %1,1\n"
"li 0,0x3500\n"
"sc\n"
"nop\n"
"mr 1,%1\n"
:
: "r"(addr), "r"(value)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12"
"li 3,1\n"
"li 4,0\n"
"mr 5,%1\n"
"li 6,0\n"
"li 7,0\n"
"lis 8,1\n"
"mr 9,%0\n"
"mr %1,1\n"
"li 0,0x3500\n"
"sc\n"
"nop\n"
"mr 1,%1\n"
:
: "r"(addr), "r"(value)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12"
);
}

View File

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

View File

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

View File

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

View File

@ -1,4 +1,5 @@
#pragma once
#include "common/dynamic_linking_defines.h"
#include "utils/logger.h"
#include <string>
@ -13,7 +14,7 @@ public:
\param functionName Name of the function
\return Returns a pointer to the entry which contains the functionName. Null on error or if the list full.
**/
static dyn_linking_function_t * getOrAddFunctionEntryByName(dyn_linking_relocation_data_t * data, const char * functionName);
static dyn_linking_function_t *getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, const char *functionName);
/**
Gets the function import entry for a given function name. If the import is not present in the list, it will be added.
@ -22,7 +23,7 @@ public:
\param importName Name of the function
\return Returns a pointer to the function import entry which contains the importName. Null on error or if the list full.
**/
static dyn_linking_import_t * getOrAddFunctionImportByName(dyn_linking_relocation_data_t * data, const char * importName);
static dyn_linking_import_t *getOrAddFunctionImportByName(dyn_linking_relocation_data_t *data, const char *importName);
/**
@ -32,7 +33,7 @@ public:
\param importName Name of the data
\return Returns a pointer to the data import entry which contains the importName. Null on error or if the list full.
**/
static dyn_linking_import_t * getOrAddDataImportByName(dyn_linking_relocation_data_t * data, const char * importName);
static dyn_linking_import_t *getOrAddDataImportByName(dyn_linking_relocation_data_t *data, const char *importName);
/**
@ -44,13 +45,16 @@ public:
\return Returns a pointer to the data import entry which contains the importName. Null on error or if the list full.
**/
static dyn_linking_import_t * getOrAddImport(dyn_linking_relocation_data_t * data, const char * importName, bool isData);
static dyn_linking_import_t *getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData);
static bool addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, const RelocationData& relocationData);
static bool addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, const RelocationData &relocationData);
static bool addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, std::string name, const ImportRPLInformation& rplInfo);
static bool addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, std::string name,
const ImportRPLInformation &rplInfo);
static bool
addReloationEntry(dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, dyn_linking_function_t *functionName, dyn_linking_import_t *importInfo);
static bool addReloationEntry(dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, dyn_linking_function_t * functionName, dyn_linking_import_t * importInfo);
private:
DynamicLinkingHelper() {
}

View File

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

View File

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

View File

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

View File

@ -26,7 +26,9 @@
class ModuleDataFactory {
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 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 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);
};

View File

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

View File

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

View File

@ -1,6 +1,6 @@
#include "RelocationData.h"
#include "utils/StringTools.h"
std::string RelocationData::toString() const{
return StringTools::strfmt("%s destination: %08X offset: %08X type: %02X addend: %d rplName: %s isData: %d \n",name.c_str(), destination, offset, type, addend, rplInfo.getName().c_str(), rplInfo.isData() );
std::string RelocationData::toString() const {
return StringTools::strfmt("%s destination: %08X offset: %08X type: %02X addend: %d rplName: %s isData: %d \n", name.c_str(), destination, offset, type, addend, rplInfo.getName().c_str(), rplInfo.isData());
}

View File

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

View File

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

View File

@ -32,20 +32,33 @@
class StringTools {
public:
static BOOL EndsWith(const std::string& a, const std::string& b);
static const char * byte_to_binary(int32_t x);
static std::string removeCharFromString(std::string& input,char toBeRemoved);
static const char * fmt(const char * format, ...);
static const wchar_t * wfmt(const char * format, ...);
static int32_t strprintf(std::string &str, const char * format, ...);
static std::string strfmt(const char * format, ...);
static BOOL char2wchar_t(const char * src, wchar_t * dest);
static int32_t strtokcmp(const char * string, const char * compare, const char * separator);
static int32_t strextcmp(const char * string, const char * extension, char seperator);
static BOOL EndsWith(const std::string &a, const std::string &b);
static const char *byte_to_binary(int32_t x);
static std::string removeCharFromString(std::string &input, char toBeRemoved);
static const char *fmt(const char *format, ...);
static const wchar_t *wfmt(const char *format, ...);
static int32_t strprintf(std::string &str, const char *format, ...);
static std::string strfmt(const char *format, ...);
static BOOL char2wchar_t(const char *src, wchar_t *dest);
static int32_t strtokcmp(const char *string, const char *compare, const char *separator);
static int32_t strextcmp(const char *string, const char *extension, char seperator);
static char *str_replace(char *orig, char *rep, char *with);
static const char * FullpathToFilename(const char *path);
static const char *FullpathToFilename(const char *path);
static void RemoveDoubleSlashs(std::string &str);
static std::vector<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 */

View File

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

View File

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

View File

@ -7,12 +7,12 @@
extern "C" {
#endif
#define LIMIT(x, min, max) \
({ \
typeof( x ) _x = x; \
typeof( min ) _min = min; \
typeof( max ) _max = max; \
( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \
#define LIMIT(x, min, max) \
({ \
typeof( x ) _x = x; \
typeof( min ) _min = min; \
typeof( max ) _max = max; \
( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \
})
#define DegToRad(a) ( (a) * 0.01745329252f )
@ -31,7 +31,7 @@ extern "C" {
#define le64(i) ((((uint64_t)le32((i) & 0xFFFFFFFFLL)) << 32) | ((uint64_t)le32(((i) & 0xFFFFFFFF00000000LL) >> 32)))
//Needs to have log_init() called beforehand.
void dumpHex(const void* data, size_t size);
void dumpHex(const void *data, size_t size);
#ifdef __cplusplus
}