Implement proper .dynamic section parsing

This commit is contained in:
fincs 2017-09-21 01:12:11 +02:00
parent 6c14d225fd
commit 1630fc1640
3 changed files with 61 additions and 120 deletions

View File

@ -3,55 +3,39 @@
_start: _start:
bl startup bl startup
.ascii "HOMEBREW"
.word 0x454d4f48
.word 0x57455242
startup: startup:
// get aslr base // get aslr base
sub x28, x30, #4 sub x28, x30, #4
// clear .bss // clear .bss
ldr x0, =__bss_start__ adrp x0, __bss_start__
ldr x1, =__bss_end__ adrp x1, __bss_end__
add x0, x0, #:lo12:__bss_start__
add x1, x1, #:lo12:__bss_end__
sub x1, x1, x0 // calculate size sub x1, x1, x0 // calculate size
add x1, x1, #7 // round up to 8 add x1, x1, #7 // round up to 8
bic x1, x1, #7 bic x1, x1, #7
mov x2, #0
add x0, x0, x28 // relocate ptr
bss_loop: bss_loop:
str x2, [x0], #8 str xzr, [x0], #8
subs x1, x1, #8 subs x1, x1, #8
bne bss_loop bne bss_loop
// relocate .got // process .dynamic section
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
mov x0, x28 mov x0, x28
ldr x3, =initSystem adrp x1, _DYNAMIC
add x3, x3, x28 add x1, x1, #:lo12:_DYNAMIC
blr x3 bl __nx_dynamic
// initialize system
mov x0, x28
bl __nx_init
// call entrypoint
mov x0, #0 // argc mov x0, #0 // argc
mov x1, #0 // argv mov x1, #0 // argv
adrp x30, __nx_exit
ldr x3, =main add x30, x30, #:lo12:__nx_exit
add x3, x3, x28 b main
ldr x2, =__nx_exit
add x2, x2, x28
mov x30, x2
br x3

View 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;
}
}
}
}

View File

@ -1,99 +1,19 @@
.text .text
.global initSystem .global __nx_init
.type initSystem, %function .type __nx_init, %function
initSystem: __nx_init:
stp x29, x30, [sp, #-16]! stp x29, x30, [sp, #-16]!
adr x1, __nx_binarybase
str x0, [x1]
bl __libnx_init bl __libnx_init
bl __appInit bl __appInit
bl __nx_libc_init_array bl __libc_init_array
ldp x29, x30, [sp], #16 ldp x29, x30, [sp], #16
ret ret
.global __nx_exit .global __nx_exit
.type __nx_exit, %function .type __nx_exit, %function
__nx_exit: __nx_exit:
bl __nx_libc_fini_array bl __libc_fini_array
bl __appExit bl __appExit
b __libnx_exit 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