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,
120122static 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