@@ -327,6 +327,7 @@ class CompileUnit {
327
327
328
328
uint64_t getLowPc () const { return LowPc; }
329
329
uint64_t getHighPc () const { return HighPc; }
330
+ bool hasLabelAt (uint64_t Addr) const { return Labels.count (Addr); }
330
331
331
332
Optional<PatchLocation> getUnitRangesAttribute () const {
332
333
return UnitRangeAttribute;
@@ -366,6 +367,10 @@ class CompileUnit {
366
367
// / Apply all fixups recored by noteForwardReference().
367
368
void fixupForwardReferences ();
368
369
370
+ // / Add the low_pc of a label that is relocatad by applying
371
+ // / offset \p PCOffset.
372
+ void addLabelLowPc (uint64_t LabelLowPc, int64_t PcOffset);
373
+
369
374
// / Add a function range [\p LowPC, \p HighPC) that is relocatad by applying
370
375
// / offset \p PCOffset.
371
376
void addFunctionRange (uint64_t LowPC, uint64_t HighPC, int64_t PCOffset);
@@ -471,6 +476,9 @@ class CompileUnit {
471
476
// / to the addresses to get the linked address.
472
477
FunctionIntervals Ranges;
473
478
479
+ // / The DW_AT_low_pc of each DW_TAG_label.
480
+ SmallDenseMap<uint64_t , uint64_t , 1 > Labels;
481
+
474
482
// / DW_AT_ranges attributes to patch after we have gathered
475
483
// / all the unit's function addresses.
476
484
// / @{
@@ -585,6 +593,10 @@ void CompileUnit::fixupForwardReferences() {
585
593
}
586
594
}
587
595
596
+ void CompileUnit::addLabelLowPc (uint64_t LabelLowPc, int64_t PcOffset) {
597
+ Labels.insert ({LabelLowPc, PcOffset});
598
+ }
599
+
588
600
void CompileUnit::addFunctionRange (uint64_t FuncLowPc, uint64_t FuncHighPc,
589
601
int64_t PcOffset) {
590
602
Ranges.insert (FuncLowPc, FuncHighPc, PcOffset);
@@ -2453,7 +2465,7 @@ unsigned DwarfLinker::shouldKeepSubprogramDIE(
2453
2465
return Flags;
2454
2466
2455
2467
uint32_t Offset = DIE.getOffset () + getULEB128Size (Abbrev->getCode ());
2456
- const DWARFUnit &OrigUnit = Unit.getOrigUnit ();
2468
+ DWARFUnit &OrigUnit = Unit.getOrigUnit ();
2457
2469
uint32_t LowPcOffset, LowPcEndOffset;
2458
2470
std::tie (LowPcOffset, LowPcEndOffset) =
2459
2471
getAttributeOffsets (Abbrev, *LowPcIdx, Offset, OrigUnit);
@@ -2471,6 +2483,20 @@ unsigned DwarfLinker::shouldKeepSubprogramDIE(
2471
2483
DIE.dump (outs (), 8 /* Indent */ , DumpOpts);
2472
2484
}
2473
2485
2486
+ if (DIE.getTag () == dwarf::DW_TAG_label) {
2487
+ if (Unit.hasLabelAt (*LowPc))
2488
+ return Flags;
2489
+ // FIXME: dsymutil-classic compat. dsymutil-classic doesn't consider labels
2490
+ // that don't fall into the CU's aranges. This is wrong IMO. Debug info
2491
+ // generation bugs aside, this is really wrong in the case of labels, where
2492
+ // a label marking the end of a function will have a PC == CU's high_pc.
2493
+ if (dwarf::toAddress (OrigUnit.getUnitDIE ().find (dwarf::DW_AT_high_pc))
2494
+ .getValueOr (UINT64_MAX) <= LowPc)
2495
+ return Flags;
2496
+ Unit.addLabelLowPc (*LowPc, MyInfo.AddrAdjust );
2497
+ return Flags | TF_Keep;
2498
+ }
2499
+
2474
2500
Flags |= TF_Keep;
2475
2501
2476
2502
Optional<uint64_t > HighPc = DIE.getHighPC (*LowPc);
@@ -2498,6 +2524,7 @@ unsigned DwarfLinker::shouldKeepDIE(RelocationManager &RelocMgr,
2498
2524
case dwarf::DW_TAG_variable:
2499
2525
return shouldKeepVariableDIE (RelocMgr, DIE, Unit, MyInfo, Flags);
2500
2526
case dwarf::DW_TAG_subprogram:
2527
+ case dwarf::DW_TAG_label:
2501
2528
return shouldKeepSubprogramDIE (RelocMgr, DIE, Unit, MyInfo, Flags);
2502
2529
case dwarf::DW_TAG_imported_module:
2503
2530
case dwarf::DW_TAG_imported_declaration:
0 commit comments