From e492ac797411010f3211083016f8d874432731a1 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 31 May 2026 17:25:53 +0100 Subject: [PATCH] ld: get_dynsym can now resolve references to global symbols --- sys/ld/elf.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/sys/ld/elf.c b/sys/ld/elf.c index 80f0394..6590a91 100644 --- a/sys/ld/elf.c +++ b/sys/ld/elf.c @@ -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; }