AArch64: implement relocations for global access
authorTim Northover <Tim.Northover@arm.com>
Sat, 4 May 2013 20:14:04 +0000 (20:14 +0000)
committerTim Northover <Tim.Northover@arm.com>
Sat, 4 May 2013 20:14:04 +0000 (20:14 +0000)
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

lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp

index 49baf750dbbc1dbdac080bd675dea1a61762c6d8..5e361ef64adee435c9cf867b1309414c5ee8ed5a 100644 (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;
+  }
   }
 }