From 447d3017e476e1dd2a5779051f26fa5eb12d9465 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Tue, 12 Oct 2021 21:51:12 -0700 Subject: [PATCH] [JITLink][MachO][arm64] Mask high bits out of immediate for LDRLiteral19. Negative deltas for LDRLiteral19 have their high bits set. If these bits aren't masked out then they will overwrite other instruction bits, leading to a bogus encoding. This long-standing relocation bug was exposed by e50aea58d59, "[JITLink][ORC] Major JITLinkMemoryManager refactor.", which caused memory layouts to be reordered, which in turn lead to a previously unseen negative delta. (Unseen because LDRLiteral19s were only created in JITLink passes where they always pointed at segments that were layed-out-after in the old layout). No testcase yet: Our existing regression test infrastructure is good at checking that operand bits are correct, but provides no easy way to test for bad opcode bits. I'll have a think about the right way to approach this. https://llvm.org/PR52153 --- llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp index bf81fc4..af1d883 100644 --- a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp @@ -627,7 +627,8 @@ private: if (Delta < -(1 << 20) || Delta > ((1 << 20) - 1)) return makeTargetOutOfRangeError(G, B, E); - uint32_t EncodedImm = (static_cast(Delta) >> 2) << 5; + uint32_t EncodedImm = + ((static_cast(Delta) >> 2) & 0x7ffff) << 5; uint32_t FixedInstr = RawInstr | EncodedImm; *(ulittle32_t *)FixupPtr = FixedInstr; break; -- 2.7.4