From 90e470470b9ed7a171340a0cb8ea332e6a01e480 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 27 Sep 2024 14:24:31 +0200 Subject: [PATCH] LLEXT: add support for detached sections Some LLEXT objects can include sections, that should not be merged with other sections of the same type. E.g. when such sections should be placed into locations, other than the default. Add support for such sections. Signed-off-by: Guennadi Liakhovetski --- include/zephyr/llext/llext.h | 6 ++++++ subsys/llext/llext_load.c | 20 +++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/include/zephyr/llext/llext.h b/include/zephyr/llext/llext.h index 9073776bf6cbb6c..36a33b769543267 100644 --- a/include/zephyr/llext/llext.h +++ b/include/zephyr/llext/llext.h @@ -135,6 +135,12 @@ struct llext_load_param { * the memory buffer, when calculating relocation targets. */ bool pre_located; + /** + * Extensions can implement custom ELF sections to be loaded in specific + * memory regions, detached from other sections of compatible types. + * This optional callback checks whether a section should be detached. + */ + bool (*section_detached)(const elf_shdr_t *); }; /** Default initializer for @ref llext_load_param */ diff --git a/subsys/llext/llext_load.c b/subsys/llext/llext_load.c index a1ce73fd44eacd4..adfbf31c60e0194 100644 --- a/subsys/llext/llext_load.c +++ b/subsys/llext/llext_load.c @@ -209,7 +209,8 @@ static int llext_find_tables(struct llext_loader *ldr) * Maps the ELF sections into regions according to their usage flags, * calculating ldr->sects and ldr->sect_map. */ -static int llext_map_sections(struct llext_loader *ldr, struct llext *ext) +static int llext_map_sections(struct llext_loader *ldr, struct llext *ext, + const struct llext_load_param *ldr_parm) { int i, j; const char *name; @@ -285,6 +286,15 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext) ldr->sect_map[i].mem_idx = mem_idx; elf_shdr_t *region = ldr->sects + mem_idx; + /* + * ELF objects can have sections for memory regions, detached from + * other sections of the same type. E.g. executable sections that will be + * placed in slower memory. Don't merge such sections into main regions + */ + if (ldr_parm && ldr_parm->section_detached && ldr_parm->section_detached(shdr)) { + continue; + } + if (region->sh_type == SHT_NULL) { /* First section of this type, copy all info to the * region descriptor. @@ -585,7 +595,11 @@ static int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext, } } - if (ldr_parm && ldr_parm->pre_located) { + const char *s_name = llext_string(ldr, ext, LLEXT_MEM_SHSTRTAB, + shdr->sh_name); + + if (ldr_parm && ldr_parm->pre_located && + (!ldr_parm->section_detached || !ldr_parm->section_detached(shdr))) { sym_tab->syms[j].addr = (uint8_t *)sym.st_value + (ldr->hdr.e_type == ET_REL ? section_addr : 0); } else { @@ -652,7 +666,7 @@ int do_llext_load(struct llext_loader *ldr, struct llext *ext, } LOG_DBG("Mapping ELF sections..."); - ret = llext_map_sections(ldr, ext); + ret = llext_map_sections(ldr, ext, ldr_parm); if (ret != 0) { LOG_ERR("Failed to map ELF sections, ret %d", ret); goto out;