Skip to content

[LLVM][DWARF] Add support for .debug_names with split dwarf #73872

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions llvm/include/llvm/CodeGen/AccelTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,25 +297,27 @@ class DWARF5AccelTableData : public AccelTableData {
};

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

public:
struct UnitIndexAndEncoding {
unsigned Index;
DWARF5AccelTableData::AttributeEncoding Endoding;
};
/// Returns type units that were constructed.
const TUVectorTy &getTypeUnitsSymbols() { return TUSymbols; }
const TUVectorTy &getTypeUnitsSymbols() { return TUSymbolsOrHashes; }
/// Add a type unit start symbol.
void addTypeUnitSymbol(DwarfTypeUnit &U);
/// Add a type unit Signature.
void addTypeUnitSignature(DwarfTypeUnit &U);
/// Convert DIE entries to explicit offset.
/// Needs to be called after DIE offsets are computed.
void convertDieToOffset() {
Expand Down
38 changes: 28 additions & 10 deletions llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,11 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
char AugmentationString[8] = {'L', 'L', 'V', 'M', '0', '7', '0', '0'};

Header(uint32_t CompUnitCount, uint32_t LocalTypeUnitCount,
uint32_t BucketCount, uint32_t NameCount)
uint32_t ForeignTypeUnitCount, uint32_t BucketCount,
uint32_t NameCount)
: CompUnitCount(CompUnitCount), LocalTypeUnitCount(LocalTypeUnitCount),
BucketCount(BucketCount), NameCount(NameCount) {}
ForeignTypeUnitCount(ForeignTypeUnitCount), BucketCount(BucketCount),
NameCount(NameCount) {}

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

void populateAbbrevsMap();

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

void emit();
};
Expand Down Expand Up @@ -450,6 +455,8 @@ void Dwarf5AccelTableWriter<DataT>::emitTUList() const {
Asm->OutStreamer->AddComment("Type unit " + Twine(TU.index()));
if (std::holds_alternative<MCSymbol *>(TU.value()))
Asm->emitDwarfSymbolReference(std::get<MCSymbol *>(TU.value()));
else if (IsSplitDwarf)
Asm->emitInt64(std::get<uint64_t>(TU.value()));
else
Asm->emitDwarfLengthOrOffset(std::get<uint64_t>(TU.value()));
}
Expand Down Expand Up @@ -551,12 +558,15 @@ Dwarf5AccelTableWriter<DataT>::Dwarf5AccelTableWriter(
ArrayRef<std::variant<MCSymbol *, uint64_t>> TypeUnits,
llvm::function_ref<
std::optional<DWARF5AccelTable::UnitIndexAndEncoding>(const DataT &)>
getIndexForEntry)
getIndexForEntry,
bool IsSplitDwarf)
: AccelTableWriter(Asm, Contents, false),
Header(CompUnits.size(), TypeUnits.size(), Contents.getBucketCount(),
Header(CompUnits.size(), IsSplitDwarf ? 0 : TypeUnits.size(),
IsSplitDwarf ? TypeUnits.size() : 0, Contents.getBucketCount(),
Contents.getUniqueNameCount()),
CompUnits(CompUnits), TypeUnits(TypeUnits),
getIndexForEntry(std::move(getIndexForEntry)) {
getIndexForEntry(std::move(getIndexForEntry)),
IsSplitDwarf(IsSplitDwarf) {
populateAbbrevsMap();
}

Expand Down Expand Up @@ -608,7 +618,10 @@ void llvm::emitDWARF5AccelTable(

for (const auto &TU : TUSymbols) {
TUIndex[TU.UniqueID] = TUCount++;
TypeUnits.push_back(TU.Label);
if (DD.useSplitDwarf())
TypeUnits.push_back(std::get<uint64_t>(TU.LabelOrSignature));
else
TypeUnits.push_back(std::get<MCSymbol *>(TU.LabelOrSignature));
}

if (CompUnits.empty())
Expand All @@ -633,12 +646,17 @@ void llvm::emitDWARF5AccelTable(
return {{CUIndex[Entry.getUnitID()],
{dwarf::DW_IDX_compile_unit, CUIndexForm}}};
return std::nullopt;
})
},
DD.useSplitDwarf())
.emit();
}

void DWARF5AccelTable::addTypeUnitSymbol(DwarfTypeUnit &U) {
TUSymbols.push_back({U.getLabelBegin(), U.getUniqueID()});
TUSymbolsOrHashes.push_back({U.getLabelBegin(), U.getUniqueID()});
}

void DWARF5AccelTable::addTypeUnitSignature(DwarfTypeUnit &U) {
TUSymbolsOrHashes.push_back({U.getTypeSignature(), U.getUniqueID()});
}

void llvm::emitDWARF5AccelTable(
Expand All @@ -650,7 +668,7 @@ void llvm::emitDWARF5AccelTable(
std::vector<std::variant<MCSymbol *, uint64_t>> TypeUnits;
Contents.finalize(Asm, "names");
Dwarf5AccelTableWriter<DWARF5AccelTableData>(Asm, Contents, CUs, TypeUnits,
getIndexForEntry)
getIndexForEntry, false)
.emit();
}

Expand Down
17 changes: 9 additions & 8 deletions llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,6 @@ void Loc::MMI::addFrameIndexExpr(const DIExpression *Expr, int FI) {

static AccelTableKind computeAccelTableKind(unsigned DwarfVersion,
bool GenerateTypeUnits,
bool HasSplitDwarf,
DebuggerKind Tuning,
const Triple &TT) {
// Honor an explicit request.
Expand All @@ -314,8 +313,7 @@ static AccelTableKind computeAccelTableKind(unsigned DwarfVersion,

// Generating DWARF5 acceleration table.
// Currently Split dwarf and non ELF format is not supported.
if (GenerateTypeUnits &&
(DwarfVersion < 5 || HasSplitDwarf || !TT.isOSBinFormatELF()))
if (GenerateTypeUnits && (DwarfVersion < 5 || !TT.isOSBinFormatELF()))
return AccelTableKind::None;

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

TheAccelTableKind =
computeAccelTableKind(DwarfVersion, GenerateTypeUnits, HasSplitDwarf,
DebuggerTuning, A->TM.getTargetTriple());
TheAccelTableKind = computeAccelTableKind(
DwarfVersion, GenerateTypeUnits, DebuggerTuning, A->TM.getTargetTriple());

// Work around a GDB bug. GDB doesn't support the standard opcode;
// SCE doesn't support GNU's; LLDB prefers the standard opcode, which
Expand Down Expand Up @@ -3532,8 +3529,12 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,
InfoHolder.computeSizeAndOffsetsForUnit(TU.first.get());
InfoHolder.emitUnit(TU.first.get(), useSplitDwarf());
if (getDwarfVersion() >= 5 &&
getAccelTableKind() == AccelTableKind::Dwarf)
AccelDebugNames.addTypeUnitSymbol(*TU.first);
getAccelTableKind() == AccelTableKind::Dwarf) {
if (useSplitDwarf())
AccelDebugNames.addTypeUnitSignature(*TU.first);
else
AccelDebugNames.addTypeUnitSymbol(*TU.first);
}
}
AccelTypeUnitsDebugNames.convertDieToOffset();
AccelDebugNames.addTypeEntries(AccelTypeUnitsDebugNames);
Expand Down
100 changes: 94 additions & 6 deletions llvm/test/DebugInfo/X86/debug-names-types.ll
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
; UNSUPPORTED: system-windows
; This checks that .debug_names can be generated with monolithic -fdebug-type-sections, and does not generate when split-dwarf is enabled.
; This checks that .debug_names can be generated with monolithic, and split-dwarf, when -fdebug-type-sections is enabled.
; Generated with: clang++ main.cpp -g2 -gdwarf-5 -gpubnames -fdebug-types-section

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

; 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
; RUN: llvm-readelf --sections %t | FileCheck %s --check-prefixes=CHECK-SPLIT

; CHECK-SPLIT-NOT: .debug_names

; CHECK: .debug_info contents:
; CHECK: DW_TAG_type_unit
; CHECK-NEXT: DW_AT_language (DW_LANG_C_plus_plus_14)
Expand Down Expand Up @@ -117,6 +112,99 @@
; CHECK-NEXT: ]
; CHECK-NEXT: }

; 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
; RUN: llvm-dwarfdump -debug-names %t | FileCheck %s --check-prefixes=CHECK-SPLIT

; CHECK-SPLIT: .debug_names contents
; CHECK-SPLIT: Foreign TU count: 1
; CHECK-SPLIT-NEXT: Bucket count: 4
; CHECK-SPLIT-NEXT: Name count: 4
; CHECK-SPLIT-NEXT: Abbreviations table size: 0x28
; CHECK-SPLIT-NEXT: Augmentation: 'LLVM0700'
; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: Compilation Unit offsets [
; CHECK-SPLIT-NEXT: CU[0]: 0x00000000
; CHECK-SPLIT-NEXT: ]
; CHECK-SPLIT-NEXT: Foreign Type Unit signatures [
; CHECK-SPLIT-NEXT: ForeignTU[0]: 0x675d23e4f33235f2
; CHECK-SPLIT-NEXT: ]
; CHECK-SPLIT-NEXT: Abbreviations [
; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV:0x[0-9a-f]*]] {
; CHECK-SPLIT-NEXT: Tag: DW_TAG_structure_type
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
; CHECK-SPLIT-NEXT: Tag: DW_TAG_structure_type
; CHECK-SPLIT-NEXT: DW_IDX_type_unit: DW_FORM_data1
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
; CHECK-SPLIT-NEXT: Tag: DW_TAG_subprogram
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] {
; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type
; CHECK-SPLIT-NEXT: DW_IDX_type_unit: DW_FORM_data1
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: ]
; CHECK-SPLIT-NEXT: Bucket 0 [
; CHECK-SPLIT-NEXT: Name 1 {
; CHECK-SPLIT-NEXT: Hash: 0xB888030
; CHECK-SPLIT-NEXT: String: {{.+}} "int"
; CHECK-SPLIT-NEXT: Entry @ {{.+}} {
; CHECK-SPLIT-NEXT: Abbrev: [[ABBREV2]]
; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: 0x00000035
; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: ]
; CHECK-SPLIT-NEXT: Bucket 1 [
; CHECK-SPLIT-NEXT: Name 2 {
; CHECK-SPLIT-NEXT: Hash: 0xB887389
; CHECK-SPLIT-NEXT: String: {{.+}} "Foo"
; CHECK-SPLIT-NEXT: Entry @ {{.+}} {
; CHECK-SPLIT-NEXT: Abbrev: [[ABBREV1]]
; CHECK-SPLIT-NEXT: Tag: DW_TAG_structure_type
; CHECK-SPLIT-NEXT: DW_IDX_type_unit: 0x00
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: 0x0000001f
; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: Entry @ 0xae {
; CHECK-SPLIT-NEXT: Abbrev: [[ABBREV]]
; CHECK-SPLIT-NEXT: Tag: DW_TAG_structure_type
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: 0x00000039
; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: ]
; CHECK-SPLIT-NEXT: Bucket 2 [
; CHECK-SPLIT-NEXT: Name 3 {
; CHECK-SPLIT-NEXT: Hash: 0x7C9A7F6A
; CHECK-SPLIT-NEXT: String: {{.+}} "main"
; CHECK-SPLIT-NEXT: Entry @ {{.+}} {
; CHECK-SPLIT-NEXT: Abbrev: [[ABBREV3]]
; CHECK-SPLIT-NEXT: Tag: DW_TAG_subprogram
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: 0x0000001a
; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: ]
; CHECK-SPLIT-NEXT: Bucket 3 [
; CHECK-SPLIT-NEXT: Name 4 {
; CHECK-SPLIT-NEXT: Hash: 0x7C952063
; CHECK-SPLIT-NEXT: String: {{.+}} "char"
; CHECK-SPLIT-NEXT: Entry @ {{.+}} {
; CHECK-SPLIT-NEXT: Abbrev: [[ABBREV4]]
; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type
; CHECK-SPLIT-NEXT: DW_IDX_type_unit: 0x00
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: 0x00000034
; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: ]
; CHECK-SPLIT-NEXT: }


; ModuleID = 'main.cpp'
source_filename = "main.cpp"
Expand Down