Index: include/llvm/CodeGen/AsmPrinter.h =================================================================== --- include/llvm/CodeGen/AsmPrinter.h +++ include/llvm/CodeGen/AsmPrinter.h @@ -148,7 +148,9 @@ DwarfDebug *getDwarfDebug() { return DD; } DwarfDebug *getDwarfDebug() const { return DD; } - + uint16_t getDwarfVersion() const; + void setDwarfVersion(uint16_t Version); + bool isPositionIndependent() const; /// Return true if assembly output should contain comments. Index: include/llvm/CodeGen/DIE.h =================================================================== --- include/llvm/CodeGen/DIE.h +++ include/llvm/CodeGen/DIE.h @@ -15,11 +15,11 @@ #define LLVM_LIB_CODEGEN_ASMPRINTER_DIE_H #include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/iterator.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/CodeGen/DwarfStringPoolEntry.h" #include "llvm/Support/AlignOf.h" #include "llvm/Support/Allocator.h" @@ -30,11 +30,14 @@ #include #include #include +#include namespace llvm { class AsmPrinter; +class DIE; class MCExpr; +class MCSection; class MCSymbol; class raw_ostream; @@ -81,7 +84,8 @@ public: DIEAbbrev(dwarf::Tag T, bool C) : Tag(T), Children(C) {} - + DIEAbbrev(const DIEAbbrev &RHS) = default; + DIEAbbrev(DIEAbbrev &&RHS) = default; /// Accessors. /// @{ dwarf::Tag getTag() const { return Tag; } @@ -108,6 +112,38 @@ }; //===--------------------------------------------------------------------===// +/// Helps unique DIEAbbrev objects and assigns abbreviation numbers. +/// +/// This class will unique the DIE abbreviations for a llvm::DIE object and +/// assign a unique abbreviation number to each unique DIEAbbrev object it +/// finds. The resulting collection of DIEAbbrev objects can then be emitted +/// into the .debug_abbrev section. + +class DIEAbbrevSet { + /// The bump allocator to use when creating DIEAbbrev objects in the uniqued + /// storage container. + BumpPtrAllocator &Alloc; + /// \brief FoldingSet that uniques the abbreviations. + llvm::FoldingSet AbbreviationsSet; + // A list of all the unique abbreviations in use. + std::vector Abbreviations; + +public: + DIEAbbrevSet(BumpPtrAllocator &A) : Alloc(A) {} + ~DIEAbbrevSet(); + /// Generate the abbreviation declaration for a DIE and return a pointer to + /// the generated abbreviation. + /// + /// \param DIE the debug info entry to generate the abbreviation for. + /// \returns A reference to the uniqued abbreviation declaration that is + /// owned by this class. + DIEAbbrev &uniqueAbbreviation(DIE &Die); + + /// Print all abbreviations using the specified asm printer. + void Emit(const AsmPrinter *AP, MCSection *Section) const; +}; + +//===--------------------------------------------------------------------===// /// An integer value DIE. /// class DIEInteger { @@ -197,8 +233,10 @@ }; //===--------------------------------------------------------------------===// -/// A container for string values. +/// A container for string pool string values. /// +/// This class is used with the DW_FORM_strp and DW_FORM_GNU_str_index forms. + class DIEString { DwarfStringPoolEntryRef S; @@ -215,6 +253,27 @@ }; //===--------------------------------------------------------------------===// +/// A container for inline string values. +/// +/// This class is used with the DW_FORM_string form. +class DIEInlineString { + std::string S; + +public: + explicit DIEInlineString(StringRef Str) : S(Str.str()) {} + + ~DIEInlineString() = default; + + /// Grab the string out of the object. + StringRef getString() const { return StringRef(S); } + + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + + void print(raw_ostream &O) const; +}; + +//===--------------------------------------------------------------------===// /// A pointer to another debug information entry. An instance of this class can /// also be used as a proxy for a debug information entry not yet defined /// (ie. types.) @@ -647,6 +706,27 @@ /// Set the abbreviation number for this DIE. void setAbbrevNumber(unsigned I) { AbbrevNumber = I; } + /// Compute the offset of this DIE and all its children. + /// + /// This function gets called just before we are going to generate the debug + /// information and gives each DIE a chance to figure out its absolute DIE + /// offset, unique its abbreviation, and return the updated offset that points + /// to the next debug info will be emitted within the .debug_info or + /// .debug_types section. After this function has been called for all DIE + /// objects, the DWARF can be generated since all DIEs will be able to + /// properly refer to other DIE objects since all DIEs have calculated their + /// offsets. + /// + /// \param AP AsmPrinter to use when calculating sizes. + /// \param AbbrevSet the abbreviation used to unique DIE abbreviations. + /// \param SecOffset the section (.debug_info or .debug_types) offset of the + /// first byte for this DIE. + /// \returns the debug info section offset for the debug info that follows + /// this DIE. + unsigned computeOffsetsAndAbbrevs(const AsmPrinter *AP, + DIEAbbrevSet &AbbrevSet, + unsigned SecOffset); + /// Climb up the parent chain to get the compile or type unit DIE this DIE /// belongs to. const DIE *getUnit() const; Index: include/llvm/CodeGen/DIEValue.def =================================================================== --- include/llvm/CodeGen/DIEValue.def +++ include/llvm/CodeGen/DIEValue.def @@ -40,6 +40,7 @@ HANDLE_DIEVALUE_LARGE(Block) HANDLE_DIEVALUE_LARGE(Loc) HANDLE_DIEVALUE_SMALL(LocList) +HANDLE_DIEVALUE_LARGE(InlineString) #undef HANDLE_DIEVALUE #undef HANDLE_DIEVALUE_SMALL Index: include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h +++ include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h @@ -101,6 +101,10 @@ dwarf::Attribute Attr, uint64_t FailValue) const; + int64_t getAttributeValueAsSignedConstant(const DWARFUnit *U, + dwarf::Attribute Attr, + int64_t FailValue) const; + uint64_t getAttributeValueAsUnsignedConstant(const DWARFUnit *U, dwarf::Attribute Attr, uint64_t FailValue) const; Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2620,3 +2620,11 @@ Sleds.emplace_back( XRayFunctionEntry{ Sled, CurrentFnSym, Kind, AlwaysInstrument, Fn }); } + +uint16_t AsmPrinter::getDwarfVersion() const { + return OutStreamer->getContext().getDwarfVersion(); +} + +void AsmPrinter::setDwarfVersion(uint16_t Version) { + OutStreamer->getContext().setDwarfVersion(Version); +} Index: lib/CodeGen/AsmPrinter/DIE.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DIE.cpp +++ lib/CodeGen/AsmPrinter/DIE.cpp @@ -115,6 +115,47 @@ return Abbrev; } +//===----------------------------------------------------------------------===// +// DIEAbbrevSet Implementation +//===----------------------------------------------------------------------===// + +DIEAbbrevSet::~DIEAbbrevSet() { + for (DIEAbbrev *Abbrev : Abbreviations) + Abbrev->~DIEAbbrev(); +} + +DIEAbbrev &DIEAbbrevSet::uniqueAbbreviation(DIE &Die) { + + FoldingSetNodeID ID; + DIEAbbrev Abbrev = Die.generateAbbrev(); + Abbrev.Profile(ID); + + void *InsertPos; + if (DIEAbbrev *Existing = + AbbreviationsSet.FindNodeOrInsertPos(ID, InsertPos)) { + Die.setAbbrevNumber(Existing->getNumber()); + return *Existing; + } + + // Move the abbreviation to the heap and assign a number. + DIEAbbrev *New = new (Alloc) DIEAbbrev(std::move(Abbrev)); + Abbreviations.push_back(New); + New->setNumber(Abbreviations.size()); + Die.setAbbrevNumber(Abbreviations.size()); + + // Store it for lookup. + AbbreviationsSet.InsertNode(New, InsertPos); + return *New; +} + +void DIEAbbrevSet::Emit(const AsmPrinter *AP, MCSection *Section) const { + if (!Abbreviations.empty()) { + // Start the debug abbrev section. + AP->OutStreamer->SwitchSection(Section); + AP->emitDwarfAbbrevs(Abbreviations); + } +} + /// Climb up the parent chain to get the unit DIE to which this DIE /// belongs. const DIE *DIE::getUnit() const { @@ -203,6 +244,42 @@ } } +unsigned DIE::computeOffsetsAndAbbrevs(const AsmPrinter *AP, + DIEAbbrevSet &AbbrevSet, + unsigned SecOffset) { + // Unique the abbreviation and allow it to set the abbreviation number + // by calling DIE::setAbbrevNumber() on this object. + const DIEAbbrev &Abbrev = AbbrevSet.uniqueAbbreviation(*this); + + // Set DIE offset to the location in the section. + setOffset(SecOffset); + + // Add the byte size of the abbreviation code. + SecOffset += getULEB128Size(getAbbrevNumber()); + + // Add the byte size of all the DIE attribute values. + for (const auto &V : values()) + SecOffset += V.SizeOf(AP); + + // Let the children compute their offsets and abbreviation numbers. + if (hasChildren()) { + (void)Abbrev; + assert(Abbrev.hasChildren() && "Children flag not set"); + + for (auto &Child : children()) + SecOffset = Child.computeOffsetsAndAbbrevs(AP, AbbrevSet, SecOffset); + + // Each child chain is terminated with a zero byte, adjust the offset. + SecOffset += sizeof(int8_t); + } + + // Compute the byte size of this DIE and all of its children correctly. This + // is needed so that top level DIE can help the compile unit set its length + // correctly. + setSize(SecOffset - getOffset()); + return SecOffset; +} + unsigned DIEValue::SizeOf(const AsmPrinter *AP) const { switch (Ty) { case isNone: @@ -249,26 +326,34 @@ return; case dwarf::DW_FORM_flag: LLVM_FALLTHROUGH; case dwarf::DW_FORM_ref1: LLVM_FALLTHROUGH; - case dwarf::DW_FORM_data1: Size = 1; break; + case dwarf::DW_FORM_data1: LLVM_FALLTHROUGH; case dwarf::DW_FORM_ref2: LLVM_FALLTHROUGH; - case dwarf::DW_FORM_data2: Size = 2; break; - case dwarf::DW_FORM_sec_offset: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_data2: LLVM_FALLTHROUGH; case dwarf::DW_FORM_strp: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_GNU_ref_alt: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_GNU_strp_alt: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_line_strp: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_sec_offset: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_strp_sup: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_ref_sup: LLVM_FALLTHROUGH; case dwarf::DW_FORM_ref4: LLVM_FALLTHROUGH; - case dwarf::DW_FORM_data4: Size = 4; break; + case dwarf::DW_FORM_data4: LLVM_FALLTHROUGH; case dwarf::DW_FORM_ref8: LLVM_FALLTHROUGH; case dwarf::DW_FORM_ref_sig8: LLVM_FALLTHROUGH; - case dwarf::DW_FORM_data8: Size = 8; break; - case dwarf::DW_FORM_GNU_str_index: Asm->EmitULEB128(Integer); return; - case dwarf::DW_FORM_GNU_addr_index: Asm->EmitULEB128(Integer); return; - case dwarf::DW_FORM_udata: Asm->EmitULEB128(Integer); return; - case dwarf::DW_FORM_sdata: Asm->EmitSLEB128(Integer); return; - case dwarf::DW_FORM_addr: - Size = Asm->getPointerSize(); - break; + case dwarf::DW_FORM_data8: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_addr: LLVM_FALLTHROUGH; case dwarf::DW_FORM_ref_addr: - Size = SizeOf(Asm, dwarf::DW_FORM_ref_addr); + Size = SizeOf(Asm, Form); break; + case dwarf::DW_FORM_GNU_str_index: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_GNU_addr_index: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_ref_udata: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_udata: + Asm->EmitULEB128(Integer); + return; + case dwarf::DW_FORM_sdata: + Asm->EmitSLEB128(Integer); + return; default: llvm_unreachable("DIE Value form not supported yet"); } Asm->OutStreamer->EmitIntValue(Integer, Size); @@ -284,8 +369,15 @@ case dwarf::DW_FORM_data1: return sizeof(int8_t); case dwarf::DW_FORM_ref2: LLVM_FALLTHROUGH; case dwarf::DW_FORM_data2: return sizeof(int16_t); - case dwarf::DW_FORM_sec_offset: LLVM_FALLTHROUGH; case dwarf::DW_FORM_strp: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_GNU_ref_alt: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_GNU_strp_alt: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_line_strp: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_sec_offset: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_strp_sup: LLVM_FALLTHROUGH; + case dwarf::DW_FORM_ref_sup: + // 4 bytes for DWARF32, 8 bytes for DWARF64. + return 4; // TODO: support DWARF64 case dwarf::DW_FORM_ref4: LLVM_FALLTHROUGH; case dwarf::DW_FORM_data4: return sizeof(int32_t); case dwarf::DW_FORM_ref8: LLVM_FALLTHROUGH; @@ -293,12 +385,14 @@ case dwarf::DW_FORM_data8: return sizeof(int64_t); case dwarf::DW_FORM_GNU_str_index: return getULEB128Size(Integer); case dwarf::DW_FORM_GNU_addr_index: return getULEB128Size(Integer); + case dwarf::DW_FORM_ref_udata: + LLVM_FALLTHROUGH; case dwarf::DW_FORM_udata: return getULEB128Size(Integer); case dwarf::DW_FORM_sdata: return getSLEB128Size(Integer); case dwarf::DW_FORM_addr: return AP->getPointerSize(); case dwarf::DW_FORM_ref_addr: - if (AP->OutStreamer->getContext().getDwarfVersion() == 2) + if (AP->getDwarfVersion() == 2) return AP->getPointerSize(); return sizeof(int32_t); default: llvm_unreachable("DIE Value form not supported yet"); @@ -435,6 +529,28 @@ } //===----------------------------------------------------------------------===// +// DIEInlineString Implementation +//===----------------------------------------------------------------------===// +void DIEInlineString::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const { + if (Form == dwarf::DW_FORM_string) { + for (char ch : S) + AP->EmitInt8(ch); + AP->EmitInt8(0); + return; + } + llvm_unreachable("Expected valid string form"); +} + +unsigned DIEInlineString::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { + return S.size() + 1; // Emit string bytes + NULL byte. +} + +LLVM_DUMP_METHOD +void DIEInlineString::print(raw_ostream &O) const { + O << "InlineString: " << S.c_str(); +} + +//===----------------------------------------------------------------------===// // DIEEntry Implementation //===----------------------------------------------------------------------===// @@ -445,20 +561,25 @@ if (Form == dwarf::DW_FORM_ref_addr) { const DwarfDebug *DD = AP->getDwarfDebug(); unsigned Addr = Entry->getOffset(); - assert(!DD->useSplitDwarf() && "TODO: dwo files can't have relocations."); // For DW_FORM_ref_addr, output the offset from beginning of debug info // section. Entry->getOffset() returns the offset from start of the // compile unit. - DwarfCompileUnit *CU = DD->lookupUnit(Entry->getUnit()); - assert(CU && "CUDie should belong to a CU."); - Addr += CU->getDebugInfoOffset(); - if (AP->MAI->doesDwarfUseRelocationsAcrossSections()) - AP->EmitLabelPlusOffset(CU->getSectionSym(), Addr, - DIEEntry::getRefAddrSize(AP)); - else - AP->OutStreamer->EmitIntValue(Addr, DIEEntry::getRefAddrSize(AP)); - } else - AP->EmitInt32(Entry->getOffset()); + if (DD) { + assert(!DD->useSplitDwarf() && "TODO: dwo files can't have relocations."); + DwarfCompileUnit *CU = DD->lookupUnit(Entry->getUnit()); + assert(CU && "CUDie should belong to a CU."); + Addr += CU->getDebugInfoOffset(); + if (AP->MAI->doesDwarfUseRelocationsAcrossSections()) + AP->EmitLabelPlusOffset(CU->getSectionSym(), Addr, + DIEEntry::getRefAddrSize(AP)); + else + AP->OutStreamer->EmitIntValue(Addr, DIEEntry::getRefAddrSize(AP)); + return; + } + } + // Make sure we emit the correct size compile unit relative offset for + // DWARF32 or DWARF64. + AP->OutStreamer->EmitIntValue(Entry->getOffset(), SizeOf(AP, Form)); } unsigned DIEEntry::getRefAddrSize(const AsmPrinter *AP) { @@ -466,9 +587,7 @@ // specified to be four bytes in the DWARF 32-bit format and eight bytes // in the DWARF 64-bit format, while DWARF Version 2 specifies that such // references have the same size as an address on the target system. - const DwarfDebug *DD = AP->getDwarfDebug(); - assert(DD && "Expected Dwarf Debug info to be available"); - if (DD->getDwarfVersion() == 2) + if (AP->getDwarfVersion() == 2) return AP->getPointerSize(); return sizeof(int32_t); } Index: lib/CodeGen/AsmPrinter/DIEHash.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DIEHash.cpp +++ lib/CodeGen/AsmPrinter/DIEHash.cpp @@ -330,6 +330,12 @@ addULEB128(dwarf::DW_FORM_string); addString(Value.getDIEString().getString()); break; + case DIEValue::isInlineString: + addULEB128('A'); + addULEB128(Attribute); + addULEB128(dwarf::DW_FORM_string); + addString(Value.getDIEInlineString().getString()); + break; case DIEValue::isBlock: case DIEValue::isLoc: case DIEValue::isLocList: Index: lib/CodeGen/AsmPrinter/DwarfDebug.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.h +++ lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -254,9 +254,6 @@ /// Whether to emit all linkage names, or just abstract subprograms. bool UseAllLinkageNames; - /// Version of dwarf we're emitting. - unsigned DwarfVersion; - /// DWARF5 Experimental Options /// @{ bool HasDwarfAccelTables; @@ -515,7 +512,7 @@ bool useSplitDwarf() const { return HasSplitDwarf; } /// Returns the Dwarf Version. - unsigned getDwarfVersion() const { return DwarfVersion; } + uint16_t getDwarfVersion() const; /// Returns the previous CU that was being updated const DwarfCompileUnit *getPrevCU() const { return PrevCU; } Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -256,7 +256,7 @@ UseAllLinkageNames = DwarfLinkageNames == AllLinkageNames; unsigned DwarfVersionNumber = Asm->TM.Options.MCOptions.DwarfVersion; - DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber + unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber : MMI->getModule()->getDwarfVersion(); // Use dwarf 4 by default if nothing is requested. DwarfVersion = DwarfVersion ? DwarfVersion : dwarf::DWARF_VERSION; @@ -1192,7 +1192,7 @@ Fn = Scope->getFilename(); Dir = Scope->getDirectory(); if (auto *LBF = dyn_cast(Scope)) - if (DwarfVersion >= 4) + if (getDwarfVersion() >= 4) Discriminator = LBF->getDiscriminator(); unsigned CUID = Asm->OutStreamer->getContext().getDwarfCompileUnitID(); @@ -1410,8 +1410,7 @@ const DebugLocEntry::Value &Value, unsigned PieceOffsetInBits) { DIExpressionCursor ExprCursor(Value.getExpression()); - DebugLocDwarfExpression DwarfExpr(AP.getDwarfDebug()->getDwarfVersion(), - Streamer); + DebugLocDwarfExpression DwarfExpr(AP.getDwarfVersion(), Streamer); // Regular entry. if (Value.isInt()) { if (BT && (BT->getEncoding() == dwarf::DW_ATE_signed || @@ -1462,8 +1461,7 @@ assert(Offset <= PieceOffset && "overlapping or duplicate pieces"); if (Offset < PieceOffset) { // The DWARF spec seriously mandates pieces with no locations for gaps. - DebugLocDwarfExpression Expr(AP.getDwarfDebug()->getDwarfVersion(), - Streamer); + DebugLocDwarfExpression Expr(AP.getDwarfVersion(), Streamer); Expr.AddOpPiece(PieceOffset-Offset, 0); Offset += PieceOffset-Offset; } @@ -1978,3 +1976,7 @@ return; AccelTypes.AddName(InfoHolder.getStringPool().getEntry(*Asm, Name), &Die); } + +uint16_t DwarfDebug::getDwarfVersion() const { + return Asm->OutStreamer->getContext().getDwarfVersion(); +} Index: lib/CodeGen/AsmPrinter/DwarfFile.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfFile.h +++ lib/CodeGen/AsmPrinter/DwarfFile.h @@ -16,6 +16,7 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" +#include "llvm/CodeGen/DIE.h" #include "llvm/IR/Metadata.h" #include "llvm/Support/Allocator.h" #include @@ -25,10 +26,10 @@ class AsmPrinter; class DbgVariable; class DwarfCompileUnit; +class DwarfStringPool; class DwarfUnit; class DIEAbbrev; class MCSymbol; -class DIE; class LexicalScope; class StringRef; class DwarfDebug; @@ -41,11 +42,8 @@ BumpPtrAllocator AbbrevAllocator; // Used to uniquely define abbreviations. - FoldingSet AbbreviationsSet; + DIEAbbrevSet Abbrevs; - // A list of all the unique abbreviations in use. - std::vector Abbreviations; - // A pointer to all units in the section. SmallVector, 1> CUs; @@ -85,7 +83,7 @@ /// /// Compute the abbreviation for \c Die, look up its unique number, and /// return a reference to it in the uniquing table. - DIEAbbrev &assignAbbrevNumber(DIE &Die); + // DIEAbbrev &assignAbbrevNumber(DIE &Die); /// \brief Add a unit to the list of CUs. void addUnit(std::unique_ptr U); Index: lib/CodeGen/AsmPrinter/DwarfFile.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfFile.cpp +++ lib/CodeGen/AsmPrinter/DwarfFile.cpp @@ -19,38 +19,17 @@ namespace llvm { DwarfFile::DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA) - : Asm(AP), StrPool(DA, *Asm, Pref) {} + : Asm(AP), Abbrevs(AbbrevAllocator), StrPool(DA, *Asm, Pref) {} DwarfFile::~DwarfFile() { - for (DIEAbbrev *Abbrev : Abbreviations) - Abbrev->~DIEAbbrev(); } -// Define a unique number for the abbreviation. -// -DIEAbbrev &DwarfFile::assignAbbrevNumber(DIE &Die) { - FoldingSetNodeID ID; - DIEAbbrev Abbrev = Die.generateAbbrev(); - Abbrev.Profile(ID); +//// Define a unique number for the abbreviation. +//// +// DIEAbbrev &DwarfFile::assignAbbrevNumber(DIE &Die) { +// return Abbrevs.uniqueAbbreviation(Die); +//} - void *InsertPos; - if (DIEAbbrev *Existing = - AbbreviationsSet.FindNodeOrInsertPos(ID, InsertPos)) { - Die.setAbbrevNumber(Existing->getNumber()); - return *Existing; - } - - // Move the abbreviation to the heap and assign a number. - DIEAbbrev *New = new (AbbrevAllocator) DIEAbbrev(std::move(Abbrev)); - Abbreviations.push_back(New); - New->setNumber(Abbreviations.size()); - Die.setAbbrevNumber(Abbreviations.size()); - - // Store it for lookup. - AbbreviationsSet.InsertNode(New, InsertPos); - return *New; -} - void DwarfFile::addUnit(std::unique_ptr U) { CUs.push_back(std::move(U)); } @@ -98,44 +77,10 @@ // Compute the size and offset of a DIE. The offset is relative to start of the // CU. It returns the offset after laying out the DIE. unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) { - // Record the abbreviation. - const DIEAbbrev &Abbrev = assignAbbrevNumber(Die); - - // Set DIE offset - Die.setOffset(Offset); - - // Start the size with the size of abbreviation code. - Offset += getULEB128Size(Die.getAbbrevNumber()); - - // Size the DIE attribute values. - for (const auto &V : Die.values()) - // Size attribute value. - Offset += V.SizeOf(Asm); - - // Size the DIE children if any. - if (Die.hasChildren()) { - (void)Abbrev; - assert(Abbrev.hasChildren() && "Children flag not set"); - - for (auto &Child : Die.children()) - Offset = computeSizeAndOffset(Child, Offset); - - // End of children marker. - Offset += sizeof(int8_t); - } - - Die.setSize(Offset - Die.getOffset()); - return Offset; + return Die.computeOffsetsAndAbbrevs(Asm, Abbrevs, Offset); } -void DwarfFile::emitAbbrevs(MCSection *Section) { - // Check to see if it is worth the effort. - if (!Abbreviations.empty()) { - // Start the debug abbrev section. - Asm->OutStreamer->SwitchSection(Section); - Asm->emitDwarfAbbrevs(Abbreviations); - } -} +void DwarfFile::emitAbbrevs(MCSection *Section) { Abbrevs.Emit(Asm, Section); } // Emit strings into a string section. void DwarfFile::emitStrings(MCSection *StrSection, MCSection *OffsetSection) { Index: lib/CodeGen/CMakeLists.txt =================================================================== --- lib/CodeGen/CMakeLists.txt +++ lib/CodeGen/CMakeLists.txt @@ -17,6 +17,7 @@ DetectDeadLanes.cpp DFAPacketizer.cpp DwarfEHPrepare.cpp + DwarfGenerator.cpp EarlyIfConversion.cpp EdgeBundles.cpp ExecutionDepsFix.cpp Index: lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp +++ lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp @@ -269,6 +269,15 @@ return Result.hasValue() ? Result.getValue() : FailValue; } +int64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsSignedConstant( + const DWARFUnit *U, dwarf::Attribute Attr, int64_t FailValue) const { + DWARFFormValue FormValue; + if (!getAttributeValue(U, Attr, FormValue)) + return FailValue; + Optional Result = FormValue.getAsSignedConstant(); + return Result.hasValue() ? Result.getValue() : FailValue; +} + uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsignedConstant( const DWARFUnit *U, dwarf::Attribute Attr, uint64_t FailValue) const { Index: tools/dsymutil/DwarfLinker.cpp =================================================================== --- tools/dsymutil/DwarfLinker.cpp +++ tools/dsymutil/DwarfLinker.cpp @@ -660,6 +660,7 @@ void DwarfStreamer::switchToDebugInfoSection(unsigned DwarfVersion) { MS->SwitchSection(MOFI->getDwarfInfoSection()); MC->setDwarfVersion(DwarfVersion); + Asm->setDwarfVersion(DwarfVersion); } /// \brief Emit the compilation unit header for \p Unit in the Index: unittests/DebugInfo/DWARF/CMakeLists.txt =================================================================== --- unittests/DebugInfo/DWARF/CMakeLists.txt +++ unittests/DebugInfo/DWARF/CMakeLists.txt @@ -1,8 +1,16 @@ set(LLVM_LINK_COMPONENTS + ${LLVM_TARGETS_TO_BUILD} DebugInfoDWARF + CodeGen + Core + MC + MIRParser + Support + Target ) set(DebugInfoSources + DWARFDebugInfoTest.cpp DWARFFormValueTest.cpp )