2015-03-22 00:16:28 +00:00
|
|
|
#include "reios.h"
|
|
|
|
|
2023-03-03 15:05:12 +00:00
|
|
|
extern "C" {
|
|
|
|
#include <elf/elf.h>
|
|
|
|
}
|
2015-03-22 00:16:28 +00:00
|
|
|
|
|
|
|
#include "hw/sh4/sh4_mem.h"
|
|
|
|
|
2020-03-29 17:29:14 +00:00
|
|
|
bool reios_loadElf(const std::string& elf) {
|
2015-03-22 00:16:28 +00:00
|
|
|
|
2021-01-19 10:11:01 +00:00
|
|
|
FILE* f = nowide::fopen(elf.c_str(), "rb");
|
|
|
|
if (!f)
|
2015-03-22 00:16:28 +00:00
|
|
|
return false;
|
2021-01-19 10:11:01 +00:00
|
|
|
|
|
|
|
std::fseek(f, 0, SEEK_END);
|
|
|
|
size_t size = std::ftell(f);
|
2015-03-22 00:16:28 +00:00
|
|
|
|
2023-10-05 09:45:14 +00:00
|
|
|
if (size == 0 || size > 16_MB) {
|
2021-01-19 10:11:01 +00:00
|
|
|
std::fclose(f);
|
2015-03-22 00:16:28 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-03-03 15:05:12 +00:00
|
|
|
void* elfF = malloc(size);
|
2015-03-22 00:16:28 +00:00
|
|
|
|
2021-01-19 10:11:01 +00:00
|
|
|
std::fseek(f, 0, SEEK_SET);
|
2023-03-03 15:05:12 +00:00
|
|
|
size_t nread = std::fread(elfF, 1, size, f);
|
2021-01-19 10:11:01 +00:00
|
|
|
std::fclose(f);
|
2015-03-22 00:16:28 +00:00
|
|
|
|
2023-03-03 15:05:12 +00:00
|
|
|
elf_t elfFile;
|
2023-10-05 09:45:14 +00:00
|
|
|
if (nread != size || elf_newFile(elfF, nread, &elfFile) != 0)
|
2019-07-30 17:04:51 +00:00
|
|
|
{
|
2023-10-05 09:45:14 +00:00
|
|
|
free(elfF);
|
2015-03-22 00:16:28 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-07-30 17:04:51 +00:00
|
|
|
bool phys = false;
|
2023-10-05 09:45:14 +00:00
|
|
|
for (size_t i = 0; i < elf_getNumProgramHeaders(&elfFile); i++)
|
2019-07-30 17:04:51 +00:00
|
|
|
{
|
2024-03-24 09:16:02 +00:00
|
|
|
uint32_t type = elf_getProgramHeaderType(&elfFile, i);
|
|
|
|
if (type != PT_LOAD) {
|
|
|
|
DEBUG_LOG(REIOS, "Ignoring section %d type %d", (int)i, type);
|
|
|
|
continue;
|
|
|
|
}
|
2019-07-30 17:04:51 +00:00
|
|
|
// Load that section
|
|
|
|
uint64_t dest;
|
|
|
|
if (phys)
|
2023-03-03 15:05:12 +00:00
|
|
|
dest = elf_getProgramHeaderPaddr(&elfFile, i);
|
2019-07-30 17:04:51 +00:00
|
|
|
else
|
2023-03-03 15:05:12 +00:00
|
|
|
dest = elf_getProgramHeaderVaddr(&elfFile, i);
|
|
|
|
size_t len = elf_getProgramHeaderFileSize(&elfFile, i);
|
|
|
|
void *src = (u8 *)(elfFile.elfFile) + elf_getProgramHeaderOffset(&elfFile, i);
|
2015-03-22 00:16:28 +00:00
|
|
|
u8* ptr = GetMemPtr(dest, len);
|
2019-07-30 17:04:51 +00:00
|
|
|
if (ptr == NULL)
|
|
|
|
{
|
2024-03-24 09:16:02 +00:00
|
|
|
WARN_LOG(REIOS, "Invalid load address for section %d: %08lx", (int)i, (long)dest);
|
2019-07-30 17:04:51 +00:00
|
|
|
continue;
|
|
|
|
}
|
2024-03-24 09:16:02 +00:00
|
|
|
DEBUG_LOG(REIOS, "Loading section %d to %08lx - %08lx", (int)i, (long)dest, (long)(dest + len - 1));
|
2019-07-30 17:04:51 +00:00
|
|
|
memcpy(ptr, src, len);
|
2015-03-22 00:16:28 +00:00
|
|
|
ptr += len;
|
2023-03-03 15:05:12 +00:00
|
|
|
memset(ptr, 0, elf_getProgramHeaderMemorySize(&elfFile, i) - len);
|
2015-03-22 00:16:28 +00:00
|
|
|
}
|
2023-10-05 09:45:14 +00:00
|
|
|
free(elfF);
|
2015-03-22 00:16:28 +00:00
|
|
|
|
|
|
|
return true;
|
2019-07-30 17:04:51 +00:00
|
|
|
}
|