Skip to content

Commit d5170f5

Browse files
committed
[LLVM][DWARF] Add support for .debug_names with split dwarf
Enables Type Units with DWARF5 accelerator tables for split dwarf. It is still under discussion what is the best way to implement support for de-duplication in DWP. This will be in follow up PR.
1 parent bc4e0c0 commit d5170f5

File tree

4 files changed

+137
-28
lines changed

4 files changed

+137
-28
lines changed

llvm/include/llvm/CodeGen/AccelTable.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,25 +297,27 @@ class DWARF5AccelTableData : public AccelTableData {
297297
};
298298

299299
struct TypeUnitMetaInfo {
300-
// Symbol for start of the TU section.
301-
MCSymbol *Label;
300+
// Symbol for start of the TU section or signature if this is SplitDwarf.
301+
std::variant<MCSymbol *, uint64_t> LabelOrSignature;
302302
// Unique ID of Type Unit.
303303
unsigned UniqueID;
304304
};
305305
using TUVectorTy = SmallVector<TypeUnitMetaInfo, 1>;
306306
class DWARF5AccelTable : public AccelTable<DWARF5AccelTableData> {
307307
// Symbols to start of all the TU sections that were generated.
308-
TUVectorTy TUSymbols;
308+
TUVectorTy TUSymbolsOrHashes;
309309

310310
public:
311311
struct UnitIndexAndEncoding {
312312
unsigned Index;
313313
DWARF5AccelTableData::AttributeEncoding Endoding;
314314
};
315315
/// Returns type units that were constructed.
316-
const TUVectorTy &getTypeUnitsSymbols() { return TUSymbols; }
316+
const TUVectorTy &getTypeUnitsSymbols() { return TUSymbolsOrHashes; }
317317
/// Add a type unit start symbol.
318318
void addTypeUnitSymbol(DwarfTypeUnit &U);
319+
/// Add a type unit Signature.
320+
void addTypeUnitSignature(DwarfTypeUnit &U);
319321
/// Convert DIE entries to explicit offset.
320322
/// Needs to be called after DIE offsets are computed.
321323
void convertDieToOffset() {

llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,11 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
201201
char AugmentationString[8] = {'L', 'L', 'V', 'M', '0', '7', '0', '0'};
202202

203203
Header(uint32_t CompUnitCount, uint32_t LocalTypeUnitCount,
204-
uint32_t BucketCount, uint32_t NameCount)
204+
uint32_t ForeignTypeUnitCount, uint32_t BucketCount,
205+
uint32_t NameCount)
205206
: CompUnitCount(CompUnitCount), LocalTypeUnitCount(LocalTypeUnitCount),
206-
BucketCount(BucketCount), NameCount(NameCount) {}
207+
ForeignTypeUnitCount(ForeignTypeUnitCount), BucketCount(BucketCount),
208+
NameCount(NameCount) {}
207209

208210
void emit(Dwarf5AccelTableWriter &Ctx);
209211
};
@@ -220,6 +222,8 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
220222
MCSymbol *AbbrevStart = Asm->createTempSymbol("names_abbrev_start");
221223
MCSymbol *AbbrevEnd = Asm->createTempSymbol("names_abbrev_end");
222224
MCSymbol *EntryPool = Asm->createTempSymbol("names_entries");
225+
// Indicates if this module is built with Split Dwarf enabled.
226+
bool IsSplitDwarf = false;
223227

224228
void populateAbbrevsMap();
225229

@@ -238,7 +242,8 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
238242
ArrayRef<std::variant<MCSymbol *, uint64_t>> TypeUnits,
239243
llvm::function_ref<
240244
std::optional<DWARF5AccelTable::UnitIndexAndEncoding>(const DataT &)>
241-
getIndexForEntry);
245+
getIndexForEntry,
246+
bool IsSplitDwarf);
242247

243248
void emit();
244249
};
@@ -450,6 +455,8 @@ void Dwarf5AccelTableWriter<DataT>::emitTUList() const {
450455
Asm->OutStreamer->AddComment("Type unit " + Twine(TU.index()));
451456
if (std::holds_alternative<MCSymbol *>(TU.value()))
452457
Asm->emitDwarfSymbolReference(std::get<MCSymbol *>(TU.value()));
458+
else if (IsSplitDwarf)
459+
Asm->emitInt64(std::get<uint64_t>(TU.value()));
453460
else
454461
Asm->emitDwarfLengthOrOffset(std::get<uint64_t>(TU.value()));
455462
}
@@ -551,12 +558,15 @@ Dwarf5AccelTableWriter<DataT>::Dwarf5AccelTableWriter(
551558
ArrayRef<std::variant<MCSymbol *, uint64_t>> TypeUnits,
552559
llvm::function_ref<
553560
std::optional<DWARF5AccelTable::UnitIndexAndEncoding>(const DataT &)>
554-
getIndexForEntry)
561+
getIndexForEntry,
562+
bool IsSplitDwarf)
555563
: AccelTableWriter(Asm, Contents, false),
556-
Header(CompUnits.size(), TypeUnits.size(), Contents.getBucketCount(),
564+
Header(CompUnits.size(), IsSplitDwarf ? 0 : TypeUnits.size(),
565+
IsSplitDwarf ? TypeUnits.size() : 0, Contents.getBucketCount(),
557566
Contents.getUniqueNameCount()),
558567
CompUnits(CompUnits), TypeUnits(TypeUnits),
559-
getIndexForEntry(std::move(getIndexForEntry)) {
568+
getIndexForEntry(std::move(getIndexForEntry)),
569+
IsSplitDwarf(IsSplitDwarf) {
560570
populateAbbrevsMap();
561571
}
562572

@@ -608,7 +618,10 @@ void llvm::emitDWARF5AccelTable(
608618

609619
for (const auto &TU : TUSymbols) {
610620
TUIndex[TU.UniqueID] = TUCount++;
611-
TypeUnits.push_back(TU.Label);
621+
if (DD.useSplitDwarf())
622+
TypeUnits.push_back(std::get<uint64_t>(TU.LabelOrSignature));
623+
else
624+
TypeUnits.push_back(std::get<MCSymbol *>(TU.LabelOrSignature));
612625
}
613626

614627
if (CompUnits.empty())
@@ -633,12 +646,17 @@ void llvm::emitDWARF5AccelTable(
633646
return {{CUIndex[Entry.getUnitID()],
634647
{dwarf::DW_IDX_compile_unit, CUIndexForm}}};
635648
return std::nullopt;
636-
})
649+
},
650+
DD.useSplitDwarf())
637651
.emit();
638652
}
639653

640654
void DWARF5AccelTable::addTypeUnitSymbol(DwarfTypeUnit &U) {
641-
TUSymbols.push_back({U.getLabelBegin(), U.getUniqueID()});
655+
TUSymbolsOrHashes.push_back({U.getLabelBegin(), U.getUniqueID()});
656+
}
657+
658+
void DWARF5AccelTable::addTypeUnitSignature(DwarfTypeUnit &U) {
659+
TUSymbolsOrHashes.push_back({U.getTypeSignature(), U.getUniqueID()});
642660
}
643661

644662
void llvm::emitDWARF5AccelTable(
@@ -650,7 +668,7 @@ void llvm::emitDWARF5AccelTable(
650668
std::vector<std::variant<MCSymbol *, uint64_t>> TypeUnits;
651669
Contents.finalize(Asm, "names");
652670
Dwarf5AccelTableWriter<DWARF5AccelTableData>(Asm, Contents, CUs, TypeUnits,
653-
getIndexForEntry)
671+
getIndexForEntry, false)
654672
.emit();
655673
}
656674

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,6 @@ void Loc::MMI::addFrameIndexExpr(const DIExpression *Expr, int FI) {
305305

306306
static AccelTableKind computeAccelTableKind(unsigned DwarfVersion,
307307
bool GenerateTypeUnits,
308-
bool HasSplitDwarf,
309308
DebuggerKind Tuning,
310309
const Triple &TT) {
311310
// Honor an explicit request.
@@ -314,8 +313,7 @@ static AccelTableKind computeAccelTableKind(unsigned DwarfVersion,
314313

315314
// Generating DWARF5 acceleration table.
316315
// Currently Split dwarf and non ELF format is not supported.
317-
if (GenerateTypeUnits &&
318-
(DwarfVersion < 5 || HasSplitDwarf || !TT.isOSBinFormatELF()))
316+
if (GenerateTypeUnits && (DwarfVersion < 5 || !TT.isOSBinFormatELF()))
319317
return AccelTableKind::None;
320318

321319
// Accelerator tables get emitted if targetting DWARF v5 or LLDB. DWARF v5
@@ -403,9 +401,8 @@ DwarfDebug::DwarfDebug(AsmPrinter *A)
403401
A->TM.getTargetTriple().isOSBinFormatWasm()) &&
404402
GenerateDwarfTypeUnits;
405403

406-
TheAccelTableKind =
407-
computeAccelTableKind(DwarfVersion, GenerateTypeUnits, HasSplitDwarf,
408-
DebuggerTuning, A->TM.getTargetTriple());
404+
TheAccelTableKind = computeAccelTableKind(
405+
DwarfVersion, GenerateTypeUnits, DebuggerTuning, A->TM.getTargetTriple());
409406

410407
// Work around a GDB bug. GDB doesn't support the standard opcode;
411408
// SCE doesn't support GNU's; LLDB prefers the standard opcode, which
@@ -3532,8 +3529,12 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,
35323529
InfoHolder.computeSizeAndOffsetsForUnit(TU.first.get());
35333530
InfoHolder.emitUnit(TU.first.get(), useSplitDwarf());
35343531
if (getDwarfVersion() >= 5 &&
3535-
getAccelTableKind() == AccelTableKind::Dwarf)
3536-
AccelDebugNames.addTypeUnitSymbol(*TU.first);
3532+
getAccelTableKind() == AccelTableKind::Dwarf) {
3533+
if (useSplitDwarf())
3534+
AccelDebugNames.addTypeUnitSignature(*TU.first);
3535+
else
3536+
AccelDebugNames.addTypeUnitSymbol(*TU.first);
3537+
}
35373538
}
35383539
AccelTypeUnitsDebugNames.convertDieToOffset();
35393540
AccelDebugNames.addTypeEntries(AccelTypeUnitsDebugNames);

llvm/test/DebugInfo/X86/debug-names-types.ll

Lines changed: 94 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
; UNSUPPORTED: system-windows
2-
; This checks that .debug_names can be generated with monolithic -fdebug-type-sections, and does not generate when split-dwarf is enabled.
2+
; This checks that .debug_names can be generated with monolithic, and split-dwarf, when -fdebug-type-sections is enabled.
33
; Generated with: clang++ main.cpp -g2 -gdwarf-5 -gpubnames -fdebug-types-section
44

55
; RUN: llc -mtriple=x86_64 -generate-type-units -dwarf-version=5 -filetype=obj %s -o %t
66
; RUN: llvm-dwarfdump -debug-info -debug-names %t | FileCheck %s
77

8-
; RUN: llc -mtriple=x86_64 -generate-type-units -dwarf-version=5 -filetype=obj -split-dwarf-file=%t.mainTypes.dwo --split-dwarf-output=%t.mainTypes.dwo %s -o %t
9-
; RUN: llvm-readelf --sections %t | FileCheck %s --check-prefixes=CHECK-SPLIT
10-
11-
; CHECK-SPLIT-NOT: .debug_names
12-
138
; CHECK: .debug_info contents:
149
; CHECK: DW_TAG_type_unit
1510
; CHECK-NEXT: DW_AT_language (DW_LANG_C_plus_plus_14)
@@ -117,6 +112,99 @@
117112
; CHECK-NEXT: ]
118113
; CHECK-NEXT: }
119114

115+
; RUN: llc -mtriple=x86_64 -generate-type-units -dwarf-version=5 -filetype=obj -split-dwarf-file=%t.mainTypes.dwo --split-dwarf-output=%t.mainTypes.dwo %s -o %t
116+
; RUN: llvm-dwarfdump -debug-names %t | FileCheck %s --check-prefixes=CHECK-SPLIT
117+
118+
; CHECK-SPLIT: .debug_names contents
119+
; CHECK-SPLIT: Foreign TU count: 1
120+
; CHECK-SPLIT-NEXT: Bucket count: 4
121+
; CHECK-SPLIT-NEXT: Name count: 4
122+
; CHECK-SPLIT-NEXT: Abbreviations table size: 0x28
123+
; CHECK-SPLIT-NEXT: Augmentation: 'LLVM0700'
124+
; CHECK-SPLIT-NEXT: }
125+
; CHECK-SPLIT-NEXT: Compilation Unit offsets [
126+
; CHECK-SPLIT-NEXT: CU[0]: 0x00000000
127+
; CHECK-SPLIT-NEXT: ]
128+
; CHECK-SPLIT-NEXT: Foreign Type Unit signatures [
129+
; CHECK-SPLIT-NEXT: ForeignTU[0]: 0x675d23e4f33235f2
130+
; CHECK-SPLIT-NEXT: ]
131+
; CHECK-SPLIT-NEXT: Abbreviations [
132+
; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV:0x[0-9a-f]*]] {
133+
; CHECK-SPLIT-NEXT: Tag: DW_TAG_structure_type
134+
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
135+
; CHECK-SPLIT-NEXT: }
136+
; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
137+
; CHECK-SPLIT-NEXT: Tag: DW_TAG_structure_type
138+
; CHECK-SPLIT-NEXT: DW_IDX_type_unit: DW_FORM_data1
139+
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
140+
; CHECK-SPLIT-NEXT: }
141+
; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
142+
; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type
143+
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
144+
; CHECK-SPLIT-NEXT: }
145+
; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
146+
; CHECK-SPLIT-NEXT: Tag: DW_TAG_subprogram
147+
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
148+
; CHECK-SPLIT-NEXT: }
149+
; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] {
150+
; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type
151+
; CHECK-SPLIT-NEXT: DW_IDX_type_unit: DW_FORM_data1
152+
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
153+
; CHECK-SPLIT-NEXT: }
154+
; CHECK-SPLIT-NEXT: ]
155+
; CHECK-SPLIT-NEXT: Bucket 0 [
156+
; CHECK-SPLIT-NEXT: Name 1 {
157+
; CHECK-SPLIT-NEXT: Hash: 0xB888030
158+
; CHECK-SPLIT-NEXT: String: {{.+}} "int"
159+
; CHECK-SPLIT-NEXT: Entry @ {{.+}} {
160+
; CHECK-SPLIT-NEXT: Abbrev: [[ABBREV2]]
161+
; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type
162+
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: 0x00000035
163+
; CHECK-SPLIT-NEXT: }
164+
; CHECK-SPLIT-NEXT: }
165+
; CHECK-SPLIT-NEXT: ]
166+
; CHECK-SPLIT-NEXT: Bucket 1 [
167+
; CHECK-SPLIT-NEXT: Name 2 {
168+
; CHECK-SPLIT-NEXT: Hash: 0xB887389
169+
; CHECK-SPLIT-NEXT: String: {{.+}} "Foo"
170+
; CHECK-SPLIT-NEXT: Entry @ {{.+}} {
171+
; CHECK-SPLIT-NEXT: Abbrev: [[ABBREV1]]
172+
; CHECK-SPLIT-NEXT: Tag: DW_TAG_structure_type
173+
; CHECK-SPLIT-NEXT: DW_IDX_type_unit: 0x00
174+
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: 0x0000001f
175+
; CHECK-SPLIT-NEXT: }
176+
; CHECK-SPLIT-NEXT: Entry @ 0xae {
177+
; CHECK-SPLIT-NEXT: Abbrev: [[ABBREV]]
178+
; CHECK-SPLIT-NEXT: Tag: DW_TAG_structure_type
179+
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: 0x00000039
180+
; CHECK-SPLIT-NEXT: }
181+
; CHECK-SPLIT-NEXT: }
182+
; CHECK-SPLIT-NEXT: ]
183+
; CHECK-SPLIT-NEXT: Bucket 2 [
184+
; CHECK-SPLIT-NEXT: Name 3 {
185+
; CHECK-SPLIT-NEXT: Hash: 0x7C9A7F6A
186+
; CHECK-SPLIT-NEXT: String: {{.+}} "main"
187+
; CHECK-SPLIT-NEXT: Entry @ {{.+}} {
188+
; CHECK-SPLIT-NEXT: Abbrev: [[ABBREV3]]
189+
; CHECK-SPLIT-NEXT: Tag: DW_TAG_subprogram
190+
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: 0x0000001a
191+
; CHECK-SPLIT-NEXT: }
192+
; CHECK-SPLIT-NEXT: }
193+
; CHECK-SPLIT-NEXT: ]
194+
; CHECK-SPLIT-NEXT: Bucket 3 [
195+
; CHECK-SPLIT-NEXT: Name 4 {
196+
; CHECK-SPLIT-NEXT: Hash: 0x7C952063
197+
; CHECK-SPLIT-NEXT: String: {{.+}} "char"
198+
; CHECK-SPLIT-NEXT: Entry @ {{.+}} {
199+
; CHECK-SPLIT-NEXT: Abbrev: [[ABBREV4]]
200+
; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type
201+
; CHECK-SPLIT-NEXT: DW_IDX_type_unit: 0x00
202+
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: 0x00000034
203+
; CHECK-SPLIT-NEXT: }
204+
; CHECK-SPLIT-NEXT: }
205+
; CHECK-SPLIT-NEXT: ]
206+
; CHECK-SPLIT-NEXT: }
207+
120208

121209
; ModuleID = 'main.cpp'
122210
source_filename = "main.cpp"

0 commit comments

Comments
 (0)