Copy the executables to the end of the memory region

This commit is contained in:
Maschell 2021-12-28 18:22:35 +01:00
parent f926166929
commit 86f124baaa
4 changed files with 31 additions and 18 deletions

View File

@ -30,8 +30,6 @@
#define MEMORY_REGION_SIZE 0x00700000
#define MEMORY_REGION_END (MEMORY_REGION_START + MEMORY_REGION_SIZE)
#define gModuleData ((module_information_t *) (MEMORY_REGION_START))
bool CheckRunning() {
switch (ProcUIProcessMessages(true)) {
case PROCUI_STATUS_EXITING: {
@ -77,9 +75,10 @@ int main(int argc, char **argv) {
IOS_Close(handle);
}
// 0x100 because before the .text section is a .init section
// Currently the size of the .init is ~ 0x24 bytes. We substract 0x100 to be safe.
uint32_t textSectionStart = textStart() - 0x1000;
// We substract 0x100 to be safe.
uint32_t textSectionStart = textStart() - 0x100;
auto gModuleData = (module_information_t *) (textSectionStart - sizeof(module_information_t));
std::string environment_path = std::string(environmentPath);
if (strncmp(environmentPath, "fs:/vol/external01/wiiu/environments/", strlen("fs:/vol/external01/wiiu/environments/")) != 0) {
@ -113,10 +112,10 @@ int main(int argc, char **argv) {
RevertMainHook();
for (int i = 0; i < setupModules.GetFilecount(); i++) {
uint32_t destination_address = ((uint32_t) gModuleData + (sizeof(module_information_t) + 0x0000FFFF)) & 0xFFFF0000;
uint32_t destination_address_end = ((uint32_t) gModuleData) & 0xFFFF0000;
memset((void *) gModuleData, 0, sizeof(module_information_t));
DEBUG_FUNCTION_LINE("Trying to run %s", setupModules.GetFilepath(i));
auto moduleData = ModuleDataFactory::load(setupModules.GetFilepath(i), &destination_address, textSectionStart - destination_address, gModuleData->trampolines,
DEBUG_FUNCTION_LINE("Trying to run %s.", setupModules.GetFilepath(i), destination_address_end, ((uint32_t) gModuleData) - MEMORY_REGION_START);
auto moduleData = ModuleDataFactory::load(setupModules.GetFilepath(i), destination_address_end, ((uint32_t) gModuleData) - MEMORY_REGION_START, gModuleData->trampolines,
DYN_LINK_TRAMPOLIN_LIST_LENGTH);
if (!moduleData) {
DEBUG_FUNCTION_LINE("Failed to load %s", setupModules.GetFilepath(i));

View File

@ -25,7 +25,7 @@
using namespace ELFIO;
std::optional<std::shared_ptr<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) {
ModuleDataFactory::load(const std::string &path, uint32_t destination_address_end, uint32_t maximum_size, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length) {
elfio reader;
std::shared_ptr<ModuleData> moduleData = std::make_shared<ModuleData>();
@ -36,10 +36,26 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p
}
uint32_t sec_num = reader.sections.size();
auto **destinations = (uint8_t **) malloc(sizeof(uint8_t *) * sec_num);
uint32_t baseOffset = *destination_address_ptr;
uint32_t sizeOfModule = 0;
for (uint32_t i = 0; i < sec_num; ++i) {
section *psec = reader.sections[i];
if (psec->get_type() == 0x80000002) {
continue;
}
if ((psec->get_type() == SHT_PROGBITS || psec->get_type() == SHT_NOBITS) && (psec->get_flags() & SHF_ALLOC)) {
sizeOfModule += psec->get_size() + 1;
}
}
if (sizeOfModule > maximum_size) {
DEBUG_FUNCTION_LINE("Module is too big.");
return {};
}
uint32_t baseOffset = (destination_address_end - sizeOfModule) & 0xFFFFFF00;
uint32_t offset_text = baseOffset;
uint32_t offset_data = offset_text;
@ -131,18 +147,16 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p
moduleData->addRelocationData(reloc);
}
DCFlushRange((void *) *destination_address_ptr, totalSize);
ICInvalidateRange((void *) *destination_address_ptr, totalSize);
DCFlushRange((void *) baseOffset, totalSize);
ICInvalidateRange((void *) baseOffset, totalSize);
free(destinations);
moduleData->setStartAddress(*destination_address_ptr);
moduleData->setStartAddress(baseOffset);
moduleData->setEndAddress(endAddress);
moduleData->setEntrypoint(entrypoint);
DEBUG_FUNCTION_LINE("Saved entrypoint as %08X", entrypoint);
*destination_address_ptr = (*destination_address_ptr + totalSize + 0x100) & 0xFFFFFF00;
return moduleData;
}

View File

@ -27,7 +27,7 @@
class ModuleDataFactory {
public:
static std::optional<std::shared_ptr<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);
load(const std::string &path, uint32_t destination_address_end, 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

@ -1,4 +1,4 @@
.section ".text"
.section ".crt0"
.global textStart
textStart:
mflr 4;