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 committed Sep 27, 2024
1 parent 00e3101 commit 799a5b3
Show file tree
Hide file tree
Showing 2 changed files with 23 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 *);

Check warning on line 143 in include/zephyr/llext/llext.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

FUNCTION_ARGUMENTS

include/zephyr/llext/llext.h:143 function definition argument 'const elf_shdr_t *' should also have an identifier name
};

/** Default initializer for @ref llext_load_param */
Expand Down
20 changes: 17 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,11 @@ static int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext,
}
}

if (ldr_parm->pre_located) {
const char *s_name = llext_string(ldr, ext, LLEXT_MEM_SHSTRTAB,
shdr->sh_name);

Check notice on line 601 in subsys/llext/llext_load.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/llext/llext_load.c:601 - const char *s_name = llext_string(ldr, ext, LLEXT_MEM_SHSTRTAB, - shdr->sh_name); + const char *s_name = + llext_string(ldr, ext, LLEXT_MEM_SHSTRTAB, shdr->sh_name);
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 +672,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 799a5b3

Please sign in to comment.