Add architecture-specific ELF relocation support for RISC-V, enabling dynamic relocation of position-independent ELF binaries. The implemetation reuses the existing relocate_image().
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <[email protected]> Signed-off-by: Sascha Hauer <[email protected]> --- arch/riscv/lib/reloc.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/arch/riscv/lib/reloc.c b/arch/riscv/lib/reloc.c index 18b13a7013cff4032c12b999470f265dbda13c51..9a5004cf5b762b39bb98f7f0ab112c204185b33a 100644 --- a/arch/riscv/lib/reloc.c +++ b/arch/riscv/lib/reloc.c @@ -75,3 +75,58 @@ void relocate_to_current_adr(void) sync_caches_for_execution(); } + +#if __riscv_xlen == 64 + +/* + * Apply RISC-V 64-bit ELF relocations + */ +int elf_apply_relocations(struct elf_image *elf, const void *dyn_seg) +{ + Elf64_Rela *rela; + void *rel_ptr; + u64 relasz; + phys_addr_t base = (phys_addr_t)elf->reloc_offset; + int ret; + + ret = elf_parse_dynamic_section_rela(elf, dyn_seg, &rel_ptr, &relasz); + if (ret) + return ret; + + rela = (Elf64_Rela *)rel_ptr; + + relocate_image(base, rela, (void *)rela + relasz, NULL, NULL); + + return 0; +} + +#else /* 32-bit RISC-V */ + +/* + * Apply RISC-V 32-bit ELF relocations + */ +int elf_apply_relocations(struct elf_image *elf, const void *dyn_seg) +{ + Elf32_Rela *rela; + void *rel_ptr; + u64 relasz; + phys_addr_t base = (phys_addr_t)elf->reloc_offset; + int ret; + + if (elf->class != ELFCLASS32) { + pr_err("Wrong ELF class for RISC-V 32 relocation\n"); + return -EINVAL; + } + + ret = elf_parse_dynamic_section_rela(elf, dyn_seg, &rel_ptr, &relasz); + if (ret) + return ret; + + rela = (Elf32_Rela *)rel_ptr; + + relocate_image(base, rela, (void *)rela + relasz, NULL, NULL); + + return 0; +} + +#endif -- 2.47.3
