Skip to content

Commit 9de581b

Browse files
committed
[ORC] Moch MachOPlatform unwind-info fixes.
Some eh-frame records are CIEs, which don't point to functions. We need to skip these records. This patch reuses EHFrameCFIBlockInspector to identify function targets, rather than a custom loop. Any performance impact will be minimal, and essentially irrelevant once compact-unwind support re-lands (since at that point we'll discard most eh-frame records). For unwind-info sections: don't assume one block per record: the unwind-info section packs all records into a single block.
1 parent 19a4135 commit 9de581b

File tree

1 file changed

+11
-31
lines changed

1 file changed

+11
-31
lines changed

llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "llvm/ExecutionEngine/Orc/MachOPlatform.h"
1010

1111
#include "llvm/BinaryFormat/MachO.h"
12+
#include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
1213
#include "llvm/ExecutionEngine/JITLink/MachO.h"
1314
#include "llvm/ExecutionEngine/JITLink/aarch64.h"
1415
#include "llvm/ExecutionEngine/JITLink/x86_64.h"
@@ -1257,58 +1258,37 @@ MachOPlatform::MachOPlatformPlugin::findUnwindSectionInfo(
12571258
// that section points to to the CodeBlocks vector.
12581259
SmallVector<Block *> CodeBlocks;
12591260
auto ScanUnwindInfoSection = [&](Section &Sec, ExecutorAddrRange &SecRange,
1260-
auto GetCodeForRecord) {
1261+
auto AddCodeBlocks) {
12611262
if (Sec.blocks().empty())
12621263
return;
12631264
SecRange = (*Sec.blocks().begin())->getRange();
12641265
for (auto *B : Sec.blocks()) {
12651266
auto R = B->getRange();
12661267
SecRange.Start = std::min(SecRange.Start, R.Start);
12671268
SecRange.End = std::max(SecRange.End, R.End);
1268-
if (auto *CodeBlock = GetCodeForRecord(*B))
1269-
CodeBlocks.push_back(CodeBlock);
1269+
AddCodeBlocks(*B);
12701270
}
12711271
};
12721272

12731273
if (Section *EHFrameSec = G.findSectionByName(MachOEHFrameSectionName)) {
1274-
ScanUnwindInfoSection(
1275-
*EHFrameSec, US.DwarfSection, [&](Block &B) -> Block * {
1276-
// Filter out CIE, personality, etc. edges.
1277-
SmallVector<Edge *, 4> BEdges;
1278-
for (auto &E : B.edges())
1279-
BEdges.push_back(&E);
1280-
llvm::sort(BEdges, [](const Edge *LHS, const Edge *RHS) {
1281-
return LHS->getOffset() < RHS->getOffset();
1282-
});
1283-
if (BEdges.size() < 2)
1284-
return nullptr;
1285-
auto &TargetBlock = BEdges[1]->getTarget().getBlock();
1286-
#ifndef NDEBUG
1287-
auto &TargetSection = TargetBlock.getSection();
1288-
assert(&TargetSection != EHFrameSec &&
1289-
(TargetSection.getMemProt() & MemProt::Exec) ==
1290-
MemProt::Exec &&
1291-
"Invalid eh-frame function target");
1292-
#endif // NDEBUG
1293-
return &TargetBlock;
1294-
});
1274+
ScanUnwindInfoSection(*EHFrameSec, US.DwarfSection, [&](Block &B) {
1275+
if (auto *Fn = jitlink::EHFrameCFIBlockInspector::FromEdgeScan(B)
1276+
.getPCBeginEdge())
1277+
if (Fn->getTarget().isDefined())
1278+
CodeBlocks.push_back(&Fn->getTarget().getBlock());
1279+
});
12951280
}
12961281

12971282
if (Section *CUInfoSec = G.findSectionByName(MachOUnwindInfoSectionName)) {
12981283
ScanUnwindInfoSection(
1299-
*CUInfoSec, US.CompactUnwindSection, [&](Block &B) -> Block * {
1300-
// Compact unwind records should just have a keep-alive pointing to
1301-
// the target function.
1302-
assert(B.edges_size() == 1 &&
1303-
"unwind-info record should only have one edge");
1284+
*CUInfoSec, US.CompactUnwindSection, [&](Block &B) {
13041285
for (auto &E : B.edges()) {
13051286
assert(E.getTarget().isDefined() &&
13061287
"unwind-info record edge has external target");
13071288
assert(E.getKind() == Edge::KeepAlive &&
13081289
"unwind-info record has unexpected edge kind");
1309-
return &E.getTarget().getBlock();
1290+
CodeBlocks.push_back(&E.getTarget().getBlock());
13101291
}
1311-
return nullptr;
13121292
});
13131293
}
13141294

0 commit comments

Comments
 (0)