llext: fix a confusion between section indices

A common pattern is used throughout llext.c:

ext->mem[ldr->sect_map[sym.st_shndx]]

where ldr->sect_map[sym.st_shndx] actually contains indices from
enum llext_section but ext->mem[] is indexed, using enum llext_mem
values. Fix this by changing ldr->sect_map[] to actually contain
enum llext_mem values.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
This commit is contained in:
Guennadi Liakhovetski 2023-11-14 12:51:27 +01:00 committed by Carles Cufí
commit 21cea07b8c
3 changed files with 21 additions and 9 deletions

View file

@ -33,6 +33,7 @@ enum llext_mem {
LLEXT_MEM_DATA, LLEXT_MEM_DATA,
LLEXT_MEM_RODATA, LLEXT_MEM_RODATA,
LLEXT_MEM_BSS, LLEXT_MEM_BSS,
LLEXT_MEM_SYMTAB,
LLEXT_MEM_STRTAB, LLEXT_MEM_STRTAB,
LLEXT_MEM_SHSTRTAB, LLEXT_MEM_SHSTRTAB,

View file

@ -42,6 +42,8 @@ enum llext_section {
LLEXT_SECT_COUNT, LLEXT_SECT_COUNT,
}; };
enum llext_mem;
/** /**
* @brief Linkable loadable extension loader context * @brief Linkable loadable extension loader context
*/ */
@ -90,7 +92,7 @@ struct llext_loader {
/** @cond ignore */ /** @cond ignore */
elf_ehdr_t hdr; elf_ehdr_t hdr;
elf_shdr_t sects[LLEXT_SECT_COUNT]; elf_shdr_t sects[LLEXT_SECT_COUNT];
uint32_t *sect_map; enum llext_mem *sect_map;
uint32_t sect_cnt; uint32_t sect_cnt;
/** @endcond */ /** @endcond */
}; };

View file

@ -128,18 +128,18 @@ static int llext_find_tables(struct llext_loader *ldr)
case SHT_DYNSYM: case SHT_DYNSYM:
LOG_DBG("symtab at %d", i); LOG_DBG("symtab at %d", i);
ldr->sects[LLEXT_SECT_SYMTAB] = shdr; ldr->sects[LLEXT_SECT_SYMTAB] = shdr;
ldr->sect_map[i] = LLEXT_SECT_SYMTAB; ldr->sect_map[i] = LLEXT_MEM_SYMTAB;
sect_cnt++; sect_cnt++;
break; break;
case SHT_STRTAB: case SHT_STRTAB:
if (ldr->hdr.e_shstrndx == i) { if (ldr->hdr.e_shstrndx == i) {
LOG_DBG("shstrtab at %d", i); LOG_DBG("shstrtab at %d", i);
ldr->sects[LLEXT_SECT_SHSTRTAB] = shdr; ldr->sects[LLEXT_SECT_SHSTRTAB] = shdr;
ldr->sect_map[i] = LLEXT_SECT_SHSTRTAB; ldr->sect_map[i] = LLEXT_MEM_SHSTRTAB;
} else { } else {
LOG_DBG("strtab at %d", i); LOG_DBG("strtab at %d", i);
ldr->sects[LLEXT_SECT_STRTAB] = shdr; ldr->sects[LLEXT_SECT_STRTAB] = shdr;
ldr->sect_map[i] = LLEXT_SECT_STRTAB; ldr->sect_map[i] = LLEXT_MEM_STRTAB;
} }
sect_cnt++; sect_cnt++;
break; break;
@ -192,22 +192,27 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext)
LOG_DBG("section %d name %s", i, name); LOG_DBG("section %d name %s", i, name);
enum llext_section sect_idx; enum llext_section sect_idx;
enum llext_mem mem_idx;
if (strcmp(name, ".text") == 0) { if (strcmp(name, ".text") == 0) {
sect_idx = LLEXT_SECT_TEXT; sect_idx = LLEXT_SECT_TEXT;
mem_idx = LLEXT_MEM_TEXT;
} else if (strcmp(name, ".data") == 0) { } else if (strcmp(name, ".data") == 0) {
sect_idx = LLEXT_SECT_DATA; sect_idx = LLEXT_SECT_DATA;
mem_idx = LLEXT_MEM_DATA;
} else if (strcmp(name, ".rodata") == 0) { } else if (strcmp(name, ".rodata") == 0) {
sect_idx = LLEXT_SECT_RODATA; sect_idx = LLEXT_SECT_RODATA;
mem_idx = LLEXT_MEM_RODATA;
} else if (strcmp(name, ".bss") == 0) { } else if (strcmp(name, ".bss") == 0) {
sect_idx = LLEXT_SECT_BSS; sect_idx = LLEXT_SECT_BSS;
mem_idx = LLEXT_MEM_BSS;
} else { } else {
LOG_DBG("Not copied section %s", name); LOG_DBG("Not copied section %s", name);
continue; continue;
} }
ldr->sects[sect_idx] = shdr; ldr->sects[sect_idx] = shdr;
ldr->sect_map[i] = sect_idx; ldr->sect_map[i] = mem_idx;
} }
return 0; return 0;
@ -230,6 +235,9 @@ static enum llext_section llext_sect_from_mem(enum llext_mem m)
case LLEXT_MEM_TEXT: case LLEXT_MEM_TEXT:
s = LLEXT_SECT_TEXT; s = LLEXT_SECT_TEXT;
break; break;
case LLEXT_MEM_SYMTAB:
s = LLEXT_SECT_SYMTAB;
break;
case LLEXT_MEM_STRTAB: case LLEXT_MEM_STRTAB:
s = LLEXT_SECT_STRTAB; s = LLEXT_SECT_STRTAB;
break; break;
@ -415,16 +423,17 @@ static int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext)
uint32_t stt = ELF_ST_TYPE(sym.st_info); uint32_t stt = ELF_ST_TYPE(sym.st_info);
uint32_t stb = ELF_ST_BIND(sym.st_info); uint32_t stb = ELF_ST_BIND(sym.st_info);
uint32_t sect = sym.st_shndx; unsigned int sect = sym.st_shndx;
if (stt == STT_FUNC && stb == STB_GLOBAL && sect != SHN_UNDEF) { if (stt == STT_FUNC && stb == STB_GLOBAL && sect != SHN_UNDEF) {
enum llext_mem mem = ldr->sect_map[sect];
enum llext_section sect_idx = llext_sect_from_mem(mem);
const char *name = llext_string(ldr, ext, LLEXT_MEM_STRTAB, sym.st_name); const char *name = llext_string(ldr, ext, LLEXT_MEM_STRTAB, sym.st_name);
__ASSERT(j <= sym_tab->sym_cnt, "Miscalculated symbol number %u\n", j); __ASSERT(j <= sym_tab->sym_cnt, "Miscalculated symbol number %u\n", j);
sym_tab->syms[j].name = name; sym_tab->syms[j].name = name;
sym_tab->syms[j].addr = sym_tab->syms[j].addr = (void *)((uintptr_t)ext->mem[mem]
(void *)((uintptr_t)ext->mem[ldr->sect_map[sym.st_shndx]]
+ sym.st_value); + sym.st_value);
LOG_DBG("function symbol %d name %s addr %p", LOG_DBG("function symbol %d name %s addr %p",
j, name, sym_tab->syms[j].addr); j, name, sym_tab->syms[j].addr);