diff options
| author | Ada Christine <adachristine18@gmail.com> | 2022-03-15 16:29:24 +0000 |
|---|---|---|
| committer | Ada Christine <adachristine18@gmail.com> | 2022-03-15 16:29:24 +0000 |
| commit | ec4aee35de3446713c6754641cdad82adc011204 (patch) | |
| tree | fb40b7b153da4bbb47ec46b40144a18fbfbcf74b /kc/reloc_x86_64.c | |
| parent | 97fcd7d1fc4574753d91e6767a8d8a7653a7f7fe (diff) | |
infrastructure for dynamic symbol resolution
Diffstat (limited to 'kc/reloc_x86_64.c')
| -rw-r--r-- | kc/reloc_x86_64.c | 45 |
1 files changed, 9 insertions, 36 deletions
diff --git a/kc/reloc_x86_64.c b/kc/reloc_x86_64.c index c70027f..63dc6e7 100644 --- a/kc/reloc_x86_64.c +++ b/kc/reloc_x86_64.c @@ -1,13 +1,9 @@ #include <kc.h> -#include <elf/elf64.h> - -#include <stddef.h> - #define STARTCODE __attribute__((section(".text.start"))) STARTCODE -static void do_rela(Elf64_Rela *rela, void *base) +static void do_rela(void *base, Elf64_Rela *rela) { union { @@ -20,7 +16,11 @@ static void do_rela(Elf64_Rela *rela, void *base) switch (ELF64_R_TYPE(rela->r_info)) { - case R_AMD64_RELATIVE: + case R_X86_64_JUMP_SLOT: + fixup = (void *)(rela->r_offset + (uintptr_t)base); + fixup->word64 += (uintptr_t)base; + break; + case R_X86_64_RELATIVE: fixup = (void *)(rela->r_offset + (uintptr_t)base); fixup->word64 = (rela->r_addend + (uintptr_t)base); break; @@ -30,40 +30,13 @@ static void do_rela(Elf64_Rela *rela, void *base) } STARTCODE -void kc_reloc(Elf64_Dyn *dyn, void *base) +void kc_reloc(void *base, Elf64_Rela *entries, size_t size, size_t entsize) { - struct - { - Elf64_Rela *entries; - size_t *size; - size_t *entsize; - } - rela = {NULL, NULL, NULL}; - - // parse the dynamic segment - while (dyn && dyn++->d_tag != DT_NULL) - { - switch (dyn->d_tag) - { - case DT_RELA: - rela.entries = (Elf64_Rela *)(dyn->d_ptr + (uintptr_t)base); - break; - case DT_RELASZ: - rela.size = &dyn->d_val; - break; - case DT_RELAENT: - rela.entsize = &dyn->d_val; - break; - default: - break; - } - } - // perform the actual relocation - for (size_t i = 0; rela.entries && (i < *rela.size / *rela.entsize); i++) + for (size_t i = 0; entries && (i < size / entsize); i++) { - do_rela(&rela.entries[i], base); + do_rela(base, &entries[i]); } } |
