Skip to content

Commit

Permalink
Copy the executables to the end of the memory region
Browse files Browse the repository at this point in the history
  • Loading branch information
Maschell committed Dec 28, 2021
1 parent f926166 commit 86f124b
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 18 deletions.
15 changes: 7 additions & 8 deletions source/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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));
Expand Down
30 changes: 22 additions & 8 deletions source/module/ModuleDataFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>();

Expand All @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion source/module/ModuleDataFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion source/pc.s
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.section ".text"
.section ".crt0"
.global textStart
textStart:
mflr 4;
Expand Down

0 comments on commit 86f124b

Please sign in to comment.