Skip to content

Commit 0f09d94

Browse files
committed
llext_manager: convert to use new LLEXT inspection API
This patch converts the llext_manager to use the new LLEXT inspection API. The new API allows to get information about sections and regions without the need to access the internal structures of the LLEXT loader, decoupling SOF and LLEXT code and making it easier to maintain. Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
1 parent 77fc666 commit 0f09d94

File tree

1 file changed

+50
-39
lines changed

1 file changed

+50
-39
lines changed

src/library_manager/llext_manager.c

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <zephyr/llext/buf_loader.h>
2929
#include <zephyr/llext/loader.h>
3030
#include <zephyr/llext/llext.h>
31+
#include <zephyr/llext/inspect.h>
3132

3233
#include <rimage/sof/user/manifest.h>
3334
#include <module/module/api_ver.h>
@@ -69,37 +70,37 @@ static int llext_manager_align_unmap(void __sparse_cache *vma, size_t size)
6970
return sys_mm_drv_unmap_region(aligned_vma, ALIGN_UP(pre_pad_size + size, PAGE_SZ));
7071
}
7172

72-
static int llext_manager_load_data_from_storage(const struct llext *ext,
73+
static int llext_manager_load_data_from_storage(const struct llext_loader *ldr,
74+
const struct llext *ext,
75+
enum llext_mem region,
7376
void __sparse_cache *vma,
74-
const uint8_t *load_base,
7577
size_t size, uint32_t flags)
7678
{
7779
unsigned int i;
80+
const void *region_addr;
7881
int ret;
79-
const elf_shdr_t *shdr;
8082

8183
ret = llext_manager_align_map(vma, size, SYS_MM_MEM_PERM_RW);
8284
if (ret < 0) {
8385
tr_err(&lib_manager_tr, "cannot map %u of %p", size, (__sparse_force void *)vma);
8486
return ret;
8587
}
8688

87-
size_t init_offset = 0;
89+
llext_get_region_info(ldr, ext, region, NULL, &region_addr, NULL);
8890

8991
/* Need to copy sections within regions individually, offsets may differ */
90-
for (i = 0, shdr = llext_section_headers(ext); i < llext_section_count(ext); i++, shdr++) {
91-
if ((uintptr_t)shdr->sh_addr < (uintptr_t)vma ||
92-
(uintptr_t)shdr->sh_addr >= (uintptr_t)vma + size)
93-
continue;
92+
for (i = 0; i < llext_section_count(ext); i++) {
93+
const elf_shdr_t *shdr;
94+
enum llext_mem s_region = LLEXT_MEM_COUNT;
95+
size_t s_offset = 0;
9496

95-
if (!init_offset)
96-
init_offset = shdr->sh_offset;
97+
llext_get_section_info(ldr, ext, i, &shdr, &s_region, &s_offset);
9798

98-
/* found a section within the region */
99-
size_t offset = shdr->sh_offset - init_offset;
99+
if (s_region != region)
100+
continue;
100101

101-
ret = memcpy_s((__sparse_force void *)shdr->sh_addr, size - offset,
102-
load_base + offset, shdr->sh_size);
102+
ret = memcpy_s((__sparse_force void *)shdr->sh_addr, size - s_offset,
103+
(const uint8_t *)region_addr + s_offset, shdr->sh_size);
103104
if (ret < 0)
104105
return ret;
105106
}
@@ -120,6 +121,10 @@ static int llext_manager_load_data_from_storage(const struct llext *ext,
120121
static int llext_manager_load_module(const struct llext *ext, const struct llext_loader *ldr,
121122
const struct lib_manager_module *mctx)
122123
{
124+
const elf_shdr_t *bss_hdr;
125+
126+
llext_get_region_info(ldr, ext, LLEXT_MEM_BSS, &bss_hdr, NULL, NULL);
127+
123128
/* Executable code (.text) */
124129
void __sparse_cache *va_base_text = (void __sparse_cache *)
125130
mctx->segment[LIB_MANAGER_TEXT].addr;
@@ -137,8 +142,8 @@ static int llext_manager_load_module(const struct llext *ext, const struct llext
137142

138143
/* .bss, should be within writable data above */
139144
void __sparse_cache *bss_addr = (void __sparse_cache *)
140-
ldr->sects[LLEXT_MEM_BSS].sh_addr;
141-
size_t bss_size = ldr->sects[LLEXT_MEM_BSS].sh_size;
145+
bss_hdr->sh_addr;
146+
size_t bss_size = bss_hdr->sh_size;
142147
int ret;
143148

144149
/* Check, that .bss is within .data */
@@ -151,7 +156,7 @@ static int llext_manager_load_module(const struct llext *ext, const struct llext
151156
va_base_data = bss_addr;
152157
data_size += bss_size;
153158
} else if ((uintptr_t)bss_addr == (uintptr_t)va_base_data +
154-
ALIGN_UP(data_size, ldr->sects[LLEXT_MEM_BSS].sh_addralign)) {
159+
ALIGN_UP(data_size, bss_hdr->sh_addralign)) {
155160
/* .bss directly behind writable data, append */
156161
data_size += bss_size;
157162
} else {
@@ -163,20 +168,20 @@ static int llext_manager_load_module(const struct llext *ext, const struct llext
163168
}
164169

165170
/* Copy Code */
166-
ret = llext_manager_load_data_from_storage(ext, va_base_text, ext->mem[LLEXT_MEM_TEXT],
167-
text_size, SYS_MM_MEM_PERM_EXEC);
171+
ret = llext_manager_load_data_from_storage(ldr, ext, LLEXT_MEM_TEXT,
172+
va_base_text, text_size, SYS_MM_MEM_PERM_EXEC);
168173
if (ret < 0)
169174
return ret;
170175

171176
/* Copy read-only data */
172-
ret = llext_manager_load_data_from_storage(ext, va_base_rodata, ext->mem[LLEXT_MEM_RODATA],
173-
rodata_size, 0);
177+
ret = llext_manager_load_data_from_storage(ldr, ext, LLEXT_MEM_RODATA,
178+
va_base_rodata, rodata_size, 0);
174179
if (ret < 0)
175180
goto e_text;
176181

177182
/* Copy writable data */
178-
ret = llext_manager_load_data_from_storage(ext, va_base_data, ext->mem[LLEXT_MEM_DATA],
179-
data_size, SYS_MM_MEM_PERM_RW);
183+
ret = llext_manager_load_data_from_storage(ldr, ext, LLEXT_MEM_DATA,
184+
va_base_data, data_size, SYS_MM_MEM_PERM_RW);
180185
if (ret < 0)
181186
goto e_rodata;
182187

@@ -240,49 +245,55 @@ static int llext_manager_link(struct llext_loader *ldr, const char *name,
240245
.relocate_local = !mctx->segment[LIB_MANAGER_TEXT].size,
241246
.pre_located = true,
242247
.section_detached = llext_manager_section_detached,
248+
.keep_section_info = true,
243249
};
250+
const elf_shdr_t *hdr;
244251
int ret;
245252

246253
ret = llext_load(ldr, name, llext, &ldr_parm);
247254
if (ret)
248255
return ret;
249256

250-
mctx->segment[LIB_MANAGER_TEXT].addr = ldr->sects[LLEXT_MEM_TEXT].sh_addr;
251-
mctx->segment[LIB_MANAGER_TEXT].size = ldr->sects[LLEXT_MEM_TEXT].sh_size;
257+
/* All code sections */
258+
llext_get_region_info(ldr, *llext, LLEXT_MEM_TEXT, &hdr, NULL, NULL);
259+
mctx->segment[LIB_MANAGER_TEXT].addr = hdr->sh_addr;
260+
mctx->segment[LIB_MANAGER_TEXT].size = hdr->sh_size;
252261

253262
tr_dbg(&lib_manager_tr, ".text: start: %#lx size %#x",
254263
mctx->segment[LIB_MANAGER_TEXT].addr,
255264
mctx->segment[LIB_MANAGER_TEXT].size);
256265

257266
/* All read-only data sections */
258-
mctx->segment[LIB_MANAGER_RODATA].addr =
259-
ldr->sects[LLEXT_MEM_RODATA].sh_addr;
260-
mctx->segment[LIB_MANAGER_RODATA].size = ldr->sects[LLEXT_MEM_RODATA].sh_size;
267+
llext_get_region_info(ldr, *llext, LLEXT_MEM_RODATA, &hdr, NULL, NULL);
268+
mctx->segment[LIB_MANAGER_RODATA].addr = hdr->sh_addr;
269+
mctx->segment[LIB_MANAGER_RODATA].size = hdr->sh_size;
261270

262271
tr_dbg(&lib_manager_tr, ".rodata: start: %#lx size %#x",
263272
mctx->segment[LIB_MANAGER_RODATA].addr,
264273
mctx->segment[LIB_MANAGER_RODATA].size);
265274

266275
/* All writable data sections */
267-
mctx->segment[LIB_MANAGER_DATA].addr =
268-
ldr->sects[LLEXT_MEM_DATA].sh_addr;
269-
mctx->segment[LIB_MANAGER_DATA].size = ldr->sects[LLEXT_MEM_DATA].sh_size;
276+
llext_get_region_info(ldr, *llext, LLEXT_MEM_DATA, &hdr, NULL, NULL);
277+
mctx->segment[LIB_MANAGER_DATA].addr = hdr->sh_addr;
278+
mctx->segment[LIB_MANAGER_DATA].size = hdr->sh_size;
270279

271280
tr_dbg(&lib_manager_tr, ".data: start: %#lx size %#x",
272281
mctx->segment[LIB_MANAGER_DATA].addr,
273282
mctx->segment[LIB_MANAGER_DATA].size);
274283

275284
*buildinfo = NULL;
276-
ssize_t binfo_o = llext_find_section(ldr, ".mod_buildinfo");
277-
278-
if (binfo_o >= 0)
279-
*buildinfo = llext_peek(ldr, binfo_o);
285+
ret = llext_section_shndx(ldr, *llext, ".mod_buildinfo");
286+
if (ret >= 0) {
287+
llext_get_section_info(ldr, *llext, ret, &hdr, NULL, NULL);
288+
*buildinfo = llext_peek(ldr, hdr->sh_offset);
289+
}
280290

281291
*mod_manifest = NULL;
282-
ssize_t mod_o = llext_find_section(ldr, ".module");
283-
284-
if (mod_o >= 0)
285-
*mod_manifest = llext_peek(ldr, mod_o);
292+
ret = llext_section_shndx(ldr, *llext, ".module");
293+
if (ret >= 0) {
294+
llext_get_section_info(ldr, *llext, ret, &hdr, NULL, NULL);
295+
*mod_manifest = llext_peek(ldr, hdr->sh_offset);
296+
}
286297

287298
return *buildinfo && *mod_manifest ? 0 : -EPROTO;
288299
}

0 commit comments

Comments
 (0)