From 1630fc16404c56ff41007652f83b8c7c2ab85734 Mon Sep 17 00:00:00 2001 From: fincs Date: Thu, 21 Sep 2017 01:12:11 +0200 Subject: [PATCH] Implement proper .dynamic section parsing --- crt0/switch_crt0.s | 52 ++++++++------------- nx/source/system/dynamic.c | 37 +++++++++++++++ nx/source/system/sysinit.s | 92 +++----------------------------------- 3 files changed, 61 insertions(+), 120 deletions(-) create mode 100644 nx/source/system/dynamic.c diff --git a/crt0/switch_crt0.s b/crt0/switch_crt0.s index 8a942ee0..ced5c18f 100644 --- a/crt0/switch_crt0.s +++ b/crt0/switch_crt0.s @@ -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 diff --git a/nx/source/system/dynamic.c b/nx/source/system/dynamic.c new file mode 100644 index 00000000..78f51df4 --- /dev/null +++ b/nx/source/system/dynamic.c @@ -0,0 +1,37 @@ +#include +#include + +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; + } + } + } +} diff --git a/nx/source/system/sysinit.s b/nx/source/system/sysinit.s index 72a6f833..200c0fb1 100644 --- a/nx/source/system/sysinit.s +++ b/nx/source/system/sysinit.s @@ -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 -