mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 12:32:40 +02:00
crt0: clean up/refactor; envSetup: properly detect NSO/NRO environment...
This commit is contained in:
parent
7c6d7849f5
commit
e655b48c41
@ -30,28 +30,21 @@ extern __attribute__((weak)) u32 __nx_applet_type;
|
|||||||
|
|
||||||
void envSetup(void* ctx, Handle main_thread, LoaderReturnFn saved_lr)
|
void envSetup(void* ctx, Handle main_thread, LoaderReturnFn saved_lr)
|
||||||
{
|
{
|
||||||
// If we're running under NSO, we should just call svcExitProcess.
|
// Detect and set up NSO environment.
|
||||||
// Otherwise we should return to loader via LR.
|
if (ctx == NULL)
|
||||||
if (saved_lr == NULL) {
|
|
||||||
g_loaderRetAddr = (LoaderReturnFn) &svcExitProcess;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
g_loaderRetAddr = saved_lr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect NSO environment.
|
|
||||||
if (main_thread != -1)
|
|
||||||
{
|
{
|
||||||
g_mainThreadHandle = main_thread;
|
// Under NSO, we use svcExitProcess as the return address and hint all syscalls as available.
|
||||||
g_isNso = true;
|
g_isNso = true;
|
||||||
|
g_mainThreadHandle = main_thread;
|
||||||
// For NSO we assume kernelhax thus access to all syscalls.
|
g_loaderRetAddr = (LoaderReturnFn) &svcExitProcess;
|
||||||
g_syscallHints[0] = g_syscallHints[1] = -1ull;
|
g_syscallHints[0] = g_syscallHints[1] = UINT64_MAX;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse NRO config entries.
|
// Save the loader return address.
|
||||||
|
g_loaderRetAddr = saved_lr;
|
||||||
|
|
||||||
|
// Parse homebrew ABI config entries.
|
||||||
ConfigEntry* ent = ctx;
|
ConfigEntry* ent = ctx;
|
||||||
|
|
||||||
while (ent->Key != EntryType_EndOfList)
|
while (ent->Key != EntryType_EndOfList)
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include "services/set.h"
|
#include "services/set.h"
|
||||||
#include "runtime/devices/fs_dev.h"
|
#include "runtime/devices/fs_dev.h"
|
||||||
|
|
||||||
void* __stack_top;
|
|
||||||
void NORETURN __nx_exit(Result rc, LoaderReturnFn retaddr);
|
void NORETURN __nx_exit(Result rc, LoaderReturnFn retaddr);
|
||||||
|
|
||||||
void virtmemSetup(void);
|
void virtmemSetup(void);
|
||||||
|
@ -1,68 +1,66 @@
|
|||||||
.section ".crt0","ax"
|
.section .crt0, "ax", %progbits
|
||||||
.global _start
|
.global _start
|
||||||
|
.align 2
|
||||||
|
|
||||||
_start:
|
_start:
|
||||||
b startup
|
b 1f
|
||||||
.word __nx_mod0 - _start
|
.word __nx_mod0 - _start
|
||||||
.ascii "HOMEBREW"
|
.ascii "HOMEBREW"
|
||||||
|
|
||||||
.org _start+0x80
|
.org _start+0x80; 1:
|
||||||
startup:
|
// Arguments on NSO entry:
|
||||||
// save lr
|
// x0=zero | x1=main thread handle
|
||||||
mov x7, x30
|
// Arguments on NRO entry (homebrew ABI):
|
||||||
|
// x0=ptr to env context | x1=UINT64_MAX (-1 aka 0xFFFFFFFFFFFFFFFF)
|
||||||
|
// Arguments on user-mode exception entry:
|
||||||
|
// x0=excpt type (non-zero) | x1=ptr to excpt context
|
||||||
|
|
||||||
// get aslr base
|
// Detect and handle user-mode exceptions first:
|
||||||
bl +4
|
// if (x0 != 0 && x1 != UINT64_MAX) __libnx_exception_entry(<inargs>);
|
||||||
sub x6, x30, #0x88
|
cmp x0, #0
|
||||||
|
ccmn x1, #1, #4, ne // 4 = Z
|
||||||
|
beq .Lcrt0_main_entry
|
||||||
|
b __libnx_exception_entry
|
||||||
|
|
||||||
// context ptr and main thread handle
|
.Lcrt0_main_entry:
|
||||||
mov x5, x0
|
// Get pointer to MOD0 struct (contains offsets to important places)
|
||||||
mov x4, x1
|
adr x28, __nx_mod0
|
||||||
|
|
||||||
// Handle the exception if needed.
|
// Calculate BSS address/size
|
||||||
// if (ctx != NULL && main_thread != -1)__libnx_exception_entry(<inargs>);
|
ldp w8, w9, [x28, #8] // load BSS start/end offset from MOD0
|
||||||
cmp x5, #0
|
sub w9, w9, w8 // calculate BSS size
|
||||||
ccmn x4, #1, #4, ne // 4 = Z
|
add w9, w9, #7 // round up to 8
|
||||||
beq bssclr_start
|
bic w9, w9, #7 // ^
|
||||||
b __libnx_exception_entry
|
add x8, x28, x8 // fixup the start pointer
|
||||||
|
|
||||||
bssclr_start:
|
// Clear the BSS in 8-byte units
|
||||||
mov x27, x7
|
1: subs w9, w9, #8
|
||||||
mov x25, x5
|
str xzr, [x8], #8
|
||||||
mov x26, x4
|
bne 1b
|
||||||
|
|
||||||
// clear .bss
|
// Preserve registers across function calls
|
||||||
adrp x0, __bss_start__
|
mov x25, x0 // entrypoint argument 0
|
||||||
adrp x1, __bss_end__
|
mov x26, x1 // entrypoint argument 1
|
||||||
add x0, x0, #:lo12:__bss_start__
|
mov x27, x30 // loader return address
|
||||||
add x1, x1, #:lo12:__bss_end__
|
|
||||||
sub x1, x1, x0 // calculate size
|
|
||||||
add x1, x1, #7 // round up to 8
|
|
||||||
bic x1, x1, #7
|
|
||||||
|
|
||||||
bss_loop:
|
// Save initial stack pointer
|
||||||
str xzr, [x0], #8
|
mov x8, sp
|
||||||
subs x1, x1, #8
|
adrp x9, __stack_top
|
||||||
bne bss_loop
|
str x8, [x9, #:lo12:__stack_top]
|
||||||
|
|
||||||
// store stack pointer
|
// Parse ELF .dynamic section (which applies relocations to our module)
|
||||||
mov x1, sp
|
adr x0, _start // get aslr base
|
||||||
adrp x0, __stack_top
|
ldr w1, [x28, #4] // pointer to .dynamic section
|
||||||
str x1, [x0, #:lo12:__stack_top]
|
add x1, x28, x1
|
||||||
|
|
||||||
// process .dynamic section
|
|
||||||
mov x0, x6
|
|
||||||
adrp x1, _DYNAMIC
|
|
||||||
add x1, x1, #:lo12:_DYNAMIC
|
|
||||||
bl __nx_dynamic
|
bl __nx_dynamic
|
||||||
|
|
||||||
// initialize system
|
// Perform system initialization
|
||||||
mov x0, x25
|
mov x0, x25
|
||||||
mov x1, x26
|
mov x1, x26
|
||||||
mov x2, x27
|
mov x2, x27
|
||||||
bl __libnx_init
|
bl __libnx_init
|
||||||
|
|
||||||
// call entrypoint
|
// Jump to the main function
|
||||||
adrp x0, __system_argc // argc
|
adrp x0, __system_argc // argc
|
||||||
ldr w0, [x0, #:lo12:__system_argc]
|
ldr w0, [x0, #:lo12:__system_argc]
|
||||||
adrp x1, __system_argv // argv
|
adrp x1, __system_argv // argv
|
||||||
@ -74,12 +72,12 @@ bss_loop:
|
|||||||
.global __nx_exit
|
.global __nx_exit
|
||||||
.type __nx_exit, %function
|
.type __nx_exit, %function
|
||||||
__nx_exit:
|
__nx_exit:
|
||||||
// restore stack pointer
|
// Restore stack pointer
|
||||||
adrp x8, __stack_top
|
adrp x8, __stack_top
|
||||||
ldr x8, [x8, #:lo12:__stack_top]
|
ldr x8, [x8, #:lo12:__stack_top]
|
||||||
mov sp, x8
|
mov sp, x8
|
||||||
|
|
||||||
// jump back to loader
|
// Jump back to loader
|
||||||
br x1
|
br x1
|
||||||
|
|
||||||
.global __nx_mod0
|
.global __nx_mod0
|
||||||
@ -96,3 +94,10 @@ __nx_mod0:
|
|||||||
.ascii "LNY0"
|
.ascii "LNY0"
|
||||||
.word __got_start__ - __nx_mod0
|
.word __got_start__ - __nx_mod0
|
||||||
.word __got_end__ - __nx_mod0
|
.word __got_end__ - __nx_mod0
|
||||||
|
|
||||||
|
.section .bss.__stack_top, "aw", %nobits
|
||||||
|
.global __stack_top
|
||||||
|
.align 3
|
||||||
|
|
||||||
|
__stack_top:
|
||||||
|
.space 8
|
||||||
|
Loading…
Reference in New Issue
Block a user