| 1 | //-------------------------------------------------------------- | 
 
 
 
 
 | 2 | //File name:    elf.c | 
 
 
 
 
 | 3 | //-------------------------------------------------------------- | 
 
 
 
 
 | 4 | #include "launchelf.h" | 
 
 
 
 
 | 5 |  | 
 
 
 
 
 | 6 | unsigned char *elfLoaderLoadFile(char *path); // Iritscen: Modeled this on config.c's loadConfig() | 
 
 
 
 
 | 7 |  | 
 
 
 
 
 | 8 | #define MAX_PATH 1025 | 
 
 
 
 
 | 9 |  | 
 
 
 
 
 | 10 | extern u8 *loader_elf; | 
 
 
 
 
 | 11 | extern int size_loader_elf; | 
 
 
 
 
 | 12 | extern u8 *fakehost_irx; | 
 
 
 
 
 | 13 | extern int size_fakehost_irx; | 
 
 
 
 
 | 14 | extern 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 | //------------------------------ | 
 
 
 
 
 | 21 | typedef 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 | //------------------------------ | 
 
 
 
 
 | 39 | typedef 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 | //-------------------------------------------------------------- | 
 
 
 
 
 | 59 | int 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 | 
 
 
 
 
 | 112 | error: | 
 
 
 
 
 | 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 | //------------------------------ | 
 
 
 
 
 | 123 | void 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() | 
 
 
 
 
 | 232 | unsigned 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 | { | 
 
 
 
 
 | 244 | failed_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 | //-------------------------------------------------------------- |