@@ -224,6 +224,8 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
224
224
MCSymbol *EntryPool = Asm->createTempSymbol (" names_entries" );
225
225
// Indicates if this module is built with Split Dwarf enabled.
226
226
bool IsSplitDwarf = false ;
227
+ DenseMap<uint64_t , MCSymbol *> DieOffsetToAccelEntrySymbol;
228
+ llvm::DenseSet<MCSymbol *> EmittedAccelEntrySymbols;
227
229
228
230
void populateAbbrevsMap ();
229
231
@@ -232,8 +234,8 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
232
234
void emitBuckets () const ;
233
235
void emitStringOffsets () const ;
234
236
void emitAbbrevs () const ;
235
- void emitEntry (const DataT &Entry) const ;
236
- void emitData () const ;
237
+ void emitEntry (const DataT &Entry);
238
+ void emitData ();
237
239
238
240
public:
239
241
Dwarf5AccelTableWriter (
@@ -414,6 +416,7 @@ static uint32_t constructAbbreviationTag(
414
416
if (EntryRet)
415
417
AbbrvTag |= 1 << EntryRet->Encoding .Index ;
416
418
AbbrvTag |= 1 << dwarf::DW_IDX_die_offset;
419
+ AbbrvTag |= 1 << dwarf::DW_IDX_parent;
417
420
AbbrvTag |= Tag << LowerBitSize;
418
421
return AbbrvTag;
419
422
}
@@ -427,10 +430,11 @@ void Dwarf5AccelTableWriter<DataT>::populateAbbrevsMap() {
427
430
unsigned Tag = static_cast <const DataT *>(Value)->getDieTag ();
428
431
uint32_t AbbrvTag = constructAbbreviationTag (Tag, EntryRet);
429
432
if (Abbreviations.count (AbbrvTag) == 0 ) {
430
- SmallVector<DWARF5AccelTableData::AttributeEncoding, 2 > UA;
433
+ SmallVector<DWARF5AccelTableData::AttributeEncoding, 3 > UA;
431
434
if (EntryRet)
432
435
UA.push_back (EntryRet->Encoding );
433
436
UA.push_back ({dwarf::DW_IDX_die_offset, dwarf::DW_FORM_ref4});
437
+ UA.push_back ({dwarf::DW_IDX_parent, dwarf::DW_FORM_ref4});
434
438
Abbreviations.try_emplace (AbbrvTag, UA);
435
439
}
436
440
}
@@ -507,7 +511,7 @@ void Dwarf5AccelTableWriter<DataT>::emitAbbrevs() const {
507
511
}
508
512
509
513
template <typename DataT>
510
- void Dwarf5AccelTableWriter<DataT>::emitEntry(const DataT &Entry) const {
514
+ void Dwarf5AccelTableWriter<DataT>::emitEntry(const DataT &Entry) {
511
515
std::optional<DWARF5AccelTable::UnitIndexAndEncoding> EntryRet =
512
516
getIndexForEntry (Entry);
513
517
uint32_t AbbrvTag = constructAbbreviationTag (Entry.getDieTag (), EntryRet);
@@ -516,6 +520,18 @@ void Dwarf5AccelTableWriter<DataT>::emitEntry(const DataT &Entry) const {
516
520
" Why wasn't this abbrev generated?" );
517
521
assert (getTagFromAbbreviationTag (AbbrevIt->first ) == Entry.getDieTag () &&
518
522
" Invalid Tag" );
523
+
524
+ // Create a label for this Entry, if not yet created by a IDX_parent
525
+ // reference to the same underlying DIE.
526
+ MCSymbol *&EntrySymbol = DieOffsetToAccelEntrySymbol[Entry.getDieOffset ()];
527
+ if (EntrySymbol == nullptr )
528
+ EntrySymbol = Asm->createTempSymbol (" symbol" );
529
+
530
+ // Emit the label for this Entry, if a label hasn't yet been emitted for some
531
+ // other Entry of the same underlying DIE (a DIE may have multiple Entries).
532
+ if (EmittedAccelEntrySymbols.insert (EntrySymbol).second )
533
+ Asm->OutStreamer ->emitLabel (EntrySymbol);
534
+
519
535
Asm->emitULEB128 (AbbrevIt->first , " Abbreviation code" );
520
536
521
537
for (const auto &AttrEnc : AbbrevIt->second ) {
@@ -531,13 +547,25 @@ void Dwarf5AccelTableWriter<DataT>::emitEntry(const DataT &Entry) const {
531
547
assert (AttrEnc.Form == dwarf::DW_FORM_ref4);
532
548
Asm->emitInt32 (Entry.getDieOffset ());
533
549
break ;
550
+ case dwarf::DW_IDX_parent: {
551
+ // If a DIE is being placed on the table, its parent is always non-null
552
+ // (top-level DIEs are not placed in the table), though the parent may not
553
+ // be indexed. Bad input is handled like a parent that is not indexed,
554
+ // i.e., with an offset that is not in the table.
555
+ uint64_t ParentOffset = Entry.getParentDieOffset ().value_or (-1 );
556
+ MCSymbol *&ParentSymbol = DieOffsetToAccelEntrySymbol[ParentOffset];
557
+ if (ParentSymbol == nullptr )
558
+ ParentSymbol = Asm->createTempSymbol (" symbol" );
559
+ Asm->emitLabelDifference (ParentSymbol, EntryPool, 4 );
560
+ break ;
561
+ }
534
562
default :
535
563
llvm_unreachable (" Unexpected index attribute!" );
536
564
}
537
565
}
538
566
}
539
567
540
- template <typename DataT> void Dwarf5AccelTableWriter<DataT>::emitData() const {
568
+ template <typename DataT> void Dwarf5AccelTableWriter<DataT>::emitData() {
541
569
Asm->OutStreamer ->emitLabel (EntryPool);
542
570
for (auto &Bucket : Contents.getBuckets ()) {
543
571
for (auto *Hash : Bucket) {
@@ -549,6 +577,11 @@ template <typename DataT> void Dwarf5AccelTableWriter<DataT>::emitData() const {
549
577
Asm->emitInt8 (0 );
550
578
}
551
579
}
580
+ // Any labels not yet emitted refer to DIEs that are not present in the
581
+ // accelerator table. Point them to end of the table.
582
+ for (MCSymbol *Symbol : make_second_range (DieOffsetToAccelEntrySymbol))
583
+ if (EmittedAccelEntrySymbols.insert (Symbol).second )
584
+ Asm->OutStreamer ->emitLabel (Symbol);
552
585
}
553
586
554
587
template <typename DataT>
0 commit comments