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_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