PayloadFromRPX/source/ElfUtils.c

144 lines
4.8 KiB
C
Raw Permalink Normal View History

2020-04-26 13:41:39 +02:00
#include <stdio.h>
#include <string.h>
#include <coreinit/cache.h>
2022-03-05 17:00:58 +01:00
#include <coreinit/debug.h>
2020-04-26 13:41:39 +02:00
#include <coreinit/memdefaultheap.h>
2022-03-05 17:00:58 +01:00
#include <utils/logger.h>
2020-04-26 13:41:39 +02:00
#include <whb/file.h>
#include <whb/log.h>
2022-03-05 17:00:58 +01:00
#include <whb/sdcard.h>
2020-04-26 13:41:39 +02:00
#include "elf_abi.h"
2020-07-22 15:12:25 +02:00
int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t *sizeOut) {
2020-04-26 13:41:39 +02:00
char path[256];
2022-03-05 17:00:58 +01:00
int result = 0;
2020-07-22 15:12:25 +02:00
char *sdRootPath = "";
2020-04-26 13:41:39 +02:00
if (!WHBMountSdCard()) {
DEBUG_FUNCTION_LINE("Failed to mount SD Card...");
2020-04-26 13:41:39 +02:00
result = -1;
goto exit;
}
sdRootPath = WHBGetSdCardMountPath();
2020-07-22 15:12:25 +02:00
sprintf(path, "%s/%s", sdRootPath, relativefilepath);
2020-04-26 13:41:39 +02:00
DEBUG_FUNCTION_LINE("Loading file %s.", path);
2020-04-26 13:41:39 +02:00
*fileOut = WHBReadWholeFile(path, sizeOut);
if (!(*fileOut)) {
result = -2;
DEBUG_FUNCTION_LINE("WHBReadWholeFile(%s) returned NULL", path);
2020-04-26 13:41:39 +02:00
goto exit;
}
2022-03-05 17:00:58 +01:00
exit:
2020-04-26 13:41:39 +02:00
WHBUnmountSdCard();
return result;
}
2020-07-22 15:12:25 +02:00
2020-04-26 13:41:39 +02:00
static void InstallMain(void *data_elf);
2020-07-22 15:12:25 +02:00
uint32_t load_loader_elf_from_sd(unsigned char *baseAddress, const char *relativePath) {
2022-03-05 17:00:58 +01:00
char *elf_data = NULL;
2020-04-26 13:41:39 +02:00
uint32_t fileSize = 0;
2020-07-22 15:12:25 +02:00
if (LoadFileToMem(relativePath, &elf_data, &fileSize) != 0) {
2020-04-26 13:41:39 +02:00
return 0;
}
InstallMain(elf_data);
2020-07-22 15:12:25 +02:00
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) elf_data;
2020-04-26 13:41:39 +02:00
uint32_t res = ehdr->e_entry;
2020-07-22 15:12:25 +02:00
MEMFreeToDefaultHeap((void *) elf_data);
2020-04-26 13:41:39 +02:00
return res;
}
2020-07-22 15:12:25 +02:00
static unsigned int get_section(unsigned char *data, const char *name, unsigned int *size, unsigned int *addr, int fail_on_not_found) {
2020-04-26 13:41:39 +02:00
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) data;
2022-03-05 17:00:58 +01:00
if (!data || !IS_ELF(*ehdr) || (ehdr->e_type != ET_EXEC) || (ehdr->e_machine != EM_PPC)) {
2020-04-26 13:41:39 +02:00
OSFatal("Invalid elf file");
}
Elf32_Shdr *shdr = (Elf32_Shdr *) (data + ehdr->e_shoff);
int i;
2020-07-22 15:12:25 +02:00
for (i = 0; i < ehdr->e_shnum; i++) {
const char *section_name = ((const char *) data) + shdr[ehdr->e_shstrndx].sh_offset + shdr[i].sh_name;
if (strcmp(section_name, name) == 0) {
if (addr) {
2020-04-26 13:41:39 +02:00
*addr = shdr[i].sh_addr;
}
if (size) {
2020-04-26 13:41:39 +02:00
*size = shdr[i].sh_size;
}
2020-04-26 13:41:39 +02:00
return shdr[i].sh_offset;
}
}
if (fail_on_not_found) {
2020-07-22 15:12:25 +02:00
OSFatal((char *) name);
}
2020-04-26 13:41:39 +02:00
return 0;
}
/* ****************************************************************** */
/* INSTALL MAIN CODE */
/* ****************************************************************** */
static void InstallMain(void *data_elf) {
// get .text section
unsigned int main_text_addr = 0;
2022-03-05 17:00:58 +01:00
unsigned int main_text_len = 0;
2020-04-26 13:41:39 +02:00
unsigned int section_offset = get_section(data_elf, ".text", &main_text_len, &main_text_addr, 1);
2022-03-05 17:00:58 +01:00
unsigned char *main_text = data_elf + section_offset;
2020-04-26 13:41:39 +02:00
/* Copy main .text to memory */
2020-07-22 15:12:25 +02:00
if (section_offset > 0) {
2020-08-23 10:37:31 +02:00
DEBUG_FUNCTION_LINE("Copy section to %08X from %08X (size: %d)", main_text_addr, main_text, main_text_len);
2020-07-22 15:12:25 +02:00
memcpy((void *) (main_text_addr), (void *) main_text, main_text_len);
DCFlushRange((void *) main_text_addr, main_text_len);
ICInvalidateRange((void *) main_text_addr, main_text_len);
2020-04-26 13:41:39 +02:00
}
// get the .rodata section
unsigned int main_rodata_addr = 0;
2022-03-05 17:00:58 +01:00
unsigned int main_rodata_len = 0;
section_offset = get_section(data_elf, ".rodata", &main_rodata_len, &main_rodata_addr, 0);
2020-07-22 15:12:25 +02:00
if (section_offset > 0) {
2020-04-26 13:41:39 +02:00
unsigned char *main_rodata = data_elf + section_offset;
/* Copy main rodata to memory */
2020-07-22 15:12:25 +02:00
memcpy((void *) (main_rodata_addr), (void *) main_rodata, main_rodata_len);
DCFlushRange((void *) main_rodata_addr, main_rodata_len);
ICInvalidateRange((void *) main_rodata_addr, main_rodata_len);
2020-04-26 13:41:39 +02:00
}
// get the .data section
unsigned int main_data_addr = 0;
2022-03-05 17:00:58 +01:00
unsigned int main_data_len = 0;
section_offset = get_section(data_elf, ".data", &main_data_len, &main_data_addr, 0);
2020-07-22 15:12:25 +02:00
if (section_offset > 0) {
2020-04-26 13:41:39 +02:00
unsigned char *main_data = data_elf + section_offset;
/* Copy main data to memory */
2020-07-22 15:12:25 +02:00
memcpy((void *) (main_data_addr), (void *) main_data, main_data_len);
DCFlushRange((void *) main_data_addr, main_data_len);
ICInvalidateRange((void *) main_data_addr, main_data_len);
2020-04-26 13:41:39 +02:00
}
// get the .bss section
unsigned int main_bss_addr = 0;
2022-03-05 17:00:58 +01:00
unsigned int main_bss_len = 0;
section_offset = get_section(data_elf, ".bss", &main_bss_len, &main_bss_addr, 0);
2020-07-22 15:12:25 +02:00
if (section_offset > 0) {
2020-04-26 13:41:39 +02:00
unsigned char *main_bss = data_elf + section_offset;
/* Copy main data to memory */
2020-07-22 15:12:25 +02:00
memcpy((void *) (main_bss_addr), (void *) main_bss, main_bss_len);
DCFlushRange((void *) main_bss_addr, main_bss_len);
ICInvalidateRange((void *) main_bss_addr, main_bss_len);
2020-04-26 13:41:39 +02:00
}
}