AArch64: implement relocations for global access

The large memory model (default and main viable for JIT) emits
addresses in need of relocation as
    movz x0, #:abs_g3:somewhere
    movk x0, #:abs_g2_nc:somewhere
    movk x0, #:abs_g1_nc:somewhere
    movk x0, #:abs_g0_nc:somewhere

To support this we must implement those four relocations in the
dynamic loader.

This allows (for example) the test-global.ll MCJIT test to pass on
AArch64.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181132 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tim Northover 2013-05-04 20:14:04 +00:00
parent 85829bb98a
commit 654c2d6b7a

View File

@ -296,6 +296,37 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section,
*TargetPtr = static_cast<uint32_t>(Result & 0xffffffffU);
break;
}
case ELF::R_AARCH64_MOVW_UABS_G3: {
uint64_t Result = Value + Addend;
// Immediate goes in bits 20:5 of MOVZ/MOVK instruction
*TargetPtr |= Result >> (48 - 5);
// Shift is "lsl #48", in bits 22:21
*TargetPtr |= 3 << 21;
break;
}
case ELF::R_AARCH64_MOVW_UABS_G2_NC: {
uint64_t Result = Value + Addend;
// Immediate goes in bits 20:5 of MOVZ/MOVK instruction
*TargetPtr |= ((Result & 0xffff00000000ULL) >> (32 - 5));
// Shift is "lsl #32", in bits 22:21
*TargetPtr |= 2 << 21;
break;
}
case ELF::R_AARCH64_MOVW_UABS_G1_NC: {
uint64_t Result = Value + Addend;
// Immediate goes in bits 20:5 of MOVZ/MOVK instruction
*TargetPtr |= ((Result & 0xffff0000U) >> (16 - 5));
// Shift is "lsl #16", in bits 22:21
*TargetPtr |= 1 << 21;
break;
}
case ELF::R_AARCH64_MOVW_UABS_G0_NC: {
uint64_t Result = Value + Addend;
// Immediate goes in bits 20:5 of MOVZ/MOVK instruction
*TargetPtr |= ((Result & 0xffffU) << 5);
// Shift is "lsl #0", in bits 22:21. No action needed.
break;
}
}
}