diff options
Diffstat (limited to 'kjarna_runtime/dynamic_x86_64.c')
| -rw-r--r-- | kjarna_runtime/dynamic_x86_64.c | 72 |
1 files changed, 65 insertions, 7 deletions
diff --git a/kjarna_runtime/dynamic_x86_64.c b/kjarna_runtime/dynamic_x86_64.c index e49f13d..3d85582 100644 --- a/kjarna_runtime/dynamic_x86_64.c +++ b/kjarna_runtime/dynamic_x86_64.c @@ -59,23 +59,81 @@ void kc_dynamic_init(char *base, Elf64_Dyn *dyn) dso_info.pltgot[2] = (uintptr_t)_rtld_link; } - kc_reloc(dso_info.base, dso_info.reladyn.entries, dso_info.reladyn.size, dso_info.reladyn.entsize); - kc_reloc(dso_info.base, dso_info.jmprel.entries, dso_info.jmprel.size, dso_info.jmprel.entsize); + kc_dynamic_reloc(base, &dso_info.jmprel); + kc_dynamic_reloc(base, &dso_info.reladyn); } void *kc_dynamic_link(struct elf64_dso_info *dso, int index) { + struct kjarna_interface *ftab = entry_params->interface; + int symindex = ELF64_R_SYM(dso->jmprel.entries[index].r_info); int strindex = dso->dynsym.entries[symindex].st_name; const char *name = &dso->dynsym.strings[strindex]; - uintptr_t *fixup = (uintptr_t *)dso->base + dso->jmprel.entries[index].r_offset; + uintptr_t *fixup = (uintptr_t *)(dso->base + dso->jmprel.entries[index].r_offset); - if (strcmp(name, "write") == 0) + // TODO: generate a symbol table for kjarna interface + // TODO: implement symbol lookup (maybe hashed too) + if (strcmp(name, "open") == 0) + { + *fixup = (uintptr_t)*ftab->open; + } + else if (strcmp(name, "close") == 0) + { + *fixup = (uintptr_t)*ftab->close; + } + else if (strcmp(name, "read") == 0) + { + *fixup = (uintptr_t)*ftab->read; + } + else if (strcmp(name, "write") == 0) + { + *fixup = (uintptr_t)*ftab->write; + } + else if (strcmp(name, "lseek") == 0) { - *fixup = (uintptr_t)*entry_params->interface->write; - return fixup; + *fixup = (uintptr_t)*ftab->lseek; } + else if (strcmp(name, "mmap") == 0) + { + *fixup = (uintptr_t)*ftab->mmap; + } + else if (strcmp(name, "munmap") == 0) + { + *fixup = (uintptr_t)*ftab->munmap; + } + else + { + return nullptr; + } + + return fixup; +} + +static void do_rela(char *base, Elf64_Rela *rela) +{ + uintptr_t *fixup = (uintptr_t *)(base + rela->r_offset); + + switch (ELF64_R_TYPE(rela->r_info)) + { + case R_X86_64_JUMP_SLOT: + *fixup += (uintptr_t)base; + break; + case R_X86_64_RELATIVE: + *fixup = (uintptr_t)(rela->r_addend + base); + break; + default: + break; + } +} + +void kc_dynamic_reloc(char *base, struct elf64_relatab *rela) +{ + // perform the actual relocation - return nullptr; + for (size_t i = 0; rela->entries && (i < rela->size); i += rela->entsize) + { + do_rela(base, &rela->entries[i]); + } } |
