Author: Lang Hames Date: 2025-02-08T16:19:54Z New Revision: 749bebc5dab440377bc8365ee0d278423d19cd92
URL: https://github.com/llvm/llvm-project/commit/749bebc5dab440377bc8365ee0d278423d19cd92 DIFF: https://github.com/llvm/llvm-project/commit/749bebc5dab440377bc8365ee0d278423d19cd92.diff LOG: [JITLink] Handle compact-unwind records that depend on DWARF FDEs. Compact-unwind encodings are more limited than DWARF frame descriptions. For functions whose frame layout cannot be described by a compact unwind encoding, the encoding for the function will specify "use DWARF", and the corresponding unwind-info record will use the low bits of the encoding to point to the FDE for the function. We test this with a frame-pointer=none function, since these frame layouts always triger a fall-back to DWARF on arm64. (cherry picked from commit 9d88ffe7f7b4a46d3bcb7bbdf0d7eb037ab5ba04) Added: llvm/test/ExecutionEngine/Orc/throw-catch-minimal.ll Modified: llvm/lib/ExecutionEngine/JITLink/CompactUnwindSupport.h llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp Removed: llvm/test/ExecutionEngine/Orc/minimal-throw-catch.ll ################################################################################ diff --git a/llvm/lib/ExecutionEngine/JITLink/CompactUnwindSupport.h b/llvm/lib/ExecutionEngine/JITLink/CompactUnwindSupport.h index c306264b6da5d26..c3f883494933562 100644 --- a/llvm/lib/ExecutionEngine/JITLink/CompactUnwindSupport.h +++ b/llvm/lib/ExecutionEngine/JITLink/CompactUnwindSupport.h @@ -61,6 +61,14 @@ template <typename CRTPImpl, size_t PtrSize> struct CompactUnwindTraits { return support::endian::read32<CRTPImpl::Endianness>(RecordContent.data() + EncodingFieldOffset); } + + static std::optional<uint32_t> encodeDWARFOffset(size_t Delta) { + uint32_t Encoded = + static_cast<uint32_t>(Delta) & CRTPImpl::DWARFSectionOffsetMask; + if (Encoded != Delta) + return std::nullopt; + return Encoded; + } }; /// Architecture specific implementation of CompactUnwindManager. @@ -133,19 +141,22 @@ template <typename CURecTraits> class CompactUnwindManager { << Fn.getName() << "\n"; }); continue; - } else { - LLVM_DEBUG({ - dbgs() << " Found record for function "; - if (Fn.hasName()) - dbgs() << Fn.getName(); - else - dbgs() << "<anon @ " << Fn.getAddress() << '>'; - dbgs() << '\n'; - }); } - bool NeedsDWARF = CURecTraits::encodingSpecifiesDWARF( - CURecTraits::readEncoding(B->getContent())); + uint32_t Encoding = CURecTraits::readEncoding(B->getContent()); + bool NeedsDWARF = CURecTraits::encodingSpecifiesDWARF(Encoding); + + LLVM_DEBUG({ + dbgs() << " Found record for function "; + if (Fn.hasName()) + dbgs() << Fn.getName(); + else + dbgs() << "<anon @ " << Fn.getAddress() << '>'; + dbgs() << ": encoding = " << formatv("{0:x}", Encoding); + if (NeedsDWARF) + dbgs() << " (needs DWARF)"; + dbgs() << "\n"; + }); auto &CURecSym = G.addAnonymousSymbol(*B, 0, CURecTraits::Size, false, false); @@ -170,7 +181,7 @@ template <typename CURecTraits> class CompactUnwindManager { KeepAliveAlreadyPresent = true; if (NeedsDWARF) { LLVM_DEBUG({ - dbgs() << " Needs DWARF: adding keep-alive edge to FDE at " + dbgs() << " Adding keep-alive edge to FDE at " << FDE.getAddress() << "\n"; }); B->addEdge(Edge::KeepAlive, 0, FDE, 0); @@ -595,8 +606,24 @@ template <typename CURecTraits> class CompactUnwindManager { ", delta to function at " + formatv("{0:x}", R.Fn->getAddress()) + " exceeds 32 bits"); + auto Encoding = R.Encoding; + + if (LLVM_UNLIKELY(CURecTraits::encodingSpecifiesDWARF(R.Encoding))) { + if (!EHFrameBase) + EHFrameBase = SectionRange(R.FDE->getSection()).getStart(); + auto FDEDelta = R.FDE->getAddress() - EHFrameBase; + + if (auto EncodedFDEDelta = CURecTraits::encodeDWARFOffset(FDEDelta)) + Encoding |= *EncodedFDEDelta; + else + return make_error<JITLinkError>( + "In " + G.getName() + " " + UnwindInfoSectionName + + ", cannot encode delta " + formatv("{0:x}", FDEDelta) + + " to FDE at " + formatv("{0:x}", R.FDE->getAddress())); + } + cantFail(W.writeInteger<uint32_t>(FnDelta)); - cantFail(W.writeInteger<uint32_t>(R.Encoding)); + cantFail(W.writeInteger<uint32_t>(Encoding)); ++RecordIdx; } @@ -639,6 +666,7 @@ template <typename CURecTraits> class CompactUnwindManager { StringRef UnwindInfoSectionName; StringRef EHFrameSectionName; Symbol *CompactUnwindBase = nullptr; + orc::ExecutorAddr EHFrameBase; size_t NumLSDAs = 0; size_t NumSecondLevelPages = 0; diff --git a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp index 4860db4f5eb37c6..3af0c0cdeb7c335 100644 --- a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp @@ -637,6 +637,7 @@ struct CompactUnwindTraits_MachO_arm64 constexpr static endianness Endianness = endianness::little; constexpr static uint32_t EncodingModeMask = 0x0f000000; + constexpr static uint32_t DWARFSectionOffsetMask = 0x00ffffff; using GOTManager = aarch64::GOTTableManager; diff --git a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp index d56dfdc07636dfe..bb5f3ab7ed43cd5 100644 --- a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp @@ -512,6 +512,7 @@ struct CompactUnwindTraits_MachO_x86_64 constexpr static endianness Endianness = endianness::little; constexpr static uint32_t EncodingModeMask = 0x0f000000; + constexpr static uint32_t DWARFSectionOffsetMask = 0x00ffffff; using GOTManager = x86_64::GOTTableManager; diff --git a/llvm/test/ExecutionEngine/Orc/minimal-throw-catch.ll b/llvm/test/ExecutionEngine/Orc/throw-catch-minimal.ll similarity index 100% rename from llvm/test/ExecutionEngine/Orc/minimal-throw-catch.ll rename to llvm/test/ExecutionEngine/Orc/throw-catch-minimal.ll _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits