llext: use llext_peek() for section pointers

Try to use llext_peek() for section pointers. If it's supported and
succeeds we don't need to allocate buffers.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
This commit is contained in:
Guennadi Liakhovetski 2023-10-25 17:05:38 +02:00 committed by Carles Cufí
parent ce4cdac3c0
commit 0bf08e5775
2 changed files with 27 additions and 9 deletions

View file

@ -12,6 +12,7 @@
#include <zephyr/llext/symbol.h>
#include <zephyr/llext/loader.h>
#include <sys/types.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
@ -52,6 +53,9 @@ struct llext {
/** Lookup table of llext memory regions */
void *mem[LLEXT_MEM_COUNT];
/** Memory allocated on heap */
bool mem_on_heap[LLEXT_MEM_COUNT];
/** Total size of the llext memory usage */
size_t mem_size;

View file

@ -255,6 +255,14 @@ static int llext_copy_section(struct llext_loader *ldr, struct llext *ext,
return 0;
}
if (ldr->sects[sect_idx].sh_type != SHT_NOBITS) {
ext->mem[mem_idx] = llext_peek(ldr, ldr->sects[sect_idx].sh_offset);
if (ext->mem[mem_idx]) {
ext->mem_on_heap[mem_idx] = false;
return 0;
}
}
ext->mem[mem_idx] = k_heap_aligned_alloc(&llext_heap, sizeof(uintptr_t),
ldr->sects[sect_idx].sh_size,
K_NO_WAIT);
@ -263,15 +271,21 @@ static int llext_copy_section(struct llext_loader *ldr, struct llext *ext,
}
ext->mem_size += ldr->sects[sect_idx].sh_size;
ret = llext_seek(ldr, ldr->sects[sect_idx].sh_offset);
if (ret != 0) {
goto err;
if (ldr->sects[sect_idx].sh_type == SHT_NOBITS) {
memset(ext->mem[mem_idx], 0, ldr->sects[sect_idx].sh_size);
} else {
ret = llext_seek(ldr, ldr->sects[sect_idx].sh_offset);
if (ret != 0) {
goto err;
}
ret = llext_read(ldr, ext->mem[mem_idx], ldr->sects[sect_idx].sh_size);
if (ret != 0) {
goto err;
}
}
ret = llext_read(ldr, ext->mem[mem_idx], ldr->sects[sect_idx].sh_size);
if (ret != 0) {
goto err;
}
ext->mem_on_heap[mem_idx] = true;
return 0;
@ -633,7 +647,7 @@ out:
if (ret != 0) {
LOG_DBG("Failed to load extension, freeing memory...");
for (enum llext_mem mem_idx = 0; mem_idx < LLEXT_MEM_COUNT; mem_idx++) {
if (ext->mem[mem_idx] != NULL) {
if (ext->mem_on_heap[mem_idx]) {
k_heap_free(&llext_heap, ext->mem[mem_idx]);
}
}
@ -714,7 +728,7 @@ void llext_unload(struct llext *ext)
sys_slist_find_and_remove(&_llext_list, &ext->_llext_list);
for (int i = 0; i < LLEXT_MEM_COUNT; i++) {
if (ext->mem[i] != NULL) {
if (ext->mem_on_heap[i]) {
LOG_DBG("freeing memory region %d", i);
k_heap_free(&llext_heap, ext->mem[i]);
ext->mem[i] = NULL;