summaryrefslogtreecommitdiff
path: root/kjarna_runtime/dynamic_x86_64.c
diff options
context:
space:
mode:
authorAda Christine <adachristine18@gmail.com>2024-02-24 00:16:09 +0000
committerAda Christine <adachristine18@gmail.com>2024-02-24 00:16:09 +0000
commita8a62bdba61177342ae38274c8196bc7a7c46fa0 (patch)
tree7147b2807cdc96716dde96c0807693ddd366ebb9 /kjarna_runtime/dynamic_x86_64.c
parentaec58be40927ec0b2a0e6742396f880d52ce38b5 (diff)
kjarna runtime
Diffstat (limited to 'kjarna_runtime/dynamic_x86_64.c')
-rw-r--r--kjarna_runtime/dynamic_x86_64.c72
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]);
+ }
}