Skip to content

Commit 18a62ce

Browse files
llext: Add parameters to arch_elf_relocate
The RISC-V port of llext requires additional parameters for handling non-adjacent HI20/LO12 relocations in arch_elf_relocate(): the current extension (struct llext), the current extension loader (struct llext_loader), the current section header (elf_shdr_t) and the current symbol (elf_sym_t). This changes the signature of arch_elf_relocate accordingly. Signed-off-by: Eric Ackermann <[email protected]>
1 parent 5a70717 commit 18a62ce

File tree

7 files changed

+58
-30
lines changed

7 files changed

+58
-30
lines changed

arch/arc/core/elf.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <zephyr/llext/elf.h>
88
#include <zephyr/llext/llext.h>
9+
#include <zephyr/llext/llext_internal.h>
910
#include <zephyr/llext/loader.h>
1011
#include <zephyr/logging/log.h>
1112
#include <zephyr/sys/util.h>
@@ -31,12 +32,18 @@ LOG_MODULE_REGISTER(elf, CONFIG_LLEXT_LOG_LEVEL);
3132
* https://github.com/foss-for-synopsys-dwc-arc-processors/arc-ABI-manual/blob/master/ARCv2_ABI.pdf
3233
* https://github.com/zephyrproject-rtos/binutils-gdb
3334
*/
34-
int arch_elf_relocate(elf_rela_t *rel, uintptr_t loc, uintptr_t sym_base_addr, const char *sym_name,
35-
uintptr_t load_bias)
35+
int arch_elf_relocate(struct llext_loader *ldr, struct llext *ext, elf_rela_t *rel,
36+
const elf_shdr_t *shdr, const elf_sym_t *sym, uintptr_t loc,
37+
uintptr_t sym_base_addr, const char *sym_name)
3638
{
3739
int ret = 0;
3840
uint32_t insn = UNALIGNED_GET((uint32_t *)loc);
3941
uint32_t value;
42+
const uintptr_t load_bias = llext_text_start(ext);
43+
44+
ARG_UNUSED(ldr);
45+
ARG_UNUSED(shdr);
46+
ARG_UNUSED(sym);
4047

4148
sym_base_addr += rel->r_addend;
4249

arch/arm/core/elf.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <zephyr/llext/elf.h>
99
#include <zephyr/llext/llext.h>
10+
#include <zephyr/llext/llext_internal.h>
1011
#include <zephyr/logging/log.h>
1112
#include <zephyr/sys/util.h>
1213

@@ -316,11 +317,17 @@ static void thm_movs_handler(elf_word reloc_type, uint32_t loc,
316317
* Do NOT mix them with not 'Thumb instructions' in the below switch/case: they are not
317318
* intended to work together.
318319
*/
319-
int arch_elf_relocate(elf_rela_t *rel, uintptr_t loc, uintptr_t sym_base_addr,
320-
const char *sym_name, uintptr_t load_bias)
320+
int arch_elf_relocate(struct llext_loader *ldr, struct llext *ext, elf_rela_t *rel,
321+
const elf_shdr_t *shdr, const elf_sym_t *sym, uintptr_t loc,
322+
uintptr_t sym_base_addr, const char *sym_name)
321323
{
322324
int ret = 0;
323325
elf_word reloc_type = ELF32_R_TYPE(rel->r_info);
326+
const uintptr_t load_bias = llext_text_start(ext);
327+
328+
ARG_UNUSED(ldr);
329+
ARG_UNUSED(shdr);
330+
ARG_UNUSED(sym);
324331

325332
LOG_DBG("%d %lx %lx %s", reloc_type, loc, sym_base_addr, sym_name);
326333

arch/arm64/core/elf.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <zephyr/llext/elf.h>
88
#include <zephyr/llext/llext.h>
9+
#include <zephyr/llext/llext_internal.h>
910
#include <zephyr/logging/log.h>
1011
#include <zephyr/sys/util.h>
1112
#include <zephyr/sys/byteorder.h>
@@ -430,13 +431,19 @@ static int imm_reloc_handler(elf_rela_t *rel, elf_word reloc_type, uintptr_t loc
430431
* @retval -ENOTSUP Unsupported relocation
431432
* @retval -ENOEXEC Invalid relocation
432433
*/
433-
int arch_elf_relocate(elf_rela_t *rel, uintptr_t loc, uintptr_t sym_base_addr, const char *sym_name,
434-
uintptr_t load_bias)
434+
int arch_elf_relocate(struct llext_loader *ldr, struct llext *ext, elf_rela_t *rel,
435+
const elf_shdr_t *shdr, const elf_sym_t *sym, uintptr_t loc,
436+
uintptr_t sym_base_addr, const char *sym_name)
435437
{
436438
int ret = 0;
437439
bool overflow_check = true;
438440
elf_word reloc_type = ELF_R_TYPE(rel->r_info);
439441

442+
ARG_UNUSED(ext);
443+
ARG_UNUSED(ldr);
444+
ARG_UNUSED(shdr);
445+
ARG_UNUSED(sym);
446+
440447
switch (reloc_type) {
441448
case R_ARM_NONE:
442449
case R_AARCH64_NONE:

arch/riscv/core/elf.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,13 @@ static long long last_u_type_jump_target;
6868
* https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc
6969
*
7070
*/
71-
int arch_elf_relocate(elf_rela_t *rel, uintptr_t loc_unsigned, uintptr_t sym_base_addr_unsigned,
72-
const char *sym_name, uintptr_t load_bias)
71+
int arch_elf_relocate(struct llext_loader *ldr, struct llext *ext, elf_rela_t *rel,
72+
const elf_shdr_t *shdr, const elf_sym_t *sym, uintptr_t loc_unsigned,
73+
uintptr_t sym_base_addr_unsigned, const char *sym_name)
7374
{
7475
/* FIXME currently, RISC-V relocations all fit in ELF_32_R_TYPE */
7576
elf_word reloc_type = ELF32_R_TYPE(rel->r_info);
77+
const uintptr_t load_bias = llext_text_start(ext);
7678
/*
7779
* The RISC-V specification uses the following symbolic names for the relocations:
7880
*
@@ -105,6 +107,10 @@ int arch_elf_relocate(elf_rela_t *rel, uintptr_t loc_unsigned, uintptr_t sym_bas
105107
sym_name, (void *)loc, (void *)sym_base_addr, (void *)load_bias,
106108
(uint64_t)reloc_type);
107109

110+
ARG_UNUSED(ldr);
111+
ARG_UNUSED(shdr);
112+
ARG_UNUSED(sym);
113+
108114
/* FIXME not all types of relocations currently supported, especially TLS */
109115

110116
switch (reloc_type) {

include/zephyr/llext/llext.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,18 +354,24 @@ int llext_add_domain(struct llext *ext, struct k_mem_domain *domain);
354354
* symbolic data such as a section, function, or object. These relocations
355355
* are architecture specific and each architecture supporting LLEXT must
356356
* implement this.
357+
* Arguments sym_base_addr, sym_name can be computed from the sym parameter,
358+
* but these parameters are provided redundantly to increase efficiency.
357359
*
360+
* @param[in] ldr Extension loader
361+
* @param[in] ext Extension being relocated refers to
358362
* @param[in] rel Relocation data provided by ELF
363+
* @param[in] shdr Header of the ELF section currently being located
364+
* @param[in] sym ELF symbol to be relocated
359365
* @param[in] loc Address of opcode to rewrite
360366
* @param[in] sym_base_addr Address of symbol referenced by relocation
361367
* @param[in] sym_name Name of symbol referenced by relocation
362-
* @param[in] load_bias `.text` load address
363368
* @retval 0 Success
364369
* @retval -ENOTSUP Unsupported relocation
365370
* @retval -ENOEXEC Invalid relocation
366371
*/
367-
int arch_elf_relocate(elf_rela_t *rel, uintptr_t loc,
368-
uintptr_t sym_base_addr, const char *sym_name, uintptr_t load_bias);
372+
int arch_elf_relocate(struct llext_loader *ldr, struct llext *ext, elf_rela_t *rel,
373+
const elf_shdr_t *shdr, const elf_sym_t *sym, uintptr_t loc,
374+
uintptr_t sym_base_addr, const char *sym_name);
369375

370376
/**
371377
* @brief Locates an ELF section in the file.

include/zephyr/llext/llext_internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ struct llext_elf_sect_map {
2828

2929
const void *llext_loaded_sect_ptr(struct llext_loader *ldr, struct llext *ext, unsigned int sh_ndx);
3030

31+
static inline uintptr_t llext_text_start(const struct llext *ext)
32+
{
33+
return (uintptr_t)ext->mem[LLEXT_MEM_TEXT];
34+
}
35+
3136
/** @endcond */
3237

3338
#ifdef __cplusplus

subsys/llext/llext_link.c

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ LOG_MODULE_DECLARE(llext, CONFIG_LLEXT_LOG_LEVEL);
2626
#define SYM_NAME_OR_SLID(name, slid) name
2727
#endif
2828

29-
__weak int arch_elf_relocate(elf_rela_t *rel, uintptr_t loc,
30-
uintptr_t sym_base_addr, const char *sym_name, uintptr_t load_bias)
29+
__weak int arch_elf_relocate(struct llext_loader *ldr, struct llext *ext, elf_rela_t *rel,
30+
const elf_shdr_t *shdr, const elf_sym_t *sym, uintptr_t loc,
31+
uintptr_t sym_base_addr, const char *sym_name)
3132
{
3233
return -ENOTSUP;
3334
}
@@ -142,20 +143,10 @@ static const void *llext_find_extension_sym(const char *sym_name, struct llext *
142143
return se.addr;
143144
}
144145

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
146+
/*
147+
* Determine address of a symbol.
157148
*/
158-
static int llext_lookup_symbol(struct llext *ext, struct llext_loader *ldr, uintptr_t *link_addr,
149+
static int llext_lookup_symbol(struct llext_loader *ldr, struct llext *ext, uintptr_t *link_addr,
159150
const elf_rela_t *rel, const elf_sym_t *sym, const char *name,
160151
const elf_shdr_t *shdr)
161152
{
@@ -219,7 +210,6 @@ static int llext_lookup_symbol(struct llext *ext, struct llext_loader *ldr, uint
219210
return 0;
220211
}
221212

222-
223213
static void llext_link_plt(struct llext_loader *ldr, struct llext *ext, elf_shdr_t *shdr,
224214
const struct llext_load_param *ldr_parm, elf_shdr_t *tgt)
225215
{
@@ -485,7 +475,7 @@ int llext_link(struct llext_loader *ldr, struct llext *ext, const struct llext_l
485475

486476
op_loc = sect_base + rel.r_offset;
487477

488-
ret = llext_lookup_symbol(ext, ldr, &link_addr, &rel, &sym, name, shdr);
478+
ret = llext_lookup_symbol(ldr, ext, &link_addr, &rel, &sym, name, shdr);
489479

490480
if (ret != 0) {
491481
LOG_ERR("Failed to lookup symbol in rela section %d entry %d!", i,
@@ -499,8 +489,8 @@ int llext_link(struct llext_loader *ldr, struct llext *ext, const struct llext_l
499489
op_loc, link_addr);
500490

501491
/* relocation */
502-
ret = arch_elf_relocate(&rel, op_loc, link_addr, name,
503-
(uintptr_t)ext->mem[LLEXT_MEM_TEXT]);
492+
ret = arch_elf_relocate(ldr, ext, &rel, shdr, &sym, op_loc, link_addr,
493+
name);
504494
if (ret != 0) {
505495
return ret;
506496
}

0 commit comments

Comments
 (0)