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,
120121static int llext_manager_load_module (const struct llext * ext , const struct llext_buf_loader * ebl ,
121122 const struct lib_manager_module * mctx )
122123{
124+ const elf_shdr_t * bss_hdr ;
125+
126+ llext_get_region_info (& ebl -> loader , 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- ebl -> loader . sects [ LLEXT_MEM_BSS ]. sh_addr ;
141- size_t bss_size = ebl -> loader . 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 , ebl -> loader . 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 (& ebl -> loader , 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 (& ebl -> loader , 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 (& ebl -> loader , 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,58 @@ static int llext_manager_link(struct llext_buf_loader *ebl, 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 (& ebl -> loader , name , llext , & ldr_parm );
247254 if (ret )
248255 return ret ;
249256
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 ;
257+ /* All code sections */
258+ llext_get_region_info (& ebl -> loader , * llext , LLEXT_MEM_TEXT ,
259+ & hdr , NULL , NULL );
260+ mctx -> segment [LIB_MANAGER_TEXT ].addr = hdr -> sh_addr ;
261+ mctx -> segment [LIB_MANAGER_TEXT ].size = hdr -> sh_size ;
252262
253263 tr_dbg (& lib_manager_tr , ".text: start: %#lx size %#x" ,
254264 mctx -> segment [LIB_MANAGER_TEXT ].addr ,
255265 mctx -> segment [LIB_MANAGER_TEXT ].size );
256266
257267 /* 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 ;
268+ llext_get_region_info (& ebl -> loader , * llext , LLEXT_MEM_RODATA ,
269+ & hdr , NULL , NULL );
270+ mctx -> segment [LIB_MANAGER_RODATA ].addr = hdr -> sh_addr ;
271+ mctx -> segment [LIB_MANAGER_RODATA ].size = hdr -> sh_size ;
261272
262273 tr_dbg (& lib_manager_tr , ".rodata: start: %#lx size %#x" ,
263274 mctx -> segment [LIB_MANAGER_RODATA ].addr ,
264275 mctx -> segment [LIB_MANAGER_RODATA ].size );
265276
266277 /* 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 ;
278+ llext_get_region_info (& ebl -> loader , * llext , LLEXT_MEM_DATA ,
279+ & hdr , NULL , NULL );
280+ mctx -> segment [LIB_MANAGER_DATA ].addr = hdr -> sh_addr ;
281+ mctx -> segment [LIB_MANAGER_DATA ].size = hdr -> sh_size ;
270282
271283 tr_dbg (& lib_manager_tr , ".data: start: %#lx size %#x" ,
272284 mctx -> segment [LIB_MANAGER_DATA ].addr ,
273285 mctx -> segment [LIB_MANAGER_DATA ].size );
274286
275287 * 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 );
288+ ret = llext_section_shndx (& ebl -> loader , * llext , ".mod_buildinfo" );
289+ if (ret >= 0 ) {
290+ llext_get_section_info (& ebl -> loader , * llext , ret , & hdr , NULL , NULL );
291+ * buildinfo = llext_peek (& ebl -> loader , hdr -> sh_offset );
292+ }
280293
281294 * mod_manifest = NULL ;
282- ssize_t mod_o = llext_find_section (& ebl -> loader , ".module" );
283-
284- if (mod_o >= 0 )
285- * mod_manifest = llext_peek (& ebl -> loader , mod_o );
295+ ret = llext_section_shndx (& ebl -> loader , * llext , ".module" );
296+ if (ret >= 0 ) {
297+ llext_get_section_info (& ebl -> loader , * llext , ret , & hdr , NULL , NULL );
298+ * mod_manifest = llext_peek (& ebl -> loader , hdr -> sh_offset );
299+ }
286300
287301 return * buildinfo && * mod_manifest ? 0 : - EPROTO ;
288302}
0 commit comments