crt0: clean up/refactor; envSetup: properly detect NSO/NRO environment...

This commit is contained in:
fincs 2020-08-04 20:18:07 +02:00
parent 7c6d7849f5
commit e655b48c41
No known key found for this signature in database
GPG Key ID: 62C7609ADA219C60
3 changed files with 62 additions and 65 deletions

View File

@ -30,28 +30,21 @@ extern __attribute__((weak)) u32 __nx_applet_type;
void envSetup(void* ctx, Handle main_thread, LoaderReturnFn saved_lr)
{
// If we're running under NSO, we should just call svcExitProcess.
// Otherwise we should return to loader via LR.
if (saved_lr == NULL) {
g_loaderRetAddr = (LoaderReturnFn) &svcExitProcess;
}
else {
g_loaderRetAddr = saved_lr;
}
// Detect NSO environment.
if (main_thread != -1)
// Detect and set up NSO environment.
if (ctx == NULL)
{
g_mainThreadHandle = main_thread;
// Under NSO, we use svcExitProcess as the return address and hint all syscalls as available.
g_isNso = true;
// For NSO we assume kernelhax thus access to all syscalls.
g_syscallHints[0] = g_syscallHints[1] = -1ull;
g_mainThreadHandle = main_thread;
g_loaderRetAddr = (LoaderReturnFn) &svcExitProcess;
g_syscallHints[0] = g_syscallHints[1] = UINT64_MAX;
return;
}
// Parse NRO config entries.
// Save the loader return address.
g_loaderRetAddr = saved_lr;
// Parse homebrew ABI config entries.
ConfigEntry* ent = ctx;
while (ent->Key != EntryType_EndOfList)

View File

@ -10,7 +10,6 @@
#include "services/set.h"
#include "runtime/devices/fs_dev.h"
void* __stack_top;
void NORETURN __nx_exit(Result rc, LoaderReturnFn retaddr);
void virtmemSetup(void);

View File

@ -1,68 +1,66 @@
.section ".crt0","ax"
.section .crt0, "ax", %progbits
.global _start
.align 2
_start:
b startup
b 1f
.word __nx_mod0 - _start
.ascii "HOMEBREW"
.org _start+0x80
startup:
// save lr
mov x7, x30
.org _start+0x80; 1:
// Arguments on NSO entry:
// x0=zero | x1=main thread handle
// 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
bl +4
sub x6, x30, #0x88
// context ptr and main thread handle
mov x5, x0
mov x4, x1
// Handle the exception if needed.
// if (ctx != NULL && main_thread != -1)__libnx_exception_entry(<inargs>);
cmp x5, #0
ccmn x4, #1, #4, ne // 4 = Z
beq bssclr_start
// Detect and handle user-mode exceptions first:
// if (x0 != 0 && x1 != UINT64_MAX) __libnx_exception_entry(<inargs>);
cmp x0, #0
ccmn x1, #1, #4, ne // 4 = Z
beq .Lcrt0_main_entry
b __libnx_exception_entry
bssclr_start:
mov x27, x7
mov x25, x5
mov x26, x4
.Lcrt0_main_entry:
// Get pointer to MOD0 struct (contains offsets to important places)
adr x28, __nx_mod0
// clear .bss
adrp x0, __bss_start__
adrp x1, __bss_end__
add x0, x0, #:lo12:__bss_start__
add x1, x1, #:lo12:__bss_end__
sub x1, x1, x0 // calculate size
add x1, x1, #7 // round up to 8
bic x1, x1, #7
// Calculate BSS address/size
ldp w8, w9, [x28, #8] // load BSS start/end offset from MOD0
sub w9, w9, w8 // calculate BSS size
add w9, w9, #7 // round up to 8
bic w9, w9, #7 // ^
add x8, x28, x8 // fixup the start pointer
bss_loop:
str xzr, [x0], #8
subs x1, x1, #8
bne bss_loop
// Clear the BSS in 8-byte units
1: subs w9, w9, #8
str xzr, [x8], #8
bne 1b
// store stack pointer
mov x1, sp
adrp x0, __stack_top
str x1, [x0, #:lo12:__stack_top]
// Preserve registers across function calls
mov x25, x0 // entrypoint argument 0
mov x26, x1 // entrypoint argument 1
mov x27, x30 // loader return address
// process .dynamic section
mov x0, x6
adrp x1, _DYNAMIC
add x1, x1, #:lo12:_DYNAMIC
// Save initial stack pointer
mov x8, sp
adrp x9, __stack_top
str x8, [x9, #:lo12:__stack_top]
// Parse ELF .dynamic section (which applies relocations to our module)
adr x0, _start // get aslr base
ldr w1, [x28, #4] // pointer to .dynamic section
add x1, x28, x1
bl __nx_dynamic
// initialize system
// Perform system initialization
mov x0, x25
mov x1, x26
mov x2, x27
bl __libnx_init
// call entrypoint
// Jump to the main function
adrp x0, __system_argc // argc
ldr w0, [x0, #:lo12:__system_argc]
adrp x1, __system_argv // argv
@ -74,12 +72,12 @@ bss_loop:
.global __nx_exit
.type __nx_exit, %function
__nx_exit:
// restore stack pointer
// Restore stack pointer
adrp x8, __stack_top
ldr x8, [x8, #:lo12:__stack_top]
mov sp, x8
// jump back to loader
// Jump back to loader
br x1
.global __nx_mod0
@ -96,3 +94,10 @@ __nx_mod0:
.ascii "LNY0"
.word __got_start__ - __nx_mod0
.word __got_end__ - __nx_mod0
.section .bss.__stack_top, "aw", %nobits
.global __stack_top
.align 3
__stack_top:
.space 8