From ba8683f29290f9ccc16b9403d537241c1e25c4f9 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Wed, 5 Aug 2020 21:07:45 -0700 Subject: [PATCH] [JITLink][MachO][AArch64] More PAGEOFF12 relocation fixes. 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. --- .../ExecutionEngine/JITLink/MachO_arm64.cpp | 35 +++++++++---------- .../JITLink/AArch64/MachO_arm64_relocations.s | 10 ++++++ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp index df5817681e2028..a7178aa1e45088 100644 --- a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp @@ -256,7 +256,7 @@ class MachOLinkGraphBuilder_arm64 : public MachOLinkGraphBuilder { // 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("Unpaired Addend reloc at " + @@ -340,6 +340,11 @@ class MachOLinkGraphBuilder_arm64 : public MachOLinkGraphBuilder { 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("GOTPAGEOFF12 target has non-zero " + "encoded addend"); break; } case GOTPageOffset12: { @@ -524,23 +529,17 @@ class MachOJITLinker_arm64 : public JITLinker { } 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; } diff --git a/llvm/test/ExecutionEngine/JITLink/AArch64/MachO_arm64_relocations.s b/llvm/test/ExecutionEngine/JITLink/AArch64/MachO_arm64_relocations.s index 4bf084296e4f6a..8cdc9150000556 100644 --- a/llvm/test/ExecutionEngine/JITLink/AArch64/MachO_arm64_relocations.s +++ b/llvm/test/ExecutionEngine/JITLink/AArch64/MachO_arm64_relocations.s @@ -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]