Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion include/zephyr/llext/llext.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,10 @@ struct llext_load_param {
bool relocate_local;
/**
* Use the virtual symbol addresses from the ELF, not addresses within
* the memory buffer, when calculating relocation targets.
* the memory buffer, when calculating relocation targets. It also
* means, that the application will take care to place the extension at
* those pre-defined addresses, so the LLEXT core doesn't have to do any
* allocation and copying internally.
*/
bool pre_located;
/**
Expand Down
2 changes: 1 addition & 1 deletion subsys/llext/llext_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ int do_llext_load(struct llext_loader *ldr, struct llext *ext,
}

LOG_DBG("Allocate and copy regions...");
ret = llext_copy_regions(ldr, ext);
ret = llext_copy_regions(ldr, ext, ldr_parm);
if (ret != 0) {
LOG_ERR("Failed to copy regions, ret %d", ret);
goto out;
Expand Down
38 changes: 26 additions & 12 deletions subsys/llext/llext_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@
}

static int llext_copy_section(struct llext_loader *ldr, struct llext *ext,
enum llext_mem mem_idx)
enum llext_mem mem_idx, const struct llext_load_param *ldr_parm)
{

Check notice on line 63 in subsys/llext/llext_mem.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_mem.c:63 -static int llext_copy_section(struct llext_loader *ldr, struct llext *ext, - enum llext_mem mem_idx, const struct llext_load_param *ldr_parm) +static int llext_copy_section(struct llext_loader *ldr, struct llext *ext, enum llext_mem mem_idx, + const struct llext_load_param *ldr_parm)
int ret;

if (!ldr->sects[mem_idx].sh_size) {
Expand All @@ -68,18 +68,31 @@
}
ext->mem_size[mem_idx] = ldr->sects[mem_idx].sh_size;

if (ldr->sects[mem_idx].sh_type != SHT_NOBITS &&
IS_ENABLED(CONFIG_LLEXT_STORAGE_WRITABLE)) {
/* Directly use data from the ELF buffer if peek() is supported */
ext->mem[mem_idx] = llext_peek(ldr, ldr->sects[mem_idx].sh_offset);
if (ext->mem[mem_idx]) {
llext_init_mem_part(ext, mem_idx, (uintptr_t)ext->mem[mem_idx],
ldr->sects[mem_idx].sh_size);
if (IS_ENABLED(CONFIG_LLEXT_STORAGE_WRITABLE)) {
if (ldr->sects[mem_idx].sh_type != SHT_NOBITS) {
/* Directly use data from the ELF buffer if peek() is supported */
ext->mem[mem_idx] = llext_peek(ldr, ldr->sects[mem_idx].sh_offset);
if (ext->mem[mem_idx]) {
llext_init_mem_part(ext, mem_idx, (uintptr_t)ext->mem[mem_idx],
ldr->sects[mem_idx].sh_size);
ext->mem_on_heap[mem_idx] = false;
return 0;
}
} else if (ldr_parm && ldr_parm->pre_located) {
/*
* ldr_parm cannot be NULL here with the current flow, but
* we add a check to make it future-proof
*/
ext->mem[mem_idx] = NULL;
ext->mem_on_heap[mem_idx] = false;
return 0;
}
}

if (ldr_parm && ldr_parm->pre_located) {
return -EFAULT;
}

/* On ARM with an MPU a pow(2, N)*32 sized and aligned region is needed,
* otherwise its typically an mmu page (sized and aligned memory region)
* we are after that we can assign memory permission bits on.
Expand Down Expand Up @@ -132,24 +145,25 @@

int llext_copy_strings(struct llext_loader *ldr, struct llext *ext)
{
int ret = llext_copy_section(ldr, ext, LLEXT_MEM_SHSTRTAB);
int ret = llext_copy_section(ldr, ext, LLEXT_MEM_SHSTRTAB, NULL);

if (!ret) {
ret = llext_copy_section(ldr, ext, LLEXT_MEM_STRTAB);
ret = llext_copy_section(ldr, ext, LLEXT_MEM_STRTAB, NULL);
}

return ret;
}

int llext_copy_regions(struct llext_loader *ldr, struct llext *ext)
int llext_copy_regions(struct llext_loader *ldr, struct llext *ext,
const struct llext_load_param *ldr_parm)
{
for (enum llext_mem mem_idx = 0; mem_idx < LLEXT_MEM_COUNT; mem_idx++) {
/* strings have already been copied */
if (ext->mem[mem_idx]) {
continue;
}

int ret = llext_copy_section(ldr, ext, mem_idx);
int ret = llext_copy_section(ldr, ext, mem_idx, ldr_parm);

if (ret < 0) {
return ret;
Expand Down
3 changes: 2 additions & 1 deletion subsys/llext/llext_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ struct llext_elf_sect_map {
*/

int llext_copy_strings(struct llext_loader *ldr, struct llext *ext);
int llext_copy_regions(struct llext_loader *ldr, struct llext *ext);
int llext_copy_regions(struct llext_loader *ldr, struct llext *ext,
const struct llext_load_param *ldr_parm);
void llext_free_regions(struct llext *ext);
void llext_adjust_mmu_permissions(struct llext *ext);

Expand Down
Loading