summaryrefslogtreecommitdiff
path: root/arch/arm64/arch_arm64.cpp
diff options
context:
space:
mode:
authorMichael Krasnitski <michael.krasnitski@gmail.com>2024-09-06 18:29:09 -0400
committermason <35282038+emesare@users.noreply.github.com>2024-09-08 14:19:50 -0700
commit3a4fb594eb6946ae67d9c47fb93927d5f9ce83ae (patch)
tree8c8fd2c9b4e7eec47c5e7838f17b939de22a69b4 /arch/arm64/arch_arm64.cpp
parentfde5ba7b66ccb5f927f6a8290d5e74bf93097ed6 (diff)
Respect ELF view endianness when calculating AArch64 relocations
Diffstat (limited to 'arch/arm64/arch_arm64.cpp')
-rw-r--r--arch/arm64/arch_arm64.cpp41
1 files changed, 24 insertions, 17 deletions
diff --git a/arch/arm64/arch_arm64.cpp b/arch/arm64/arch_arm64.cpp
index 9020b99b..e46847fa 100644
--- a/arch/arm64/arch_arm64.cpp
+++ b/arch/arm64/arch_arm64.cpp
@@ -3021,11 +3021,18 @@ class Arm64ElfRelocationHandler : public RelocationHandler
auto info = reloc->GetInfo();
if (len < info.size)
return false;
- uint64_t* dest64 = (uint64_t*)dest;
- uint32_t* dest32 = (uint32_t*)dest;
- uint16_t* dest16 = (uint16_t*)dest;
- // auto swap = [&arch](uint32_t x) { return (arch->GetEndianness() == LittleEndian)? x :
- // bswap32(x); };
+
+ BNEndianness endianness = view->GetDefaultEndianness();
+ auto write64 = [&endianness](uint64_t* dest64, uint64_t val) {
+ *dest64 = endianness == LittleEndian ? val : ToBE64(val);
+ };
+ auto write32 = [&endianness](uint32_t* dest32, uint32_t val) {
+ *dest32 = endianness == LittleEndian ? val : ToBE32(val);
+ };
+ auto write16 = [&endianness](uint16_t* dest16, uint16_t val) {
+ *dest16 = endianness == LittleEndian ? val : ToBE16(val);
+ };
+
uint64_t target = reloc->GetTarget();
Instruction inst;
switch (info.nativeType)
@@ -3036,12 +3043,12 @@ class Arm64ElfRelocationHandler : public RelocationHandler
case R_AARCH64_P32_COPY:
case R_AARCH64_P32_GLOB_DAT:
case R_AARCH64_P32_JUMP_SLOT:
- dest32[0] = target;
+ write32((uint32_t*)dest, target);
break;
case R_AARCH64_COPY:
case R_AARCH64_GLOB_DAT:
case R_AARCH64_JUMP_SLOT:
- dest64[0] = target;
+ write64((uint64_t*)dest, target);
break;
case R_AARCH64_ADR_PREL_LO21:
break;
@@ -3058,7 +3065,7 @@ class Arm64ElfRelocationHandler : public RelocationHandler
case R_AARCH64_ADD_ABS_LO12_NC:
{
ADD_SUB_IMM* decode = (ADD_SUB_IMM*)dest;
- aarch64_decompose(dest32[0], &inst, reloc->GetAddress());
+ aarch64_decompose(*(uint32_t*)dest, &inst, reloc->GetAddress());
decode->imm = target + info.addend;
break;
}
@@ -3066,33 +3073,33 @@ class Arm64ElfRelocationHandler : public RelocationHandler
case R_AARCH64_JUMP26:
{
UNCONDITIONAL_BRANCH* decode = (UNCONDITIONAL_BRANCH*)dest;
- aarch64_decompose(dest32[0], &inst, 0);
+ aarch64_decompose(*(uint32_t*)dest, &inst, 0);
decode->imm = (target + info.addend - reloc->GetAddress()) >> 2;
break;
}
case R_AARCH64_ABS16:
- dest16[0] = (uint16_t)(target + info.addend);
+ write16((uint16_t*)dest, target + info.addend);
break;
case R_AARCH64_ABS32:
- dest32[0] = (uint32_t)(target + info.addend);
+ write32((uint32_t*)dest, target + info.addend);
break;
case R_AARCH64_ABS64:
- dest64[0] = target + info.addend;
+ write64((uint64_t*)dest, target + info.addend);
break;
case R_AARCH64_PREL16:
- dest16[0] = (uint16_t)(info.addend + target - reloc->GetAddress());
+ write16((uint16_t*)dest, info.addend + target - reloc->GetAddress());
break;
case R_AARCH64_PREL32:
- dest32[0] = (uint32_t)(info.addend + target - reloc->GetAddress());
+ write32((uint32_t*)dest, info.addend + target - reloc->GetAddress());
break;
case R_AARCH64_PREL64:
- dest64[0] = info.addend + target - reloc->GetAddress();
+ write64((uint64_t*)dest, info.addend + target - reloc->GetAddress());
break;
case R_AARCH64_P32_RELATIVE:
- dest32[0] = target + info.addend;
+ write32((uint32_t*)dest, target + info.addend);
break;
case R_AARCH64_RELATIVE:
- dest64[0] = target + info.addend;
+ write64((uint64_t*)dest, target + info.addend);
break;
case R_AARCH64_LDST8_ABS_LO12_NC:
{