From 9d80849714a88ba64c278b5d739512dc72c4b859 Mon Sep 17 00:00:00 2001 From: Bradley Smith Date: Tue, 11 Feb 2014 12:59:09 +0000 Subject: [PATCH] [AArch64] Add missing PCRel relocations for AArch64 in RuntimeDyldELF llvm-svn: 201149 --- .../RuntimeDyld/RuntimeDyldELF.cpp | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index a4246e0c71ed..52f33ca11ca5 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/llvm/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(Result) >= (-1LL << 32) && + static_cast(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; + } } }