[llvm] r349799 - [MC] [AArch64] Support resolving fixups for abs_g0 etc.

Eli Friedman via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 20 11:38:07 PST 2018


Author: efriedma
Date: Thu Dec 20 11:38:07 2018
New Revision: 349799

URL: http://llvm.org/viewvc/llvm-project?rev=349799&view=rev
Log:
[MC] [AArch64] Support resolving fixups for abs_g0 etc.

This requires a bit more code than other fixups, to distingush between
abs_g0/abs_g1/etc.  Actually, I think some of the other fixups are
missing some checks, but I won't try to address that here.

I haven't seen any real-world code that uses a construct like this, but
it clearly should work, and we're considering using it in the
implementation of localescape/localrecover on Windows (see
https://reviews.llvm.org/D53540). I've verified that binutils produces
the same code as llvm-mc for the testcase.

This currently doesn't include support for the *_s variants (that
requires a bit more work to set the opcode).

Differential Revision: https://reviews.llvm.org/D55896


Added:
    llvm/trunk/test/MC/AArch64/fixup-absolute.s
Modified:
    llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
    llvm/trunk/test/MC/AArch64/fixup-out-of-range.s

Modified: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp?rev=349799&r1=349798&r2=349799&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp Thu Dec 20 11:38:07 2018
@@ -110,11 +110,11 @@ static unsigned getFixupKindNumBytes(uns
   case FK_Data_1:
     return 1;
 
-  case AArch64::fixup_aarch64_movw:
   case FK_Data_2:
   case FK_SecRel_2:
     return 2;
 
+  case AArch64::fixup_aarch64_movw:
   case AArch64::fixup_aarch64_pcrel_branch14:
   case AArch64::fixup_aarch64_add_imm12:
   case AArch64::fixup_aarch64_ldst_imm12_scale1:
@@ -145,9 +145,9 @@ static unsigned AdrImmBits(unsigned Valu
   return (hi19 << 5) | (lo2 << 29);
 }
 
-static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
-                                 MCContext &Ctx, const Triple &TheTriple,
-                                 bool IsResolved) {
+static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
+                                 uint64_t Value, MCContext &Ctx,
+                                 const Triple &TheTriple, bool IsResolved) {
   unsigned Kind = Fixup.getKind();
   int64_t SignedValue = static_cast<int64_t>(Value);
   switch (Kind) {
@@ -215,10 +215,51 @@ static uint64_t adjustFixupValue(const M
     if (Value & 0xf)
       Ctx.reportError(Fixup.getLoc(), "fixup must be 16-byte aligned");
     return Value >> 4;
-  case AArch64::fixup_aarch64_movw:
-    Ctx.reportError(Fixup.getLoc(),
-                    "no resolvable MOVZ/MOVK fixups supported yet");
+  case AArch64::fixup_aarch64_movw: {
+    AArch64MCExpr::VariantKind RefKind =
+        static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
+    if (AArch64MCExpr::getSymbolLoc(RefKind) != AArch64MCExpr::VK_ABS) {
+      if (AArch64MCExpr::getSymbolLoc(RefKind) != AArch64MCExpr::VK_SABS) {
+        // VK_GOTTPREL, VK_TPREL, VK_DTPREL are movw fixups, but they can't
+        // ever be resolved in the assembler.
+        Ctx.reportError(Fixup.getLoc(),
+                        "relocation for a thread-local variable points to an "
+                        "absolute symbol");
+        return Value;
+      }
+      Ctx.reportError(Fixup.getLoc(),
+                      "resolvable R_AARCH64_MOVW_SABS_G* fixups are not "
+                       "yet implemented");
+      return Value;
+    }
+    if (!IsResolved) {
+      // FIXME: Figure out when this can actually happen, and verify our
+      // behavior.
+      Ctx.reportError(Fixup.getLoc(), "unresolved movw fixup not yet "
+                                      "implemented");
+      return Value;
+    }
+    switch (AArch64MCExpr::getAddressFrag(RefKind)) {
+    case AArch64MCExpr::VK_G0:
+      break;
+    case AArch64MCExpr::VK_G1:
+      Value = Value >> 16;
+      break;
+    case AArch64MCExpr::VK_G2:
+      Value = Value >> 32;
+      break;
+    case AArch64MCExpr::VK_G3:
+      Value = Value >> 48;
+      break;
+    default:
+      llvm_unreachable("Variant kind doesn't correspond to fixup");
+    }
+    if (RefKind & AArch64MCExpr::VK_NC)
+      Value &= 0xFFFF;
+    else if (Value > 0xFFFF)
+      Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
     return Value;
+  }
   case AArch64::fixup_aarch64_pcrel_branch14:
     // Signed 16-bit immediate
     if (SignedValue > 32767 || SignedValue < -32768)
@@ -296,7 +337,7 @@ void AArch64AsmBackend::applyFixup(const
   MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
   MCContext &Ctx = Asm.getContext();
   // Apply any target-specific value adjustments.
-  Value = adjustFixupValue(Fixup, Value, Ctx, TheTriple, IsResolved);
+  Value = adjustFixupValue(Fixup, Target, Value, Ctx, TheTriple, IsResolved);
 
   // Shift the value into position.
   Value <<= Info.TargetOffset;

Added: llvm/trunk/test/MC/AArch64/fixup-absolute.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/fixup-absolute.s?rev=349799&view=auto
==============================================================================
--- llvm/trunk/test/MC/AArch64/fixup-absolute.s (added)
+++ llvm/trunk/test/MC/AArch64/fixup-absolute.s Thu Dec 20 11:38:07 2018
@@ -0,0 +1,21 @@
+// RUN: llvm-mc -triple aarch64--none-eabi -filetype obj < %s -o - | llvm-objdump -d - | FileCheck %s
+
+// CHECK: mov     x0, #1311673391471656960
+movz x0, #:abs_g3:fourpart
+// CHECK: mov     x0, #20014547599360
+movz x0, #:abs_g2:threepart
+// CHECK: movk    x0, #22136, lsl #32
+movk x0, #:abs_g2_nc:fourpart
+// CHECK: mov     x0, #305397760
+movz x0, #:abs_g1:twopart
+// CHECK: movk    x0, #37035, lsl #16
+movk x0, #:abs_g1_nc:fourpart
+// CHECK: mov     x0, #4660
+movz x0, #:abs_g0:onepart
+// CHECK: movk    x0, #52719
+movk x0, #:abs_g0_nc:fourpart
+
+onepart = 0x1234
+twopart = 0x12345678
+threepart = 0x1234567890AB
+fourpart = 0x1234567890ABCDEF

Modified: llvm/trunk/test/MC/AArch64/fixup-out-of-range.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/fixup-out-of-range.s?rev=349799&r1=349798&r2=349799&view=diff
==============================================================================
--- llvm/trunk/test/MC/AArch64/fixup-out-of-range.s (original)
+++ llvm/trunk/test/MC/AArch64/fixup-out-of-range.s Thu Dec 20 11:38:07 2018
@@ -55,6 +55,19 @@
 // CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: fixup not sufficiently aligned
   b unaligned
 
+// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: fixup value out of range
+  movz x0, #:abs_g0:value1
+
+// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: fixup value out of range
+  movz x0, #:abs_g1:value2
+
+// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: resolvable R_AARCH64_MOVW_SABS_G* fixups are not yet implemented
+  movz x0, #:abs_g0_s:value1
+
+// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: relocation for a thread-local variable points to an absolute symbol
+  movz x0, #:tprel_g0:value1
+
+
   .byte 0
 unaligned:
   .byte 0
@@ -63,3 +76,5 @@ unaligned:
   .balign 8
 distant:
   .word 0
+value1 = 0x12345678
+value2 = 0x123456789




More information about the llvm-commits mailing list