mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 20:42:44 +02:00
More loader config
This commit is contained in:
parent
fbf0b0643a
commit
94658b9f60
@ -19,18 +19,21 @@
|
|||||||
((((module)&0x1FF)) | ((description)&0x1FFF)<<9)
|
((((module)&0x1FF)) | ((description)&0x1FFF)<<9)
|
||||||
|
|
||||||
#define MODULE_LIBNX 345
|
#define MODULE_LIBNX 345
|
||||||
#define LIBNX_BADRELOC 1
|
enum {
|
||||||
#define LIBNX_OUTOFMEM 2
|
LIBNX_BADRELOC=1,
|
||||||
#define LIBNX_ALREADYMAPPED 3
|
LIBNX_OUTOFMEM,
|
||||||
#define LIBNX_BADGETINFO 4
|
LIBNX_ALREADYMAPPED,
|
||||||
#define LIBNX_BADQUERYMEMORY 5
|
LIBNX_BADGETINFO,
|
||||||
#define LIBNX_ALREADYINITIALIZED 6
|
LIBNX_BADQUERYMEMORY,
|
||||||
#define LIBNX_NOTINITIALIZED 7
|
LIBNX_ALREADYINITIALIZED,
|
||||||
#define LIBNX_NOTFOUND 8
|
LIBNX_NOTINITIALIZED,
|
||||||
#define LIBNX_IOERROR 9
|
LIBNX_NOTFOUND,
|
||||||
#define LIBNX_BADINPUT 10
|
LIBNX_IOERROR,
|
||||||
#define LIBNX_BADREENT 11
|
LIBNX_BADINPUT,
|
||||||
#define LIBNX_BUFFERPRODUCER_ERROR 12
|
LIBNX_BADREENT,
|
||||||
#define LIBNX_HANDLETOOEARLY 13
|
LIBNX_BUFFERPRODUCER_ERROR,
|
||||||
#define LIBNX_HEAPALLOCFAILED 14
|
LIBNX_HANDLETOOEARLY,
|
||||||
#define LIBNX_PARCEL_ERRBASE 100
|
LIBNX_HEAPALLOCFAILED,
|
||||||
|
LIBNX_TOOMANYOVERRIDES,
|
||||||
|
LIBNX_PARCELERROR,
|
||||||
|
};
|
||||||
|
@ -8,3 +8,11 @@ bool envIsNso(void);
|
|||||||
bool envHasHeapOverride(void);
|
bool envHasHeapOverride(void);
|
||||||
void* envGetHeapOverrideAddr(void);
|
void* envGetHeapOverrideAddr(void);
|
||||||
u64 envGetHeapOverrideSize(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);
|
||||||
|
@ -37,6 +37,8 @@ void __system_initArgv(void)
|
|||||||
|
|
||||||
rc = svcQueryMemory(&meminfo, &pageinfo, (u64)argdata);
|
rc = svcQueryMemory(&meminfo, &pageinfo, (u64)argdata);
|
||||||
|
|
||||||
|
// TODO: Use envHasArgv() here.
|
||||||
|
|
||||||
// This memory is only mapped when arguments were passed.
|
// This memory is only mapped when arguments were passed.
|
||||||
if (R_FAILED(rc) || meminfo.perm != 0x3)
|
if (R_FAILED(rc) || meminfo.perm != 0x3)
|
||||||
return;
|
return;
|
||||||
@ -110,46 +112,5 @@ void __system_initArgv(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
__system_argv[__system_argc] = NULL;
|
__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;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,9 +3,12 @@
|
|||||||
|
|
||||||
static bool g_isNso = false;
|
static bool g_isNso = false;
|
||||||
static Handle g_mainThreadHandle = INVALID_HANDLE;
|
static Handle g_mainThreadHandle = INVALID_HANDLE;
|
||||||
static void* g_loaderRetAddr = NULL;
|
static LoaderReturnFn g_loaderRetAddr = NULL;
|
||||||
static void* g_overrideHeapAddr = NULL;
|
static void* g_overrideHeapAddr = NULL;
|
||||||
static u64 g_overrideHeapSize = 0;
|
static u64 g_overrideHeapSize = 0;
|
||||||
|
static u64 g_overrideArgc = 0;
|
||||||
|
static void* g_overrideArgv = NULL;
|
||||||
|
static u64 g_syscallHints[0x80/8];
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 Key;
|
u32 Key;
|
||||||
@ -13,6 +16,10 @@ typedef struct {
|
|||||||
u64 Value[2];
|
u64 Value[2];
|
||||||
} ConfigEntry;
|
} ConfigEntry;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
IsMandatory = BIT(0),
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
EntryType_EndOfList=0,
|
EntryType_EndOfList=0,
|
||||||
EntryType_MainThreadHandle=1,
|
EntryType_MainThreadHandle=1,
|
||||||
@ -30,6 +37,10 @@ void envParse(void* ctx, Handle main_thread)
|
|||||||
{
|
{
|
||||||
g_mainThreadHandle = main_thread;
|
g_mainThreadHandle = main_thread;
|
||||||
g_isNso = true;
|
g_isNso = true;
|
||||||
|
|
||||||
|
// For NSO we assume kernelhax thus access to all syscalls.
|
||||||
|
memset((void*) &g_syscallHints, 0xFF, sizeof(g_syscallHints));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,23 +64,39 @@ void envParse(void* ctx, Handle main_thread)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case EntryType_OverrideService:
|
case EntryType_OverrideService:
|
||||||
// TODO
|
smAddOverrideHandle(ent->Value[0], ent->Value[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EntryType_Argv:
|
case EntryType_Argv:
|
||||||
// TODO
|
g_overrideArgc = ent->Value[0];
|
||||||
|
g_overrideArgv = (void*) ent->Value[1];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EntryType_SyscallAvailableHint:
|
case EntryType_SyscallAvailableHint: {
|
||||||
// TODO
|
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;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case EntryType_AppletType:
|
case EntryType_AppletType:
|
||||||
// TODO
|
// TODO
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// TODO
|
if (ent->Flags & IsMandatory)
|
||||||
|
{
|
||||||
|
// Encountered unknown but mandatory key, bail back to loader.
|
||||||
|
g_loaderRetAddr(346 | ((100 + ent->Key) << 9));
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,3 +128,19 @@ void* envGetHeapOverrideAddr(void) {
|
|||||||
u64 envGetHeapOverrideSize(void) {
|
u64 envGetHeapOverrideSize(void) {
|
||||||
return g_overrideHeapSize;
|
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)));
|
||||||
|
}
|
||||||
|
@ -15,7 +15,7 @@ static size_t g_smOverridesNum = 0;
|
|||||||
void smAddOverrideHandle(u64 name, Handle handle)
|
void smAddOverrideHandle(u64 name, Handle handle)
|
||||||
{
|
{
|
||||||
if (g_smOverridesNum == MAX_OVERRIDES)
|
if (g_smOverridesNum == MAX_OVERRIDES)
|
||||||
fatalSimple(1);
|
fatalSimple(MAKERESULT(MODULE_LIBNX, LIBNX_TOOMANYOVERRIDES));
|
||||||
|
|
||||||
size_t i = g_smOverridesNum;
|
size_t i = g_smOverridesNum;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user