Skip to content

Commit daaf575

Browse files
committed
LLEXT: fix a needless allocation
When CONFIG_LLEXT_STORAGE_WRITABLE is selected and .pre_located is set, the BSS section is allocated by the user too, no need to allocate it internally. Signed-off-by: Guennadi Liakhovetski <[email protected]>
1 parent 5249619 commit daaf575

File tree

4 files changed

+33
-15
lines changed

4 files changed

+33
-15
lines changed

include/zephyr/llext/llext.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,10 @@ struct llext_load_param {
132132
bool relocate_local;
133133
/**
134134
* Use the virtual symbol addresses from the ELF, not addresses within
135-
* the memory buffer, when calculating relocation targets.
135+
* the memory buffer, when calculating relocation targets. It also
136+
* means, that the application will take care to place the extension at
137+
* those pre-defined addresses, so the LLEXT core doesn't have to do any
138+
* allocation and copying internally.
136139
*/
137140
bool pre_located;
138141
/**

subsys/llext/llext_load.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ int do_llext_load(struct llext_loader *ldr, struct llext *ext,
684684
}
685685

686686
LOG_DBG("Allocate and copy regions...");
687-
ret = llext_copy_regions(ldr, ext);
687+
ret = llext_copy_regions(ldr, ext, ldr_parm);
688688
if (ret != 0) {
689689
LOG_ERR("Failed to copy regions, ret %d", ret);
690690
goto out;

subsys/llext/llext_mem.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ static void llext_init_mem_part(struct llext *ext, enum llext_mem mem_idx,
5959
}
6060

6161
static int llext_copy_section(struct llext_loader *ldr, struct llext *ext,
62-
enum llext_mem mem_idx)
62+
enum llext_mem mem_idx, const struct llext_load_param *ldr_parm)
6363
{
6464
int ret;
6565

@@ -68,18 +68,31 @@ static int llext_copy_section(struct llext_loader *ldr, struct llext *ext,
6868
}
6969
ext->mem_size[mem_idx] = ldr->sects[mem_idx].sh_size;
7070

71-
if (ldr->sects[mem_idx].sh_type != SHT_NOBITS &&
72-
IS_ENABLED(CONFIG_LLEXT_STORAGE_WRITABLE)) {
73-
/* Directly use data from the ELF buffer if peek() is supported */
74-
ext->mem[mem_idx] = llext_peek(ldr, ldr->sects[mem_idx].sh_offset);
75-
if (ext->mem[mem_idx]) {
76-
llext_init_mem_part(ext, mem_idx, (uintptr_t)ext->mem[mem_idx],
77-
ldr->sects[mem_idx].sh_size);
71+
if (IS_ENABLED(CONFIG_LLEXT_STORAGE_WRITABLE)) {
72+
if (ldr->sects[mem_idx].sh_type != SHT_NOBITS) {
73+
/* Directly use data from the ELF buffer if peek() is supported */
74+
ext->mem[mem_idx] = llext_peek(ldr, ldr->sects[mem_idx].sh_offset);
75+
if (ext->mem[mem_idx]) {
76+
llext_init_mem_part(ext, mem_idx, (uintptr_t)ext->mem[mem_idx],
77+
ldr->sects[mem_idx].sh_size);
78+
ext->mem_on_heap[mem_idx] = false;
79+
return 0;
80+
}
81+
} else if (ldr_parm && ldr_parm->pre_located) {
82+
/*
83+
* ldr_parm cannot be NULL here with the current flow, but
84+
* we add a check to make it future-proof
85+
*/
86+
ext->mem[mem_idx] = NULL;
7887
ext->mem_on_heap[mem_idx] = false;
7988
return 0;
8089
}
8190
}
8291

92+
if (ldr_parm && ldr_parm->pre_located) {
93+
return -EFAULT;
94+
}
95+
8396
/* On ARM with an MPU a pow(2, N)*32 sized and aligned region is needed,
8497
* otherwise its typically an mmu page (sized and aligned memory region)
8598
* we are after that we can assign memory permission bits on.
@@ -132,24 +145,25 @@ static int llext_copy_section(struct llext_loader *ldr, struct llext *ext,
132145

133146
int llext_copy_strings(struct llext_loader *ldr, struct llext *ext)
134147
{
135-
int ret = llext_copy_section(ldr, ext, LLEXT_MEM_SHSTRTAB);
148+
int ret = llext_copy_section(ldr, ext, LLEXT_MEM_SHSTRTAB, NULL);
136149

137150
if (!ret) {
138-
ret = llext_copy_section(ldr, ext, LLEXT_MEM_STRTAB);
151+
ret = llext_copy_section(ldr, ext, LLEXT_MEM_STRTAB, NULL);
139152
}
140153

141154
return ret;
142155
}
143156

144-
int llext_copy_regions(struct llext_loader *ldr, struct llext *ext)
157+
int llext_copy_regions(struct llext_loader *ldr, struct llext *ext,
158+
const struct llext_load_param *ldr_parm)
145159
{
146160
for (enum llext_mem mem_idx = 0; mem_idx < LLEXT_MEM_COUNT; mem_idx++) {
147161
/* strings have already been copied */
148162
if (ext->mem[mem_idx]) {
149163
continue;
150164
}
151165

152-
int ret = llext_copy_section(ldr, ext, mem_idx);
166+
int ret = llext_copy_section(ldr, ext, mem_idx, ldr_parm);
153167

154168
if (ret < 0) {
155169
return ret;

subsys/llext/llext_priv.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ struct llext_elf_sect_map {
2020
*/
2121

2222
int llext_copy_strings(struct llext_loader *ldr, struct llext *ext);
23-
int llext_copy_regions(struct llext_loader *ldr, struct llext *ext);
23+
int llext_copy_regions(struct llext_loader *ldr, struct llext *ext,
24+
const struct llext_load_param *ldr_parm);
2425
void llext_free_regions(struct llext *ext);
2526
void llext_adjust_mmu_permissions(struct llext *ext);
2627

0 commit comments

Comments
 (0)