[llvm] 9d88ffe - [JITLink] Handle compact-unwind records that depend on DWARF FDEs.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 5 21:10:37 PST 2025
Author: Lang Hames
Date: 2025-02-06T16:10:30+11:00
New Revision: 9d88ffe7f7b4a46d3bcb7bbdf0d7eb037ab5ba04
URL: https://github.com/llvm/llvm-project/commit/9d88ffe7f7b4a46d3bcb7bbdf0d7eb037ab5ba04
DIFF: https://github.com/llvm/llvm-project/commit/9d88ffe7f7b4a46d3bcb7bbdf0d7eb037ab5ba04.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.
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
More information about the llvm-commits
mailing list