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

View File

@ -25,7 +25,7 @@
using namespace ELFIO; using namespace ELFIO;
std::optional<std::shared_ptr<ModuleData>> 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; elfio reader;
std::shared_ptr<ModuleData> moduleData = std::make_shared<ModuleData>(); 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(); uint32_t sec_num = reader.sections.size();
auto **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; 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_text = baseOffset;
uint32_t offset_data = offset_text; uint32_t offset_data = offset_text;
@ -131,18 +147,16 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p
moduleData->addRelocationData(reloc); moduleData->addRelocationData(reloc);
} }
DCFlushRange((void *) *destination_address_ptr, totalSize); DCFlushRange((void *) baseOffset, totalSize);
ICInvalidateRange((void *) *destination_address_ptr, totalSize); ICInvalidateRange((void *) baseOffset, totalSize);
free(destinations); free(destinations);
moduleData->setStartAddress(*destination_address_ptr); moduleData->setStartAddress(baseOffset);
moduleData->setEndAddress(endAddress); moduleData->setEndAddress(endAddress);
moduleData->setEntrypoint(entrypoint); moduleData->setEntrypoint(entrypoint);
DEBUG_FUNCTION_LINE("Saved entrypoint as %08X", entrypoint); DEBUG_FUNCTION_LINE("Saved entrypoint as %08X", entrypoint);
*destination_address_ptr = (*destination_address_ptr + totalSize + 0x100) & 0xFFFFFF00;
return moduleData; return moduleData;
} }

View File

@ -27,7 +27,7 @@
class ModuleDataFactory { class ModuleDataFactory {
public: public:
static std::optional<std::shared_ptr<ModuleData>> 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, 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); uint32_t trampolin_data_length);

View File

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