From 36c9777be8db8083e0e7a2d2d0a46b25b63a12af Mon Sep 17 00:00:00 2001 From: Ilya Tagunov Date: Tue, 19 Nov 2024 13:23:20 +0000 Subject: [PATCH] llext: fix unaligned access for ARC We hit some unaligned access faults running our internal tests. Not every 32-bit instruction is 32-bit aligned; some are 16-bit aligned. Make all reads and writes potentially unaligned to be on the safe side. Signed-off-by: Ilya Tagunov --- arch/arc/core/elf.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/arc/core/elf.c b/arch/arc/core/elf.c index 7bdb5b08fcf..9f9f1073431 100644 --- a/arch/arc/core/elf.c +++ b/arch/arc/core/elf.c @@ -8,6 +8,7 @@ #include #include #include +#include LOG_MODULE_REGISTER(elf, CONFIG_LLEXT_LOG_LEVEL); @@ -17,7 +18,7 @@ LOG_MODULE_REGISTER(elf, CONFIG_LLEXT_LOG_LEVEL); #define R_ARC_32_ME 27 /* ARCompact insns packed in memory have Middle Endian encoding */ -#define ME(x) ((x & 0xffff0000) >> 16) | ((x & 0xffff) << 16); +#define ME(x) (((x & 0xffff0000) >> 16) | ((x & 0xffff) << 16)) /** * @brief Architecture specific function for relocating shared elf @@ -34,7 +35,7 @@ int arch_elf_relocate(elf_rela_t *rel, uintptr_t loc, uintptr_t sym_base_addr, c uintptr_t load_bias) { int ret = 0; - uint32_t insn = *(uint32_t *)loc; + uint32_t insn = UNALIGNED_GET((uint32_t *)loc); uint32_t value; sym_base_addr += rel->r_addend; @@ -44,7 +45,7 @@ int arch_elf_relocate(elf_rela_t *rel, uintptr_t loc, uintptr_t sym_base_addr, c switch (reloc_type) { case R_ARC_32: case R_ARC_B26: - *(uint32_t *)loc = sym_base_addr; + UNALIGNED_PUT(sym_base_addr, (uint32_t *)loc); break; case R_ARC_S25W_PCREL: /* ((S + A) - P) >> 2 @@ -64,10 +65,10 @@ int arch_elf_relocate(elf_rela_t *rel, uintptr_t loc, uintptr_t sym_base_addr, c insn = ME(insn); - *(uint32_t *)loc = insn; + UNALIGNED_PUT(insn, (uint32_t *)loc); break; case R_ARC_32_ME: - *(uint32_t *)loc = ME(sym_base_addr); + UNALIGNED_PUT(ME(sym_base_addr), (uint32_t *)loc); break; default: LOG_ERR("unknown relocation: %u\n", reloc_type);