[llvm] 2216ee4 - This patch allows llvm-dwarfutil to utilize accelerator tables
Alexey Lapshin via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 16 05:49:08 PST 2023
Author: Alexey Lapshin
Date: 2023-01-16T14:42:30+01:00
New Revision: 2216ee4909f01d6547fd3bda978c00b2c587ff2f
URL: https://github.com/llvm/llvm-project/commit/2216ee4909f01d6547fd3bda978c00b2c587ff2f
DIFF: https://github.com/llvm/llvm-project/commit/2216ee4909f01d6547fd3bda978c00b2c587ff2f.diff
LOG: This patch allows llvm-dwarfutil to utilize accelerator tables
generation code from DWARFLinker. It adds command line option:
--build-accelerator [none,DWARF]
Build accelerator tables(default: none)
=none - Do not build accelerators
=DWARF - Build accelerator tables according to the resulting DWARF version
DWARFv4: .debug_pubnames and .debug_pubtypes
DWARFv5: .debug_names
Differential Revision: https://reviews.llvm.org/D139638
Added:
llvm/test/tools/llvm-dwarfutil/ELF/X86/Inputs/dwarf5.out
llvm/test/tools/llvm-dwarfutil/ELF/X86/accelerator-dwarf4.test
llvm/test/tools/llvm-dwarfutil/ELF/X86/accelerator-dwarf5.test
llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-pubnames.test
llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-pubtypes.test
Modified:
llvm/include/llvm/CodeGen/AsmPrinter.h
llvm/include/llvm/DWARFLinker/DWARFLinker.h
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
llvm/lib/CodeGen/AsmPrinter/DIE.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
llvm/lib/DWARFLinker/DWARFLinker.cpp
llvm/lib/DWARFLinker/DWARFStreamer.cpp
llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf4-macro.test
llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro.test
llvm/test/tools/llvm-dwarfutil/ELF/X86/verbose.test
llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
llvm/tools/llvm-dwarfutil/Options.h
llvm/tools/llvm-dwarfutil/Options.td
llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp
llvm/unittests/CodeGen/TestAsmPrinter.cpp
Removed:
llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-names.test
llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-pubnames.test
llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-pubtypes.test
################################################################################
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index a88056534458f..33fda248120bd 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -327,6 +327,14 @@ class AsmPrinter : public MachineFunctionPass {
/// definition in the same module.
MCSymbol *getSymbolPreferLocal(const GlobalValue &GV) const;
+ bool doesDwarfUseRelocationsAcrossSections() const {
+ return DwarfUsesRelocationsAcrossSections;
+ }
+
+ void setDwarfUsesRelocationsAcrossSections(bool Enable) {
+ DwarfUsesRelocationsAcrossSections = Enable;
+ }
+
//===------------------------------------------------------------------===//
// XRay instrumentation implementation.
//===------------------------------------------------------------------===//
@@ -820,6 +828,8 @@ class AsmPrinter : public MachineFunctionPass {
mutable unsigned LastFn = 0;
mutable unsigned Counter = ~0U;
+ bool DwarfUsesRelocationsAcrossSections = false;
+
/// This method emits the header for the current function.
virtual void emitFunctionHeader();
diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/DWARFLinker.h
index a9473bef49dc3..619d878b7b5da 100644
--- a/llvm/include/llvm/DWARFLinker/DWARFLinker.h
+++ b/llvm/include/llvm/DWARFLinker/DWARFLinker.h
@@ -705,7 +705,7 @@ class DWARFLinker {
/// it to \p Die.
/// \returns the size of the new attribute.
unsigned cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec,
- const DWARFFormValue &Val,
+ unsigned AttrSize, const DWARFFormValue &Val,
const CompileUnit &Unit,
AttributesInfo &Info);
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 0f5e1648f09d7..f40ddad5d8895 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -350,6 +350,8 @@ AsmPrinter::AsmPrinter(TargetMachine &tm, std::unique_ptr<MCStreamer> Streamer)
OutContext(Streamer->getContext()), OutStreamer(std::move(Streamer)),
SM(*this) {
VerboseAsm = OutStreamer->isVerboseAsm();
+ DwarfUsesRelocationsAcrossSections =
+ MAI->doesDwarfUseRelocationsAcrossSections();
}
AsmPrinter::~AsmPrinter() {
@@ -4033,7 +4035,7 @@ unsigned int AsmPrinter::getDwarfOffsetByteSize() const {
dwarf::FormParams AsmPrinter::getDwarfFormParams() const {
return {getDwarfVersion(), uint8_t(getPointerSize()),
OutStreamer->getContext().getDwarfFormat(),
- MAI->doesDwarfUseRelocationsAcrossSections()};
+ doesDwarfUseRelocationsAcrossSections()};
}
unsigned int AsmPrinter::getUnitLengthFieldByteSize() const {
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
index bfa53f5b93749..ecaa64afab4da 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
@@ -163,7 +163,7 @@ void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label,
}
// If the format uses relocations with dwarf, refer to the symbol directly.
- if (MAI->doesDwarfUseRelocationsAcrossSections()) {
+ if (doesDwarfUseRelocationsAcrossSections()) {
OutStreamer->emitSymbolValue(Label, getDwarfOffsetByteSize());
return;
}
@@ -175,7 +175,7 @@ void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label,
}
void AsmPrinter::emitDwarfStringOffset(DwarfStringPoolEntry S) const {
- if (MAI->doesDwarfUseRelocationsAcrossSections()) {
+ if (doesDwarfUseRelocationsAcrossSections()) {
assert(S.Symbol && "No symbol available");
emitDwarfSymbolReference(S.Symbol);
return;
diff --git a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
index f324eada6a074..308d4b1b5d610 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -580,7 +580,7 @@ void DIEString::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
DIEInteger(S.getIndex()).emitValue(AP, Form);
return;
case dwarf::DW_FORM_strp:
- if (AP->MAI->doesDwarfUseRelocationsAcrossSections())
+ if (AP->doesDwarfUseRelocationsAcrossSections())
DIELabel(S.getSymbol()).emitValue(AP, Form);
else
DIEInteger(S.getOffset()).emitValue(AP, Form);
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp
index 67b72f0b455db..2292590b135ea 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp
@@ -20,7 +20,7 @@ using namespace llvm;
DwarfStringPool::DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm,
StringRef Prefix)
: Pool(A), Prefix(Prefix),
- ShouldCreateSymbols(Asm.MAI->doesDwarfUseRelocationsAcrossSections()) {}
+ ShouldCreateSymbols(Asm.doesDwarfUseRelocationsAcrossSections()) {}
StringMapEntry<DwarfStringPool::EntryTy> &
DwarfStringPool::getEntryImpl(AsmPrinter &Asm, StringRef Str) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 9497a6a3207f0..c2ff899c04abe 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1796,7 +1796,7 @@ void DwarfUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute,
void DwarfUnit::addSectionLabel(DIE &Die, dwarf::Attribute Attribute,
const MCSymbol *Label, const MCSymbol *Sec) {
- if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
+ if (Asm->doesDwarfUseRelocationsAcrossSections())
addLabel(Die, Attribute, DD->getDwarfSectionOffsetForm(), Label);
else
addSectionDelta(Die, Attribute, Label, Sec);
@@ -1819,7 +1819,7 @@ void DwarfTypeUnit::addGlobalType(const DIType *Ty, const DIE &Die,
}
const MCSymbol *DwarfUnit::getCrossSectionRelativeBaseAddress() const {
- if (!Asm->MAI->doesDwarfUseRelocationsAcrossSections())
+ if (!Asm->doesDwarfUseRelocationsAcrossSections())
return nullptr;
if (isDwoUnit())
return nullptr;
diff --git a/llvm/lib/DWARFLinker/DWARFLinker.cpp b/llvm/lib/DWARFLinker/DWARFLinker.cpp
index d496245434ff7..2d1282455b6b1 100644
--- a/llvm/lib/DWARFLinker/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/DWARFLinker.cpp
@@ -1151,14 +1151,14 @@ unsigned DWARFLinker::DIECloner::cloneBlockAttribute(
}
unsigned DWARFLinker::DIECloner::cloneAddressAttribute(
- DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val,
- const CompileUnit &Unit, AttributesInfo &Info) {
+ DIE &Die, AttributeSpec AttrSpec, unsigned AttrSize,
+ const DWARFFormValue &Val, const CompileUnit &Unit, AttributesInfo &Info) {
if (LLVM_UNLIKELY(Linker.Options.Update)) {
if (AttrSpec.Attr == dwarf::DW_AT_low_pc)
Info.HasLowPc = true;
Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
dwarf::Form(AttrSpec.Form), DIEInteger(Val.getRawUValue()));
- return Unit.getOrigUnit().getAddressByteSize();
+ return AttrSize;
}
dwarf::Form Form = AttrSpec.Form;
@@ -1348,7 +1348,7 @@ unsigned DWARFLinker::DIECloner::cloneAttribute(
IsLittleEndian);
case dwarf::DW_FORM_addr:
case dwarf::DW_FORM_addrx:
- return cloneAddressAttribute(Die, AttrSpec, Val, Unit, Info);
+ return cloneAddressAttribute(Die, AttrSpec, AttrSize, Val, Unit, Info);
case dwarf::DW_FORM_data1:
case dwarf::DW_FORM_data2:
case dwarf::DW_FORM_data4:
@@ -1417,17 +1417,16 @@ void DWARFLinker::DIECloner::addObjCAccelerator(CompileUnit &Unit,
}
}
-static bool
-shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec,
- uint16_t Tag, bool InDebugMap, bool SkipPC,
- bool InFunctionScope) {
+static bool shouldSkipAttribute(
+ bool Update, DWARFAbbreviationDeclaration::AttributeSpec AttrSpec,
+ uint16_t Tag, bool InDebugMap, bool SkipPC, bool InFunctionScope) {
switch (AttrSpec.Attr) {
default:
return false;
case dwarf::DW_AT_low_pc:
case dwarf::DW_AT_high_pc:
case dwarf::DW_AT_ranges:
- return SkipPC;
+ return !Update && SkipPC;
case dwarf::DW_AT_str_offsets_base:
// FIXME: Use the string offset table with Dwarf 5.
return true;
@@ -1438,7 +1437,8 @@ shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec,
// wrong for globals where we will keep a wrong address. It is mostly
// harmless for locals, but there is no point in keeping these anyway when
// the function wasn't linked.
- return (SkipPC || (!InFunctionScope && Tag == dwarf::DW_TAG_variable &&
+ return !Update &&
+ (SkipPC || (!InFunctionScope && Tag == dwarf::DW_TAG_variable &&
!InDebugMap)) &&
!DWARFFormValue(AttrSpec.Form).isFormClass(DWARFFormValue::FC_Block);
}
@@ -1544,8 +1544,7 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
}
for (const auto &AttrSpec : Abbrev->attributes()) {
- if (LLVM_LIKELY(!Update) &&
- shouldSkipAttribute(AttrSpec, Die->getTag(), Info.InDebugMap,
+ if (shouldSkipAttribute(Update, AttrSpec, Die->getTag(), Info.InDebugMap,
Flags & TF_SkipPC, Flags & TF_InFunctionScope)) {
DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset,
U.getFormParams());
diff --git a/llvm/lib/DWARFLinker/DWARFStreamer.cpp b/llvm/lib/DWARFLinker/DWARFStreamer.cpp
index 01a7e5a4f3e3f..94dcd78f98b42 100644
--- a/llvm/lib/DWARFLinker/DWARFStreamer.cpp
+++ b/llvm/lib/DWARFLinker/DWARFStreamer.cpp
@@ -105,6 +105,7 @@ bool DwarfStreamer::init(Triple TheTriple,
Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS)));
if (!Asm)
return error("no asm printer for target " + TripleName, Context), false;
+ Asm->setDwarfUsesRelocationsAcrossSections(false);
RangesSectionSize = 0;
LocSectionSize = 0;
diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/Inputs/dwarf5.out b/llvm/test/tools/llvm-dwarfutil/ELF/X86/Inputs/dwarf5.out
new file mode 100755
index 0000000000000..24ec57913066e
Binary files /dev/null and b/llvm/test/tools/llvm-dwarfutil/ELF/X86/Inputs/dwarf5.out
diff er
diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/accelerator-dwarf4.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/accelerator-dwarf4.test
new file mode 100644
index 0000000000000..0a107aa2ff57d
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/accelerator-dwarf4.test
@@ -0,0 +1,33 @@
+## This test checks that .debug_names accelerator tables are
+## generated if --build-accelerator=DWARF option is specified
+## and source file has DWARFv4 debug info.
+
+# RUN: yaml2obj %p/Inputs/common.yaml -o %t.o
+
+# RUN: llvm-dwarfutil --no-garbage-collection --build-accelerator=DWARF %t.o %t1
+# RUN: llvm-dwarfdump --verify %t1 | FileCheck %s --check-prefix=VERIFY
+# RUN: llvm-dwarfdump -a %t1 | FileCheck %s
+
+# RUN: llvm-dwarfutil --garbage-collection --build-accelerator=DWARF %t.o %t1
+# RUN: llvm-dwarfdump --verify %t1 | FileCheck %s --check-prefix=VERIFY
+# RUN: llvm-dwarfdump -a %t1 | FileCheck %s
+
+# VERIFY: No errors
+
+# CHECK: .debug_names contents:
+# CHECK: Compilation Unit offsets [
+# CHECK: CU[0]: 0x00000000
+# CHECK: ]
+# CHECK: Abbreviations
+# CHECK: String: {{.*}} "foo1"
+# CHECK: Tag: DW_TAG_subprogram
+# CHECK: String: {{.*}} "class1"
+# CHECK: Tag: DW_TAG_class_type
+# CHECK: String: {{.*}} "float"
+# CHECK: Tag: DW_TAG_base_type
+# CHECK: String: {{.*}} "int"
+# CHECK: Tag: DW_TAG_base_type
+# CHECK: String: {{.*}} "var1"
+# CHECK: Tag: DW_TAG_variable
+# CHECK: String: {{.*}} "char"
+# CHECK: Tag: DW_TAG_base_type
diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/accelerator-dwarf5.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/accelerator-dwarf5.test
new file mode 100644
index 0000000000000..05872423efc12
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/accelerator-dwarf5.test
@@ -0,0 +1,31 @@
+## This test checks that .debug_names accelerator table
+## is generated if --build-accelerator=DWARF option is
+## specified and source file has DWARFv5 debug info.
+
+# RUN: llvm-dwarfutil --no-garbage-collection --build-accelerator=DWARF %p/Inputs/dwarf5.out %t1
+# RUN: llvm-dwarfdump --verify %t1 | FileCheck %s --check-prefix=VERIFY
+# RUN: llvm-dwarfdump -a %t1 | FileCheck %s
+
+# RUN: llvm-dwarfutil --garbage-collection --build-accelerator=DWARF %p/Inputs/dwarf5.out %t1
+# RUN: llvm-dwarfdump --verify %t1 | FileCheck %s --check-prefix=VERIFY
+# RUN: llvm-dwarfdump -a %t1 | FileCheck %s
+
+# VERIFY: No errors
+
+# CHECK: .debug_names contents:
+# CHECK: Compilation Unit offsets [
+# CHECK: CU[0]: 0x00000000
+# CHECK: ]
+# CHECK: Abbreviations
+# CHECK: String: {{.*}} "_Z3foov"
+# CHECK: Tag: DW_TAG_subprogram
+# CHECK: String: {{.*}} "int"
+# CHECK: Tag: DW_TAG_base_type
+# CHECK: String: {{.*}} "foo"
+# CHECK: Tag: DW_TAG_subprogram
+# CHECK: String: {{.*}} "A"
+# CHECK: Tag: DW_TAG_structure_type
+# CHECK: String: {{.*}} "main"
+# CHECK: Tag: DW_TAG_subprogram
+# CHECK: String: {{.*}} "char"
+# CHECK: Tag: DW_TAG_base_type
diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf4-macro.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf4-macro.test
index 0377a0aa63ec7..a84653c612cb7 100644
--- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf4-macro.test
+++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf4-macro.test
@@ -45,6 +45,11 @@
#RUN: llvm-dwarfdump -verify %t1 | FileCheck %s
#RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefix=MACINFO
+## Check that macro table preserved during updating accelerator tables.
+#RUN: llvm-dwarfutil --no-garbage-collection --build-accelerator=DWARF %p/Inputs/dwarf4-macro.out %t1
+#RUN: llvm-dwarfdump -verify %t1 | FileCheck %s
+#RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefixes=MACINFO,NAMES
+
#CHECK: No errors.
#MACINFO: .debug_info contents
@@ -2222,3 +2227,7 @@
#MACINFO-NEXT: DW_MACINFO_define - lineno: 0 macro: __STDC_UTF_16__ 1
#MACINFO-NEXT: DW_MACINFO_define - lineno: 0 macro: __STDC_UTF_32__ 1
#MACINFO-NEXT: DW_MACINFO_define - lineno: 0 macro: __GCC_HAVE_DWARF2_CFI_ASM 1
+
+
+#NAMES: .debug_names contents
+#NAMES: Name Index
diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro.test
index 278ba56f34ac8..57487be9d4270 100644
--- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro.test
+++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-macro.test
@@ -45,6 +45,11 @@
#RUN: llvm-dwarfdump -verify %t1 | FileCheck %s
#RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefix=MACRO
+## Check that macro table preserved during updating accelerator tables.
+#RUN: llvm-dwarfutil --no-garbage-collection --build-accelerator=DWARF %p/Inputs/dwarf5-macro.out %t1
+#RUN: llvm-dwarfdump -verify %t1 | FileCheck %s
+#RUN: llvm-dwarfdump -a %t1 | FileCheck %s --check-prefixes=MACRO,NAMES
+
#CHECK: No errors.
#MACRO: .debug_info contents
@@ -2228,3 +2233,6 @@
#MACRO-NEXT: DW_MACRO_define_str{{[px]}} - lineno: 0 macro: __STDC_UTF_16__ 1
#MACRO-NEXT: DW_MACRO_define_str{{[px]}} - lineno: 0 macro: __STDC_UTF_32__ 1
#MACRO-NEXT: DW_MACRO_define_str{{[px]}} - lineno: 0 macro: __GCC_HAVE_DWARF2_CFI_ASM 1
+
+#NAMES: .debug_names contents
+#NAMES: Name Index
diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/verbose.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/verbose.test
index 6675d7cd8a3bb..940bc34e0c2c5 100644
--- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/verbose.test
+++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/verbose.test
@@ -16,7 +16,7 @@
# RUN: llvm-dwarfutil %t.o %t1 -j 1 --verbose --verify 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-VERIFY
# CHECK-NOT: warning: --num-threads set to 1 because verbose mode is specified
-# CHECK: Do garbage collection for debug info ...
+# CHECK: Do debug info linking...
# CHECK: Input compilation unit:
# CHECK: DW_TAG_compile_unit
# CHECK: Keeping subprogram DIE
diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-pubnames.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-pubnames.test
similarity index 67%
rename from llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-pubnames.test
rename to llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-pubnames.test
index 3aa42a843aaca..f6b939e918deb 100644
--- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-pubnames.test
+++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-pubnames.test
@@ -1,11 +1,18 @@
## This test checks the warning message displayed if input file
-## contains .debug_pubnames section.
+## contains .debug_pubnames section which is incompatible with
+## requested accelerator table.
# RUN: yaml2obj %s -o %t.o
-# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o
+# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o --check-prefix=WARN1
-# CHECK: [[FILE]]: warning: '.debug_pubnames' is not currently supported: section will be skipped
+# RUN: llvm-dwarfutil --build-accelerator=DWARF --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o --check-prefix=WARN2
+
+# RUN: llvm-dwarfutil --build-accelerator=DWARF --no-garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o --check-prefix=WARN2
+
+# WARN1: [[FILE]]: warning: '.debug_pubnames' will be deleted as no accelerator tables are requested
+
+# WARN2: [[FILE]]: warning: '.debug_pubnames' will be replaced with requested .debug_names table
--- !ELF
FileHeader:
@@ -41,7 +48,8 @@ DWARF:
- Attribute: DW_AT_high_pc
Form: DW_FORM_data8
debug_info:
- - Version: 4
+ - Version: 5
+ UnitType: DW_UT_compile
Entries:
- AbbrCode: 1
Values:
diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-pubtypes.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-pubtypes.test
similarity index 67%
rename from llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-pubtypes.test
rename to llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-pubtypes.test
index 4134349f014f9..a0ea6369e28a7 100644
--- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-pubtypes.test
+++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-pubtypes.test
@@ -1,11 +1,18 @@
## This test checks the warning message displayed if input file
-## contains .debug_pubtypes section.
+## contains .debug_pubtypes section which is incompatible with
+## requested accelerator table.
# RUN: yaml2obj %s -o %t.o
+
+# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o --check-prefix=WARN1
-# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o
+# RUN: llvm-dwarfutil --build-accelerator=DWARF --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o --check-prefix=WARN2
-# CHECK: [[FILE]]: warning: '.debug_pubtypes' is not currently supported: section will be skipped
+# RUN: llvm-dwarfutil --build-accelerator=DWARF --no-garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o --check-prefix=WARN2
+
+# WARN1: [[FILE]]: warning: '.debug_pubtypes' will be deleted as no accelerator tables are requested
+
+# WARN2: [[FILE]]: warning: '.debug_pubtypes' will be replaced with requested .debug_names table
--- !ELF
FileHeader:
@@ -41,7 +48,8 @@ DWARF:
- Attribute: DW_AT_high_pc
Form: DW_FORM_data8
debug_info:
- - Version: 4
+ - Version: 5
+ UnitType: DW_UT_compile
Entries:
- AbbrCode: 1
Values:
diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-names.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-names.test
deleted file mode 100644
index a68855294edb4..0000000000000
--- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-names.test
+++ /dev/null
@@ -1,54 +0,0 @@
-## This test checks the warning message displayed if input file
-## contains .debug_names section.
-
-# RUN: yaml2obj %s -o %t.o
-
-# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o
-
-# CHECK: [[FILE]]: warning: '.debug_names' is not currently supported: section will be skipped
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- Address: 0x1000
- AddressAlign: 0x0000000000000010
- Content: "FFFFFFFF"
- - Name: .debug_names
- Type: SHT_PROGBITS
- Flags: [ ]
- Content: "0000"
-DWARF:
- debug_abbrev:
- - Table:
- - Tag: DW_TAG_compile_unit
- Children: DW_CHILDREN_yes
- Attributes:
- - Attribute: DW_AT_producer
- Form: DW_FORM_string
- - Attribute: DW_AT_language
- Form: DW_FORM_data2
- - Attribute: DW_AT_name
- Form: DW_FORM_string
- - Attribute: DW_AT_low_pc
- Form: DW_FORM_addr
- - Attribute: DW_AT_high_pc
- Form: DW_FORM_data8
- debug_info:
- - Version: 4
- Entries:
- - AbbrCode: 1
- Values:
- - CStr: by_hand
- - Value: 0x04
- - CStr: CU1
- - Value: 0x1000
- - Value: 0x4
- - AbbrCode: 0
-...
diff --git a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
index adf48cd87e0d9..ef222f8cc1a4f 100644
--- a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
+++ b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
@@ -252,9 +252,63 @@ static bool knownByDWARFUtil(StringRef SecName) {
.Case(".debug_macinfo", true)
.Case(".debug_str", true)
.Case(".debug_str_offsets", true)
+ .Case(".debug_pubnames", true)
+ .Case(".debug_pubtypes", true)
+ .Case(".debug_names", true)
.Default(false);
}
+static std::optional<DwarfLinkerAccelTableKind>
+getAcceleratorTableKind(StringRef SecName) {
+ return llvm::StringSwitch<std::optional<DwarfLinkerAccelTableKind>>(SecName)
+ .Case(".debug_pubnames", DwarfLinkerAccelTableKind::Pub)
+ .Case(".debug_pubtypes", DwarfLinkerAccelTableKind::Pub)
+ .Case(".debug_names", DwarfLinkerAccelTableKind::DebugNames)
+ .Default(std::nullopt);
+}
+
+static std::string getMessageForReplacedAcceleratorTables(
+ SmallVector<StringRef> &AccelTableNamesToReplace,
+ DwarfUtilAccelKind TargetTable) {
+ std::string Message;
+
+ Message += "'";
+ for (StringRef Name : AccelTableNamesToReplace) {
+ if (Message.size() > 1)
+ Message += ", ";
+ Message += Name;
+ }
+
+ Message += "' will be replaced with requested ";
+
+ switch (TargetTable) {
+ case DwarfUtilAccelKind::DWARF:
+ Message += ".debug_names table";
+ break;
+
+ default:
+ assert(false);
+ }
+
+ return Message;
+}
+
+static std::string getMessageForDeletedAcceleratorTables(
+ SmallVector<StringRef> &AccelTableNamesToReplace) {
+ std::string Message;
+
+ Message += "'";
+ for (StringRef Name : AccelTableNamesToReplace) {
+ if (Message.size() > 1)
+ Message += ", ";
+ Message += Name;
+ }
+
+ Message += "' will be deleted as no accelerator tables are requested";
+
+ return Message;
+}
+
Error linkDebugInfo(object::ObjectFile &File, const Options &Options,
raw_pwrite_stream &OutStream) {
@@ -288,12 +342,6 @@ Error linkDebugInfo(object::ObjectFile &File, const Options &Options,
std::unique_ptr<DWARFContext> Context = DWARFContext::create(File);
- uint16_t MaxDWARFVersion = 0;
- std::function<void(const DWARFUnit &Unit)> OnCUDieLoaded =
- [&MaxDWARFVersion](const DWARFUnit &Unit) {
- MaxDWARFVersion = std::max(Unit.getVersion(), MaxDWARFVersion);
- };
-
// Create DWARF linker.
DWARFLinker DebugInfoLinker(&OutStreamer, DwarfLinkerClient::LLD);
@@ -309,16 +357,6 @@ Error linkDebugInfo(object::ObjectFile &File, const Options &Options,
std::vector<std::unique_ptr<AddressesMap>> AddresssMapForLinking(1);
std::vector<std::string> EmptyWarnings;
- // Unknown debug sections would be removed. Display warning
- // for such sections.
- for (SectionName Sec : Context->getDWARFObj().getSectionNames()) {
- if (isDebugSection(Sec.Name) && !knownByDWARFUtil(Sec.Name))
- warning(
- formatv("'{0}' is not currently supported: section will be skipped",
- Sec.Name),
- Options.InputFileName);
- }
-
// Add object files to the DWARFLinker.
AddresssMapForLinking[0] =
std::make_unique<ObjFileAddressMap>(*Context, Options, File);
@@ -327,6 +365,12 @@ Error linkDebugInfo(object::ObjectFile &File, const Options &Options,
File.getFileName(), &*Context, AddresssMapForLinking[0].get(),
EmptyWarnings);
+ uint16_t MaxDWARFVersion = 0;
+ std::function<void(const DWARFUnit &Unit)> OnCUDieLoaded =
+ [&MaxDWARFVersion](const DWARFUnit &Unit) {
+ MaxDWARFVersion = std::max(Unit.getVersion(), MaxDWARFVersion);
+ };
+
for (size_t I = 0; I < ObjectsForLinking.size(); I++)
DebugInfoLinker.addObjectFile(*ObjectsForLinking[I], nullptr,
OnCUDieLoaded);
@@ -338,6 +382,61 @@ Error linkDebugInfo(object::ObjectFile &File, const Options &Options,
if (Error Err = DebugInfoLinker.setTargetDWARFVersion(MaxDWARFVersion))
return Err;
+ SmallVector<DwarfLinkerAccelTableKind> AccelTables;
+
+ switch (Options.AccelTableKind) {
+ case DwarfUtilAccelKind::None:
+ // Nothing to do.
+ break;
+ case DwarfUtilAccelKind::DWARF:
+ // use .debug_names for all DWARF versions.
+ AccelTables.push_back(DwarfLinkerAccelTableKind::DebugNames);
+ break;
+ }
+
+ // Add accelerator tables to DWARFLinker.
+ for (DwarfLinkerAccelTableKind Table : AccelTables)
+ DebugInfoLinker.addAccelTableKind(Table);
+
+ SmallVector<StringRef> AccelTableNamesToReplace;
+ SmallVector<StringRef> AccelTableNamesToDelete;
+
+ // Unknown debug sections or non-requested accelerator sections would be
+ // removed. Display warning for such sections.
+ for (SectionName Sec : Context->getDWARFObj().getSectionNames()) {
+ if (isDebugSection(Sec.Name)) {
+ std::optional<DwarfLinkerAccelTableKind> SrcAccelTableKind =
+ getAcceleratorTableKind(Sec.Name);
+
+ if (SrcAccelTableKind) {
+ assert(knownByDWARFUtil(Sec.Name));
+
+ if (Options.AccelTableKind == DwarfUtilAccelKind::None)
+ AccelTableNamesToDelete.push_back(Sec.Name);
+ else if (std::find(AccelTables.begin(), AccelTables.end(),
+ *SrcAccelTableKind) == AccelTables.end())
+ AccelTableNamesToReplace.push_back(Sec.Name);
+ } else if (!knownByDWARFUtil(Sec.Name)) {
+ assert(!SrcAccelTableKind);
+ warning(
+ formatv("'{0}' is not currently supported: section will be skipped",
+ Sec.Name),
+ Options.InputFileName);
+ }
+ }
+ }
+
+ // Display message for the replaced accelerator tables.
+ if (!AccelTableNamesToReplace.empty())
+ warning(getMessageForReplacedAcceleratorTables(AccelTableNamesToReplace,
+ Options.AccelTableKind),
+ Options.InputFileName);
+
+ // Display message for the removed accelerator tables.
+ if (!AccelTableNamesToDelete.empty())
+ warning(getMessageForDeletedAcceleratorTables(AccelTableNamesToDelete),
+ Options.InputFileName);
+
// Link debug info.
if (Error Err = DebugInfoLinker.link())
return Err;
diff --git a/llvm/tools/llvm-dwarfutil/Options.h b/llvm/tools/llvm-dwarfutil/Options.h
index c993200ceb4b7..38fa2b9eda631 100644
--- a/llvm/tools/llvm-dwarfutil/Options.h
+++ b/llvm/tools/llvm-dwarfutil/Options.h
@@ -24,6 +24,12 @@ enum class TombstoneKind {
Exec, /// match with address range of executable sections.
};
+/// The kind of accelerator table.
+enum class DwarfUtilAccelKind : uint8_t {
+ None,
+ DWARF // DWARFv5: .debug_names
+};
+
struct Options {
std::string InputFileName;
std::string OutputFileName;
@@ -34,6 +40,7 @@ struct Options {
bool Verbose = false;
int NumThreads = 0;
bool Verify = false;
+ DwarfUtilAccelKind AccelTableKind = DwarfUtilAccelKind::None;
std::string getSeparateDebugFileName() const {
return OutputFileName + ".debug";
diff --git a/llvm/tools/llvm-dwarfutil/Options.td b/llvm/tools/llvm-dwarfutil/Options.td
index 4ab1b51d808d8..d4541188c0c2a 100644
--- a/llvm/tools/llvm-dwarfutil/Options.td
+++ b/llvm/tools/llvm-dwarfutil/Options.td
@@ -5,6 +5,14 @@ multiclass BB<string name, string help1, string help2> {
def no_ # NAME: Flag<["--"], "no-" # name>, HelpText<help2>;
}
+def build_accelerator: Separate<["--", "-"], "build-accelerator">,
+ MetaVarName<"[none,DWARF]">,
+ HelpText<"Build accelerator tables(default: none)\n"
+ " =none - Do not build accelerators\n"
+ " =DWARF - .debug_names are generated for all DWARF versions\n"
+ >;
+def: Joined<["--", "-"], "build-accelerator=">, Alias<build_accelerator>;
+
def help : Flag<["--"], "help">,
HelpText<"Prints this help output">;
diff --git a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp
index 0e87c1370fd3d..74b6104bc6689 100644
--- a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp
+++ b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp
@@ -123,6 +123,19 @@ static Error validateAndSetOptions(opt::InputArgList &Args, Options &Options) {
formatv("unknown tombstone value: '{0}'", S).str().c_str());
}
+ if (opt::Arg *BuildAccelerator = Args.getLastArg(OPT_build_accelerator)) {
+ StringRef S = BuildAccelerator->getValue();
+
+ if (S == "none")
+ Options.AccelTableKind = DwarfUtilAccelKind::None;
+ else if (S == "DWARF")
+ Options.AccelTableKind = DwarfUtilAccelKind::DWARF;
+ else
+ return createStringError(
+ std::errc::invalid_argument,
+ formatv("unknown build-accelerator value: '{0}'", S).str().c_str());
+ }
+
if (Options.Verbose) {
if (Options.NumThreads != 1 && Args.hasArg(OPT_threads))
warning("--num-threads set to 1 because verbose mode is specified");
@@ -423,8 +436,9 @@ static Error saveCopyOfFile(const Options &Opts, ObjectFile &InputFile) {
}
static Error applyCLOptions(const struct Options &Opts, ObjectFile &InputFile) {
- if (Opts.DoGarbageCollection) {
- verbose("Do garbage collection for debug info ...", Opts.Verbose);
+ if (Opts.DoGarbageCollection ||
+ Opts.AccelTableKind != DwarfUtilAccelKind::None) {
+ verbose("Do debug info linking...", Opts.Verbose);
DebugInfoBits LinkedDebugInfo;
raw_svector_ostream OutStream(LinkedDebugInfo);
diff --git a/llvm/unittests/CodeGen/TestAsmPrinter.cpp b/llvm/unittests/CodeGen/TestAsmPrinter.cpp
index b651fcfcb2dfd..7f6b52df39af6 100644
--- a/llvm/unittests/CodeGen/TestAsmPrinter.cpp
+++ b/llvm/unittests/CodeGen/TestAsmPrinter.cpp
@@ -80,11 +80,5 @@ llvm::Error TestAsmPrinter::init(const Target *TheTarget, StringRef TripleName,
}
void TestAsmPrinter::setDwarfUsesRelocationsAcrossSections(bool Enable) {
- struct HackMCAsmInfo : MCAsmInfo {
- void setDwarfUsesRelocationsAcrossSections(bool Enable) {
- DwarfUsesRelocationsAcrossSections = Enable;
- }
- };
- static_cast<HackMCAsmInfo *>(const_cast<MCAsmInfo *>(TM->getMCAsmInfo()))
- ->setDwarfUsesRelocationsAcrossSections(Enable);
+ Asm->setDwarfUsesRelocationsAcrossSections(Enable);
}
More information about the llvm-commits
mailing list