Skip to content

Commit

Permalink
LLEXT: add support for detached sections
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
lyakh authored and henrikbrixandersen committed Sep 29, 2024
1 parent 0aa6b1c commit c6bf743
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 3 deletions.
6 changes: 6 additions & 0 deletions include/zephyr/llext/llext.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *shdr);
};

/** Default initializer for @ref llext_load_param */
Expand Down
17 changes: 14 additions & 3 deletions subsys/llext/llext_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,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;
Expand Down Expand Up @@ -286,6 +287,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->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.
Expand Down Expand Up @@ -586,7 +596,8 @@ static int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext,
}
}

if (ldr_parm->pre_located) {
if (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 {
Expand Down Expand Up @@ -658,7 +669,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;
Expand Down

0 comments on commit c6bf743

Please sign in to comment.