[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
This commit is contained in:
Bradley Smith 2014-02-11 12:59:09 +00:00
parent 8615ab4a4a
commit 79ced8c5fa

View File

@ -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;
}
}
}