llext: fix read-only extension image

When using the LLEXT buffer loader we now avoid copying extensions
from storage to allocated memory by pointing directly into the stored
image. We then also perform linking and relocation in that memory,
which modifies its contents. However, this is impossible if that
storage is read-only. Add a Kconfig flag to distinguish between
writable and read-only storage types. Also use that flag to decide,
whether the extension image in test_llext_simple.c should be defined
as const or not.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
This commit is contained in:
Guennadi Liakhovetski 2023-11-23 16:50:20 +01:00 committed by Anas Nashif
commit dbea13a1c7
4 changed files with 14 additions and 2 deletions

View file

@ -27,6 +27,12 @@ config LLEXT_SHELL_MAX_SIZE
help help
When loading llext with shell it is stored in a temporary buffer of this size When loading llext with shell it is stored in a temporary buffer of this size
config LLEXT_STORAGE_WRITABLE
bool "llext storage is writable"
help
Select if LLEXT storage is writable, i.e. if extensions are stored in
RAM and can be modified in place
module = LLEXT module = LLEXT
module-str = llext module-str = llext
source "subsys/logging/Kconfig.template.log_config" source "subsys/logging/Kconfig.template.log_config"

View file

@ -303,7 +303,8 @@ static int llext_copy_section(struct llext_loader *ldr, struct llext *ext,
return 0; return 0;
} }
if (ldr->sects[sect_idx].sh_type != SHT_NOBITS) { if (ldr->sects[sect_idx].sh_type != SHT_NOBITS &&
IS_ENABLED(CONFIG_LLEXT_STORAGE_WRITABLE)) {
ext->mem[mem_idx] = llext_peek(ldr, ldr->sects[sect_idx].sh_offset); ext->mem[mem_idx] = llext_peek(ldr, ldr->sects[sect_idx].sh_offset);
if (ext->mem[mem_idx]) { if (ext->mem[mem_idx]) {
ext->mem_on_heap[mem_idx] = false; ext->mem_on_heap[mem_idx] = false;

View file

@ -10,7 +10,10 @@
#include <zephyr/llext/buf_loader.h> #include <zephyr/llext/buf_loader.h>
#if defined(CONFIG_ARM) /* ARMV7 */ || defined(CONFIG_XTENSA) #if defined(CONFIG_ARM) /* ARMV7 */ || defined(CONFIG_XTENSA)
const static uint8_t hello_world_elf[] __aligned(4) = { #ifndef CONFIG_LLEXT_STORAGE_WRITABLE
const
#endif
static uint8_t hello_world_elf[] __aligned(4) = {
#include "hello_world.inc" #include "hello_world.inc"
}; };
#endif #endif

View file

@ -11,6 +11,8 @@ tests:
- nuvoton_pfm_m487 # See #63167 - nuvoton_pfm_m487 # See #63167
llext.simple.xtensa: llext.simple.xtensa:
arch_allow: xtensa arch_allow: xtensa
extra_configs:
- CONFIG_LLEXT_STORAGE_WRITABLE=y
# Broken platforms # Broken platforms
platform_exclude: platform_exclude:
- qemu_xtensa_mmu # ELF sections are read-only, and without peek() .text copy isn't executable - qemu_xtensa_mmu # ELF sections are read-only, and without peek() .text copy isn't executable