Skip to content

Commit e99d9d5

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 d644f18 commit e99d9d5

File tree

1 file changed

+55
-38
lines changed

1 file changed

+55
-38
lines changed

src/library_manager/llext_manager.c

Lines changed: 55 additions & 38 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,38 @@ 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;
81+
size_t region_size;
7882
int ret;
79-
const elf_shdr_t *shdr;
8083

8184
ret = llext_manager_align_map(vma, size, SYS_MM_MEM_PERM_RW);
8285
if (ret < 0) {
8386
tr_err(&lib_manager_tr, "cannot map %u of %p", size, (__sparse_force void *)vma);
8487
return ret;
8588
}
8689

87-
size_t init_offset = 0;
90+
llext_get_region_info(ldr, ext, region, NULL, &region_addr, &region_size);
8891

8992
/* 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;
93+
for (i = 0; i < llext_section_count(ext); i++) {
94+
const elf_shdr_t *shdr;
95+
enum llext_mem s_region = LLEXT_MEM_COUNT;
96+
size_t s_offset = 0;
9497

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

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

101-
ret = memcpy_s((__sparse_force void *)shdr->sh_addr, size - offset,
102-
load_base + offset, shdr->sh_size);
103+
ret = memcpy_s((__sparse_force void *)shdr->sh_addr, size - s_offset,
104+
(const uint8_t *)region_addr + s_offset, shdr->sh_size);
103105
if (ret < 0)
104106
return ret;
105107
}
@@ -120,6 +122,10 @@ static int llext_manager_load_data_from_storage(const struct llext *ext,
120122
static int llext_manager_load_module(const struct llext *ext, const struct llext_buf_loader *ebl,
121123
const struct lib_manager_module *mctx)
122124
{
125+
const elf_shdr_t *bss_hdr;
126+
127+
llext_get_region_info(&ebl->loader, ext, LLEXT_MEM_BSS, &bss_hdr, NULL, NULL);
128+
123129
/* Executable code (.text) */
124130
void __sparse_cache *va_base_text = (void __sparse_cache *)
125131
mctx->segment[LIB_MANAGER_TEXT].addr;
@@ -137,8 +143,8 @@ static int llext_manager_load_module(const struct llext *ext, const struct llext
137143

138144
/* .bss, should be within writable data above */
139145
void __sparse_cache *bss_addr = (void __sparse_cache *)
140-
ebl->loader.sects[LLEXT_MEM_BSS].sh_addr;
141-
size_t bss_size = ebl->loader.sects[LLEXT_MEM_BSS].sh_size;
146+
bss_hdr->sh_addr;
147+
size_t bss_size = bss_hdr->sh_size;
142148
int ret;
143149

144150
/* Check, that .bss is within .data */
@@ -151,7 +157,7 @@ static int llext_manager_load_module(const struct llext *ext, const struct llext
151157
va_base_data = bss_addr;
152158
data_size += bss_size;
153159
} else if ((uintptr_t)bss_addr == (uintptr_t)va_base_data +
154-
ALIGN_UP(data_size, ebl->loader.sects[LLEXT_MEM_BSS].sh_addralign)) {
160+
ALIGN_UP(data_size, bss_hdr->sh_addralign)) {
155161
/* .bss directly behind writable data, append */
156162
data_size += bss_size;
157163
} else {
@@ -163,20 +169,20 @@ static int llext_manager_load_module(const struct llext *ext, const struct llext
163169
}
164170

165171
/* 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);
172+
ret = llext_manager_load_data_from_storage(&ebl->loader, ext, LLEXT_MEM_TEXT,
173+
va_base_text, text_size, SYS_MM_MEM_PERM_EXEC);
168174
if (ret < 0)
169175
return ret;
170176

171177
/* 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);
178+
ret = llext_manager_load_data_from_storage(&ebl->loader, ext, LLEXT_MEM_RODATA,
179+
va_base_rodata, rodata_size, 0);
174180
if (ret < 0)
175181
goto e_text;
176182

177183
/* 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);
184+
ret = llext_manager_load_data_from_storage(&ebl->loader, ext, LLEXT_MEM_DATA,
185+
va_base_data, data_size, SYS_MM_MEM_PERM_RW);
180186
if (ret < 0)
181187
goto e_rodata;
182188

@@ -240,49 +246,60 @@ static int llext_manager_link(struct llext_buf_loader *ebl, const char *name,
240246
.relocate_local = !mctx->segment[LIB_MANAGER_TEXT].size,
241247
.pre_located = true,
242248
.section_detached = llext_manager_section_detached,
249+
.keep_section_info = true,
243250
};
251+
const elf_shdr_t *hdr;
244252
int ret;
245253

246254
ret = llext_load(&ebl->loader, name, &md->llext, &ldr_parm);
247255
if (ret)
248256
return ret;
249257

250-
mctx->segment[LIB_MANAGER_TEXT].addr = ebl->loader.sects[LLEXT_MEM_TEXT].sh_addr;
251-
mctx->segment[LIB_MANAGER_TEXT].size = ebl->loader.sects[LLEXT_MEM_TEXT].sh_size;
258+
/* All code sections */
259+
llext_get_region_info(&ebl->loader, md->llext, LLEXT_MEM_TEXT,
260+
&hdr, NULL, NULL);
261+
mctx->segment[LIB_MANAGER_TEXT].addr = hdr->sh_addr;
262+
mctx->segment[LIB_MANAGER_TEXT].size = hdr->sh_size;
252263

253264
tr_dbg(&lib_manager_tr, ".text: start: %#lx size %#x",
254265
mctx->segment[LIB_MANAGER_TEXT].addr,
255266
mctx->segment[LIB_MANAGER_TEXT].size);
256267

257268
/* All read-only data sections */
258-
mctx->segment[LIB_MANAGER_RODATA].addr =
259-
ebl->loader.sects[LLEXT_MEM_RODATA].sh_addr;
260-
mctx->segment[LIB_MANAGER_RODATA].size = ebl->loader.sects[LLEXT_MEM_RODATA].sh_size;
269+
llext_get_region_info(&ebl->loader, md->llext, LLEXT_MEM_RODATA,
270+
&hdr, NULL, NULL);
271+
mctx->segment[LIB_MANAGER_RODATA].addr = hdr->sh_addr;
272+
mctx->segment[LIB_MANAGER_RODATA].size = hdr->sh_size;
261273

262274
tr_dbg(&lib_manager_tr, ".rodata: start: %#lx size %#x",
263275
mctx->segment[LIB_MANAGER_RODATA].addr,
264276
mctx->segment[LIB_MANAGER_RODATA].size);
265277

266278
/* All writable data sections */
267-
mctx->segment[LIB_MANAGER_DATA].addr =
268-
ebl->loader.sects[LLEXT_MEM_DATA].sh_addr;
269-
mctx->segment[LIB_MANAGER_DATA].size = ebl->loader.sects[LLEXT_MEM_DATA].sh_size;
279+
llext_get_region_info(&ebl->loader, md->llext, LLEXT_MEM_DATA,
280+
&hdr, NULL, NULL);
281+
mctx->segment[LIB_MANAGER_DATA].addr = hdr->sh_addr;
282+
mctx->segment[LIB_MANAGER_DATA].size = hdr->sh_size;
270283

271284
tr_dbg(&lib_manager_tr, ".data: start: %#lx size %#x",
272285
mctx->segment[LIB_MANAGER_DATA].addr,
273286
mctx->segment[LIB_MANAGER_DATA].size);
274287

275288
*buildinfo = NULL;
276-
ssize_t binfo_o = llext_find_section(&ebl->loader, ".mod_buildinfo");
277-
278-
if (binfo_o >= 0)
279-
*buildinfo = llext_peek(&ebl->loader, binfo_o);
289+
ret = llext_section_shndx(&ebl->loader, md->llext, ".mod_buildinfo");
290+
if (ret >= 0) {
291+
llext_get_section_info(&ebl->loader, md->llext, ret, &hdr, NULL, NULL);
292+
*buildinfo = llext_peek(&ebl->loader, hdr->sh_offset);
293+
}
280294

281295
*mod_manifest = NULL;
282-
ssize_t mod_o = llext_find_section(&ebl->loader, ".module");
296+
ret = llext_section_shndx(&ebl->loader, md->llext, ".module");
297+
if (ret >= 0) {
298+
llext_get_section_info(&ebl->loader, md->llext, ret, &hdr, NULL, NULL);
299+
*mod_manifest = llext_peek(&ebl->loader, hdr->sh_offset);
300+
}
283301

284-
if (mod_o >= 0)
285-
*mod_manifest = llext_peek(&ebl->loader, mod_o);
302+
llext_free_inspection_data(&ebl->loader, md->llext);
286303

287304
return *buildinfo && *mod_manifest ? 0 : -EPROTO;
288305
}

0 commit comments

Comments
 (0)