WUMSLoader/source/module/DynamicLinkingHelper.cpp

112 lines
5.1 KiB
C++
Raw Normal View History

2020-04-28 14:43:07 +02:00
#include "DynamicLinkingHelper.h"
2022-02-04 21:44:03 +01:00
#include "utils/logger.h"
#include <coreinit/dynload.h>
2021-12-07 18:23:18 +01:00
#include <cstdio>
#include <cstring>
2020-04-28 14:43:07 +02:00
#include <vector>
2020-05-17 19:05:51 +02:00
dyn_linking_function_t *DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, const char *functionName) {
2021-12-07 18:23:18 +01:00
if (data == nullptr) {
return nullptr;
2020-04-28 14:43:07 +02:00
}
2021-12-07 18:23:18 +01:00
if (functionName == nullptr) {
return nullptr;
2020-04-28 14:43:07 +02:00
}
2021-12-07 18:23:18 +01:00
dyn_linking_function_t *result = nullptr;
2022-02-04 21:44:03 +01:00
for (auto &function : data->functions) {
2021-12-07 18:23:18 +01:00
dyn_linking_function_t *curEntry = &function;
2020-05-17 19:05:51 +02:00
if (strlen(curEntry->functionName) == 0) {
if (strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) {
2020-04-28 14:43:07 +02:00
DEBUG_FUNCTION_LINE("Failed to add function name, it's too long.\n");
2021-12-07 18:23:18 +01:00
return nullptr;
2020-04-28 14:43:07 +02:00
}
2020-05-17 19:05:51 +02:00
strncpy(curEntry->functionName, functionName, DYN_LINK_FUNCTION_NAME_LENGTH);
2020-04-28 14:43:07 +02:00
result = curEntry;
break;
}
2020-05-17 19:05:51 +02:00
if (strncmp(curEntry->functionName, functionName, DYN_LINK_FUNCTION_NAME_LENGTH) == 0) {
2020-04-28 14:43:07 +02:00
result = curEntry;
break;
}
}
return result;
}
2020-05-17 19:05:51 +02:00
dyn_linking_import_t *DynamicLinkingHelper::getOrAddFunctionImportByName(dyn_linking_relocation_data_t *data, const char *importName) {
2020-04-28 14:43:07 +02:00
return getOrAddImport(data, importName, false);
}
2020-05-17 19:05:51 +02:00
dyn_linking_import_t *DynamicLinkingHelper::getOrAddDataImportByName(dyn_linking_relocation_data_t *data, const char *importName) {
2020-04-28 14:43:07 +02:00
return getOrAddImport(data, importName, true);
}
2020-05-17 19:05:51 +02:00
dyn_linking_import_t *DynamicLinkingHelper::getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData) {
2021-12-07 18:23:18 +01:00
if (importName == nullptr || data == nullptr) {
return nullptr;
2020-04-28 14:43:07 +02:00
}
2021-12-07 18:23:18 +01:00
dyn_linking_import_t *result = nullptr;
2022-02-04 21:44:03 +01:00
for (auto &import : data->imports) {
2021-12-07 18:23:18 +01:00
dyn_linking_import_t *curEntry = &import;
2020-05-17 19:05:51 +02:00
if (strlen(curEntry->importName) == 0) {
if (strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) {
2020-04-28 14:43:07 +02:00
DEBUG_FUNCTION_LINE("Failed to add Import, it's too long.\n");
2021-12-07 18:23:18 +01:00
return nullptr;
2020-04-28 14:43:07 +02:00
}
2020-05-17 19:05:51 +02:00
strncpy(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH);
2020-04-28 14:43:07 +02:00
curEntry->isData = isData;
2022-02-04 21:44:03 +01:00
result = curEntry;
2020-04-28 14:43:07 +02:00
break;
}
2020-05-17 19:05:51 +02:00
if (strncmp(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH) == 0 && (curEntry->isData == isData)) {
2020-04-28 14:43:07 +02:00
return curEntry;
}
}
return result;
}
2021-09-23 18:38:29 +02:00
bool DynamicLinkingHelper::addRelocationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length,
2021-12-07 18:23:18 +01:00
const std::shared_ptr<RelocationData> &relocationData) {
return addReloationEntry(linking_data, linking_entries, linking_entry_length, relocationData->getType(), relocationData->getOffset(), relocationData->getAddend(), relocationData->getDestination(),
relocationData->getName(),
relocationData->getImportRPLInformation());
2020-04-28 14:43:07 +02:00
}
2021-09-23 18:38:29 +02:00
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,
2021-12-07 18:23:18 +01:00
const std::string &name, const std::shared_ptr<ImportRPLInformation> &rplInfo) {
dyn_linking_import_t *importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo->getName().c_str(), rplInfo->isData());
if (importInfoGbl == nullptr) {
2020-05-17 19:05:51 +02:00
DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d rpl files to import reached.\n", DYN_LINK_IMPORT_LIST_LENGTH);
2020-04-28 14:43:07 +02:00
return false;
}
2020-05-17 19:05:51 +02:00
dyn_linking_function_t *functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(linking_data, name.c_str());
2021-12-07 18:23:18 +01:00
if (functionInfo == nullptr) {
2020-05-17 19:05:51 +02:00
DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d function to be relocated reached.\n", DYN_LINK_FUNCTION_LIST_LENGTH);
2020-04-28 14:43:07 +02:00
return false;
}
2021-09-18 11:55:01 +02:00
return addRelocationEntry(linking_entries, linking_entry_length, type, offset, addend, destination, functionInfo,
importInfoGbl);
2020-04-28 14:43:07 +02:00
}
2021-09-23 18:38:29 +02:00
bool DynamicLinkingHelper::addRelocationEntry(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,
2021-09-18 11:55:01 +02:00
dyn_linking_import_t *importInfo) {
2020-05-17 19:05:51 +02:00
for (uint32_t i = 0; i < linking_entry_length; i++) {
dyn_linking_relocation_entry_t *curEntry = &(linking_entries[i]);
2021-12-07 18:23:18 +01:00
if (curEntry->functionEntry != nullptr) {
2020-04-28 14:43:07 +02:00
continue;
}
2022-02-04 21:44:03 +01:00
curEntry->type = type;
curEntry->offset = offset;
curEntry->addend = addend;
curEntry->destination = destination;
2020-04-28 14:43:07 +02:00
curEntry->functionEntry = functionName;
2022-02-04 21:44:03 +01:00
curEntry->importEntry = importInfo;
2020-04-28 14:43:07 +02:00
return true;
}
return false;
}