diff --git a/include/zephyr/llext/llext.h b/include/zephyr/llext/llext.h index 60ce1cae47a..96bd64d2854 100644 --- a/include/zephyr/llext/llext.h +++ b/include/zephyr/llext/llext.h @@ -142,6 +142,15 @@ int llext_call_fn(struct llext *ext, const char *sym_name); */ void arch_elf_relocate(elf_rela_t *rel, uintptr_t opaddr, uintptr_t opval); +/** + * @brief Find an ELF section + * + * @param loader Extension loader data and context + * @param search_name Section name to search for + * @retval Section offset or a negative error code + */ +ssize_t llext_find_section(struct llext_loader *loader, const char *search_name); + /** * @brief Architecture specific function for updating addresses via relocation table * diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 57e8fb2e828..6598652840b 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -47,6 +47,33 @@ sys_slist_t *llext_list(void) return &_llext_list; } +ssize_t llext_find_section(struct llext_loader *ldr, const char *search_name) +{ + elf_shdr_t *shdr; + unsigned int i; + size_t pos; + + for (i = 0, pos = ldr->hdr.e_shoff; + i < ldr->hdr.e_shnum; + i++, pos += ldr->hdr.e_shentsize) { + shdr = llext_peek(ldr, pos); + if (!shdr) { + /* The peek() method isn't supported */ + return -EOPNOTSUPP; + } + + const char *name = llext_peek(ldr, + ldr->sects[LLEXT_SECT_SHSTRTAB].sh_offset + + shdr->sh_name); + + if (!strcmp(name, search_name)) { + return shdr->sh_offset; + } + } + + return -ENOENT; +} + struct llext *llext_by_name(const char *name) { sys_slist_t *mlist = llext_list();