ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
elf.c
Go to the documentation of this file.
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 <malloc.h>
17 
18 #include "elf.h"
19 
20 // Loader ELF variables
21 extern u8 loader_elf[];
22 extern int size_loader_elf;
23 
24 // ELF-loading stuff
25 #define ELF_MAGIC 0x464c457f
26 #define ELF_PT_LOAD 1
27 
28 static bool file_exists(const char *filename) {
29  struct stat buffer;
30  return (stat (filename, &buffer) == 0);
31 }
32 
33 int LoadELFFromFile(const char *filename, int argc, char *argv[])
34 {
35  u8 *boot_elf;
36  elf_header_t *eh;
37  elf_pheader_t *eph;
38  void *pdata;
39  int i;
40  int new_argc = argc + 1;
41 
42  // We need to check that the ELF file before continue
43  if (!file_exists(filename)) {
44  return -1; // ELF file doesn't exists
45  }
46  // ELF Exists
47  char *new_argv[new_argc];
48 
49  new_argv[0] = (char *)filename;
50  for (i = 0; i < argc; i++) {
51  new_argv[i + 1] = argv[i];
52  }
53 
54  /* NB: LOADER.ELF is embedded */
55  boot_elf = (u8 *)loader_elf;
56  eh = (elf_header_t *)boot_elf;
57  if (_lw((u32)&eh->ident) != ELF_MAGIC)
58  asm volatile("break\n");
59 
60  eph = (elf_pheader_t *)(boot_elf + eh->phoff);
61 
62  /* Scan through the ELF's program headers and copy them into RAM, then zero out any non-loaded regions. */
63  for (i = 0; i < eh->phnum; i++) {
64  if (eph[i].type != ELF_PT_LOAD)
65  continue;
66 
67  pdata = (void *)(boot_elf + eph[i].offset);
68  memcpy(eph[i].vaddr, pdata, eph[i].filesz);
69 
70  if (eph[i].memsz > eph[i].filesz)
71  memset(eph[i].vaddr + eph[i].filesz, 0, eph[i].memsz - eph[i].filesz);
72  }
73 
74  /* Let's go. */
75  SifExitRpc();
76  FlushCache(0);
77  FlushCache(2);
78 
79  return ExecPS2((void *)eh->entry, NULL, new_argc, new_argv);
80 }
u8 loader_elf[]
#define ELF_PT_LOAD
Definition: elf.c:26
int size_loader_elf
static bool file_exists(const char *filename)
Definition: elf.c:28
int LoadELFFromFile(const char *filename, int argc, char *argv[])
Definition: elf.c:33
#define ELF_MAGIC
Definition: elf.c:25
void FlushCache(s32 operation)
s32 ExecPS2(void *entry, void *gp, int num_args, char *args[])
u8 buffer[128]
Definition: rpc_client.c:19
void SifExitRpc(void)
u32 phoff
Definition: elf.h:27
u16 phnum
Definition: elf.h:32
u32 entry
Definition: elf.h:26
u8 ident[16]
Definition: elf.h:22
#define NULL
Definition: tamtypes.h:91
unsigned int u32
Definition: tamtypes.h:30
static u32 _lw(u32 addr)
Definition: tamtypes.h:96
unsigned char u8
Definition: tamtypes.h:23