flycast/core/reios/reios_elf.cpp

64 lines
1.4 KiB
C++
Raw Normal View History

2015-03-22 00:16:28 +00:00
#include "reios.h"
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
FILE* f = nowide::fopen(elf.c_str(), "rb");
if (!f)
2015-03-22 00:16:28 +00:00
return false;
std::fseek(f, 0, SEEK_END);
size_t size = std::ftell(f);
2015-03-22 00:16:28 +00:00
2023-07-01 10:47:02 +00:00
if (size > 16_MB) {
std::fclose(f);
2015-03-22 00:16:28 +00:00
return false;
}
void* elfF = malloc(size);
memset(elfF, 0, size);
2015-03-22 00:16:28 +00:00
std::fseek(f, 0, SEEK_SET);
size_t nread = std::fread(elfF, 1, size, f);
std::fclose(f);
2015-03-22 00:16:28 +00:00
elf_t elfFile;
if (nread != size || elf_newFile(elfF, nread, &elfFile) != 0 || elf_checkFile(&elfFile) != 0)
2019-07-30 17:04:51 +00:00
{
free((void*)elfFile.elfFile);
2015-03-22 00:16:28 +00:00
return false;
}
2019-07-30 17:04:51 +00:00
bool phys = false;
for (int i = 0; i < elf_getNumProgramHeaders(&elfFile); i++)
2019-07-30 17:04:51 +00:00
{
// Load that section
uint64_t dest;
if (phys)
dest = elf_getProgramHeaderPaddr(&elfFile, i);
2019-07-30 17:04:51 +00:00
else
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)
{
WARN_LOG(REIOS, "Invalid load address for section %d: %08lx", i, (long)dest);
2019-07-30 17:04:51 +00:00
continue;
}
DEBUG_LOG(REIOS, "Loading section %d to %08lx - %08lx", 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;
memset(ptr, 0, elf_getProgramHeaderMemorySize(&elfFile, i) - len);
2015-03-22 00:16:28 +00:00
}
free((void*)elfFile.elfFile);
2015-03-22 00:16:28 +00:00
return true;
2019-07-30 17:04:51 +00:00
}