More loader config

This commit is contained in:
plutoo 2018-01-13 00:18:04 +01:00
parent fbf0b0643a
commit 94658b9f60
5 changed files with 78 additions and 63 deletions

View File

@ -19,18 +19,21 @@
((((module)&0x1FF)) | ((description)&0x1FFF)<<9)
#define MODULE_LIBNX 345
#define LIBNX_BADRELOC 1
#define LIBNX_OUTOFMEM 2
#define LIBNX_ALREADYMAPPED 3
#define LIBNX_BADGETINFO 4
#define LIBNX_BADQUERYMEMORY 5
#define LIBNX_ALREADYINITIALIZED 6
#define LIBNX_NOTINITIALIZED 7
#define LIBNX_NOTFOUND 8
#define LIBNX_IOERROR 9
#define LIBNX_BADINPUT 10
#define LIBNX_BADREENT 11
#define LIBNX_BUFFERPRODUCER_ERROR 12
#define LIBNX_HANDLETOOEARLY 13
#define LIBNX_HEAPALLOCFAILED 14
#define LIBNX_PARCEL_ERRBASE 100
enum {
LIBNX_BADRELOC=1,
LIBNX_OUTOFMEM,
LIBNX_ALREADYMAPPED,
LIBNX_BADGETINFO,
LIBNX_BADQUERYMEMORY,
LIBNX_ALREADYINITIALIZED,
LIBNX_NOTINITIALIZED,
LIBNX_NOTFOUND,
LIBNX_IOERROR,
LIBNX_BADINPUT,
LIBNX_BADREENT,
LIBNX_BUFFERPRODUCER_ERROR,
LIBNX_HANDLETOOEARLY,
LIBNX_HEAPALLOCFAILED,
LIBNX_TOOMANYOVERRIDES,
LIBNX_PARCELERROR,
};

View File

@ -8,3 +8,11 @@ bool envIsNso(void);
bool envHasHeapOverride(void);
void* envGetHeapOverrideAddr(void);
u64 envGetHeapOverrideSize(void);
bool envHasArgv(void);
u64 envGetArgc(void);
void* envGetArgv(void);
bool envIsSyscallHinted(u8 svc);
typedef void __attribute__((noreturn)) (*LoaderReturnFn)(int result_code);

View File

@ -37,6 +37,8 @@ void __system_initArgv(void)
rc = svcQueryMemory(&meminfo, &pageinfo, (u64)argdata);
// TODO: Use envHasArgv() here.
// This memory is only mapped when arguments were passed.
if (R_FAILED(rc) || meminfo.perm != 0x3)
return;
@ -110,46 +112,5 @@ void __system_initArgv(void)
}
__system_argv[__system_argc] = NULL;
//TODO: How to handle args for NRO?
/*
int i;
const char* arglist = envGetSystemArgList();
const char* temp = arglist;
// Check if the argument list is present
if (!temp)
return;
// Retrieve argc
__system_argc = *(u32*)temp;
temp += sizeof(u32);
// Find the end of the argument data
for (i = 0; i < __system_argc; i ++)
{
for (; *temp; temp ++);
temp ++;
}
// Reserve heap memory for argv data
u32 argSize = temp - arglist - sizeof(u32);
__system_argv = (char**)fake_heap_start;
fake_heap_start += sizeof(char**)*(__system_argc + 1);
char* argCopy = fake_heap_start;
fake_heap_start += argSize;
// Fill argv array
memcpy(argCopy, &arglist[4], argSize);
temp = argCopy;
for (i = 0; i < __system_argc; i ++)
{
__system_argv[i] = (char*)temp;
for (; *temp; temp ++);
temp ++;
}
__system_argv[__system_argc] = NULL;
*/
}

View File

@ -3,9 +3,12 @@
static bool g_isNso = false;
static Handle g_mainThreadHandle = INVALID_HANDLE;
static void* g_loaderRetAddr = NULL;
static LoaderReturnFn g_loaderRetAddr = NULL;
static void* g_overrideHeapAddr = NULL;
static u64 g_overrideHeapSize = 0;
static u64 g_overrideArgc = 0;
static void* g_overrideArgv = NULL;
static u64 g_syscallHints[0x80/8];
typedef struct {
u32 Key;
@ -13,6 +16,10 @@ typedef struct {
u64 Value[2];
} ConfigEntry;
enum {
IsMandatory = BIT(0),
};
enum {
EntryType_EndOfList=0,
EntryType_MainThreadHandle=1,
@ -30,6 +37,10 @@ void envParse(void* ctx, Handle main_thread)
{
g_mainThreadHandle = main_thread;
g_isNso = true;
// For NSO we assume kernelhax thus access to all syscalls.
memset((void*) &g_syscallHints, 0xFF, sizeof(g_syscallHints));
return;
}
@ -53,23 +64,39 @@ void envParse(void* ctx, Handle main_thread)
break;
case EntryType_OverrideService:
// TODO
smAddOverrideHandle(ent->Value[0], ent->Value[1]);
break;
case EntryType_Argv:
// TODO
g_overrideArgc = ent->Value[0];
g_overrideArgv = (void*) ent->Value[1];
break;
case EntryType_SyscallAvailableHint:
// TODO
case EntryType_SyscallAvailableHint: {
int i, j;
for (i=0; i<2; i++) for (j=0; j<8; j++)
{
u8 svc = ent->Value[i] >> (8*j);
if (svc < 0x80)
g_syscallHints[svc/64] |= 1llu << (svc%64);
}
break;
}
case EntryType_AppletType:
// TODO
break;
default:
// TODO
if (ent->Flags & IsMandatory)
{
// Encountered unknown but mandatory key, bail back to loader.
g_loaderRetAddr(346 | ((100 + ent->Key) << 9));
}
break;
}
@ -101,3 +128,19 @@ void* envGetHeapOverrideAddr(void) {
u64 envGetHeapOverrideSize(void) {
return g_overrideHeapSize;
}
bool envHasArgv(void) {
return g_overrideArgv != NULL;
}
u64 envGetArgc(void) {
return g_overrideArgc;
}
void* envGetArgv(void) {
return g_overrideArgv;
}
bool envIsSyscallHinted(u8 svc) {
return !!(g_syscallHints[svc/64] & (1llu << (svc%64)));
}

View File

@ -15,7 +15,7 @@ static size_t g_smOverridesNum = 0;
void smAddOverrideHandle(u64 name, Handle handle)
{
if (g_smOverridesNum == MAX_OVERRIDES)
fatalSimple(1);
fatalSimple(MAKERESULT(MODULE_LIBNX, LIBNX_TOOMANYOVERRIDES));
size_t i = g_smOverridesNum;