source: ps2launchargs/source/uLaunchELF/elf.c@ 1123

Last change on this file since 1123 was 1101, checked in by iritscen, 7 years ago

Added following to ps2launchargs:\n-Source code.\n-DLL needed to run ps2client.\n-Instructions for building uLaunchELF.

  • Property svn:executable set to *
File size: 7.5 KB
Line 
1//--------------------------------------------------------------
2//File name: elf.c
3//--------------------------------------------------------------
4#include "launchelf.h"
5
6unsigned char *elfLoaderLoadFile(char *path); // Iritscen: Modeled this on config.c's loadConfig()
7
8#define MAX_PATH 1025
9
10extern u8 *loader_elf;
11extern int size_loader_elf;
12extern u8 *fakehost_irx;
13extern int size_fakehost_irx;
14extern char LaunchElfDir[MAX_PATH]; // Iritscen: "extern"ed from main.c
15
16// ELF-loading stuff
17#define ELF_MAGIC 0x464c457f
18#define ELF_PT_LOAD 1
19
20//------------------------------
21typedef struct
22{
23 u8 ident[16]; // struct definition for ELF object header
24 u16 type;
25 u16 machine;
26 u32 version;
27 u32 entry;
28 u32 phoff;
29 u32 shoff;
30 u32 flags;
31 u16 ehsize;
32 u16 phentsize;
33 u16 phnum;
34 u16 shentsize;
35 u16 shnum;
36 u16 shstrndx;
37} elf_header_t;
38//------------------------------
39typedef struct
40{
41 u32 type; // struct definition for ELF program section header
42 u32 offset;
43 void *vaddr;
44 u32 paddr;
45 u32 filesz;
46 u32 memsz;
47 u32 flags;
48 u32 align;
49} elf_pheader_t;
50//--------------------------------------------------------------
51//End of data declarations
52//--------------------------------------------------------------
53//Start of function code
54//--------------------------------------------------------------
55// checkELFheader Tests for valid ELF file
56// Modified version of loader from Independence
57// (C) 2003 Marcus R. Brown <mrbrown@0xd6.org>
58//--------------------------------------------------------------
59int checkELFheader(char *path)
60{
61 elf_header_t elf_head;
62 u8 *boot_elf = (u8 *) &elf_head;
63 elf_header_t *eh = (elf_header_t *) boot_elf;
64 int fd, size=0, ret;
65 char fullpath[MAX_PATH], tmp[MAX_PATH], *p;
66
67 strcpy(fullpath,path);
68 if( !strncmp(fullpath, "mc", 2)
69 ||!strncmp(fullpath, "vmc", 3)
70 ||!strncmp(fullpath, "rom", 3)
71 ||!strncmp(fullpath, "cdrom", 5)
72 ||!strncmp(fullpath, "cdfs", 4)
73 ){; //fullpath is already correct
74 }else if(!strncmp(fullpath, "hdd0:", 5)) {
75 p = &path[5];
76 if(*p == '/')
77 p++;
78 sprintf(tmp, "hdd0:%s", p);
79 p = strchr(tmp, '/');
80 sprintf(fullpath, "pfs0:%s", p);
81 *p = 0;
82 if( (ret = mountParty(tmp)) < 0)
83 goto error;
84 fullpath[3] += ret;
85 }else if(!strncmp(fullpath, "mass", 4)){
86 char *pathSep;
87
88 pathSep = strchr(path, '/');
89 if(pathSep && (pathSep-path<7) && pathSep[-1]==':')
90 strcpy(fullpath+(pathSep-path), pathSep+1);
91 }else if(!strncmp(fullpath, "host:", 5)){
92 if(path[5] == '/')
93 strcpy(fullpath+5, path+6);
94 } else {
95 return 0; //return 0 for unrecognized device
96 }
97 if ((fd = genOpen(fullpath, O_RDONLY)) < 0)
98 goto error;
99 size = genLseek(fd, 0, SEEK_END);
100 if (!size){
101 genClose(fd);
102 goto error;
103 }
104 genLseek(fd, 0, SEEK_SET);
105 genRead(fd, boot_elf, sizeof(elf_header_t));
106 genClose(fd);
107
108 if ((_lw((u32)&eh->ident) != ELF_MAGIC) || eh->type != 2)
109 goto error;
110
111 return 1; //return 1 for successful check
112error:
113 return -1; //return -1 for failed check
114}
115//------------------------------
116//End of func: int checkELFheader(const char *path)
117//--------------------------------------------------------------
118// RunLoaderElf loads LOADER.ELF from program memory and passes
119// args of selected ELF and partition to it
120// Modified version of loader from Independence
121// (C) 2003 Marcus R. Brown <mrbrown@0xd6.org>
122//------------------------------
123void RunLoaderElf(char *filename, char *party)
124{
125 u8 *boot_elf;
126 elf_header_t *eh;
127 elf_pheader_t *eph;
128 void *pdata;
129 int ret, i;
130 int argc; // Iritscen: Added to allow add'l args
131 char *argv[16/*MAX_ARGS*/]; // Iritscen: Changed from "2" to allow add'l args
132
133 if((!strncmp(party, "hdd0:", 5)) && (!strncmp(filename, "pfs0:", 5))){
134 char fakepath[128], *p;
135 if(0 > fileXioMount("pfs0:", party, FIO_MT_RDONLY)){
136 //Some error occurred, it could be due to something else having used pfs0
137 unmountParty(0); //So we try unmounting pfs0, to try again
138 if(0 > fileXioMount("pfs0:", party, FIO_MT_RDONLY))
139 return; //If it still fails, we have to give up...
140 }
141 strcpy(fakepath,filename);
142 p=strrchr(fakepath,'/');
143 if(p==NULL) strcpy(fakepath,"pfs0:");
144 else
145 {
146 p++;
147 *p='\0';
148 }
149 //printf("Loading fakehost.irx %i bytes\n", size_fakehost_irx);
150 //printf("Faking for path \"%s\" on partition \"%s\"\n", fakepath, party);
151 SifExecModuleBuffer(&fakehost_irx, size_fakehost_irx, strlen(fakepath), fakepath, &ret);
152
153 }
154
155/* NB: LOADER.ELF is embedded */
156 boot_elf = (u8 *)&loader_elf;
157 eh = (elf_header_t *)boot_elf;
158 if (_lw((u32)&eh->ident) != ELF_MAGIC)
159 while (1);
160
161 eph = (elf_pheader_t *)(boot_elf + eh->phoff);
162
163/* Scan through the ELF's program headers and copy them into RAM, then
164 zero out any non-loaded regions. */
165 for (i = 0; i < eh->phnum; i++)
166 {
167 if (eph[i].type != ELF_PT_LOAD)
168 continue;
169
170 pdata = (void *)(boot_elf + eph[i].offset);
171 memcpy(eph[i].vaddr, pdata, eph[i].filesz);
172
173 if (eph[i].memsz > eph[i].filesz)
174 memset(eph[i].vaddr + eph[i].filesz, 0,
175 eph[i].memsz - eph[i].filesz);
176 }
177
178/* Let's go. */
179 fioExit();
180 SifInitRpc(0);
181 SifExitRpc();
182 FlushCache(0);
183 FlushCache(2);
184
185 argv[0] = filename;
186 argv[1] = party;
187 argc = 2;
188
189 // Iritscen: Load launch args from file
190 char txtPath[MAX_PATH];
191 strcpy(txtPath, LaunchElfDir); // a path like "host:C:/Users/Home/pcsx2/uLaunchELF/"
192 strcat(txtPath, "LaunchArgs.txt");
193 printf("uLaunchELF: Attempting to open %s...\n", txtPath);
194 unsigned char *argsTxt = elfLoaderLoadFile(txtPath);
195 if (argsTxt != NULL)
196 {
197 int argsRead = 0;
198 unsigned char *lineStart = argsTxt, *scanner = lineStart;
199 while (*lineStart != '\0' && argsRead < 16 /*MAX_ARGS*/)
200 {
201 // Find end of line and copy line to an argv[] element
202 while (*scanner != '\r' && *scanner != '\n' && *scanner != '\0')
203 scanner++;
204 int length = scanner - lineStart;
205 argv[argsRead + 2] = malloc(length + 1);
206 strncpy(argv[argsRead + 2], lineStart, length);
207 argv[argsRead + 2][length] = '\0';
208 printf("Got argument %s.\n", argv[argsRead + 2]);
209
210 // Advance to next line
211 while (*scanner == '\r' || *scanner == '\n')
212 scanner++;
213 lineStart = scanner;
214 argsRead++;
215 }
216
217 argc += argsRead;
218 printf("uLaunchELF: Passing %d argument(s) to the loader for the game:\n", argsRead);
219 int a;
220 for (a = 0; a < argsRead; a++)
221 printf(" arg %d: %s\n", a + 1, argv[a + 2]);
222 }
223 else
224 printf("uLaunchELF: Could not load LaunchArgs.txt from disk!\n");
225
226 ExecPS2((void *)eh->entry, 0, argc, argv);
227}
228//------------------------------
229//End of func: void RunLoaderElf(char *filename, char *party)
230//--------------------------------------------------------------
231// Iritscen: Modeled this on config.c's loadConfig()
232unsigned char *elfLoaderLoadFile(char *path)
233{
234 int fd = -1, tst;
235 size_t fileSize;
236 char filePath[MAX_PATH];
237 unsigned char *RAM_p;
238
239 if ((tst = genFixPath(path, filePath)) >= 0)
240 fd = genOpen(filePath, O_RDONLY);
241
242 if (fd < 0)
243 {
244failed_load:
245 return NULL;
246 }
247 fileSize = genLseek(fd, 0, SEEK_END);
248 printf("fileSize=%d\n", fileSize);
249 genLseek(fd, 0, SEEK_SET);
250 RAM_p = (char*)malloc(fileSize);
251 if (RAM_p == NULL)
252 {
253 genClose(fd);
254 goto failed_load;
255 }
256
257 genRead(fd, RAM_p, fileSize); // read file as one long string
258 genClose(fd);
259 RAM_p[fileSize] = '\0'; // terminate the file contents string
260 return RAM_p;
261}
262//--------------------------------------------------------------
263//End of file: elf.c
264//--------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.