llext: Fix a bug in section linking

When relocating section symbol addresses the value where the
relocation is to be written is an offset into the section to load.

Simply rewriting it with the section address is not enough, we need
to write the address of the section with the offset into it.

Signed-off-by: Tom Burdick <thomas.burdick@intel.com>
This commit is contained in:
Tom Burdick 2023-10-04 11:33:16 -05:00 committed by Fabio Baltieri
commit c678f25bc1
3 changed files with 79 additions and 48 deletions

View file

@ -508,6 +508,8 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext)
uintptr_t link_addr, op_loc, op_code;
op_loc = loc + rel.r_offset;
/* If symbol is undefined, then we need to look it up */
if (sym.st_shndx == SHN_UNDEF) {
link_addr = (uintptr_t)llext_find_sym(NULL, name);
@ -525,7 +527,10 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext)
name, link_addr, op_code);
}
} else if (ELF_ST_TYPE(sym.st_info) == STT_SECTION) {
link_addr = (uintptr_t)ext->mem[ldr->sect_map[sym.st_shndx]];
/* Current relocation location holds an offset into the section */
link_addr = (uintptr_t)ext->mem[ldr->sect_map[sym.st_shndx]]
+ sym.st_value
+ *((uintptr_t *)op_loc);
LOG_INF("found section symbol %s addr 0x%lx", name, link_addr);
} else {
@ -533,8 +538,6 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext)
continue;
}
op_loc = loc + rel.r_offset;
LOG_INF("relocating (linking) symbol %s type %d binding %d ndx %d offset "
"%d link section %d",
name, ELF_ST_TYPE(sym.st_info), ELF_ST_BIND(sym.st_info),