PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
elf.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# (c) 2020 Francisco Javier Trujillo Mata <fjtrujy@gmail.com>
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include <string.h>
12#include <sifrpc.h>
13#include <kernel.h>
14#include <sys/stat.h>
15#include <stdbool.h>
16#include <stdlib.h>
17
18#include "elf.h"
19
20// Loader ELF variables
21extern u8 loader_elf[];
22extern int size_loader_elf;
23
24// ELF-loading stuff
25#define ELF_MAGIC 0x464c457f
26#define ELF_PT_LOAD 1
27
28static bool file_exists(const char *filename) {
29 struct stat buffer;
30 return (stat (filename, &buffer) == 0);
31}
32
33/* IMPORTANT: This method wipe memory where the loader is going to be allocated
34* This values come from the linkfile used by the loader.c
35MEMORY {
36 bios : ORIGIN = 0x00000000, LENGTH = 528K --- 0x00000000 - 0x00084000: BIOS memory
37 bram : ORIGIN = 0x00084000, LENGTH = 496K --- 0x00084000 - 0x00100000: BIOS unused memory
38 gram : ORIGIN = 0x00100000, LENGTH = 31M --- 0x00100000 - 0x02000000: GAME memory
39}
40*/
41
42static void wipe_bramMem(void) {
43 int i;
44 for (i = 0x00084000; i < 0x100000; i += 64) {
45 asm volatile(
46 "\tsq $0, 0(%0) \n"
47 "\tsq $0, 16(%0) \n"
48 "\tsq $0, 32(%0) \n"
49 "\tsq $0, 48(%0) \n" ::"r"(i));
50 }
51}
52
53int LoadELFFromFileWithPartition(const char *filename, const char *partition, int argc, char *argv[]) {
54 u8 *boot_elf;
55 elf_header_t *eh;
56 elf_pheader_t *eph;
57 void *pdata;
58 int i;
59 int new_argc = argc + 2;
60
61 // We need to check that the ELF file before continue
62 if (!file_exists(filename)) {
63 return -1; // ELF file doesn't exists
64 }
65 // ELF Exists
66 wipe_bramMem();
67
68 // Preparing filename and partition to be sent in the argv
69 char *new_argv[argc + 2];
70 new_argv[0] = partition != NULL ? (char *)partition : "";
71 new_argv[1] = (char *)filename;
72 for (i = 0; i < argc; i++) {
73 new_argv[i + 2] = argv[i];
74 }
75
76 /* NB: LOADER.ELF is embedded */
77 boot_elf = (u8 *)loader_elf;
78 eh = (elf_header_t *)boot_elf;
79 if (_lw((u32)&eh->ident) != ELF_MAGIC)
80 __builtin_trap();
81
82 eph = (elf_pheader_t *)(boot_elf + eh->phoff);
83
84 /* Scan through the ELF's program headers and copy them into RAM, then zero out any non-loaded regions. */
85 for (i = 0; i < eh->phnum; i++) {
86 if (eph[i].type != ELF_PT_LOAD)
87 continue;
88
89 pdata = (void *)(boot_elf + eph[i].offset);
90 memcpy(eph[i].vaddr, pdata, eph[i].filesz);
91
92 if (eph[i].memsz > eph[i].filesz)
93 memset((void *)((u8 *)(eph[i].vaddr) + eph[i].filesz), 0, eph[i].memsz - eph[i].filesz);
94 }
95
96 /* Let's go. */
97 SifExitRpc();
98 FlushCache(0);
99 FlushCache(2);
100
101 return ExecPS2((void *)eh->entry, NULL, new_argc, new_argv);
102}
103
104int LoadELFFromFile(const char *filename, int argc, char *argv[])
105{
106 return LoadELFFromFileWithPartition(filename, NULL, argc, argv);
107}
int LoadELFFromFileWithPartition(const char *filename, const char *partition, int argc, char *argv[])
Definition elf.c:53