diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -327,6 +327,14 @@ /// 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 @@ 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 --- a/llvm/include/llvm/DWARFLinker/DWARFLinker.h +++ b/llvm/include/llvm/DWARFLinker/DWARFLinker.h @@ -705,7 +705,7 @@ /// 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 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -350,6 +350,8 @@ OutContext(Streamer->getContext()), OutStreamer(std::move(Streamer)), SM(*this) { VerboseAsm = OutStreamer->isVerboseAsm(); + DwarfUsesRelocationsAcrossSections = + MAI->doesDwarfUseRelocationsAcrossSections(); } AsmPrinter::~AsmPrinter() { @@ -4033,7 +4035,7 @@ 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 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -163,7 +163,7 @@ } // 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::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 --- a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp @@ -580,7 +580,7 @@ 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 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp @@ -20,7 +20,7 @@ DwarfStringPool::DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm, StringRef Prefix) : Pool(A), Prefix(Prefix), - ShouldCreateSymbols(Asm.MAI->doesDwarfUseRelocationsAcrossSections()) {} + ShouldCreateSymbols(Asm.doesDwarfUseRelocationsAcrossSections()) {} StringMapEntry & DwarfStringPool::getEntryImpl(AsmPrinter &Asm, StringRef Str) { diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1796,7 +1796,7 @@ 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 @@ } 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 --- a/llvm/lib/DWARFLinker/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/DWARFLinker.cpp @@ -1151,14 +1151,14 @@ } 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 @@ 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 @@ } } -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 @@ // 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 @@ } 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 --- a/llvm/lib/DWARFLinker/DWARFStreamer.cpp +++ b/llvm/lib/DWARFLinker/DWARFStreamer.cpp @@ -105,6 +105,7 @@ Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr(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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@&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 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 --- 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 @@ - 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 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 --- 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 @@ - 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 --- 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 --- a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp +++ b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp @@ -252,9 +252,63 @@ .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 +getAcceleratorTableKind(StringRef SecName) { + return llvm::StringSwitch>(SecName) + .Case(".debug_pubnames", DwarfLinkerAccelTableKind::Pub) + .Case(".debug_pubtypes", DwarfLinkerAccelTableKind::Pub) + .Case(".debug_names", DwarfLinkerAccelTableKind::DebugNames) + .Default(std::nullopt); +} + +static std::string getMessageForReplacedAcceleratorTables( + SmallVector &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 &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 @@ std::unique_ptr Context = DWARFContext::create(File); - uint16_t MaxDWARFVersion = 0; - std::function OnCUDieLoaded = - [&MaxDWARFVersion](const DWARFUnit &Unit) { - MaxDWARFVersion = std::max(Unit.getVersion(), MaxDWARFVersion); - }; - // Create DWARF linker. DWARFLinker DebugInfoLinker(&OutStreamer, DwarfLinkerClient::LLD); @@ -309,16 +357,6 @@ std::vector> AddresssMapForLinking(1); std::vector 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(*Context, Options, File); @@ -327,6 +365,12 @@ File.getFileName(), &*Context, AddresssMapForLinking[0].get(), EmptyWarnings); + uint16_t MaxDWARFVersion = 0; + std::function 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 @@ if (Error Err = DebugInfoLinker.setTargetDWARFVersion(MaxDWARFVersion)) return Err; + SmallVector 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 AccelTableNamesToReplace; + SmallVector 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 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 --- a/llvm/tools/llvm-dwarfutil/Options.h +++ b/llvm/tools/llvm-dwarfutil/Options.h @@ -24,6 +24,12 @@ 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 @@ 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 --- a/llvm/tools/llvm-dwarfutil/Options.td +++ b/llvm/tools/llvm-dwarfutil/Options.td @@ -5,6 +5,14 @@ def no_ # NAME: Flag<["--"], "no-" # name>, HelpText; } +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; + 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 --- a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp +++ b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp @@ -123,6 +123,19 @@ 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 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 --- a/llvm/unittests/CodeGen/TestAsmPrinter.cpp +++ b/llvm/unittests/CodeGen/TestAsmPrinter.cpp @@ -80,11 +80,5 @@ } void TestAsmPrinter::setDwarfUsesRelocationsAcrossSections(bool Enable) { - struct HackMCAsmInfo : MCAsmInfo { - void setDwarfUsesRelocationsAcrossSections(bool Enable) { - DwarfUsesRelocationsAcrossSections = Enable; - } - }; - static_cast(const_cast(TM->getMCAsmInfo())) - ->setDwarfUsesRelocationsAcrossSections(Enable); + Asm->setDwarfUsesRelocationsAcrossSections(Enable); }