Blame SOURCES/0001-Fix-R_AARCH64_MOVW_UABS_G3-relocation.patch

4cbaf7
From 29cf3bd00fe84ddab138c9311fe288bb9da8a273 Mon Sep 17 00:00:00 2001
4cbaf7
From: root <root@mammon-seattle-raw.austin.arm.com>
4cbaf7
Date: Thu, 9 Mar 2017 12:22:48 -0600
4cbaf7
Subject: [PATCH] Fix R_AARCH64_MOVW_UABS_G3 relocation
4cbaf7
4cbaf7
Summary: The relocation is missing mask so an address that
4cbaf7
has non-zero bits in 47:43 may overwrite the register
4cbaf7
number. (Frequently shows up as target register changed
4cbaf7
to xzr....)
4cbaf7
4cbaf7
Reviewers: t.p.northover, lhames
4cbaf7
Subscribers: davide, aemerson, rengolin, llvm-commits
4cbaf7
Differential Revision: https://reviews.llvm.org/D27609
4cbaf7
---
4cbaf7
 llvm-3.9.1.src/include/llvm/Object/ELFObjectFile.h |   2 +-
4cbaf7
 llvm-3.9.1.src/include/llvm/Object/RelocVisitor.h  |   1 +
4cbaf7
 .../ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp |  67 +++++++++-----
4cbaf7
 .../RuntimeDyld/AArch64/ELF_ARM64_BE-relocations.s | 102 +++++++++++++++++++++
4cbaf7
 .../RuntimeDyld/AArch64/ELF_ARM64_relocations.s    |  99 ++++++++++++++++++++
4cbaf7
 5 files changed, 249 insertions(+), 22 deletions(-)
4cbaf7
 create mode 100644 llvm-3.9.1.src/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_BE-relocations.s
4cbaf7
 create mode 100644 llvm-3.9.1.src/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_relocations.s
4cbaf7
4cbaf7
diff --git a/llvm-3.9.1.src/include/llvm/Object/ELFObjectFile.h b/llvm-3.9.1.src/include/llvm/Object/ELFObjectFile.h
4cbaf7
index 07c6364..d3b83f9 100644
4cbaf7
--- a/llvm-3.9.1.src/include/llvm/Object/ELFObjectFile.h
4cbaf7
+++ b/llvm-3.9.1.src/include/llvm/Object/ELFObjectFile.h
4cbaf7
@@ -907,7 +907,7 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
4cbaf7
   case ELF::EM_X86_64:
4cbaf7
     return Triple::x86_64;
4cbaf7
   case ELF::EM_AARCH64:
4cbaf7
-    return Triple::aarch64;
4cbaf7
+    return IsLittleEndian ? Triple::aarch64 : Triple::aarch64_be;
4cbaf7
   case ELF::EM_ARM:
4cbaf7
     return Triple::arm;
4cbaf7
   case ELF::EM_AVR:
4cbaf7
diff --git a/llvm-3.9.1.src/include/llvm/Object/RelocVisitor.h b/llvm-3.9.1.src/include/llvm/Object/RelocVisitor.h
4cbaf7
index 5e0df98..b59e8ec 100644
4cbaf7
--- a/llvm-3.9.1.src/include/llvm/Object/RelocVisitor.h
4cbaf7
+++ b/llvm-3.9.1.src/include/llvm/Object/RelocVisitor.h
4cbaf7
@@ -86,6 +86,7 @@ private:
4cbaf7
           return RelocToApply();
4cbaf7
         }
4cbaf7
       case Triple::aarch64:
4cbaf7
+      case Triple::aarch64_be:
4cbaf7
         switch (RelocType) {
4cbaf7
         case llvm::ELF::R_AARCH64_ABS32:
4cbaf7
           return visitELF_AARCH64_ABS32(R, Value);
4cbaf7
diff --git a/llvm-3.9.1.src/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm-3.9.1.src/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
4cbaf7
index 9cbdb13..9e04b5d 100644
4cbaf7
--- a/llvm-3.9.1.src/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
4cbaf7
+++ b/llvm-3.9.1.src/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
4cbaf7
@@ -309,6 +309,8 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section,
4cbaf7
   uint32_t *TargetPtr =
4cbaf7
       reinterpret_cast<uint32_t *>(Section.getAddressWithOffset(Offset));
4cbaf7
   uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
4cbaf7
+  // Data should use target endian. Code should always use little endian.
4cbaf7
+  bool isBE = Arch == Triple::aarch64_be;
4cbaf7
 
4cbaf7
   DEBUG(dbgs() << "resolveAArch64Relocation, LocalAddress: 0x"
4cbaf7
                << format("%llx", Section.getAddressWithOffset(Offset))
4cbaf7
@@ -324,14 +326,22 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section,
4cbaf7
   case ELF::R_AARCH64_ABS64: {
4cbaf7
     uint64_t *TargetPtr =
4cbaf7
         reinterpret_cast<uint64_t *>(Section.getAddressWithOffset(Offset));
4cbaf7
-    *TargetPtr = Value + Addend;
4cbaf7
+    if (isBE)
4cbaf7
+      support::ubig64_t::ref{TargetPtr} = Value + Addend;
4cbaf7
+    else
4cbaf7
+      support::ulittle64_t::ref{TargetPtr} = Value + Addend;
4cbaf7
     break;
4cbaf7
   }
4cbaf7
   case ELF::R_AARCH64_PREL32: {
4cbaf7
     uint64_t Result = Value + Addend - FinalAddress;
4cbaf7
     assert(static_cast<int64_t>(Result) >= INT32_MIN &&
4cbaf7
            static_cast<int64_t>(Result) <= UINT32_MAX);
4cbaf7
-    *TargetPtr = static_cast<uint32_t>(Result & 0xffffffffU);
4cbaf7
+    if (isBE)
4cbaf7
+      support::ubig32_t::ref{TargetPtr} =
4cbaf7
+        static_cast<uint32_t>(Result & 0xffffffffU);
4cbaf7
+    else
4cbaf7
+      support::ulittle32_t::ref{TargetPtr} =
4cbaf7
+        static_cast<uint32_t>(Result & 0xffffffffU);
4cbaf7
     break;
4cbaf7
   }
4cbaf7
   case ELF::R_AARCH64_CALL26: // fallthrough
4cbaf7
@@ -339,6 +349,7 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section,
4cbaf7
     // Operation: S+A-P. Set Call or B immediate value to bits fff_fffc of the
4cbaf7
     // calculation.
4cbaf7
     uint64_t BranchImm = Value + Addend - FinalAddress;
4cbaf7
+    uint32_t TargetValue = support::ulittle32_t::ref{TargetPtr};
4cbaf7
 
4cbaf7
     // "Check that -2^27 <= result < 2^27".
4cbaf7
     assert(isInt<28>(BranchImm));
4cbaf7
@@ -352,91 +363,105 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section,
4cbaf7
   }
4cbaf7
   case ELF::R_AARCH64_MOVW_UABS_G3: {
4cbaf7
     uint64_t Result = Value + Addend;
4cbaf7
+    uint32_t TargetValue = support::ulittle32_t::ref{TargetPtr};
4cbaf7
 
4cbaf7
     // AArch64 code is emitted with .rela relocations. The data already in any
4cbaf7
     // bits affected by the relocation on entry is garbage.
4cbaf7
-    *TargetPtr &= 0xffe0001fU;
4cbaf7
+    TargetValue &= 0xffe0001fU;
4cbaf7
     // Immediate goes in bits 20:5 of MOVZ/MOVK instruction
4cbaf7
-    *TargetPtr |= Result >> (48 - 5);
4cbaf7
+    TargetValue |= ((Result & 0xffff000000000000ULL) >> (48 - 5));
4cbaf7
     // Shift must be "lsl #48", in bits 22:21
4cbaf7
-    assert((*TargetPtr >> 21 & 0x3) == 3 && "invalid shift for relocation");
4cbaf7
+    assert((TargetValue >> 21 & 0x3) == 3 && "invalid shift for relocation");
4cbaf7
+    support::ulittle32_t::ref{TargetPtr} = TargetValue;
4cbaf7
     break;
4cbaf7
   }
4cbaf7
   case ELF::R_AARCH64_MOVW_UABS_G2_NC: {
4cbaf7
     uint64_t Result = Value + Addend;
4cbaf7
+    uint32_t TargetValue = support::ulittle32_t::ref{TargetPtr};
4cbaf7
 
4cbaf7
     // AArch64 code is emitted with .rela relocations. The data already in any
4cbaf7
     // bits affected by the relocation on entry is garbage.
4cbaf7
-    *TargetPtr &= 0xffe0001fU;
4cbaf7
+    TargetValue &= 0xffe0001fU;
4cbaf7
     // Immediate goes in bits 20:5 of MOVZ/MOVK instruction
4cbaf7
-    *TargetPtr |= ((Result & 0xffff00000000ULL) >> (32 - 5));
4cbaf7
+    TargetValue |= ((Result & 0xffff00000000ULL) >> (32 - 5));
4cbaf7
     // Shift must be "lsl #32", in bits 22:21
4cbaf7
-    assert((*TargetPtr >> 21 & 0x3) == 2 && "invalid shift for relocation");
4cbaf7
+    assert((TargetValue >> 21 & 0x3) == 2 && "invalid shift for relocation");
4cbaf7
+    support::ulittle32_t::ref{TargetPtr} = TargetValue;
4cbaf7
     break;
4cbaf7
   }
4cbaf7
   case ELF::R_AARCH64_MOVW_UABS_G1_NC: {
4cbaf7
     uint64_t Result = Value + Addend;
4cbaf7
+    uint32_t TargetValue = support::ulittle32_t::ref{TargetPtr};
4cbaf7
 
4cbaf7
     // AArch64 code is emitted with .rela relocations. The data already in any
4cbaf7
     // bits affected by the relocation on entry is garbage.
4cbaf7
-    *TargetPtr &= 0xffe0001fU;
4cbaf7
+    TargetValue &= 0xffe0001fU;
4cbaf7
     // Immediate goes in bits 20:5 of MOVZ/MOVK instruction
4cbaf7
-    *TargetPtr |= ((Result & 0xffff0000U) >> (16 - 5));
4cbaf7
+    TargetValue |= ((Result & 0xffff0000U) >> (16 - 5));
4cbaf7
     // Shift must be "lsl #16", in bits 22:2
4cbaf7
-    assert((*TargetPtr >> 21 & 0x3) == 1 && "invalid shift for relocation");
4cbaf7
+    assert((TargetValue >> 21 & 0x3) == 1 && "invalid shift for relocation");
4cbaf7
+    support::ulittle32_t::ref{TargetPtr} = TargetValue;
4cbaf7
     break;
4cbaf7
   }
4cbaf7
   case ELF::R_AARCH64_MOVW_UABS_G0_NC: {
4cbaf7
     uint64_t Result = Value + Addend;
4cbaf7
+    uint32_t TargetValue = support::ulittle32_t::ref{TargetPtr};
4cbaf7
 
4cbaf7
     // AArch64 code is emitted with .rela relocations. The data already in any
4cbaf7
     // bits affected by the relocation on entry is garbage.
4cbaf7
-    *TargetPtr &= 0xffe0001fU;
4cbaf7
+    TargetValue &= 0xffe0001fU;
4cbaf7
     // Immediate goes in bits 20:5 of MOVZ/MOVK instruction
4cbaf7
-    *TargetPtr |= ((Result & 0xffffU) << 5);
4cbaf7
+    TargetValue |= ((Result & 0xffffU) << 5);
4cbaf7
     // Shift must be "lsl #0", in bits 22:21.
4cbaf7
-    assert((*TargetPtr >> 21 & 0x3) == 0 && "invalid shift for relocation");
4cbaf7
+    assert((TargetValue >> 21 & 0x3) == 0 && "invalid shift for relocation");
4cbaf7
+    support::ulittle32_t::ref{TargetPtr} = TargetValue;
4cbaf7
     break;
4cbaf7
   }
4cbaf7
   case ELF::R_AARCH64_ADR_PREL_PG_HI21: {
4cbaf7
     // Operation: Page(S+A) - Page(P)
4cbaf7
     uint64_t Result =
4cbaf7
         ((Value + Addend) & ~0xfffULL) - (FinalAddress & ~0xfffULL);
4cbaf7
+    uint32_t TargetValue = support::ulittle32_t::ref{TargetPtr};
4cbaf7
 
4cbaf7
     // Check that -2^32 <= X < 2^32
4cbaf7
     assert(isInt<33>(Result) && "overflow check failed for relocation");
4cbaf7
 
4cbaf7
     // AArch64 code is emitted with .rela relocations. The data already in any
4cbaf7
     // bits affected by the relocation on entry is garbage.
4cbaf7
-    *TargetPtr &= 0x9f00001fU;
4cbaf7
+    TargetValue &= 0x9f00001fU;
4cbaf7
     // Immediate goes in bits 30:29 + 5:23 of ADRP instruction, taken
4cbaf7
     // from bits 32:12 of X.
4cbaf7
-    *TargetPtr |= ((Result & 0x3000U) << (29 - 12));
4cbaf7
-    *TargetPtr |= ((Result & 0x1ffffc000ULL) >> (14 - 5));
4cbaf7
+    TargetValue |= ((Result & 0x3000U) << (29 - 12));
4cbaf7
+    TargetValue |= ((Result & 0x1ffffc000ULL) >> (14 - 5));
4cbaf7
+    support::ulittle32_t::ref{TargetPtr} = TargetValue;
4cbaf7
     break;
4cbaf7
   }
4cbaf7
   case ELF::R_AARCH64_LDST32_ABS_LO12_NC: {
4cbaf7
     // Operation: S + A
4cbaf7
     uint64_t Result = Value + Addend;
4cbaf7
+    uint32_t TargetValue = support::ulittle32_t::ref{TargetPtr};
4cbaf7
 
4cbaf7
     // AArch64 code is emitted with .rela relocations. The data already in any
4cbaf7
     // bits affected by the relocation on entry is garbage.
4cbaf7
-    *TargetPtr &= 0xffc003ffU;
4cbaf7
+    TargetValue &= 0xffc003ffU;
4cbaf7
     // Immediate goes in bits 21:10 of LD/ST instruction, taken
4cbaf7
     // from bits 11:2 of X
4cbaf7
-    *TargetPtr |= ((Result & 0xffc) << (10 - 2));
4cbaf7
+    TargetValue |= ((Result & 0xffc) << (10 - 2));
4cbaf7
+    support::ulittle32_t::ref{TargetPtr} = TargetValue;
4cbaf7
     break;
4cbaf7
   }
4cbaf7
   case ELF::R_AARCH64_LDST64_ABS_LO12_NC: {
4cbaf7
     // Operation: S + A
4cbaf7
     uint64_t Result = Value + Addend;
4cbaf7
+    uint32_t TargetValue = support::ulittle32_t::ref{TargetPtr};
4cbaf7
 
4cbaf7
     // AArch64 code is emitted with .rela relocations. The data already in any
4cbaf7
     // bits affected by the relocation on entry is garbage.
4cbaf7
-    *TargetPtr &= 0xffc003ffU;
4cbaf7
+    TargetValue &= 0xffc003ffU;
4cbaf7
     // Immediate goes in bits 21:10 of LD/ST instruction, taken
4cbaf7
     // from bits 11:3 of X
4cbaf7
-    *TargetPtr |= ((Result & 0xff8) << (10 - 3));
4cbaf7
+    TargetValue |= ((Result & 0xff8) << (10 - 3));
4cbaf7
+    support::ulittle32_t::ref{TargetPtr} = TargetValue;
4cbaf7
     break;
4cbaf7
   }
4cbaf7
   }
4cbaf7
diff --git a/llvm-3.9.1.src/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_BE-relocations.s b/llvm-3.9.1.src/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_BE-relocations.s
4cbaf7
new file mode 100644
4cbaf7
index 0000000..01d01e5
4cbaf7
--- /dev/null
4cbaf7
+++ b/llvm-3.9.1.src/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_BE-relocations.s
4cbaf7
@@ -0,0 +1,102 @@
4cbaf7
+# RUN: llvm-mc -triple=aarch64_be-none-linux-gnu -filetype=obj -o %T/be-reloc.o %s
4cbaf7
+# RUN: llvm-rtdyld -triple=aarch64_be-none-linux-gnu -verify -dummy-extern f=0x0123456789abcdef -check=%s %T/be-reloc.o
4cbaf7
+
4cbaf7
+        .text
4cbaf7
+        .globl  g
4cbaf7
+        .p2align        2
4cbaf7
+        .type   g,@function
4cbaf7
+g:
4cbaf7
+# R_AARCH64_MOVW_UABS_G3
4cbaf7
+        movz    x0, #:abs_g3:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G2_NC
4cbaf7
+        movk    x0, #:abs_g2_nc:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G1_NC
4cbaf7
+        movk    x0, #:abs_g1_nc:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G0_NC
4cbaf7
+        movk    x0, #:abs_g0_nc:f
4cbaf7
+        ret
4cbaf7
+        .Lfunc_end0:
4cbaf7
+        .size   g, .Lfunc_end0-g
4cbaf7
+
4cbaf7
+        .type   k,@object
4cbaf7
+        .data
4cbaf7
+        .globl  k
4cbaf7
+        .p2align        3
4cbaf7
+k:
4cbaf7
+        .xword  f
4cbaf7
+        .size   k, 8
4cbaf7
+
4cbaf7
+# LE instructions read as BE
4cbaf7
+# rtdyld-check: *{4}(g) = 0x6024e0d2
4cbaf7
+# rtdyld-check: *{4}(g + 4) = 0xe0acc8f2
4cbaf7
+# rtdyld-check: *{4}(g + 8) = 0x6035b1f2
4cbaf7
+# rtdyld-check: *{4}(g + 12) = 0xe0bd99f2
4cbaf7
+# rtdyld-check: *{8}k = f
4cbaf7
+# RUN: llvm-mc -triple=aarch64_be-none-linux-gnu -filetype=obj -o %T/be-reloc.o %s
4cbaf7
+# RUN: llvm-rtdyld -triple=aarch64_be-none-linux-gnu -verify -dummy-extern f=0x0123456789abcdef -check=%s %T/be-reloc.o
4cbaf7
+
4cbaf7
+        .text
4cbaf7
+        .globl  g
4cbaf7
+        .p2align        2
4cbaf7
+        .type   g,@function
4cbaf7
+g:
4cbaf7
+# R_AARCH64_MOVW_UABS_G3
4cbaf7
+        movz    x0, #:abs_g3:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G2_NC
4cbaf7
+        movk    x0, #:abs_g2_nc:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G1_NC
4cbaf7
+        movk    x0, #:abs_g1_nc:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G0_NC
4cbaf7
+        movk    x0, #:abs_g0_nc:f
4cbaf7
+        ret
4cbaf7
+        .Lfunc_end0:
4cbaf7
+        .size   g, .Lfunc_end0-g
4cbaf7
+
4cbaf7
+        .type   k,@object
4cbaf7
+        .data
4cbaf7
+        .globl  k
4cbaf7
+        .p2align        3
4cbaf7
+k:
4cbaf7
+        .xword  f
4cbaf7
+        .size   k, 8
4cbaf7
+
4cbaf7
+# LE instructions read as BE
4cbaf7
+# rtdyld-check: *{4}(g) = 0x6024e0d2
4cbaf7
+# rtdyld-check: *{4}(g + 4) = 0xe0acc8f2
4cbaf7
+# rtdyld-check: *{4}(g + 8) = 0x6035b1f2
4cbaf7
+# rtdyld-check: *{4}(g + 12) = 0xe0bd99f2
4cbaf7
+# rtdyld-check: *{8}k = f
4cbaf7
+# RUN: llvm-mc -triple=aarch64_be-none-linux-gnu -filetype=obj -o %T/be-reloc.o %s
4cbaf7
+# RUN: llvm-rtdyld -triple=aarch64_be-none-linux-gnu -verify -dummy-extern f=0x0123456789abcdef -check=%s %T/be-reloc.o
4cbaf7
+
4cbaf7
+        .text
4cbaf7
+        .globl  g
4cbaf7
+        .p2align        2
4cbaf7
+        .type   g,@function
4cbaf7
+g:
4cbaf7
+# R_AARCH64_MOVW_UABS_G3
4cbaf7
+        movz    x0, #:abs_g3:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G2_NC
4cbaf7
+        movk    x0, #:abs_g2_nc:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G1_NC
4cbaf7
+        movk    x0, #:abs_g1_nc:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G0_NC
4cbaf7
+        movk    x0, #:abs_g0_nc:f
4cbaf7
+        ret
4cbaf7
+        .Lfunc_end0:
4cbaf7
+        .size   g, .Lfunc_end0-g
4cbaf7
+
4cbaf7
+        .type   k,@object
4cbaf7
+        .data
4cbaf7
+        .globl  k
4cbaf7
+        .p2align        3
4cbaf7
+k:
4cbaf7
+        .xword  f
4cbaf7
+        .size   k, 8
4cbaf7
+
4cbaf7
+# LE instructions read as BE
4cbaf7
+# rtdyld-check: *{4}(g) = 0x6024e0d2
4cbaf7
+# rtdyld-check: *{4}(g + 4) = 0xe0acc8f2
4cbaf7
+# rtdyld-check: *{4}(g + 8) = 0x6035b1f2
4cbaf7
+# rtdyld-check: *{4}(g + 12) = 0xe0bd99f2
4cbaf7
+# rtdyld-check: *{8}k = f
4cbaf7
diff --git a/llvm-3.9.1.src/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_relocations.s b/llvm-3.9.1.src/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_relocations.s
4cbaf7
new file mode 100644
4cbaf7
index 0000000..e07fa97
4cbaf7
--- /dev/null
4cbaf7
+++ b/llvm-3.9.1.src/test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_relocations.s
4cbaf7
@@ -0,0 +1,99 @@
4cbaf7
+# RUN: llvm-mc -triple=arm64-none-linux-gnu -filetype=obj -o %T/reloc.o %s
4cbaf7
+# RUN: llvm-rtdyld -triple=arm64-none-linux-gnu -verify -dummy-extern f=0x0123456789abcdef -check=%s %T/reloc.o
4cbaf7
+
4cbaf7
+        .text
4cbaf7
+        .globl  g
4cbaf7
+        .p2align        2
4cbaf7
+        .type   g,@function
4cbaf7
+g:
4cbaf7
+# R_AARCH64_MOVW_UABS_G3
4cbaf7
+        movz    x0, #:abs_g3:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G2_NC
4cbaf7
+        movk    x0, #:abs_g2_nc:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G1_NC
4cbaf7
+        movk    x0, #:abs_g1_nc:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G0_NC
4cbaf7
+        movk    x0, #:abs_g0_nc:f
4cbaf7
+        ret
4cbaf7
+        .Lfunc_end0:
4cbaf7
+        .size   g, .Lfunc_end0-g
4cbaf7
+
4cbaf7
+        .type   k,@object
4cbaf7
+        .data
4cbaf7
+        .globl  k
4cbaf7
+        .p2align        3
4cbaf7
+k:
4cbaf7
+        .xword  f
4cbaf7
+        .size   k, 8
4cbaf7
+
4cbaf7
+# rtdyld-check: *{4}(g) = 0xd2e02460
4cbaf7
+# rtdyld-check: *{4}(g + 4) = 0xf2c8ace0
4cbaf7
+# rtdyld-check: *{4}(g + 8) = 0xf2b13560
4cbaf7
+# rtdyld-check: *{4}(g + 12) = 0xf299bde0
4cbaf7
+# rtdyld-check: *{8}k = f
4cbaf7
+# RUN: llvm-mc -triple=arm64-none-linux-gnu -filetype=obj -o %T/reloc.o %s
4cbaf7
+# RUN: llvm-rtdyld -triple=arm64-none-linux-gnu -verify -dummy-extern f=0x0123456789abcdef -check=%s %T/reloc.o
4cbaf7
+
4cbaf7
+        .text
4cbaf7
+        .globl  g
4cbaf7
+        .p2align        2
4cbaf7
+        .type   g,@function
4cbaf7
+g:
4cbaf7
+# R_AARCH64_MOVW_UABS_G3
4cbaf7
+        movz    x0, #:abs_g3:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G2_NC
4cbaf7
+        movk    x0, #:abs_g2_nc:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G1_NC
4cbaf7
+        movk    x0, #:abs_g1_nc:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G0_NC
4cbaf7
+        movk    x0, #:abs_g0_nc:f
4cbaf7
+        ret
4cbaf7
+        .Lfunc_end0:
4cbaf7
+        .size   g, .Lfunc_end0-g
4cbaf7
+
4cbaf7
+        .type   k,@object
4cbaf7
+        .data
4cbaf7
+        .globl  k
4cbaf7
+        .p2align        3
4cbaf7
+k:
4cbaf7
+        .xword  f
4cbaf7
+        .size   k, 8
4cbaf7
+
4cbaf7
+# rtdyld-check: *{4}(g) = 0xd2e02460
4cbaf7
+# rtdyld-check: *{4}(g + 4) = 0xf2c8ace0
4cbaf7
+# rtdyld-check: *{4}(g + 8) = 0xf2b13560
4cbaf7
+# rtdyld-check: *{4}(g + 12) = 0xf299bde0
4cbaf7
+# rtdyld-check: *{8}k = f
4cbaf7
+# RUN: llvm-mc -triple=arm64-none-linux-gnu -filetype=obj -o %T/reloc.o %s
4cbaf7
+# RUN: llvm-rtdyld -triple=arm64-none-linux-gnu -verify -dummy-extern f=0x0123456789abcdef -check=%s %T/reloc.o
4cbaf7
+
4cbaf7
+        .text
4cbaf7
+        .globl  g
4cbaf7
+        .p2align        2
4cbaf7
+        .type   g,@function
4cbaf7
+g:
4cbaf7
+# R_AARCH64_MOVW_UABS_G3
4cbaf7
+        movz    x0, #:abs_g3:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G2_NC
4cbaf7
+        movk    x0, #:abs_g2_nc:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G1_NC
4cbaf7
+        movk    x0, #:abs_g1_nc:f
4cbaf7
+# R_AARCH64_MOVW_UABS_G0_NC
4cbaf7
+        movk    x0, #:abs_g0_nc:f
4cbaf7
+        ret
4cbaf7
+        .Lfunc_end0:
4cbaf7
+        .size   g, .Lfunc_end0-g
4cbaf7
+
4cbaf7
+        .type   k,@object
4cbaf7
+        .data
4cbaf7
+        .globl  k
4cbaf7
+        .p2align        3
4cbaf7
+k:
4cbaf7
+        .xword  f
4cbaf7
+        .size   k, 8
4cbaf7
+
4cbaf7
+# rtdyld-check: *{4}(g) = 0xd2e02460
4cbaf7
+# rtdyld-check: *{4}(g + 4) = 0xf2c8ace0
4cbaf7
+# rtdyld-check: *{4}(g + 8) = 0xf2b13560
4cbaf7
+# rtdyld-check: *{4}(g + 12) = 0xf299bde0
4cbaf7
+# rtdyld-check: *{8}k = f
4cbaf7
-- 
4cbaf7
2.12.0
4cbaf7