From 20cd940095a4c24a4c91674dc4f0a9a0e6b442be Mon Sep 17 00:00:00 2001 From: yellows8 Date: Sat, 17 Feb 2018 21:25:21 -0500 Subject: [PATCH] Implemented arg parsing for NRO env. When args aren't available, set __system_argv to {ptr to NULL} instead of NULL. --- nx/source/runtime/argv.c | 153 ++++++++++++++++++++++----------------- 1 file changed, 85 insertions(+), 68 deletions(-) diff --git a/nx/source/runtime/argv.c b/nx/source/runtime/argv.c index 412b07b0..72975c54 100644 --- a/nx/source/runtime/argv.c +++ b/nx/source/runtime/argv.c @@ -13,6 +13,8 @@ extern char* fake_heap_end; extern u32 __argdata__; +static char* g_argv_empty = NULL; + void argvSetup(void) { Result rc=0; @@ -21,22 +23,20 @@ void argvSetup(void) u8 *argdata = (u8*)&__argdata__; u32 *arg32 = (u32*)argdata; - u64 argdata_allocsize; - u64 argdata_strsize; - u32 argvptr_pos; + u64 argdata_allocsize=0; + u64 argdata_strsize=0; + u32 argvptr_pos=0; u32 max_argv; u32 argi; u32 arglen=0; bool quote_flag=0; bool end_flag=0; - char *args; + char *args = NULL; char *argstart; char *argstorage; __system_argc = 0; - __system_argv = NULL; - - // TODO: Use envHasArgv()/envGetArgv() here for the NRO case. + __system_argv = &g_argv_empty; if (envIsNso()) { memset(&meminfo, 0, sizeof(meminfo)); @@ -57,67 +57,84 @@ void argvSetup(void) argvptr_pos = 0x20 + argdata_strsize+1; if (argvptr_pos >= argdata_allocsize) return; - argstorage = (char*)&argdata[argvptr_pos]; - - argvptr_pos += (argdata_strsize+1 + 0x9) & ~0x7; - if (argvptr_pos >= argdata_allocsize) return; - - max_argv = (argdata_allocsize - argvptr_pos) >> 3; - if (max_argv < 2) return; - - __system_argv = (char**)&argdata[argvptr_pos]; - - argstart = NULL; - - for(argi=0; argi= max_argv) break; - } - } - } - - if (arglen && __system_argc < max_argv) { - strncpy(argstorage, argstart, arglen); - argstorage[arglen] = 0; - __system_argv[__system_argc] = argstorage; - __system_argc++; - } - - __system_argv[__system_argc] = NULL; } + else if (envHasArgv()) { + args = envGetArgv(); + argdata_allocsize = 0x9000;//Use the same size as NSO. + argdata_strsize = strlen(args); + argdata = (u8*)fake_heap_start; + + if (argdata_strsize==0) return; + + if (fake_heap_end - fake_heap_start < argdata_allocsize) return; + + fake_heap_start += argdata_allocsize; + + argvptr_pos = 0; + + memset(argdata, 0, argdata_allocsize); + } + + argstorage = (char*)&argdata[argvptr_pos]; + + argvptr_pos += (argdata_strsize+1 + 0x9) & ~0x7; + if (argvptr_pos >= argdata_allocsize) return; + + max_argv = (argdata_allocsize - argvptr_pos) >> 3; + if (max_argv < 2) return; + + __system_argv = (char**)&argdata[argvptr_pos]; + + argstart = NULL; + + for(argi=0; argi= max_argv) break; + } + } + } + + if (arglen && __system_argc < max_argv) { + strncpy(argstorage, argstart, arglen); + argstorage[arglen] = 0; + __system_argv[__system_argc] = argstorage; + __system_argc++; + } + + __system_argv[__system_argc] = NULL; }