From 00b6ae5bbcac1e1d9986535d4522734cc3fc2740 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 13 Dec 2024 17:34:57 +0100 Subject: [PATCH] llext: xtensa: fix RELATIVE relocations With dynamically linked / shared ELF objects the displacement between file offsets and memory addresses can differ between sections. Therefore we cannot use .text for all such relocations and have to locate the respective section instead. Signed-off-by: Guennadi Liakhovetski --- arch/xtensa/core/elf.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/arch/xtensa/core/elf.c b/arch/xtensa/core/elf.c index 3a7a4947ffb..17337f4a7bc 100644 --- a/arch/xtensa/core/elf.c +++ b/arch/xtensa/core/elf.c @@ -42,9 +42,22 @@ static void xtensa_elf_relocate(struct llext_loader *ldr, struct llext *ext, case R_XTENSA_RELATIVE: ; /* Relocate a local symbol: Xtensa specific. Seems to only be used with PIC */ - uintptr_t text = (uintptr_t)ext->mem[LLEXT_MEM_TEXT]; + unsigned int sh_ndx; - *got_entry += text - addr; + for (sh_ndx = 0; sh_ndx < ext->sect_cnt; sh_ndx++) { + if (ext->sect_hdrs[sh_ndx].sh_addr <= *got_entry && + *got_entry < + ext->sect_hdrs[sh_ndx].sh_addr + ext->sect_hdrs[sh_ndx].sh_size) + break; + } + + if (sh_ndx == ext->sect_cnt) { + LOG_ERR("%#x not found in any of the sections", *got_entry); + return; + } + + *got_entry += (uintptr_t)llext_loaded_sect_ptr(ldr, ext, sh_ndx) - + ext->sect_hdrs[sh_ndx].sh_addr; break; case R_XTENSA_GLOB_DAT: case R_XTENSA_JMP_SLOT: