ld: resolve: fix incorrect symbol and GOT index calculation
This commit is contained in:
@@ -6,17 +6,42 @@
|
|||||||
|
|
||||||
uintptr_t dl_runtime_resolve(struct elf_image *img, unsigned long sym_id)
|
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 *sym
|
||||||
= (elf_sym_t *)((virt_addr_t)img->e_base + img->e_dynsym);
|
= (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
|
const char *sym_name = (const char *)img->e_base + img->e_strtab
|
||||||
+ sym[sym_id + 1].st_name;
|
+ sym[sym_id].st_name;
|
||||||
// kern_logf("%s: request for symbol %s", img->e_leaf.l_name, sym_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_addr = elf_image_find_linked_symbol(img, sym_name);
|
||||||
virt_addr_t *sym_slot
|
kern_tracef("symbol %s = %zx", sym_name, sym_addr);
|
||||||
= (virt_addr_t *)((virt_addr_t)img->e_base + img->e_got_plt
|
kern_tracef("slot %s = %zx", sym_name, &got[slot_id]);
|
||||||
+ ((sym_id + 3) * sizeof(virt_addr_t)));
|
got[slot_id] = sym_addr;
|
||||||
// kern_logf("symbol %s = %zx", sym_name, sym_addr);
|
|
||||||
// kern_logf("slot %s = %zx", sym_name, sym_slot);
|
|
||||||
*sym_slot = sym_addr;
|
|
||||||
return sym_addr;
|
return sym_addr;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user