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/llext.h>
|
||||||
#include <zephyr/llext/loader.h>
|
#include <zephyr/llext/loader.h>
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
|
#include <zephyr/sys/util.h>
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(elf, CONFIG_LLEXT_LOG_LEVEL);
|
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
|
#define R_ARC_32_ME 27
|
||||||
|
|
||||||
/* ARCompact insns packed in memory have Middle Endian encoding */
|
/* 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
|
* @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)
|
uintptr_t load_bias)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint32_t insn = *(uint32_t *)loc;
|
uint32_t insn = UNALIGNED_GET((uint32_t *)loc);
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
|
|
||||||
sym_base_addr += rel->r_addend;
|
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) {
|
switch (reloc_type) {
|
||||||
case R_ARC_32:
|
case R_ARC_32:
|
||||||
case R_ARC_B26:
|
case R_ARC_B26:
|
||||||
*(uint32_t *)loc = sym_base_addr;
|
UNALIGNED_PUT(sym_base_addr, (uint32_t *)loc);
|
||||||
break;
|
break;
|
||||||
case R_ARC_S25W_PCREL:
|
case R_ARC_S25W_PCREL:
|
||||||
/* ((S + A) - P) >> 2
|
/* ((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);
|
insn = ME(insn);
|
||||||
|
|
||||||
*(uint32_t *)loc = insn;
|
UNALIGNED_PUT(insn, (uint32_t *)loc);
|
||||||
break;
|
break;
|
||||||
case R_ARC_32_ME:
|
case R_ARC_32_ME:
|
||||||
*(uint32_t *)loc = ME(sym_base_addr);
|
UNALIGNED_PUT(ME(sym_base_addr), (uint32_t *)loc);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERR("unknown relocation: %u\n", reloc_type);
|
LOG_ERR("unknown relocation: %u\n", reloc_type);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue