diff --git a/sys/ld/resolve.c b/sys/ld/resolve.c index 6949108..c106ee3 100644 --- a/sys/ld/resolve.c +++ b/sys/ld/resolve.c @@ -6,17 +6,42 @@ uintptr_t dl_runtime_resolve(struct elf_image *img, unsigned long sym_id) { + unsigned long slot_id = sym_id; + switch (img->e_rel_entsize[ELF_RT_PLTREL]) { + case sizeof(elf_rela_t): { + elf_rela_t *rela + = (elf_rela_t *)((virt_addr_t)img->e_base + + img->e_rel_offset[ELF_RT_PLTREL]); + elf_rela_t *rela_sym = &rela[sym_id]; + kern_tracef( + "rela %u -> .dynsym %u, .got %u", + sym_id, + ELF64_R_SYM(rela_sym->r_info), + slot_id); + sym_id = ELF64_R_SYM(rela_sym->r_info); + /* the first three entries in the GOT are not symbols. */ + slot_id += 3; + break; + } + + default: + return 0; + } + elf_sym_t *sym = (elf_sym_t *)((virt_addr_t)img->e_base + img->e_dynsym); + virt_addr_t *got + = (virt_addr_t *)((virt_addr_t)img->e_base + img->e_got_plt); const char *sym_name = (const char *)img->e_base + img->e_strtab - + sym[sym_id + 1].st_name; - // kern_logf("%s: request for symbol %s", img->e_leaf.l_name, sym_name); + + sym[sym_id].st_name; + kern_tracef( + "%s: request for symbol %u: %s", + img->e_leaf.l_name, + sym_id, + sym_name); virt_addr_t sym_addr = elf_image_find_linked_symbol(img, sym_name); - virt_addr_t *sym_slot - = (virt_addr_t *)((virt_addr_t)img->e_base + img->e_got_plt - + ((sym_id + 3) * sizeof(virt_addr_t))); - // kern_logf("symbol %s = %zx", sym_name, sym_addr); - // kern_logf("slot %s = %zx", sym_name, sym_slot); - *sym_slot = sym_addr; + kern_tracef("symbol %s = %zx", sym_name, sym_addr); + kern_tracef("slot %s = %zx", sym_name, &got[slot_id]); + got[slot_id] = sym_addr; return sym_addr; }