From 76221cbae00c7d6152ea694e095b7aa2c47f58d2 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Tue, 12 Sep 2017 21:50:41 +0000 Subject: [PATCH] IR: Represent -ggnu-pubnames with a flag on the DICompileUnit. This allows the flag to be persisted through to LTO. Differential Revision: https://reviews.llvm.org/D37655 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313078 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/DIBuilder.h | 5 +- include/llvm/IR/DebugInfoMetadata.h | 36 ++--- lib/AsmParser/LLParser.cpp | 5 +- lib/Bitcode/Reader/MetadataLoader.cpp | 5 +- lib/Bitcode/Writer/BitcodeWriter.cpp | 1 + lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 30 +++- lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 2 + lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 143 +++++++----------- lib/CodeGen/AsmPrinter/DwarfDebug.h | 38 ++--- lib/IR/AsmWriter.cpp | 1 + lib/IR/DIBuilder.cpp | 4 +- lib/IR/DebugInfo.cpp | 2 +- lib/IR/DebugInfoMetadata.cpp | 11 +- test/Bitcode/dicompileunit-gnu-pubnames.ll | 6 + test/DebugInfo/X86/gnu-public-names-empty.ll | 4 +- test/DebugInfo/X86/gnu-public-names-gmlt.ll | 4 +- .../X86/gnu-public-names-multiple-cus.ll | 24 +++ test/DebugInfo/X86/gnu-public-names-tu.ll | 4 +- test/DebugInfo/X86/gnu-public-names.ll | 6 +- unittests/IR/MetadataTest.cpp | 13 +- 20 files changed, 178 insertions(+), 166 deletions(-) create mode 100644 test/Bitcode/dicompileunit-gnu-pubnames.ll create mode 100644 test/DebugInfo/X86/gnu-public-names-multiple-cus.ll diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h index 6d8677ad354f5..dd6cc44c9465d 100644 --- a/include/llvm/IR/DIBuilder.h +++ b/include/llvm/IR/DIBuilder.h @@ -112,6 +112,8 @@ namespace llvm { /// \param SplitDebugInlining Whether to emit inline debug info. /// \param DebugInfoForProfiling Whether to emit extra debug info for /// profile collection. + /// \param GnuPubnames Whether to emit .debug_gnu_pubnames section instead + /// of .debug_pubnames. DICompileUnit * createCompileUnit(unsigned Lang, DIFile *File, StringRef Producer, bool isOptimized, StringRef Flags, unsigned RV, @@ -119,7 +121,8 @@ namespace llvm { DICompileUnit::DebugEmissionKind Kind = DICompileUnit::DebugEmissionKind::FullDebug, uint64_t DWOId = 0, bool SplitDebugInlining = true, - bool DebugInfoForProfiling = false); + bool DebugInfoForProfiling = false, + bool GnuPubnames = false); /// Create a file descriptor to hold debugging information for a file. /// \param Filename File name. diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 890e08107a422..f6c11ce00d1d8 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -1068,16 +1068,17 @@ class DICompileUnit : public DIScope { uint64_t DWOId; bool SplitDebugInlining; bool DebugInfoForProfiling; + bool GnuPubnames; DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage, bool IsOptimized, unsigned RuntimeVersion, unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining, - bool DebugInfoForProfiling, ArrayRef Ops) + bool DebugInfoForProfiling, bool GnuPubnames, ArrayRef Ops) : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops), SourceLanguage(SourceLanguage), IsOptimized(IsOptimized), RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind), DWOId(DWOId), SplitDebugInlining(SplitDebugInlining), - DebugInfoForProfiling(DebugInfoForProfiling) { + DebugInfoForProfiling(DebugInfoForProfiling), GnuPubnames(GnuPubnames) { assert(Storage != Uniqued); } ~DICompileUnit() = default; @@ -1091,15 +1092,14 @@ class DICompileUnit : public DIScope { DIGlobalVariableExpressionArray GlobalVariables, DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, - StorageType Storage, bool ShouldCreate = true) { - return getImpl(Context, SourceLanguage, File, - getCanonicalMDString(Context, Producer), IsOptimized, - getCanonicalMDString(Context, Flags), RuntimeVersion, - getCanonicalMDString(Context, SplitDebugFilename), - EmissionKind, EnumTypes.get(), RetainedTypes.get(), - GlobalVariables.get(), ImportedEntities.get(), Macros.get(), - DWOId, SplitDebugInlining, DebugInfoForProfiling, Storage, - ShouldCreate); + bool GnuPubnames, StorageType Storage, bool ShouldCreate = true) { + return getImpl( + Context, SourceLanguage, File, getCanonicalMDString(Context, Producer), + IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion, + getCanonicalMDString(Context, SplitDebugFilename), EmissionKind, + EnumTypes.get(), RetainedTypes.get(), GlobalVariables.get(), + ImportedEntities.get(), Macros.get(), DWOId, SplitDebugInlining, + DebugInfoForProfiling, GnuPubnames, Storage, ShouldCreate); } static DICompileUnit * getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File, @@ -1108,7 +1108,7 @@ class DICompileUnit : public DIScope { unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining, - bool DebugInfoForProfiling, StorageType Storage, + bool DebugInfoForProfiling, bool GnuPubnames, StorageType Storage, bool ShouldCreate = true); TempDICompileUnit cloneImpl() const { @@ -1118,7 +1118,7 @@ class DICompileUnit : public DIScope { getEmissionKind(), getEnumTypes(), getRetainedTypes(), getGlobalVariables(), getImportedEntities(), getMacros(), DWOId, getSplitDebugInlining(), - getDebugInfoForProfiling()); + getDebugInfoForProfiling(), getGnuPubnames()); } public: @@ -1133,11 +1133,12 @@ class DICompileUnit : public DIScope { DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes, DIGlobalVariableExpressionArray GlobalVariables, DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, - uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling), + uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, + bool GnuPubnames), (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining, - DebugInfoForProfiling)) + DebugInfoForProfiling, GnuPubnames)) DEFINE_MDNODE_GET_DISTINCT_TEMPORARY( DICompileUnit, (unsigned SourceLanguage, Metadata *File, MDString *Producer, @@ -1145,11 +1146,11 @@ class DICompileUnit : public DIScope { MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId, - bool SplitDebugInlining, bool DebugInfoForProfiling), + bool SplitDebugInlining, bool DebugInfoForProfiling, bool GnuPubnames), (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining, - DebugInfoForProfiling)) + DebugInfoForProfiling, GnuPubnames)) TempDICompileUnit clone() const { return cloneImpl(); } @@ -1160,6 +1161,7 @@ class DICompileUnit : public DIScope { return (DebugEmissionKind)EmissionKind; } bool getDebugInfoForProfiling() const { return DebugInfoForProfiling; } + bool getGnuPubnames() const { return GnuPubnames; } StringRef getProducer() const { return getStringOperand(1); } StringRef getFlags() const { return getStringOperand(2); } StringRef getSplitDebugFilename() const { return getStringOperand(3); } diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index a1bb860219222..f8f709a03bc64 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -4099,7 +4099,8 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { OPTIONAL(macros, MDField, ); \ OPTIONAL(dwoId, MDUnsignedField, ); \ OPTIONAL(splitDebugInlining, MDBoolField, = true); \ - OPTIONAL(debugInfoForProfiling, MDBoolField, = false); + OPTIONAL(debugInfoForProfiling, MDBoolField, = false); \ + OPTIONAL(gnuPubnames, MDBoolField, = false); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4107,7 +4108,7 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { Context, language.Val, file.Val, producer.Val, isOptimized.Val, flags.Val, runtimeVersion.Val, splitDebugFilename.Val, emissionKind.Val, enums.Val, retainedTypes.Val, globals.Val, imports.Val, macros.Val, dwoId.Val, - splitDebugInlining.Val, debugInfoForProfiling.Val); + splitDebugInlining.Val, debugInfoForProfiling.Val, gnuPubnames.Val); return false; } diff --git a/lib/Bitcode/Reader/MetadataLoader.cpp b/lib/Bitcode/Reader/MetadataLoader.cpp index 3aadee457bfc7..daae5edbd1706 100644 --- a/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1355,7 +1355,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_COMPILE_UNIT: { - if (Record.size() < 14 || Record.size() > 18) + if (Record.size() < 14 || Record.size() > 19) return error("Invalid record"); // Ignore Record[0], which indicates whether this compile unit is @@ -1369,7 +1369,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( Record.size() <= 15 ? nullptr : getMDOrNull(Record[15]), Record.size() <= 14 ? 0 : Record[14], Record.size() <= 16 ? true : Record[16], - Record.size() <= 17 ? false : Record[17]); + Record.size() <= 17 ? false : Record[17], + Record.size() <= 18 ? false : Record[18]); MetadataList.assignValue(CU, NextMetadataNo); NextMetadataNo++; diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 317a5db2bc5c1..3c7e10faa5d0e 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1555,6 +1555,7 @@ void ModuleBitcodeWriter::writeDICompileUnit(const DICompileUnit *N, Record.push_back(VE.getMetadataOrNullID(N->getMacros().get())); Record.push_back(N->getSplitDebugInlining()); Record.push_back(N->getDebugInfoForProfiling()); + Record.push_back(N->getGnuPubnames()); Stream.EmitRecord(bitc::METADATA_COMPILE_UNIT, Record, Abbrev); Record.clear(); diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 321c5106ae81d..3892d06e9b017 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -52,6 +52,16 @@ using namespace llvm; +enum DefaultOnOff { Default, Enable, Disable }; + +static cl::opt +DwarfPubSections("generate-dwarf-pub-sections", cl::Hidden, + cl::desc("Generate DWARF pubnames and pubtypes sections"), + cl::values(clEnumVal(Default, "Default for platform"), + clEnumVal(Enable, "Enabled"), + clEnumVal(Disable, "Disabled")), + cl::init(Default)); + DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU) @@ -755,10 +765,22 @@ void DwarfCompileUnit::emitHeader(bool UseOffsets) { DwarfUnit::emitCommonHeader(UseOffsets, UT); } +bool DwarfCompileUnit::hasDwarfPubSections() const { + // Opting in to GNU Pubnames/types overrides the default to ensure these are + // generated for things like Gold's gdb_index generation. + if (CUNode->getGnuPubnames()) + return true; + + if (DwarfPubSections == Default) + return DD->tuneForGDB() && !includeMinimalInlineScopes(); + + return DwarfPubSections == Enable; +} + /// addGlobalName - Add a new global name to the compile unit. void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die, const DIScope *Context) { - if (!DD->hasDwarfPubSections(includeMinimalInlineScopes())) + if (!hasDwarfPubSections()) return; std::string FullName = getParentContextString(Context) + Name.str(); GlobalNames[FullName] = &Die; @@ -766,7 +788,7 @@ void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die, void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name, const DIScope *Context) { - if (!DD->hasDwarfPubSections(includeMinimalInlineScopes())) + if (!hasDwarfPubSections()) return; std::string FullName = getParentContextString(Context) + Name.str(); // Insert, allowing the entry to remain as-is if it's already present @@ -779,7 +801,7 @@ void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name, /// Add a new global type to the unit. void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die, const DIScope *Context) { - if (!DD->hasDwarfPubSections(includeMinimalInlineScopes())) + if (!hasDwarfPubSections()) return; std::string FullName = getParentContextString(Context) + Ty->getName().str(); GlobalTypes[FullName] = &Die; @@ -787,7 +809,7 @@ void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die, void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty, const DIScope *Context) { - if (!DD->hasDwarfPubSections(includeMinimalInlineScopes())) + if (!hasDwarfPubSections()) return; std::string FullName = getParentContextString(Context) + Ty->getName().str(); // Insert, allowing the entry to remain as-is if it's already present diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 080dc3ea24747..68482eb7e3584 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -289,6 +289,8 @@ class DwarfCompileUnit final : public DwarfUnit { void setBaseAddress(const MCSymbol *Base) { BaseAddress = Base; } const MCSymbol *getBaseAddress() const { return BaseAddress; } + + bool hasDwarfPubSections() const; }; } // end namespace llvm diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index e44ad4ea3026f..499780a173b4b 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -89,11 +89,6 @@ static cl::opt UseDwarfRangesBaseAddressSpecifier( "use-dwarf-ranges-base-address-specifier", cl::Hidden, cl::desc("Use base address specifiers in debug_ranges"), cl::init(false)); -static cl::opt - GenerateGnuPubSections("generate-gnu-dwarf-pub-sections", cl::Hidden, - cl::desc("Generate GNU-style pubnames and pubtypes"), - cl::init(false)); - static cl::opt GenerateARangeSection("generate-arange-section", cl::Hidden, cl::desc("Generate dwarf aranges"), @@ -120,14 +115,6 @@ DwarfAccelTables("dwarf-accel-tables", cl::Hidden, clEnumVal(Disable, "Disabled")), cl::init(Default)); -static cl::opt -DwarfPubSections("generate-dwarf-pub-sections", cl::Hidden, - cl::desc("Generate DWARF pubnames and pubtypes sections"), - cl::values(clEnumVal(Default, "Default for platform"), - clEnumVal(Enable, "Enabled"), - clEnumVal(Disable, "Disabled")), - cl::init(Default)); - enum LinkageNameOption { DefaultLinkageNames, AllLinkageNames, @@ -414,20 +401,8 @@ void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU, } } -bool DwarfDebug::hasDwarfPubSections(bool includeMinimalInlineScopes) const { - // Opting in to GNU Pubnames/types overrides the default to ensure these are - // generated for things like Gold's gdb_index generation. - if (GenerateGnuPubSections) - return true; - - if (DwarfPubSections == Default) - return tuneForGDB() && !includeMinimalInlineScopes; - - return DwarfPubSections == Enable; -} - void DwarfDebug::addGnuPubAttributes(DwarfCompileUnit &U, DIE &D) const { - if (!hasDwarfPubSections(U.includeMinimalInlineScopes())) + if (!U.hasDwarfPubSections()) return; U.addFlag(D, dwarf::DW_AT_GNU_pubnames); @@ -792,12 +767,7 @@ void DwarfDebug::endModule() { } // Emit the pubnames and pubtypes sections if requested. - // The condition is optimistically correct - any CU not using GMLT (& - // implicit/default pubnames state) might still have pubnames. - if (hasDwarfPubSections(/* gmlt */ false)) { - emitDebugPubNames(GenerateGnuPubSections); - emitDebugPubTypes(GenerateGnuPubSections); - } + emitDebugPubSections(); // clean up. // FIXME: AbstractVariables.clear(); @@ -1493,83 +1463,74 @@ static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU, } } -/// emitDebugPubNames - Emit visible names into a debug pubnames section. -void DwarfDebug::emitDebugPubNames(bool GnuStyle) { - MCSection *PSec = GnuStyle - ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection() - : Asm->getObjFileLowering().getDwarfPubNamesSection(); - - emitDebugPubSection(GnuStyle, PSec, "Names", - &DwarfCompileUnit::getGlobalNames); -} - -void DwarfDebug::emitDebugPubSection( - bool GnuStyle, MCSection *PSec, StringRef Name, - const StringMap &(DwarfCompileUnit::*Accessor)() const) { +/// emitDebugPubSections - Emit visible names and types into debug pubnames and +/// pubtypes sections. +void DwarfDebug::emitDebugPubSections() { for (const auto &NU : CUMap) { DwarfCompileUnit *TheU = NU.second; - - const auto &Globals = (TheU->*Accessor)(); - - if (!hasDwarfPubSections(TheU->includeMinimalInlineScopes())) + if (!TheU->hasDwarfPubSections()) continue; - if (auto *Skeleton = TheU->getSkeleton()) - TheU = Skeleton; + bool GnuStyle = TheU->getCUNode()->getGnuPubnames(); - // Start the dwarf pubnames section. - Asm->OutStreamer->SwitchSection(PSec); + Asm->OutStreamer->SwitchSection( + GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection() + : Asm->getObjFileLowering().getDwarfPubNamesSection()); + emitDebugPubSection(GnuStyle, "Names", TheU, TheU->getGlobalNames()); - // Emit the header. - Asm->OutStreamer->AddComment("Length of Public " + Name + " Info"); - MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + Name + "_begin"); - MCSymbol *EndLabel = Asm->createTempSymbol("pub" + Name + "_end"); - Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); + Asm->OutStreamer->SwitchSection( + GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection() + : Asm->getObjFileLowering().getDwarfPubTypesSection()); + emitDebugPubSection(GnuStyle, "Types", TheU, TheU->getGlobalTypes()); + } +} - Asm->OutStreamer->EmitLabel(BeginLabel); +void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name, + DwarfCompileUnit *TheU, + const StringMap &Globals) { + if (auto *Skeleton = TheU->getSkeleton()) + TheU = Skeleton; - Asm->OutStreamer->AddComment("DWARF Version"); - Asm->EmitInt16(dwarf::DW_PUBNAMES_VERSION); + // Emit the header. + Asm->OutStreamer->AddComment("Length of Public " + Name + " Info"); + MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + Name + "_begin"); + MCSymbol *EndLabel = Asm->createTempSymbol("pub" + Name + "_end"); + Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); - Asm->OutStreamer->AddComment("Offset of Compilation Unit Info"); - Asm->emitDwarfSymbolReference(TheU->getLabelBegin()); + Asm->OutStreamer->EmitLabel(BeginLabel); - Asm->OutStreamer->AddComment("Compilation Unit Length"); - Asm->EmitInt32(TheU->getLength()); + Asm->OutStreamer->AddComment("DWARF Version"); + Asm->EmitInt16(dwarf::DW_PUBNAMES_VERSION); - // Emit the pubnames for this compilation unit. - for (const auto &GI : Globals) { - const char *Name = GI.getKeyData(); - const DIE *Entity = GI.second; + Asm->OutStreamer->AddComment("Offset of Compilation Unit Info"); + Asm->emitDwarfSymbolReference(TheU->getLabelBegin()); - Asm->OutStreamer->AddComment("DIE offset"); - Asm->EmitInt32(Entity->getOffset()); + Asm->OutStreamer->AddComment("Compilation Unit Length"); + Asm->EmitInt32(TheU->getLength()); - if (GnuStyle) { - dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheU, Entity); - Asm->OutStreamer->AddComment( - Twine("Kind: ") + dwarf::GDBIndexEntryKindString(Desc.Kind) + ", " + - dwarf::GDBIndexEntryLinkageString(Desc.Linkage)); - Asm->EmitInt8(Desc.toBits()); - } + // Emit the pubnames for this compilation unit. + for (const auto &GI : Globals) { + const char *Name = GI.getKeyData(); + const DIE *Entity = GI.second; - Asm->OutStreamer->AddComment("External Name"); - Asm->OutStreamer->EmitBytes(StringRef(Name, GI.getKeyLength() + 1)); + Asm->OutStreamer->AddComment("DIE offset"); + Asm->EmitInt32(Entity->getOffset()); + + if (GnuStyle) { + dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheU, Entity); + Asm->OutStreamer->AddComment( + Twine("Kind: ") + dwarf::GDBIndexEntryKindString(Desc.Kind) + ", " + + dwarf::GDBIndexEntryLinkageString(Desc.Linkage)); + Asm->EmitInt8(Desc.toBits()); } - Asm->OutStreamer->AddComment("End Mark"); - Asm->EmitInt32(0); - Asm->OutStreamer->EmitLabel(EndLabel); + Asm->OutStreamer->AddComment("External Name"); + Asm->OutStreamer->EmitBytes(StringRef(Name, GI.getKeyLength() + 1)); } -} - -void DwarfDebug::emitDebugPubTypes(bool GnuStyle) { - MCSection *PSec = GnuStyle - ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection() - : Asm->getObjFileLowering().getDwarfPubTypesSection(); - emitDebugPubSection(GnuStyle, PSec, "Types", - &DwarfCompileUnit::getGlobalTypes); + Asm->OutStreamer->AddComment("End Mark"); + Asm->EmitInt32(0); + Asm->OutStreamer->EmitLabel(EndLabel); } /// Emit null-terminated strings into a debug str section. diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index b9f17d61d77cb..24a50c63b4978 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -314,16 +314,6 @@ class DwarfDebug : public DebugHandlerBase { // Identify a debugger for "tuning" the debug info. DebuggerKind DebuggerTuning = DebuggerKind::Default; - /// \defgroup DebuggerTuning Predicates to tune DWARF for a given debugger. - /// - /// Returns whether we are "tuning" for a given debugger. - /// Should be used only within the constructor, to set feature flags. - /// @{ - bool tuneForGDB() const { return DebuggerTuning == DebuggerKind::GDB; } - bool tuneForLLDB() const { return DebuggerTuning == DebuggerKind::LLDB; } - bool tuneForSCE() const { return DebuggerTuning == DebuggerKind::SCE; } - /// @} - MCDwarfDwoLineTable *getDwoLineTable(const DwarfCompileUnit &); const SmallVectorImpl> &getUnits() { @@ -374,21 +364,12 @@ class DwarfDebug : public DebugHandlerBase { /// Emit type dies into a hashed accelerator table. void emitAccelTypes(); - /// Emit visible names into a debug pubnames section. - /// \param GnuStyle determines whether or not we want to emit - /// additional information into the table ala newer gcc for gdb - /// index. - void emitDebugPubNames(bool GnuStyle = false); + /// Emit visible names and types into debug pubnames and pubtypes sections. + void emitDebugPubSections(); - /// Emit visible types into a debug pubtypes section. - /// \param GnuStyle determines whether or not we want to emit - /// additional information into the table ala newer gcc for gdb - /// index. - void emitDebugPubTypes(bool GnuStyle = false); - - void emitDebugPubSection( - bool GnuStyle, MCSection *PSec, StringRef Name, - const StringMap &(DwarfCompileUnit::*Accessor)() const); + void emitDebugPubSection(bool GnuStyle, StringRef Name, + DwarfCompileUnit *TheU, + const StringMap &Globals); /// Emit null-terminated strings into a debug str section. void emitDebugStr(); @@ -577,7 +558,14 @@ class DwarfDebug : public DebugHandlerBase { /// going to be null. bool isLexicalScopeDIENull(LexicalScope *Scope); - bool hasDwarfPubSections(bool includeMinimalInlineScopes) const; + /// \defgroup DebuggerTuning Predicates to tune DWARF for a given debugger. + /// + /// Returns whether we are "tuning" for a given debugger. + /// @{ + bool tuneForGDB() const { return DebuggerTuning == DebuggerKind::GDB; } + bool tuneForLLDB() const { return DebuggerTuning == DebuggerKind::LLDB; } + bool tuneForSCE() const { return DebuggerTuning == DebuggerKind::SCE; } + /// @} }; } // end namespace llvm diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index 3443c6a3d78a3..f351aa1d615a0 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -1742,6 +1742,7 @@ static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N, Printer.printBool("splitDebugInlining", N->getSplitDebugInlining(), true); Printer.printBool("debugInfoForProfiling", N->getDebugInfoForProfiling(), false); + Printer.printBool("gnuPubnames", N->getGnuPubnames(), false); Out << ")"; } diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp index 87edc563eba01..1a40d5ce13dae 100644 --- a/lib/IR/DIBuilder.cpp +++ b/lib/IR/DIBuilder.cpp @@ -127,7 +127,7 @@ DICompileUnit *DIBuilder::createCompileUnit( unsigned Lang, DIFile *File, StringRef Producer, bool isOptimized, StringRef Flags, unsigned RunTimeVer, StringRef SplitName, DICompileUnit::DebugEmissionKind Kind, uint64_t DWOId, - bool SplitDebugInlining, bool DebugInfoForProfiling) { + bool SplitDebugInlining, bool DebugInfoForProfiling, bool GnuPubnames) { assert(((Lang <= dwarf::DW_LANG_Fortran08 && Lang >= dwarf::DW_LANG_C89) || (Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) && @@ -137,7 +137,7 @@ DICompileUnit *DIBuilder::createCompileUnit( CUNode = DICompileUnit::getDistinct( VMContext, Lang, File, Producer, isOptimized, Flags, RunTimeVer, SplitName, Kind, nullptr, nullptr, nullptr, nullptr, nullptr, DWOId, - SplitDebugInlining, DebugInfoForProfiling); + SplitDebugInlining, DebugInfoForProfiling, GnuPubnames); // Create a named metadata so that it is easier to find cu in a module. NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu"); diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp index 1b24af105bbb2..1dc6c5bdd51f4 100644 --- a/lib/IR/DebugInfo.cpp +++ b/lib/IR/DebugInfo.cpp @@ -473,7 +473,7 @@ class DebugTypeInfoRemoval { CU->getSplitDebugFilename(), DICompileUnit::LineTablesOnly, EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities, CU->getMacros(), CU->getDWOId(), CU->getSplitDebugInlining(), - CU->getDebugInfoForProfiling()); + CU->getDebugInfoForProfiling(), CU->getGnuPubnames()); } DILocation *getReplacementMDLocation(DILocation *MLD) { diff --git a/lib/IR/DebugInfoMetadata.cpp b/lib/IR/DebugInfoMetadata.cpp index 005aac821f9f2..9ef8c35dbd030 100644 --- a/lib/IR/DebugInfoMetadata.cpp +++ b/lib/IR/DebugInfoMetadata.cpp @@ -391,7 +391,7 @@ DICompileUnit *DICompileUnit::getImpl( unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, - StorageType Storage, bool ShouldCreate) { + bool GnuPubnames, StorageType Storage, bool ShouldCreate) { assert(Storage != Uniqued && "Cannot unique DICompileUnit"); assert(isCanonical(Producer) && "Expected canonical MDString"); assert(isCanonical(Flags) && "Expected canonical MDString"); @@ -401,11 +401,10 @@ DICompileUnit *DICompileUnit::getImpl( File, Producer, Flags, SplitDebugFilename, EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities, Macros}; - return storeImpl(new (array_lengthof(Ops)) - DICompileUnit(Context, Storage, SourceLanguage, - IsOptimized, RuntimeVersion, EmissionKind, - DWOId, SplitDebugInlining, - DebugInfoForProfiling, Ops), + return storeImpl(new (array_lengthof(Ops)) DICompileUnit( + Context, Storage, SourceLanguage, IsOptimized, + RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining, + DebugInfoForProfiling, GnuPubnames, Ops), Storage); } diff --git a/test/Bitcode/dicompileunit-gnu-pubnames.ll b/test/Bitcode/dicompileunit-gnu-pubnames.ll new file mode 100644 index 0000000000000..31c28501647a3 --- /dev/null +++ b/test/Bitcode/dicompileunit-gnu-pubnames.ll @@ -0,0 +1,6 @@ +; RUN: llvm-as -disable-verify -o - %s | llvm-dis | FileCheck %s + +!named = !{!0} +; CHECK: !DICompileUnit({{.*}}, gnuPubnames: true) +!0 = distinct !DICompileUnit(language: 12, file: !1, gnuPubnames: true) +!1 = !DIFile(filename: "path/to/file", directory: "/path/to/dir") diff --git a/test/DebugInfo/X86/gnu-public-names-empty.ll b/test/DebugInfo/X86/gnu-public-names-empty.ll index e3afd4781716f..2ba26b6aa8a37 100644 --- a/test/DebugInfo/X86/gnu-public-names-empty.ll +++ b/test/DebugInfo/X86/gnu-public-names-empty.ll @@ -1,4 +1,4 @@ -; RUN: llc -mtriple=x86_64-pc-linux-gnu -generate-gnu-dwarf-pub-sections -filetype=obj < %s | llvm-dwarfdump -v - | FileCheck %s +; RUN: llc -mtriple=x86_64-pc-linux-gnu -filetype=obj < %s | llvm-dwarfdump -v - | FileCheck %s ; Generated from: @@ -17,7 +17,7 @@ !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!3, !4} -!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.4 (trunk 191846) (llvm/trunk 191866)", isOptimized: false, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !5, globals: !2, imports: !2) +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.4 (trunk 191846) (llvm/trunk 191866)", isOptimized: false, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !5, globals: !2, imports: !2, gnuPubnames: true) !1 = !DIFile(filename: "foo.c", directory: "/usr/local/google/home/echristo/tmp") !2 = !{} !3 = !{i32 2, !"Dwarf Version", i32 4} diff --git a/test/DebugInfo/X86/gnu-public-names-gmlt.ll b/test/DebugInfo/X86/gnu-public-names-gmlt.ll index dd2856e11cdb0..2cd37a54f84f4 100644 --- a/test/DebugInfo/X86/gnu-public-names-gmlt.ll +++ b/test/DebugInfo/X86/gnu-public-names-gmlt.ll @@ -1,4 +1,4 @@ -; RUN: llc -mtriple=x86_64-pc-linux-gnu -filetype=obj < %s -generate-gnu-dwarf-pub-sections | llvm-dwarfdump -v - | FileCheck --check-prefix=GPUB --check-prefix=CHECK %s +; RUN: sed -e 's/gnuPubnames: false/gnuPubnames: true/' %s | llc -mtriple=x86_64-pc-linux-gnu -filetype=obj | llvm-dwarfdump -v - | FileCheck --check-prefix=GPUB --check-prefix=CHECK %s ; RUN: llc -mtriple=x86_64-pc-linux-gnu -filetype=obj < %s -generate-dwarf-pub-sections=Enable | llvm-dwarfdump -v - | FileCheck --check-prefix=PUB --check-prefix=CHECK %s ; RUN: llc -mtriple=x86_64-pc-linux-gnu -filetype=obj < %s | llvm-dwarfdump -v - | FileCheck --check-prefix=NONE %s @@ -53,7 +53,7 @@ attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail- !llvm.module.flags = !{!3, !4, !5} !llvm.ident = !{!6} -!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 5.0.0 (trunk 303768) (llvm/trunk 303774)", isOptimized: false, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2) +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 5.0.0 (trunk 303768) (llvm/trunk 303774)", isOptimized: false, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2, gnuPubnames: false) !1 = !DIFile(filename: "gnu-public-names-gmlt.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch") !2 = !{} !3 = !{i32 2, !"Dwarf Version", i32 4} diff --git a/test/DebugInfo/X86/gnu-public-names-multiple-cus.ll b/test/DebugInfo/X86/gnu-public-names-multiple-cus.ll new file mode 100644 index 0000000000000..990360cc2503c --- /dev/null +++ b/test/DebugInfo/X86/gnu-public-names-multiple-cus.ll @@ -0,0 +1,24 @@ +; RUN: llc < %s | FileCheck %s + +!llvm.dbg.cu = !{!4, !11} +!llvm.module.flags = !{!7} + +; CHECK: .section .debug_pubnames +; CHECK: .asciz "a" + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = !DIGlobalVariable(name: "a", scope: null, file: !2, line: 2, type: !3, isLocal: false, isDefinition: true) +!2 = !DIFile(filename: "g.c", directory: "/tmp") +!3 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!4 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6) +!5 = !{} +!6 = !{!0} +!7 = !{i32 1, !"Debug Info Version", i32 3} + +; CHECK: .section .debug_gnu_pubnames +; CHECK: .asciz "b" + +!8 = !DIGlobalVariableExpression(var: !9, expr: !DIExpression()) +!9 = !DIGlobalVariable(name: "b", scope: null, file: !2, line: 2, type: !3, isLocal: false, isDefinition: true) +!10 = !{!8} +!11 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !10, gnuPubnames: true) diff --git a/test/DebugInfo/X86/gnu-public-names-tu.ll b/test/DebugInfo/X86/gnu-public-names-tu.ll index a9a34c2a50e80..2a9bc9602f95d 100644 --- a/test/DebugInfo/X86/gnu-public-names-tu.ll +++ b/test/DebugInfo/X86/gnu-public-names-tu.ll @@ -1,4 +1,4 @@ -; RUN: llc -mtriple=x86_64-pc-linux-gnu -generate-type-units -generate-gnu-dwarf-pub-sections -filetype=obj < %s | llvm-dwarfdump -v - | FileCheck %s +; RUN: llc -mtriple=x86_64-pc-linux-gnu -generate-type-units -filetype=obj < %s | llvm-dwarfdump -v - | FileCheck %s ; Generated from: @@ -39,7 +39,7 @@ !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) !1 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 8, type: !6, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 5.0.0 (trunk 293904) (llvm/trunk 293908)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5) +!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 5.0.0 (trunk 293904) (llvm/trunk 293908)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, gnuPubnames: true) !3 = !DIFile(filename: "type.cpp", directory: "/tmp/dbginfo") !4 = !{} !5 = !{!0} diff --git a/test/DebugInfo/X86/gnu-public-names.ll b/test/DebugInfo/X86/gnu-public-names.ll index 34f58b387e41e..5e93bf4ab2a73 100644 --- a/test/DebugInfo/X86/gnu-public-names.ll +++ b/test/DebugInfo/X86/gnu-public-names.ll @@ -1,5 +1,5 @@ -; RUN: llc -mtriple=x86_64-pc-linux-gnu -generate-gnu-dwarf-pub-sections < %s | FileCheck -check-prefix=ASM %s -; RUN: llc -mtriple=x86_64-pc-linux-gnu -generate-gnu-dwarf-pub-sections -filetype=obj < %s | llvm-dwarfdump -v - | FileCheck %s +; RUN: llc -mtriple=x86_64-pc-linux-gnu < %s | FileCheck -check-prefix=ASM %s +; RUN: llc -mtriple=x86_64-pc-linux-gnu -filetype=obj < %s | llvm-dwarfdump -v - | FileCheck %s ; ModuleID = 'dwarf-public-names.cpp' ; ; Generated from: @@ -302,7 +302,7 @@ attributes #1 = { nounwind readnone } !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) !1 = !DIGlobalVariable(name: "static_member_variable", linkageName: "_ZN1C22static_member_variableE", scope: !2, file: !3, line: 7, type: !9, isLocal: false, isDefinition: true, declaration: !8) -!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 3.7.0 (trunk 234897) (llvm/trunk 234911)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !21, imports: !44) +!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 3.7.0 (trunk 234897) (llvm/trunk 234911)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !21, imports: !44, gnuPubnames: true) !3 = !DIFile(filename: "gnu-public-names.cpp", directory: "/tmp/dbginfo") !4 = !{} !5 = !{!6, !17} diff --git a/unittests/IR/MetadataTest.cpp b/unittests/IR/MetadataTest.cpp index 93173f72371b7..611b82720e9d9 100644 --- a/unittests/IR/MetadataTest.cpp +++ b/unittests/IR/MetadataTest.cpp @@ -92,10 +92,10 @@ class MetadataTest : public testing::Test { return DIFile::getDistinct(Context, "file.c", "/path/to/dir"); } DICompileUnit *getUnit() { - return DICompileUnit::getDistinct(Context, 1, getFile(), "clang", false, - "-g", 2, "", DICompileUnit::FullDebug, - getTuple(), getTuple(), getTuple(), - getTuple(), getTuple(), 0, true, false); + return DICompileUnit::getDistinct( + Context, 1, getFile(), "clang", false, "-g", 2, "", + DICompileUnit::FullDebug, getTuple(), getTuple(), getTuple(), + getTuple(), getTuple(), 0, true, false, false); } DIType *getBasicType(StringRef Name) { return DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, Name); @@ -1417,7 +1417,7 @@ TEST_F(DICompileUnitTest, get) { Context, SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId, true, - false); + false, false); EXPECT_EQ(dwarf::DW_TAG_compile_unit, N->getTag()); EXPECT_EQ(SourceLanguage, N->getSourceLanguage()); @@ -1474,7 +1474,8 @@ TEST_F(DICompileUnitTest, replaceArrays) { auto *N = DICompileUnit::getDistinct( Context, SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, - RetainedTypes, nullptr, ImportedEntities, nullptr, DWOId, true, false); + RetainedTypes, nullptr, ImportedEntities, nullptr, DWOId, true, false, + false); auto *GlobalVariables = MDTuple::getDistinct(Context, None); EXPECT_EQ(nullptr, N->getGlobalVariables().get());