[JITLink][MachO][AArch64] More PAGEOFF12 relocation fixes.
authorLang Hames <lhames@gmail.com>
Thu, 6 Aug 2020 04:07:45 +0000 (21:07 -0700)
committerLang Hames <lhames@gmail.com>
Thu, 6 Aug 2020 04:09:45 +0000 (21:09 -0700)
Correctly sign extend the addend, and fix implicit shift operand decoding
(it incorrectly returned 0 for some cases), and check that the initial
encoded immediate is 0.

llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp
llvm/test/ExecutionEngine/JITLink/AArch64/MachO_arm64_relocations.s

index df58176..a7178aa 100644 (file)
@@ -256,7 +256,7 @@ private:
           // If this is an Addend relocation then process it and move to the
           // paired reloc.
 
-          Addend = RI.r_symbolnum;
+          Addend = SignExtend64(RI.r_symbolnum, 24);
 
           if (RelItr == RelEnd)
             return make_error<JITLinkError>("Unpaired Addend reloc at " +
@@ -340,6 +340,11 @@ private:
             TargetSymbol = TargetSymbolOrErr->GraphSymbol;
           else
             return TargetSymbolOrErr.takeError();
+          uint32_t Instr = *(const ulittle32_t *)FixupContent;
+          uint32_t EncodedAddend = (Instr & 0x003FFC00) >> 10;
+          if (EncodedAddend != 0)
+            return make_error<JITLinkError>("GOTPAGEOFF12 target has non-zero "
+                                            "encoded addend");
           break;
         }
         case GOTPageOffset12: {
@@ -524,23 +529,17 @@ private:
   }
 
   static unsigned getPageOffset12Shift(uint32_t Instr) {
-    constexpr uint32_t LDRLiteralMask = 0x3ffffc00;
-
-    // Check for a GPR LDR immediate with a zero embedded literal.
-    // If found, the top two bits contain the shift.
-    if ((Instr & LDRLiteralMask) == 0x39400000)
-      return Instr >> 30;
-
-    // Check for a Neon LDR immediate of size 64-bit or less with a zero
-    // embedded literal. If found, the top two bits contain the shift.
-    if ((Instr & LDRLiteralMask) == 0x3d400000)
-      return Instr >> 30;
-
-    // Check for a Neon LDR immediate of size 128-bit with a zero embedded
-    // literal.
-    constexpr uint32_t SizeBitsMask = 0xc0000000;
-    if ((Instr & (LDRLiteralMask | SizeBitsMask)) == 0x3dc00000)
-      return 4;
+    constexpr uint32_t LoadStoreImm12Mask = 0x3b000000;
+    constexpr uint32_t Vec128Mask = 0x04800000;
+
+    if ((Instr & LoadStoreImm12Mask) == 0x39000000) {
+      uint32_t ImplicitShift = Instr >> 30;
+      if (ImplicitShift == 0)
+        if ((Instr & Vec128Mask) == Vec128Mask)
+          ImplicitShift = 4;
+
+      return ImplicitShift;
+    }
 
     return 0;
   }
index 4bf0842..8cdc915 100644 (file)
@@ -61,7 +61,9 @@ test_gotpageoff12:
 # jitlink-check: decode_operand(test_page21, 1) = ((named_data + 256) - test_page21)[32:12]
 # jitlink-check: decode_operand(test_pageoff12add, 2) = (named_data + 256)[11:0]
 # jitlink-check: decode_operand(test_pageoff12gpr8, 2) = (named_data + 256)[11:0]
+# jitlink-cherk: decode_operand(test_pageoff12gpr8s, 2) = (named_data + 256)[11:0]
 # jitlink-check: decode_operand(test_pageoff12gpr16, 2) = (named_data + 256)[11:1]
+# jitlink-check: decode_operand(test_pageoff12gpr16s, 2) = (named_data + 256)[11:1]
 # jitlink-check: decode_operand(test_pageoff12gpr32, 2) = (named_data + 256)[11:2]
 # jitlink-check: decode_operand(test_pageoff12gpr64, 2) = (named_data + 256)[11:3]
 # jitlink-check: decode_operand(test_pageoff12neon8, 2) = (named_data + 256)[11:0]
@@ -82,10 +84,18 @@ test_pageoff12add:
 test_pageoff12gpr8:
         ldrb  w0, [x0, named_data@PAGEOFF + 256]
 
+        .globl  test_pageoff12gpr8s
+test_pageoff12gpr8s:
+        ldrsb w0, [x0, named_data@PAGEOFF + 256]
+
         .globl  test_pageoff12gpr16
 test_pageoff12gpr16:
         ldrh  w0, [x0, named_data@PAGEOFF + 256]
 
+        .globl  test_pageoff12gpr16s
+test_pageoff12gpr16s:
+        ldrsh w0, [x0, named_data@PAGEOFF + 256]
+
         .globl  test_pageoff12gpr32
 test_pageoff12gpr32:
         ldr   w0, [x0, named_data@PAGEOFF + 256]