diff --git a/cube/swiss/source/aram/sidestep.c b/cube/swiss/source/aram/sidestep.c index d1a0c0bd..ecd2553f 100644 --- a/cube/swiss/source/aram/sidestep.c +++ b/cube/swiss/source/aram/sidestep.c @@ -303,11 +303,11 @@ u32 DOLSize(DOLHEADER *dol) * * Pass in a memory pointer to a previously loaded DOL ****************************************************************************/ -int DOLtoARAM(unsigned char *dol, int argc, char *argv[]) +int DOLtoARAM(unsigned char *dol, char *argz, size_t argz_len) { u32 sizeinbytes; int i; - struct __argv dolargs; + struct __argv args; /*** Make sure ARAM subsystem is alive! ***/ AR_Init(NULL, 0); /*** No stack - we need it all ***/ @@ -331,6 +331,18 @@ int DOLtoARAM(unsigned char *dol, int argc, char *argv[]) /*** This may seem strange, but in developing d0lLZ we found some with section addresses with zero length ***/ if (dolhdr->textAddress[i] && dolhdr->textLength[i]) { + if (dolhdr->entryPoint >= dolhdr->textAddress[i] && + dolhdr->entryPoint < (dolhdr->textAddress[i] + dolhdr->textLength[i])) + { + u32 *entrypoint = (u32 *) (dol + (dolhdr->entryPoint - dolhdr->textAddress[i]) + dolhdr->textOffset[i]); + + if (entrypoint[1] != ARGV_MAGIC) + { + argz = NULL; + argz_len = 0; + } + } + ARAMPut(dol + dolhdr->textOffset[i], (char *) ((dolhdr->textAddress[i] - minaddress) + ARAMSTART), dolhdr->textLength[i]); } @@ -347,30 +359,18 @@ int DOLtoARAM(unsigned char *dol, int argc, char *argv[]) } /*** Pass a command line ***/ - if (argc) + if (argz) { - dolargs.argvMagic = ARGV_MAGIC; - dolargs.argc = argc; - dolargs.length = 1; + args.argvMagic = ARGV_MAGIC; + args.commandLine = argz; + args.length = argz_len; - for (i = 0; i < argc; i++) - { - size_t argLength = strlen(argv[i]) + 1; - dolargs.length += argLength; - } - dolargs.commandLine = malloc(dolargs.length); + ARAMPut((unsigned char *) args.commandLine, (char *) ((maxaddress - minaddress) + ARAMSTART), args.length); - unsigned int position = 0; - for (i = 0; i < argc; i++) - { - size_t argLength = strlen(argv[i]) + 1; - memcpy(dolargs.commandLine + position, argv[i], argLength); - position += argLength; - } - dolargs.commandLine[dolargs.length - 1] = '\0'; - DCStoreRange(dolargs.commandLine, dolargs.length); + args.commandLine = (char *) maxaddress; + sizeinbytes += args.length; - ARAMPut((unsigned char *) &dolargs, (char *) (dolhdr->entryPoint - minaddress + 8 + ARAMSTART), sizeof(struct __argv)); + ARAMPut((unsigned char *) &args, (char *) ((dolhdr->entryPoint + 8 - minaddress) + ARAMSTART), sizeof(struct __argv)); } /*** Now go run it ***/ @@ -400,7 +400,7 @@ static void ELFMinMax(Elf32_Ehdr *ehdr, Elf32_Phdr *phdr) } } -int ELFtoARAM(unsigned char *elf, int argc, char *argv[]) +int ELFtoARAM(unsigned char *elf, char *argz, size_t argz_len) { Elf32_Ehdr *ehdr; Elf32_Phdr *phdr; @@ -429,35 +429,35 @@ int ELFtoARAM(unsigned char *elf, int argc, char *argv[]) { if (phdr[i].p_type == PT_LOAD) { + if (ehdr->e_entry >= phdr[i].p_vaddr && + ehdr->e_entry < (phdr[i].p_vaddr + phdr[i].p_filesz)) + { + u32 *entrypoint = (u32 *) (elf + (ehdr->e_entry - phdr[i].p_vaddr) + phdr[i].p_offset); + + if (entrypoint[1] != ARGV_MAGIC) + { + argz = NULL; + argz_len = 0; + } + } + ARAMPut(elf + phdr[i].p_offset, (char *) ((phdr[i].p_vaddr - minaddress) + ARAMSTART), phdr[i].p_filesz); } } /*** Pass a command line ***/ - if (argc) + if (argz) { args.argvMagic = ARGV_MAGIC; - args.argc = argc; - args.length = 1; + args.commandLine = argz; + args.length = argz_len; - for (i = 0; i < argc; i++) - { - size_t argLength = strlen(argv[i]) + 1; - args.length += argLength; - } - args.commandLine = malloc(args.length); + ARAMPut((unsigned char *) args.commandLine, (char *) ((maxaddress - minaddress) + ARAMSTART), args.length); - unsigned int position = 0; - for (i = 0; i < argc; i++) - { - size_t argLength = strlen(argv[i]) + 1; - memcpy(args.commandLine + position, argv[i], argLength); - position += argLength; - } - args.commandLine[args.length - 1] = '\0'; - DCStoreRange(args.commandLine, args.length); + args.commandLine = (char *) maxaddress; + sizeinbytes += args.length; - ARAMPut((unsigned char *) &args, (char *) (ehdr->e_entry - minaddress + 8 + ARAMSTART), sizeof(struct __argv)); + ARAMPut((unsigned char *) &args, (char *) ((ehdr->e_entry + 8 - minaddress) + ARAMSTART), sizeof(struct __argv)); } /*** Now go run it ***/ diff --git a/cube/swiss/source/aram/sidestep.h b/cube/swiss/source/aram/sidestep.h index 40d47f4f..d90d176a 100644 --- a/cube/swiss/source/aram/sidestep.h +++ b/cube/swiss/source/aram/sidestep.h @@ -34,8 +34,8 @@ typedef struct { } DOLHEADER; u32 DOLSize(DOLHEADER *dol); -int DOLtoARAM(unsigned char *dol, int argc, char *argv[]); -int ELFtoARAM(unsigned char *elf, int argc, char *argv[]); +int DOLtoARAM(unsigned char *dol, char *argz, size_t argz_len); +int ELFtoARAM(unsigned char *elf, char *argz, size_t argz_len); int BINtoARAM(unsigned char *bin, int len, unsigned int entrypoint); #endif diff --git a/cube/swiss/source/config/dolparameters.c b/cube/swiss/source/config/dolparameters.c index e05432b1..697f6f08 100644 --- a/cube/swiss/source/config/dolparameters.c +++ b/cube/swiss/source/config/dolparameters.c @@ -6,6 +6,7 @@ - by emu_kidid for Swiss 28/07/2015 ----------------------------------------------------------- */ +#include #include #include #include @@ -124,18 +125,13 @@ Parameters* getParameters() { return &_parameters; } -void populateArgv(int *argc, char *argv[], char *filename) { +void populateArgv(char **argz, size_t *argz_len, char *filename) { int i = 0; Parameters* params = getParameters(); print_gecko("There are %i parameters\r\n", params->num_params); for(i = 0; i < params->num_params; i++) { Parameter *param = ¶ms->parameters[i]; if(param->enable) { - if(*argc == 0) { - // Filename first - argv[0] = getExternalPath(filename); - *argc += 1; - } ParameterValue *arg = ¶m->arg; ParameterValue *val = ¶m->values[param->currentValueIdx]; //print_gecko("Arg: (%s) [%s] is enabled with value (%s) [%s]\r\n", @@ -147,9 +143,9 @@ void populateArgv(int *argc, char *argv[], char *filename) { else sprintf(argvEntry, "%s=%s", arg->value, val->value); print_gecko("Argv entry: [%s]\r\n", argvEntry); - argv[*argc] = argvEntry; - *argc+=1; + argz_add(argz, argz_len, argvEntry); + free(argvEntry); } } - print_gecko("Arg count: %i\r\n", *argc); + print_gecko("Arg count: %i\r\n", argz_count(*argz, *argz_len)); } diff --git a/cube/swiss/source/config/dolparameters.h b/cube/swiss/source/config/dolparameters.h index 593ea5e9..0d40d599 100644 --- a/cube/swiss/source/config/dolparameters.h +++ b/cube/swiss/source/config/dolparameters.h @@ -51,5 +51,5 @@ typedef struct { void parseParameters(char *filecontents); Parameters* getParameters(); -void populateArgv(int *argc, char *argv[], char *filename); +void populateArgv(char **argz, size_t *argz_len, char *filename); #endif diff --git a/cube/swiss/source/swiss.c b/cube/swiss/source/swiss.c index b4246b42..363ad891 100644 --- a/cube/swiss/source/swiss.c +++ b/cube/swiss/source/swiss.c @@ -4,6 +4,7 @@ * */ +#include #include #include #include /*** Wrapper to include common libogc headers ***/ @@ -1017,10 +1018,10 @@ void load_app(ExecutableFile *fileToPatch) BINtoARAM(buffer, sizeToRead, 0x81300000); } else if(type == PATCH_DOL) { - DOLtoARAM(buffer, 0, NULL); + DOLtoARAM(buffer, NULL, 0); } else if(type == PATCH_ELF) { - ELFtoARAM(buffer, 0, NULL); + ELFtoARAM(buffer, NULL, 0); } } @@ -1069,26 +1070,20 @@ void boot_dol() } // Build a command line to pass to the DOL - int argc = 0; - char *argv[1024]; + char *argz = getExternalPath(&curFile.name[0]); + size_t argz_len = strlen(argz) + 1; - u32 readTest; char fileName[PATHNAME_MAX]; memset(&fileName[0], 0, PATHNAME_MAX); strncpy(&fileName[0], &curFile.name[0], strrchr(&curFile.name[0], '.') - &curFile.name[0]); print_gecko("DOL file name without extension [%s]\r\n", fileName); - file_handle *cliArgFile = calloc(1, sizeof(file_handle)); - // .cli argument file + file_handle *cliArgFile = calloc(1, sizeof(file_handle)); snprintf(cliArgFile->name, PATHNAME_MAX, "%s.cli", fileName); - if(devices[DEVICE_CUR]->readFile(cliArgFile, &readTest, 4) != 4) { - free(cliArgFile); - cliArgFile = NULL; - } // we found something, use parameters (.cli) - if(cliArgFile) { + if(devices[DEVICE_CUR]->readFile(cliArgFile, NULL, 0) == 0 && cliArgFile->size) { print_gecko("Argument file found [%s]\r\n", cliArgFile->name); char *cli_buffer = calloc(1, cliArgFile->size + 1); if(cli_buffer) { @@ -1096,43 +1091,19 @@ void boot_dol() devices[DEVICE_CUR]->readFile(cliArgFile, cli_buffer, cliArgFile->size); // Parse CLI - argv[argc] = getExternalPath(&curFile.name[0]); - argc++; - // First argument is at the beginning of the file - if(cli_buffer[0] != '\r' && cli_buffer[0] != '\n') { - argv[argc] = cli_buffer; - argc++; - } - - // Search for the others after each newline - for(i = 0; i < cliArgFile->size; i++) { - if(cli_buffer[i] == '\r' || cli_buffer[i] == '\n') { - cli_buffer[i] = '\0'; - } - else if(cli_buffer[i - 1] == '\0') { - argv[argc] = cli_buffer + i; - argc++; - - if(argc >= 1024) - break; - } - } + argz_add_sep(&argz, &argz_len, cli_buffer, '\n'); + free(cli_buffer); } } - + devices[DEVICE_CUR]->closeFile(cliArgFile); free(cliArgFile); - file_handle *dcpArgFile = calloc(1, sizeof(file_handle)); - // .dcp parameter file + file_handle *dcpArgFile = calloc(1, sizeof(file_handle)); snprintf(dcpArgFile->name, PATHNAME_MAX, "%s.dcp", fileName); - if(devices[DEVICE_CUR]->readFile(dcpArgFile, &readTest, 4) != 4) { - free(dcpArgFile); - dcpArgFile = NULL; - } // we found something, parse and display parameters for selection (.dcp) - if(dcpArgFile) { + if(devices[DEVICE_CUR]->readFile(dcpArgFile, NULL, 0) == 0 && dcpArgFile->size) { print_gecko("Argument file found [%s]\r\n", dcpArgFile->name); char *dcp_buffer = calloc(1, dcpArgFile->size + 1); if(dcp_buffer) { @@ -1141,24 +1112,26 @@ void boot_dol() // Parse DCP parseParameters(dcp_buffer); + free(dcp_buffer); + Parameters *params = (Parameters*)getParameters(); if(params->num_params > 0) { DrawArgsSelector(getRelativeName(&curFile.name[0])); // Get an argv back or none. - populateArgv(&argc, argv, (char*)&curFile.name); + populateArgv(&argz, &argz_len, &curFile.name[0]); } } } - + devices[DEVICE_CUR]->closeFile(dcpArgFile); free(dcpArgFile); if(devices[DEVICE_CUR] != NULL) devices[DEVICE_CUR]->deinit( devices[DEVICE_CUR]->initial ); // Boot if(!memcmp(dol_buffer, ELFMAG, SELFMAG)) { - ELFtoARAM(dol_buffer, argc, argc == 0 ? NULL : argv); + ELFtoARAM(dol_buffer, argz, argz_len); } else { - DOLtoARAM(dol_buffer, argc, argc == 0 ? NULL : argv); + DOLtoARAM(dol_buffer, argz, argz_len); } free(dol_buffer); diff --git a/cube/swiss/source/wiiload.c b/cube/swiss/source/wiiload.c index 8684494c..1a11f371 100644 --- a/cube/swiss/source/wiiload.c +++ b/cube/swiss/source/wiiload.c @@ -149,9 +149,9 @@ static void wiiload_handler(int sd) if (buffer) { if (!memcmp(buffer, ELFMAG, SELFMAG)) - ELFtoARAM(buffer, 0, NULL); + ELFtoARAM(buffer, args, header.args_size); else - DOLtoARAM(buffer, 0, NULL); + DOLtoARAM(buffer, args, header.args_size); } free(args);