mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 04:22:50 +02:00
Implement proper .dynamic section parsing
This commit is contained in:
parent
6c14d225fd
commit
1630fc1640
@ -3,55 +3,39 @@
|
||||
|
||||
_start:
|
||||
bl startup
|
||||
|
||||
.word 0x454d4f48
|
||||
.word 0x57455242
|
||||
.ascii "HOMEBREW"
|
||||
|
||||
startup:
|
||||
// get aslr base
|
||||
sub x28, x30, #4
|
||||
|
||||
// clear .bss
|
||||
ldr x0, =__bss_start__
|
||||
ldr x1, =__bss_end__
|
||||
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
|
||||
mov x2, #0
|
||||
add x0, x0, x28 // relocate ptr
|
||||
|
||||
bss_loop:
|
||||
str x2, [x0], #8
|
||||
str xzr, [x0], #8
|
||||
subs x1, x1, #8
|
||||
bne bss_loop
|
||||
|
||||
// relocate .got
|
||||
ldr x0, =__got_start__
|
||||
ldr x1, =__got_end__
|
||||
sub x1, x1, x0 // calculate size
|
||||
add x1, x1, #7 // round up to 8
|
||||
bic x1, x1, #7
|
||||
add x0, x0, x28 // relocate ptr
|
||||
|
||||
got_loop:
|
||||
ldr x2, [x0]
|
||||
add x2, x2, x28
|
||||
str x2, [x0], #8
|
||||
subs x1, x1, #8
|
||||
bne got_loop
|
||||
|
||||
// process .dynamic section
|
||||
mov x0, x28
|
||||
ldr x3, =initSystem
|
||||
add x3, x3, x28
|
||||
blr x3
|
||||
adrp x1, _DYNAMIC
|
||||
add x1, x1, #:lo12:_DYNAMIC
|
||||
bl __nx_dynamic
|
||||
|
||||
// initialize system
|
||||
mov x0, x28
|
||||
bl __nx_init
|
||||
|
||||
// call entrypoint
|
||||
mov x0, #0 // argc
|
||||
mov x1, #0 // argv
|
||||
|
||||
ldr x3, =main
|
||||
add x3, x3, x28
|
||||
ldr x2, =__nx_exit
|
||||
add x2, x2, x28
|
||||
mov x30, x2
|
||||
br x3
|
||||
|
||||
adrp x30, __nx_exit
|
||||
add x30, x30, #:lo12:__nx_exit
|
||||
b main
|
||||
|
37
nx/source/system/dynamic.c
Normal file
37
nx/source/system/dynamic.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include <switch/types.h>
|
||||
#include <elf.h>
|
||||
|
||||
void __nx_dynamic(uintptr_t base, const Elf64_Dyn* dyn)
|
||||
{
|
||||
const Elf64_Rela* rela = NULL;
|
||||
u64 relasz = 0;
|
||||
|
||||
for (; dyn->d_tag != DT_NULL; dyn++)
|
||||
{
|
||||
switch (dyn->d_tag)
|
||||
{
|
||||
case DT_RELA:
|
||||
rela = (const Elf64_Rela*)(base + dyn->d_un.d_ptr);
|
||||
break;
|
||||
case DT_RELASZ:
|
||||
relasz = dyn->d_un.d_val / sizeof(Elf64_Rela);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rela == NULL)
|
||||
for (;;); // Panic
|
||||
|
||||
for (; relasz--; rela++)
|
||||
{
|
||||
switch (ELF64_R_TYPE(rela->r_info))
|
||||
{
|
||||
case R_AARCH64_RELATIVE:
|
||||
{
|
||||
u64* ptr = (u64*)(base + rela->r_offset);
|
||||
*ptr = base + rela->r_addend;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,99 +1,19 @@
|
||||
.text
|
||||
.global initSystem
|
||||
.type initSystem, %function
|
||||
.global __nx_init
|
||||
.type __nx_init, %function
|
||||
|
||||
initSystem:
|
||||
__nx_init:
|
||||
stp x29, x30, [sp, #-16]!
|
||||
adr x1, __nx_binarybase
|
||||
str x0, [x1]
|
||||
bl __libnx_init
|
||||
|
||||
bl __appInit
|
||||
bl __nx_libc_init_array
|
||||
bl __libc_init_array
|
||||
ldp x29, x30, [sp], #16
|
||||
ret
|
||||
|
||||
.global __nx_exit
|
||||
.type __nx_exit, %function
|
||||
.type __nx_exit, %function
|
||||
|
||||
__nx_exit:
|
||||
bl __nx_libc_fini_array
|
||||
bl __libc_fini_array
|
||||
bl __appExit
|
||||
|
||||
b __libnx_exit
|
||||
|
||||
__nx_libc_init_array:
|
||||
stp x29, x30, [sp, #-16]!
|
||||
stp x21, x22, [sp, #-16]!
|
||||
stp x19, x20, [sp, #-16]!
|
||||
adr x3, __nx_binarybase
|
||||
ldr x20, [x3]
|
||||
|
||||
ldr x0, =__preinit_array_start
|
||||
ldr x1, =__preinit_array_end
|
||||
sub x1, x1, x0
|
||||
add x21, x0, x20
|
||||
lsr x19, x1, #3
|
||||
cbz x19, __nx_libc_init_array_end0
|
||||
|
||||
__nx_libc_init_array_lp0:
|
||||
ldr x3, [x21], #8
|
||||
sub x19, x19, #1
|
||||
add x3, x3, x20
|
||||
blr x3
|
||||
cbnz x19, __nx_libc_init_array_lp0
|
||||
|
||||
__nx_libc_init_array_end0:
|
||||
bl _init
|
||||
|
||||
ldr x0, =__init_array_start
|
||||
ldr x1, =__init_array_end
|
||||
sub x1, x1, x0
|
||||
add x21, x0, x20
|
||||
lsr x19, x1, #3
|
||||
cbz x19, __nx_libc_init_array_end1
|
||||
|
||||
__nx_libc_init_array_lp1:
|
||||
ldr x3, [x21], #8
|
||||
sub x19, x19, #1
|
||||
add x3, x3, x20
|
||||
blr x3
|
||||
cbnz x19, __nx_libc_init_array_lp1
|
||||
|
||||
__nx_libc_init_array_end1:
|
||||
ldp x19, x20, [sp], #16
|
||||
ldp x21, x22, [sp], #16
|
||||
ldp x29, x30, [sp], #16
|
||||
ret
|
||||
|
||||
__nx_libc_fini_array:
|
||||
stp x29, x30, [sp, #-16]!
|
||||
stp x21, x22, [sp, #-16]!
|
||||
stp x19, x20, [sp, #-16]!
|
||||
adr x3, __nx_binarybase
|
||||
ldr x20, [x3]
|
||||
|
||||
ldr x0, =__fini_array_start
|
||||
ldr x1, =__fini_array_end
|
||||
sub x1, x1, x0
|
||||
add x21, x0, x20
|
||||
lsr x19, x1, #3
|
||||
cbz x19, __nx_libc_fini_array_end
|
||||
|
||||
__nx_libc_fini_array_lp:
|
||||
sub x19, x19, #1
|
||||
ldr x3, [x21, x19, lsl #3]
|
||||
add x3, x3, x20
|
||||
blr x3
|
||||
cbnz x19, __nx_libc_fini_array_lp
|
||||
|
||||
__nx_libc_fini_array_end:
|
||||
ldp x19, x20, [sp], #16
|
||||
ldp x21, x22, [sp], #16
|
||||
ldp x29, x30, [sp], #16
|
||||
ret
|
||||
|
||||
.data
|
||||
__nx_binarybase:
|
||||
.dword 0
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user