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:
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

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,15 +1,12 @@
.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
@ -17,83 +14,6 @@ initSystem:
.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