Implement support for WUMS 0.2

This commit is contained in:
Maschell
2021-09-17 16:22:54 +02:00
parent b17b522d6b
commit 74f7b8a662
11 changed files with 118 additions and 113 deletions

View File

@@ -138,10 +138,6 @@ public:
return this->initBeforeRelocationDoneHook;
}
[[nodiscard]] bool isSkipWUTInit() const {
return this->skipWUTInit;
}
void setSkipEntrypoint(bool value) {
this->skipEntrypoint = value;
}
@@ -149,10 +145,6 @@ public:
this->initBeforeRelocationDoneHook = value;
}
void setSkipWUTInit(bool value) {
this->skipWUTInit = value;
}
bool relocationsDone = false;
private:
std::vector<RelocationData> relocation_data_list;
@@ -171,5 +163,4 @@ private:
uint32_t entrypoint = 0;
bool skipEntrypoint = false;
bool initBeforeRelocationDoneHook = false;
bool skipWUTInit = false;
};

View File

@@ -21,16 +21,12 @@
#include <coreinit/cache.h>
#include <wums.h>
#include "ModuleDataFactory.h"
#include "elfio/elfio.hpp"
#include "utils/utils.h"
#include "ElfUtils.h"
#include "SectionInfo.h"
#include "ExportData.h"
#include "HookData.h"
using namespace ELFIO;
std::optional<ModuleData> ModuleDataFactory::load(std::string path, uint32_t *destination_address_ptr, uint32_t maximum_size, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length) {
std::optional<ModuleData> ModuleDataFactory::load(const std::string& path, uint32_t *destination_address_ptr, uint32_t maximum_size, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length) {
elfio reader;
ModuleData moduleData;
@@ -42,7 +38,7 @@ std::optional<ModuleData> ModuleDataFactory::load(std::string path, uint32_t *de
uint32_t sec_num = reader.sections.size();
uint8_t **destinations = (uint8_t **) malloc(sizeof(uint8_t *) * sec_num);
auto **destinations = (uint8_t **) malloc(sizeof(uint8_t *) * sec_num);
uint32_t baseOffset = *destination_address_ptr;
@@ -69,7 +65,7 @@ std::optional<ModuleData> ModuleDataFactory::load(std::string path, uint32_t *de
return {};
}
uint32_t address = (uint32_t) psec->get_address();
auto address = (uint32_t) psec->get_address();
destinations[psec->get_index()] = (uint8_t *) baseOffset;
@@ -102,18 +98,17 @@ std::optional<ModuleData> ModuleDataFactory::load(std::string path, uint32_t *de
}
//nextAddress = ROUNDUP(destination + sectionSize,0x100);
if (psec->get_name().compare(".bss") == 0) {
if (psec->get_name() == ".bss") {
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) {
memset(reinterpret_cast<void *>(destination), 0, sectionSize);
} else if (psec->get_name() == ".sbss") {
moduleData.setSBSSLocation(destination, sectionSize);
DEBUG_FUNCTION_LINE("Saved %s section info. Location: %08X size: %08X", psec->get_name().c_str(), destination, sectionSize);
memset(reinterpret_cast<void *>(destination), 0, sectionSize);
}
moduleData.addSectionInfo(SectionInfo(psec->get_name(), destination, sectionSize));
DEBUG_FUNCTION_LINE("Saved %s section info. Location: %08X size: %08X", psec->get_name().c_str(), destination, sectionSize);
if (endAddress < destination + sectionSize) {
endAddress = destination + sectionSize;
}
@@ -143,8 +138,8 @@ std::optional<ModuleData> ModuleDataFactory::load(std::string path, uint32_t *de
std::optional<SectionInfo> secInfo = moduleData.getSectionInfo(".wums.exports");
if (secInfo && secInfo->getSize() > 0) {
size_t entries_count = secInfo->getSize() / sizeof(wums_entry_t);
wums_entry_t *entries = (wums_entry_t *) secInfo->getAddress();
if (entries != NULL) {
auto *entries = (wums_entry_t *) secInfo->getAddress();
if (entries != nullptr) {
for (size_t j = 0; j < entries_count; j++) {
wums_entry_t *exp = &entries[j];
DEBUG_FUNCTION_LINE("Saving export of type %08X, name %s, target: %08X"/*,pluginData.getPluginInformation()->getName().c_str()*/, exp->type, exp->name, (void *) exp->address);
@@ -157,8 +152,8 @@ std::optional<ModuleData> ModuleDataFactory::load(std::string path, uint32_t *de
secInfo = moduleData.getSectionInfo(".wums.hooks");
if (secInfo && secInfo->getSize() > 0) {
size_t entries_count = secInfo->getSize() / sizeof(wums_hook_t);
wums_hook_t *hooks = (wums_hook_t *) secInfo->getAddress();
if (hooks != NULL) {
auto *hooks = (wums_hook_t *) secInfo->getAddress();
if (hooks != nullptr) {
for (size_t j = 0; j < entries_count; j++) {
wums_hook_t *hook = &hooks[j];
DEBUG_FUNCTION_LINE("Saving hook of type %08X, target: %08X"/*,pluginData.getPluginInformation()->getName().c_str()*/, hook->type, hook->target);
@@ -170,8 +165,8 @@ std::optional<ModuleData> ModuleDataFactory::load(std::string path, uint32_t *de
secInfo = moduleData.getSectionInfo(".wums.meta");
if (secInfo && secInfo->getSize() > 0) {
wums_entry_t *entries = (wums_entry_t *) secInfo->getAddress();
if (entries != NULL) {
auto *entries = (wums_entry_t *) secInfo->getAddress();
if (entries != nullptr) {
char *curEntry = (char *) secInfo->getAddress();
while ((uint32_t) curEntry < (uint32_t) secInfo->getAddress() + secInfo->getSize()) {
@@ -180,7 +175,7 @@ std::optional<ModuleData> ModuleDataFactory::load(std::string path, uint32_t *de
continue;
}
auto firstFound = std::string(curEntry).find_first_of("=");
auto firstFound = std::string(curEntry).find_first_of('=');
if (firstFound != std::string::npos) {
curEntry[firstFound] = '\0';
std::string key(curEntry);
@@ -203,16 +198,8 @@ std::optional<ModuleData> ModuleDataFactory::load(std::string path, uint32_t *de
} else {
moduleData.setInitBeforeRelocationDoneHook(false);
}
} else if (key == "skipwutInit") {
if (value == "true") {
DEBUG_FUNCTION_LINE("skipwutInit = %s", value.c_str());
moduleData.setSkipWUTInit(true);
} else {
moduleData.setSkipWUTInit(false);
}
}
if (key == "wums") {
if (value != "0.1") {
} else if (key == "wums") {
if (value != "0.2") {
DEBUG_FUNCTION_LINE("Warning: Ignoring module - Unsupported WUMS version: %s.\n", value.c_str());
return std::nullopt;
}
@@ -314,7 +301,7 @@ bool ModuleDataFactory::linkSection(elfio &reader, uint32_t section_index, uint3
break;
}
uint32_t adjusted_sym_value = (uint32_t) sym_value;
auto adjusted_sym_value = (uint32_t) sym_value;
if ((adjusted_sym_value >= 0x02000000) && adjusted_sym_value < 0x10000000) {
adjusted_sym_value -= 0x02000000;
adjusted_sym_value += base_text;

View File

@@ -26,7 +26,7 @@
class ModuleDataFactory {
public:
static std::optional<ModuleData> load(std::string path, uint32_t *destination_address_ptr, uint32_t maximum_size, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length);
static std::optional<ModuleData> load(const std::string& path, uint32_t *destination_address_ptr, 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);

View File

@@ -28,12 +28,12 @@ bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformati
std::vector<ExportData> exportData = module.getExportDataList();
for (auto const &curExport : exportData) {
bool found = false;
for (uint32_t j = 0; j < EXPORT_ENTRY_LIST_LENGTH; j++) {
export_data_t *export_entry = &(module_data->export_entries[j]);
if (export_entry->address == 0) {
export_entry->type = curExport.getType();
strncpy(export_entry->name, curExport.getName().c_str(), EXPORT_MAXIMUM_NAME_LENGTH);
export_entry->address = (uint32_t) curExport.getAddress();
for (auto &export_entry : module_data->export_entries) {
if (export_entry.address == 0) {
export_entry.type = curExport.getType();
export_entry.name[0] = '\0';
strncat(export_entry.name, curExport.getName().c_str(), sizeof(export_entry.name) - 1);
export_entry.address = (uint32_t) curExport.getAddress();
found = true;
break;
}
@@ -47,11 +47,10 @@ bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformati
std::vector<HookData> hookData = module.getHookDataList();
for (auto const &curHook : hookData) {
bool found = false;
for (uint32_t j = 0; j < HOOK_ENTRY_LIST_LENGTH; j++) {
hook_data_t *hook_entry = &(module_data->hook_entries[j]);
if (hook_entry->target == 0) {
hook_entry->type = curHook.getType();
hook_entry->target = (uint32_t) curHook.getTarget();
for (auto &hook_entry : module_data->hook_entries) {
if (hook_entry.target == 0) {
hook_entry.type = curHook.getType();
hook_entry.target = (uint32_t) curHook.getTarget();
found = true;
break;
}
@@ -73,7 +72,6 @@ bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformati
module_data->entrypoint = module.getEntrypoint();
module_data->skipEntrypoint = module.isSkipEntrypoint();
module_data->initBeforeRelocationDoneHook = module.isInitBeforeRelocationDoneHook();
module_data->skipWUTInit = module.isSkipWUTInit();
moduleInformation->number_used_modules++;
@@ -85,7 +83,7 @@ bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformati
std::vector<ModuleData> ModuleDataPersistence::loadModuleData(module_information_t *moduleInformation) {
std::vector<ModuleData> result;
if (moduleInformation == NULL) {
if (moduleInformation == nullptr) {
DEBUG_FUNCTION_LINE("moduleInformation == NULL\n");
return result;
}
@@ -110,48 +108,38 @@ std::vector<ModuleData> ModuleDataPersistence::loadModuleData(module_information
moduleData.setSkipEntrypoint(module_data->skipEntrypoint);
moduleData.setInitBeforeRelocationDoneHook(module_data->initBeforeRelocationDoneHook);
for (uint32_t j = 0; j < EXPORT_ENTRY_LIST_LENGTH; j++) {
export_data_t *export_entry = &(module_data->export_entries[j]);
for (auto &export_entrie : module_data->export_entries) {
export_data_t *export_entry = &export_entrie;
if (export_entry->address == 0) {
continue;
}
moduleData.addExportData(ExportData(static_cast<wums_entry_type_t>(export_entry->type), export_entry->name, reinterpret_cast<const void *>(export_entry->address)));
}
for (uint32_t j = 0; j < HOOK_ENTRY_LIST_LENGTH; j++) {
hook_data_t *hook_entry = &(module_data->hook_entries[j]);
if (hook_entry->target == 0) {
for (auto &hook_entry : module_data->hook_entries) {
if (hook_entry.target == 0) {
continue;
}
moduleData.addHookData(HookData(static_cast<wums_hook_type_t>(hook_entry->type), reinterpret_cast<const void *>(hook_entry->target)));
moduleData.addHookData(HookData(static_cast<wums_hook_type_t>(hook_entry.type), reinterpret_cast<const void *>(hook_entry.target)));
}
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 == 0) {
for (auto &linking_entry : module_data->linking_entries) {
if (linking_entry.destination == nullptr) {
break;
}
dyn_linking_import_t *importEntry = linking_entry->importEntry;
if (importEntry == NULL) {
dyn_linking_import_t *importEntry = linking_entry.importEntry;
if (importEntry == nullptr) {
DEBUG_FUNCTION_LINE("importEntry was NULL, skipping relocation entry\n");
continue;
}
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 == nullptr) {
DEBUG_FUNCTION_LINE("functionEntry was NULL, skipping relocation entry\n");
continue;
}
if (functionEntry->functionName == NULL) {
DEBUG_FUNCTION_LINE("functionEntry->functionName was NULL, skipping relocation entry\n");
continue;
}
ImportRPLInformation rplInfo(importEntry->importName, importEntry->isData);
RelocationData reloc(linking_entry->type, linking_entry->offset, linking_entry->addend, linking_entry->destination, functionEntry->functionName, rplInfo);
RelocationData reloc(linking_entry.type, linking_entry.offset, linking_entry.addend, linking_entry.destination, functionEntry->functionName, rplInfo);
moduleData.addRelocationData(reloc);
}