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 <Ilya.Tagunov@synopsys.com>
This commit is contained in:
parent
d18f4256ee
commit
36c9777be8
1 changed files with 6 additions and 5 deletions
|
@ -8,6 +8,7 @@
|
|||
#include <zephyr/llext/llext.h>
|
||||
#include <zephyr/llext/loader.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
|
||||
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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue