@@ -142,6 +142,84 @@ static const void *llext_find_extension_sym(const char *sym_name, struct llext *
142
142
return se .addr ;
143
143
}
144
144
145
+ /**
146
+ * @brief Determine address of a symbol.
147
+ *
148
+ * @param ext llext extension
149
+ * @param ldr llext loader
150
+ * @param link_addr (output) resolved address
151
+ * @param rel relocation entry
152
+ * @param sym symbol entry
153
+ * @param name symbol name
154
+ * @param shdr section header
155
+ *
156
+ * @return 0 for OK, negative for error
157
+ */
158
+ static int llext_lookup_symbol (struct llext * ext , struct llext_loader * ldr , uintptr_t * link_addr ,
159
+ const elf_rela_t * rel , const elf_sym_t * sym , const char * name ,
160
+ const elf_shdr_t * shdr )
161
+ {
162
+ if (ELF_R_SYM (rel -> r_info ) == 0 ) {
163
+ /*
164
+ * no symbol
165
+ * example: R_ARM_V4BX relocation, R_ARM_RELATIVE
166
+ */
167
+ * link_addr = 0 ;
168
+ } else if (sym -> st_shndx == SHN_UNDEF ) {
169
+ /* If symbol is undefined, then we need to look it up */
170
+ * link_addr = (uintptr_t )llext_find_sym (NULL , SYM_NAME_OR_SLID (name , sym -> st_value ));
171
+
172
+ if (* link_addr == 0 ) {
173
+ /* Try loaded tables */
174
+ struct llext * dep ;
175
+
176
+ * link_addr = (uintptr_t )llext_find_extension_sym (name , & dep );
177
+ if (* link_addr ) {
178
+ llext_dependency_add (ext , dep );
179
+ }
180
+ }
181
+
182
+ if (* link_addr == 0 ) {
183
+ LOG_ERR ("Undefined symbol with no entry in "
184
+ "symbol table %s, offset %zd, link section %d" ,
185
+ name , (size_t )rel -> r_offset , shdr -> sh_link );
186
+ return - ENODATA ;
187
+ }
188
+
189
+ LOG_INF ("found symbol %s at 0x%lx" , name , * link_addr );
190
+ } else if (sym -> st_shndx == SHN_ABS ) {
191
+ /* Absolute symbol */
192
+ * link_addr = sym -> st_value ;
193
+ } else if ((sym -> st_shndx < ldr -> hdr .e_shnum ) &&
194
+ !IN_RANGE (sym -> st_shndx , SHN_LORESERVE , SHN_HIRESERVE )) {
195
+ /* This check rejects all relocations whose target symbol has a section index higher
196
+ * than the maximum possible in this ELF file, or belongs in the reserved range:
197
+ * they will be caught by the `else` below and cause an error to be returned. This
198
+ * aborts the LLEXT's loading and prevents execution of improperly relocated code,
199
+ * which is dangerous.
200
+ *
201
+ * Note that the unsupported SHN_COMMON section is rejected as part of this check.
202
+ * Also note that SHN_ABS would be rejected as well, but we want to handle it
203
+ * properly: for this reason, this check must come AFTER handling the case where the
204
+ * symbol's section index is SHN_ABS!
205
+ *
206
+ *
207
+ * For regular symbols, the link address is obtained by adding st_value to the start
208
+ * address of the section in which the target symbol resides.
209
+ */
210
+ * link_addr =
211
+ (uintptr_t )llext_loaded_sect_ptr (ldr , ext , sym -> st_shndx ) + sym -> st_value ;
212
+ } else {
213
+ LOG_ERR ("cannot apply relocation: "
214
+ "target symbol has unexpected section index %d (0x%X)" ,
215
+ sym -> st_shndx , sym -> st_shndx );
216
+ return - ENOEXEC ;
217
+ }
218
+
219
+ return 0 ;
220
+ }
221
+
222
+
145
223
static void llext_link_plt (struct llext_loader * ldr , struct llext * ext , elf_shdr_t * shdr ,
146
224
const struct llext_load_param * ldr_parm , elf_shdr_t * tgt )
147
225
{
@@ -407,64 +485,12 @@ int llext_link(struct llext_loader *ldr, struct llext *ext, const struct llext_l
407
485
408
486
op_loc = sect_base + rel .r_offset ;
409
487
410
- if (ELF_R_SYM (rel .r_info ) == 0 ) {
411
- /* no symbol ex: R_ARM_V4BX relocation, R_ARM_RELATIVE */
412
- link_addr = 0 ;
413
- } else if (sym .st_shndx == SHN_UNDEF ) {
414
- /* If symbol is undefined, then we need to look it up */
415
- link_addr = (uintptr_t )llext_find_sym (NULL ,
416
- SYM_NAME_OR_SLID (name , sym .st_value ));
417
-
418
- if (link_addr == 0 ) {
419
- /* Try loaded tables */
420
- struct llext * dep ;
421
-
422
- link_addr = (uintptr_t )llext_find_extension_sym (name , & dep );
423
- if (link_addr ) {
424
- llext_dependency_add (ext , dep );
425
- }
426
- }
427
-
428
- if (link_addr == 0 ) {
429
- LOG_ERR ("Undefined symbol with no entry in "
430
- "symbol table %s, offset %zd, link section %d" ,
431
- name , (size_t )rel .r_offset , shdr -> sh_link );
432
- return - ENODATA ;
433
- }
488
+ ret = llext_lookup_symbol (ext , ldr , & link_addr , & rel , & sym , name , shdr );
434
489
435
- LOG_INF ("found symbol %s at 0x%lx" , name , link_addr );
436
- } else if (sym .st_shndx == SHN_ABS ) {
437
- /* Absolute symbol */
438
- link_addr = sym .st_value ;
439
- } else if ((sym .st_shndx < ldr -> hdr .e_shnum ) &&
440
- !IN_RANGE (sym .st_shndx , SHN_LORESERVE , SHN_HIRESERVE )) {
441
- /* This check rejects all relocations whose target symbol
442
- * has a section index higher than the maximum possible
443
- * in this ELF file, or belongs in the reserved range:
444
- * they will be caught by the `else` below and cause an
445
- * error to be returned. This aborts the LLEXT's loading
446
- * and prevents execution of improperly relocated code,
447
- * which is dangerous.
448
- *
449
- * Note that the unsupported SHN_COMMON section is rejected
450
- * as part of this check. Also note that SHN_ABS would be
451
- * rejected as well, but we want to handle it properly:
452
- * for this reason, this check must come AFTER handling
453
- * the case where the symbol's section index is SHN_ABS!
454
- *
455
- *
456
- * For regular symbols, the link address is obtained by
457
- * adding st_value to the start address of the section
458
- * in which the target symbol resides.
459
- */
460
- link_addr = (uintptr_t )llext_loaded_sect_ptr (ldr , ext ,
461
- sym .st_shndx )
462
- + sym .st_value ;
463
- } else {
464
- LOG_ERR ("rela section %d, entry %d: cannot apply relocation: "
465
- "target symbol has unexpected section index %d (0x%X)" ,
466
- i , j , sym .st_shndx , sym .st_shndx );
467
- return - ENOEXEC ;
490
+ if (ret != 0 ) {
491
+ LOG_ERR ("Failed to lookup symbol in rela section %d entry %d!" , i ,
492
+ j );
493
+ return ret ;
468
494
}
469
495
470
496
LOG_INF ("writing relocation symbol %s type %zd sym %zd at addr 0x%lx "
0 commit comments