ld: get_dynsym can now resolve references to global symbols

This commit is contained in:
2026-05-31 17:25:53 +01:00
parent 9af325cdee
commit e492ac7974
+23 -11
View File
@@ -261,16 +261,24 @@ static int parse_phdr(struct elf_image *image)
}
#if 1
static elf_sym_t *get_dynsym(struct elf_image *image, size_t index)
static virt_addr_t get_dynsym(struct elf_image *image, size_t index)
{
elf_sym_t *sym = (elf_sym_t *)(image->e_base + image->e_dynsym
+ (index * image->e_dynsym_entsize));
const char *sym_name = (const char *)(image->e_base + image->e_strtab
+ sym->st_name);
if (!sym->st_value) {
return NULL;
if (sym->st_value) {
return image->e_base + sym->st_value;
}
return sym;
virt_addr_t sym_addr = find_global_symbol(sym_name);
if (sym_addr) {
return sym_addr;
}
kern_tracef("cannot resolve symbol %s", sym_name);
return 0;
}
static void resolve_symbol(unsigned int slot)
@@ -289,7 +297,7 @@ static int do_rela(struct elf_image *image, elf_rela_t *rela, bool lazy)
rela->r_offset);
#endif
int type = ELF64_R_TYPE(rela->r_info);
elf_sym_t *sym = NULL;
virt_addr_t v = 0;
switch (type) {
case R_X86_64_JUMP_SLOT:
@@ -303,13 +311,13 @@ static int do_rela(struct elf_image *image, elf_rela_t *rela, bool lazy)
#endif
break;
case R_X86_64_GLOB_DAT:
sym = get_dynsym(image, ELF64_R_SYM(rela->r_info));
if (!sym) {
v = get_dynsym(image, ELF64_R_SYM(rela->r_info));
if (!v) {
return ENOEXEC;
}
*(uint64_t *)(image->e_base + rela->r_offset)
= image->e_base + sym->st_value + rela->r_addend;
= v + rela->r_addend;
#if 0
kern_tracef(
"GLOB_DAT: offset=%zx, symbol=%zu, addend=%zx",
@@ -319,13 +327,13 @@ static int do_rela(struct elf_image *image, elf_rela_t *rela, bool lazy)
#endif
break;
case R_X86_64_64:
sym = get_dynsym(image, ELF64_R_SYM(rela->r_info));
if (!sym) {
v = get_dynsym(image, ELF64_R_SYM(rela->r_info));
if (!v) {
return ENOEXEC;
}
*(uint64_t *)(image->e_base + rela->r_offset)
= image->e_base + sym->st_value + rela->r_addend;
= v + rela->r_addend;
#if 0
kern_tracef(
"64: offset=%zx, symbol=%zu, addend=%zx",
@@ -404,6 +412,7 @@ static int relocate_rel(
size_t size,
size_t entsize)
{
kern_tracef("relocate_rel (unsupported)");
return ENOEXEC;
}
@@ -624,16 +633,19 @@ int elf_image_load(struct elf_image *img)
int e = reserve_exec_region(img);
if (e != SUCCESS) {
kern_log("error 1");
return e;
}
e = map_image(img);
if (e != SUCCESS) {
kern_log("error 2");
return e;
}
e = elf_image_parse_dynamic(img);
if (e != SUCCESS) {
kern_log("error 3");
return e;
}