sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
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#ifdef _EE
44 int i;
45 for (i = 0x00084000; i < 0x100000; i += 64) {
46 __asm__ __volatile__(
47 "\tsq $0, 0(%0) \n"
48 "\tsq $0, 16(%0) \n"
49 "\tsq $0, 32(%0) \n"
50 "\tsq $0, 48(%0) \n" ::"r"(i));
51 }
52#else
53 memset((void *)0x00084000, 0, 0x100000 - 0x00084000);
54#endif
55}
56
57static int LoadELFFromFileResetCommon(const char *filename, const char *partition, int reset, int argc, char *argv[]) {
58 u8 *boot_elf;
59 elf_header_t *eh;
60 elf_pheader_t *eph;
61 void *pdata;
62 int i;
63 int new_argc = argc + 3;
64
65 // We need to check that the ELF file before continue
66 if (!file_exists(filename)) {
67 return -1; // ELF file doesn't exists
68 }
69 // ELF Exists
70 wipe_bramMem();
71
72 // Preparing filename and partition to be sent in the argv
73 char *new_argv[argc + 3];
74 new_argv[0] = partition != NULL ? (char *)partition : "";
75 new_argv[1] = (char *)filename;
76 new_argv[2] = reset ? "1" : "0";
77 for (i = 0; i < argc; i++) {
78 new_argv[i + 3] = argv[i];
79 }
80
81 /* NB: LOADER.ELF is embedded */
82 boot_elf = (u8 *)loader_elf;
83 eh = (elf_header_t *)boot_elf;
84 if (_lw((u32)&eh->ident) != ELF_MAGIC)
85 __builtin_trap();
86
87 eph = (elf_pheader_t *)(boot_elf + eh->phoff);
88
89 /* Scan through the ELF's program headers and copy them into RAM, then zero out any non-loaded regions. */
90 for (i = 0; i < eh->phnum; i++) {
91 if (eph[i].type != ELF_PT_LOAD)
92 continue;
93
94 pdata = (void *)(boot_elf + eph[i].offset);
95 memcpy(eph[i].vaddr, pdata, eph[i].filesz);
96
97 if (eph[i].memsz > eph[i].filesz)
98 memset((void *)((u8 *)(eph[i].vaddr) + eph[i].filesz), 0, eph[i].memsz - eph[i].filesz);
99 }
100
101 /* Let's go. */
102 sceSifExitRpc();
103 FlushCache(0);
104 FlushCache(2);
105
106 return ExecPS2((void *)eh->entry, NULL, new_argc, new_argv);
107}
108
109int LoadELFFromFileWithPartition(const char *filename, const char *partition, int argc, char *argv[]) {
110 return LoadELFFromFileResetCommon(filename, partition, 1, argc, argv);
111}
112
113int LoadELFFromFileWithPartitionNoReset(const char *filename, const char *partition, int argc, char *argv[]) {
114 return LoadELFFromFileResetCommon(filename, partition, 0, argc, argv);
115}
116
117int LoadELFFromFile(const char *filename, int argc, char *argv[])
118{
119 return LoadELFFromFileWithPartition(filename, NULL, argc, argv);
120}
int LoadELFFromFileWithPartition(const char *filename, const char *partition, int argc, char *argv[])
Definition elf.c:109