summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBradley Smith <bradley.smith@arm.com>2014-02-11 12:59:09 +0000
committerBradley Smith <bradley.smith@arm.com>2014-02-11 12:59:09 +0000
commit79ced8c5fa4e88394a9c4577537af4044d7a29f9 (patch)
tree31070856f0a0f31fcb8b48590fac2f903d61bdce
parent8615ab4a4ac99e6b57714aa34c2ecbb67414137d (diff)
downloadllvm-79ced8c5fa4e88394a9c4577537af4044d7a29f9.tar.gz
llvm-79ced8c5fa4e88394a9c4577537af4044d7a29f9.tar.bz2
llvm-79ced8c5fa4e88394a9c4577537af4044d7a29f9.tar.xz
[AArch64] Add missing PCRel relocations for AArch64 in RuntimeDyldELF
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201149 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index a4246e0c71..52f33ca11c 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -454,6 +454,48 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section,
assert((*TargetPtr >> 21 & 0x3) == 0 && "invalid shift for relocation");
break;
}
+ case ELF::R_AARCH64_ADR_PREL_PG_HI21: {
+ // Operation: Page(S+A) - Page(P)
+ uint64_t Result = ((Value + Addend) & ~0xfffULL) - (FinalAddress & ~0xfffULL);
+
+ // Check that -2^32 <= X < 2^32
+ assert(static_cast<int64_t>(Result) >= (-1LL << 32) &&
+ static_cast<int64_t>(Result) < (1LL << 32) &&
+ "overflow check failed for relocation");
+
+ // AArch64 code is emitted with .rela relocations. The data already in any
+ // bits affected by the relocation on entry is garbage.
+ *TargetPtr &= 0x9f00001fU;
+ // Immediate goes in bits 30:29 + 5:23 of ADRP instruction, taken
+ // from bits 32:12 of X.
+ *TargetPtr |= ((Result & 0x3000U) << (29 - 12));
+ *TargetPtr |= ((Result & 0x1ffffc000ULL) >> (14 - 5));
+ break;
+ }
+ case ELF::R_AARCH64_LDST32_ABS_LO12_NC: {
+ // Operation: S + A
+ uint64_t Result = Value + Addend;
+
+ // AArch64 code is emitted with .rela relocations. The data already in any
+ // bits affected by the relocation on entry is garbage.
+ *TargetPtr &= 0xffc003ffU;
+ // Immediate goes in bits 21:10 of LD/ST instruction, taken
+ // from bits 11:2 of X
+ *TargetPtr |= ((Result & 0xffc) << (10 - 2));
+ break;
+ }
+ case ELF::R_AARCH64_LDST64_ABS_LO12_NC: {
+ // Operation: S + A
+ uint64_t Result = Value + Addend;
+
+ // AArch64 code is emitted with .rela relocations. The data already in any
+ // bits affected by the relocation on entry is garbage.
+ *TargetPtr &= 0xffc003ffU;
+ // Immediate goes in bits 21:10 of LD/ST instruction, taken
+ // from bits 11:3 of X
+ *TargetPtr |= ((Result & 0xff8) << (10 - 3));
+ break;
+ }
}
}