@@ -1256,30 +1256,61 @@ MachOPlatform::MachOPlatformPlugin::findUnwindSectionInfo(
1256
1256
// ScanSection records a section range and adds any executable blocks that
1257
1257
// that section points to to the CodeBlocks vector.
1258
1258
SmallVector<Block *> CodeBlocks;
1259
- auto ScanUnwindInfoSection = [&](Section &Sec, ExecutorAddrRange &SecRange) {
1259
+ auto ScanUnwindInfoSection = [&](Section &Sec, ExecutorAddrRange &SecRange,
1260
+ auto GetCodeForRecord) {
1260
1261
if (Sec.blocks ().empty ())
1261
1262
return ;
1262
1263
SecRange = (*Sec.blocks ().begin ())->getRange ();
1263
1264
for (auto *B : Sec.blocks ()) {
1264
1265
auto R = B->getRange ();
1265
1266
SecRange.Start = std::min (SecRange.Start , R.Start );
1266
1267
SecRange.End = std::max (SecRange.End , R.End );
1267
- for (auto &E : B->edges ()) {
1268
- if (E.getKind () != Edge::KeepAlive || !E.getTarget ().isDefined ())
1269
- continue ;
1270
- auto &TargetBlock = E.getTarget ().getBlock ();
1271
- auto &TargetSection = TargetBlock.getSection ();
1272
- if ((TargetSection.getMemProt () & MemProt::Exec) == MemProt::Exec)
1273
- CodeBlocks.push_back (&TargetBlock);
1274
- }
1268
+ if (auto *CodeBlock = GetCodeForRecord (*B))
1269
+ CodeBlocks.push_back (CodeBlock);
1275
1270
}
1276
1271
};
1277
1272
1278
- if (Section *EHFrameSec = G.findSectionByName (MachOEHFrameSectionName))
1279
- ScanUnwindInfoSection (*EHFrameSec, US.DwarfSection );
1273
+ 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
+ });
1295
+ }
1280
1296
1281
- if (Section *CUInfoSec = G.findSectionByName (MachOUnwindInfoSectionName))
1282
- ScanUnwindInfoSection (*CUInfoSec, US.CompactUnwindSection );
1297
+ if (Section *CUInfoSec = G.findSectionByName (MachOUnwindInfoSectionName)) {
1298
+ 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" );
1304
+ for (auto &E : B.edges ()) {
1305
+ assert (E.getTarget ().isDefined () &&
1306
+ " unwind-info record edge has external target" );
1307
+ assert (E.getKind () == Edge::KeepAlive &&
1308
+ " unwind-info record has unexpected edge kind" );
1309
+ return &E.getTarget ().getBlock ();
1310
+ }
1311
+ return nullptr ;
1312
+ });
1313
+ }
1283
1314
1284
1315
// If we didn't find any pointed-to code-blocks then there's no need to
1285
1316
// register any info.
0 commit comments