Skip to content

Commit

Permalink
- Rewrite argument passing.
Browse files Browse the repository at this point in the history
- Enable argument passing in wiiload server.
  • Loading branch information
Extrems committed Feb 7, 2023
1 parent 634f6d0 commit 4378079
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 101 deletions.
84 changes: 42 additions & 42 deletions cube/swiss/source/aram/sidestep.c
Expand Up @@ -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 ***/
Expand 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]);
}
Expand All @@ -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 ***/
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 ***/
Expand Down
4 changes: 2 additions & 2 deletions cube/swiss/source/aram/sidestep.h
Expand Up @@ -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
Expand Down
14 changes: 5 additions & 9 deletions cube/swiss/source/config/dolparameters.c
Expand Up @@ -6,6 +6,7 @@
- by emu_kidid for Swiss 28/07/2015
----------------------------------------------------------- */

#include <argz.h>
#include <gccore.h>
#include <string.h>
#include <malloc.h>
Expand Down Expand Up @@ -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 = &params->parameters[i];
if(param->enable) {
if(*argc == 0) {
// Filename first
argv[0] = getExternalPath(filename);
*argc += 1;
}
ParameterValue *arg = &param->arg;
ParameterValue *val = &param->values[param->currentValueIdx];
//print_gecko("Arg: (%s) [%s] is enabled with value (%s) [%s]\r\n",
Expand All @@ -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));
}
2 changes: 1 addition & 1 deletion cube/swiss/source/config/dolparameters.h
Expand Up @@ -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
63 changes: 18 additions & 45 deletions cube/swiss/source/swiss.c
Expand Up @@ -4,6 +4,7 @@
*
*/

#include <argz.h>
#include <stdio.h>
#include <stdarg.h>
#include <gccore.h> /*** Wrapper to include common libogc headers ***/
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -1069,70 +1070,40 @@ 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) {
devices[DEVICE_CUR]->seekFile(cliArgFile, 0, DEVICE_HANDLER_SEEK_SET);
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) {
Expand All @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions cube/swiss/source/wiiload.c
Expand Up @@ -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);
Expand Down

0 comments on commit 4378079

Please sign in to comment.