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 @@ -22,6 +22,7 @@ #include "llvm/CodeGen/AsmPrinterHandler.h" #include "llvm/CodeGen/DwarfStringPoolEntry.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugSection.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/LLVMContext.h" #include "llvm/Support/ErrorHandling.h" @@ -79,6 +80,74 @@ class RemarkStreamer; } +class DwarfDebugSectionImpl : public DwarfDebugSectionAsm { +public: + DwarfDebugSectionImpl(AsmPrinter *AP, MCStreamer *OutStreamer, + TargetMachine *TM, const MCAsmInfo *MAI, bool IsVerbose) + : AP(AP), OutStreamer(OutStreamer), TM(TM), MAI(MAI), + IsVerbose(IsVerbose) {} + + uint16_t getDwarfVersion() const override; + + void setDwarfVersion(uint16_t Version) override; + + unsigned getAddressSize() const override; + + /// Emit a byte directive and value. + void writeInt8(int Value) override; + + /// Emit a short directive and value. + void writeInt16(int Value) override; + + /// Emit a long directive and value. + void writeInt32(int Value) override; + + /// Emit a long long directive and value. + void writeInt64(uint64_t Value) override; + + /// Emit the specified signed leb128 value. + void writeSLEB128(int64_t Value, const char *Desc = nullptr) override; + + /// Emit the specified unsigned leb128 value. + void writeULEB128(uint64_t Value, const char *Desc = nullptr, + unsigned PadTo = 0) override; + + bool isAsm() const override { return true; } + + dwarf::DwarfFormat getDwarfFormat() const override; + + void writeIntValue(uint64_t Value, unsigned Size) override; + + bool doesDwarfUseRelocationsAcrossSections() const override; + + void writeBytes(StringRef Data) override; + + AsmPrinter *getAsmPrinter() { return AP; } + + void addBlankLine() override; + + void writeDebugValue(const MCExpr *Value, unsigned Size) override; + + void writeLabelReference(const MCSymbol *Label, unsigned Size, + bool IsSectionRelative = false) override; + + void writeLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, + unsigned Size, bool IsSectionRelative) override; + + void writeLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, + unsigned Size) override; + + void writeDwarfSymbolReference(const MCSymbol *Label, + bool ForceOffset = false) override; + +private: + AsmPrinter *AP; + MCStreamer *OutStreamer; + TargetMachine *TM; + const MCAsmInfo *MAI; + bool IsVerbose; +}; + /// This class is intended to be used as a driving class for all asm writers. class AsmPrinter : public MachineFunctionPass { public: @@ -198,6 +267,8 @@ /// If the current module uses dwarf CFI annotations strictly for debugging. bool isCFIMoveForDebugging = false; + std::unique_ptr DebugSection; + protected: explicit AsmPrinter(TargetMachine &TM, std::unique_ptr Streamer); @@ -206,6 +277,9 @@ DwarfDebug *getDwarfDebug() { return DD; } DwarfDebug *getDwarfDebug() const { return DD; } + DwarfDebugSection *getCurDwarfDebugSection() const { + return DebugSection.get(); + } uint16_t getDwarfVersion() const; void setDwarfVersion(uint16_t Version); @@ -580,12 +654,6 @@ /// Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified. virtual unsigned getISAEncoding() { return 0; } - /// Emit the directive and value for debug thread local expression - /// - /// \p Value - The value to emit. - /// \p Size - The size of the integer (in bytes) to emit. - virtual void emitDebugValue(const MCExpr *Value, unsigned Size) const; - //===------------------------------------------------------------------===// // Dwarf Lowering Routines //===------------------------------------------------------------------===// @@ -600,7 +668,7 @@ emitDwarfAbbrev(*Abbrev); // Mark end of abbreviations. - emitULEB128(0, "EOM(3)"); + getCurDwarfDebugSection()->writeULEB128(0, "EOM(3)"); } void emitDwarfAbbrev(const DIEAbbrev &Abbrev) const; diff --git a/llvm/include/llvm/CodeGen/DIE.h b/llvm/include/llvm/CodeGen/DIE.h --- a/llvm/include/llvm/CodeGen/DIE.h +++ b/llvm/include/llvm/CodeGen/DIE.h @@ -22,6 +22,7 @@ #include "llvm/ADT/iterator_range.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/DwarfStringPoolEntry.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugSection.h" #include "llvm/Support/AlignOf.h" #include "llvm/Support/Allocator.h" #include @@ -119,7 +120,7 @@ void Profile(FoldingSetNodeID &ID) const; /// Print the abbreviation using the specified asm printer. - void Emit(const AsmPrinter *AP) const; + void Emit(DwarfDebugSection *Dwarf) const; void print(raw_ostream &O) const; void dump() const; @@ -190,8 +191,8 @@ uint64_t getValue() const { return Integer; } void setValue(uint64_t Val) { Integer = Val; } - void emitValue(const AsmPrinter *Asm, dwarf::Form Form) const; - unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + void emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const; + unsigned SizeOf(const DwarfDebugSection *Dwarf, dwarf::Form Form) const; void print(raw_ostream &O) const; }; @@ -207,8 +208,8 @@ /// Get MCExpr. const MCExpr *getValue() const { return Expr; } - void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + void emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const; + unsigned SizeOf(const DwarfDebugSection *Dwarf, dwarf::Form Form) const; void print(raw_ostream &O) const; }; @@ -224,8 +225,8 @@ /// Get MCSymbol. const MCSymbol *getValue() const { return Label; } - void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + void emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const; + unsigned SizeOf(const DwarfDebugSection *Dwarf, dwarf::Form Form) const; void print(raw_ostream &O) const; }; @@ -242,9 +243,9 @@ : CU(TheCU), Index(Idx) {} /// EmitValue - Emit base type reference. - void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; + void emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const; /// SizeOf - Determine size of the base type reference in bytes. - unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const DwarfDebugSection *Dwarf, dwarf::Form Form) const; void print(raw_ostream &O) const; }; @@ -259,8 +260,8 @@ public: DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) : LabelHi(Hi), LabelLo(Lo) {} - void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + void emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const; + unsigned SizeOf(const DwarfDebugSection *Dwarf, dwarf::Form Form) const; void print(raw_ostream &O) const; }; @@ -278,8 +279,8 @@ /// Grab the string out of the object. StringRef getString() const { return S.getString(); } - void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + void emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const; + unsigned SizeOf(const DwarfDebugSection *Dwarf, dwarf::Form Form) const; void print(raw_ostream &O) const; }; @@ -300,8 +301,8 @@ /// Grab the string out of the object. StringRef getString() const { return S; } - void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + void emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const; + unsigned SizeOf(const DwarfDebugSection *Dwarf, dwarf::Form Form) const; void print(raw_ostream &O) const; }; @@ -319,8 +320,8 @@ DIE &getEntry() const { return *Entry; } - void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + void emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const; + unsigned SizeOf(const DwarfDebugSection *Dwarf, dwarf::Form Form) const; void print(raw_ostream &O) const; }; @@ -338,8 +339,8 @@ /// Grab the current index out. size_t getValue() const { return Index; } - void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + void emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const; + unsigned SizeOf(const DwarfDebugSection *Dwarf, dwarf::Form Form) const; void print(raw_ostream &O) const; }; @@ -485,10 +486,10 @@ #include "llvm/CodeGen/DIEValue.def" /// Emit value via the Dwarf writer. - void emitValue(const AsmPrinter *AP) const; + void emitValue(DwarfDebugSection *Dwarf) const; /// Return the size of a value in bytes. - unsigned SizeOf(const AsmPrinter *AP) const; + unsigned SizeOf(const DwarfDebugSection *Dwarf) const; void print(raw_ostream &O) const; void dump() const; @@ -790,12 +791,12 @@ /// properly refer to other DIE objects since all DIEs have calculated their /// offsets. /// - /// \param AP AsmPrinter to use when calculating sizes. + /// \param Dwarf DwarfDebugStream to use when calculating sizes. /// \param AbbrevSet the abbreviation used to unique DIE abbreviations. /// \param CUOffset the compile/type unit relative offset in bytes. /// \returns the offset for the DIE that follows this DIE within the /// current compile/type unit. - unsigned computeOffsetsAndAbbrevs(const AsmPrinter *AP, + unsigned computeOffsetsAndAbbrevs(DwarfDebugSection *Dwarf, DIEAbbrevSet &AbbrevSet, unsigned CUOffset); /// Climb up the parent chain to get the compile unit or type unit DIE that @@ -908,7 +909,7 @@ /// ComputeSize - Calculate the size of the location expression. /// - unsigned ComputeSize(const AsmPrinter *AP) const; + unsigned ComputeSize(const DwarfDebugSection *AP) const; // TODO: move setSize() and Size to DIEValueList. void setSize(unsigned size) { Size = size; } @@ -928,8 +929,8 @@ return dwarf::DW_FORM_block; } - void emitValue(const AsmPrinter *Asm, dwarf::Form Form) const; - unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + void emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const; + unsigned SizeOf(const DwarfDebugSection *Dwarf, dwarf::Form Form) const; void print(raw_ostream &O) const; }; @@ -945,7 +946,7 @@ /// ComputeSize - Calculate the size of the location expression. /// - unsigned ComputeSize(const AsmPrinter *AP) const; + unsigned ComputeSize(const DwarfDebugSection *Dwarf) const; // TODO: move setSize() and Size to DIEValueList. void setSize(unsigned size) { Size = size; } @@ -962,8 +963,8 @@ return dwarf::DW_FORM_block; } - void emitValue(const AsmPrinter *Asm, dwarf::Form Form) const; - unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + void emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const; + unsigned SizeOf(const DwarfDebugSection *Dwarf, dwarf::Form Form) const; void print(raw_ostream &O) const; }; diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFile.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFile.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFile.h @@ -0,0 +1,80 @@ +//===- DWARFDebugFile.h -------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGFILE_H +#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGFILE_H + +#include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/CodeGen/DIE.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugSection.h" +#include "llvm/DebugInfo/DWARF/DWARFUnit.h" +#include + +namespace llvm { + +/// This class writes DWARF constructions into +class DwarfDebugFile { +public: + virtual ~DwarfDebugFile() {} + + /// Set of methods writing DWARF constructions: + + /// Writes compile unit header. + virtual void writeCompileUnitHeader(DIEUnit &Unit) = 0; + + /// Writes compile units address ranges. + virtual void writeUnitRangesEntries(DIEUnit &Unit) = 0; + + /// Recursively write Dwarf DIE tree. + virtual void writeDwarfDIE(const DIE &Die) = 0; + + /// Set of methods returning DWARF sections: + + virtual DwarfDebugSection *getLocSection() = 0; + virtual DwarfDebugSection *getLoclistsSection() = 0; + virtual DwarfDebugSection *getArangesSection() = 0; + virtual DwarfDebugSection *getFrameSection() = 0; + virtual DwarfDebugSection *getEHFrameSection() = 0; + virtual DwarfDebugSection *getLineSection() = 0; + virtual DwarfDebugSection *getLineStrSection() = 0; + virtual DwarfDebugSection *getStrSection() = 0; + virtual DwarfDebugSection *getRangesSection() = 0; + virtual DwarfDebugSection *getRnglistsSection() = 0; + virtual DwarfDebugSection *getMacinfoSection() = 0; + virtual DwarfDebugSection *getMacinfoDWOSection() = 0; + virtual DwarfDebugSection *getPubnamesSection() = 0; + virtual DwarfDebugSection *getPubtypesSection() = 0; + virtual DwarfDebugSection *getGnuPubnamesSection() = 0; + virtual DwarfDebugSection *getGnuPubtypesSection() = 0; + virtual DwarfDebugSection *getStrOffsetsSection() = 0; + virtual void + forEachInfoDWOSections(function_ref F) = 0; + virtual void + forEachTypesDWOSections(function_ref F) = 0; + virtual DwarfDebugSection *getAbbrevDWOSection() = 0; + virtual DwarfDebugSection *getLineDWOSection() = 0; + virtual DwarfDebugSection *getLocDWOSection() = 0; + virtual DwarfDebugSection *getLoclistsDWOSection() = 0; + virtual DwarfDebugSection *getStrDWOSection() = 0; + virtual DwarfDebugSection *getStrOffsetsDWOSection() = 0; + virtual DwarfDebugSection *getRangesDWOSection() = 0; + virtual DwarfDebugSection *getRnglistsDWOSection() = 0; + virtual DwarfDebugSection *getAddrSection() = 0; + virtual DwarfDebugSection *getAppleNamesSection() = 0; + virtual DwarfDebugSection *getAppleTypesSection() = 0; + virtual DwarfDebugSection *getAppleNamespacesSection() = 0; + virtual DwarfDebugSection *getNamesSection() = 0; + virtual DwarfDebugSection *getAppleObjCSection() = 0; + virtual DwarfDebugSection *getCUIndexSection() = 0; + virtual DwarfDebugSection *getGdbIndexSection() = 0; + virtual DwarfDebugSection *getTUIndexSection() = 0; +}; + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGFILE_H diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugSection.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugSection.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugSection.h @@ -0,0 +1,149 @@ +//===- DWARFDebugSection.h ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGSECTION_H +#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGSECTION_H + +#include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCSymbol.h" +#include + +namespace llvm { + +/// This class represents routines to write unstructured data +/// into debug section. +class DwarfDebugSection { +public: + virtual ~DwarfDebugSection() {} + + /// Returns true if the destination is an assembler. + virtual bool isAsm() const = 0; + + /// Set of methods describing state of debug stream. + + /// Returns Dwarf format(32 bit/64 bit). + virtual dwarf::DwarfFormat getDwarfFormat() const = 0; + + /// Returns current address size. + virtual unsigned getAddressSize() const = 0; + + /// Set current address size. + virtual void setAddressSize(unsigned Size) {} + + /// Returns current Dwarf version number. + virtual uint16_t getDwarfVersion() const = 0; + + /// Set current Dwarf version. + virtual void setDwarfVersion(uint16_t Version) = 0; + + /// True if Dwarf2 output generally uses relocations for references to other + /// .debug_* sections. + virtual bool doesDwarfUseRelocationsAcrossSections() const = 0; + + /// Special case of EmitValue that avoids the client + /// to call concrete sized method. + virtual void writeIntValue(uint64_t Value, unsigned Size) = 0; + + /// Write a byte directive and value. + virtual void writeInt8(int Value) = 0; + + /// Write a short directive and value. + virtual void writeInt16(int Value) = 0; + + /// Write a long directive and value. + virtual void writeInt32(int Value) = 0; + + /// Write a long long directive and value. + virtual void writeInt64(uint64_t Value) = 0; + + /// Write the specified signed leb128 value. + virtual void writeSLEB128(int64_t Value, const char *Desc = nullptr) = 0; + + /// Write the specified unsigned leb128 value. + virtual void writeULEB128(uint64_t Value, const char *Desc = nullptr, + unsigned PadTo = 0) = 0; + + /// Write the specified bytes. + virtual void writeBytes(StringRef Data) = 0; +}; + +class DwarfDebugSectionAsm : public DwarfDebugSection { +public: + bool isAsm() const override { return true; } + + /// Write the directive and value for debug thread local expression + /// + /// \p Value - The value to write. + /// \p Size - The size of the integer (in bytes) to write. + virtual void writeDebugValue(const MCExpr *Value, unsigned Size) = 0; + + /// Write something like ".long Label" where the size in bytes of the + /// directive is specified by Size and Label specifies the label. + virtual void writeLabelReference(const MCSymbol *Label, unsigned Size, + bool IsSectionRelative = false) = 0; + + /// Write something like ".long Label+Offset" where the size in bytes of the + /// directive is specified by Size and Label specifies the label. This + /// implicitly uses .set if it is available. + virtual void writeLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, + unsigned Size, + bool IsSectionRelative = false) = 0; + + /// Write something like ".long Hi-Lo" where the size in bytes of the + /// directive is specified by Size and Hi/Lo specify the labels. This + /// implicitly uses .set if it is available. + virtual void writeLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, + unsigned Size) = 0; + + /// Write a reference to a symbol for use in dwarf. Different object formats + /// represent this in different ways. Some use a relocation others encode + /// the label offset in its section. + virtual void writeDwarfSymbolReference(const MCSymbol *Label, + bool ForceOffset = false) = 0; + + /// Emit a blank line to a .s file to pretty it up. + virtual void addBlankLine() = 0; +}; + +class DwarfDebugSectionBin : public DwarfDebugSection { +public: + bool isAsm() const override { return false; } + + /// returns current section size. + virtual uint64_t getSize() const = 0; + + /// Fixup a uint64_t value at the specified offset in the section. This + /// function will save the current section position, seek to the specified + /// offset, overwrite the data using Value, and then restore the section + /// position to the previous section position. + /// + /// \param Value The value to write into the section. + /// \param Offset The offset at which to write the Value within the section. + void fixup32(uint32_t Value, uint64_t Offset); + + /// Fixup a uint64_t value at the specified offset in the section. This + /// function will save the current section position, seek to the specified + /// section, overwrite the data using Value, and then restore the section + /// position to the previous section position. + /// + /// \param Value The value to write into the section. + /// \param Offset The offset at which to write the Value within the section. + void fixup64(uint64_t Value, uint64_t Offset); + + /// Pad with zeroes at the current section position until the current section + /// position matches the specified alignment. + /// + /// \param Align An integer speciying the desired alignment. This does not + /// need to be a power of two. + void alignTo(size_t Align); +}; + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGSECTION_H diff --git a/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp b/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp @@ -484,7 +484,7 @@ switch (AttrEnc.Index) { case dwarf::DW_IDX_compile_unit: { DIEInteger ID(getCUIndexForEntry(Entry)); - ID.emitValue(Asm, AttrEnc.Form); + ID.emitValue(Asm->getCurDwarfDebugSection(), AttrEnc.Form); break; } case dwarf::DW_IDX_die_offset: 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 @@ -189,6 +189,8 @@ : MachineFunctionPass(ID), TM(tm), MAI(tm.getMCAsmInfo()), OutContext(Streamer->getContext()), OutStreamer(std::move(Streamer)) { VerboseAsm = OutStreamer->isVerboseAsm(); + DebugSection = std::make_unique( + this, OutStreamer.get(), &TM, MAI, isVerbose()); } AsmPrinter::~AsmPrinter() { @@ -660,14 +662,6 @@ OutStreamer->AddBlankLine(); } -/// Emit the directive and value for debug thread local expression -/// -/// \p Value - The value to emit. -/// \p Size - The size of the integer (in bytes) to emit. -void AsmPrinter::emitDebugValue(const MCExpr *Value, unsigned Size) const { - OutStreamer->emitValue(Value, Size); -} - /// EmitFunctionHeader - This method emits the header for the current /// function. void AsmPrinter::emitFunctionHeader() { @@ -3335,3 +3329,126 @@ void AsmPrinter::setDwarfVersion(uint16_t Version) { OutStreamer->getContext().setDwarfVersion(Version); } + +uint16_t DwarfDebugSectionImpl::getDwarfVersion() const { + return OutStreamer->getContext().getDwarfVersion(); +} + +void DwarfDebugSectionImpl::setDwarfVersion(uint16_t Version) { + OutStreamer->getContext().setDwarfVersion(Version); +} + +unsigned DwarfDebugSectionImpl::getAddressSize() const { + return TM->getPointerSize(0); // FIXME: Default address space +} + +/// Emit a byte directive and value. +/// +void DwarfDebugSectionImpl::writeInt8(int Value) { + OutStreamer->emitInt8(Value); +} + +/// Emit a short directive and value. +void DwarfDebugSectionImpl::writeInt16(int Value) { + OutStreamer->emitInt16(Value); +} + +/// Emit a long directive and value. +void DwarfDebugSectionImpl::writeInt32(int Value) { + OutStreamer->emitInt32(Value); +} + +/// Emit a long long directive and value. +void DwarfDebugSectionImpl::writeInt64(uint64_t Value) { + OutStreamer->emitInt64(Value); +} + +/// EmitSLEB128 - emit the specified signed leb128 value. +void DwarfDebugSectionImpl::writeSLEB128(int64_t Value, const char *Desc) { + if (IsVerbose && Desc) + OutStreamer->AddComment(Desc); + + OutStreamer->emitSLEB128IntValue(Value); +} + +void DwarfDebugSectionImpl::writeULEB128(uint64_t Value, const char *Desc, + unsigned PadTo) { + if (IsVerbose && Desc) + OutStreamer->AddComment(Desc); + + OutStreamer->emitULEB128IntValue(Value, PadTo); +} + +void DwarfDebugSectionImpl::writeBytes(StringRef Data) { + OutStreamer->emitBytes(Data); +} + +dwarf::DwarfFormat DwarfDebugSectionImpl::getDwarfFormat() const { + return OutStreamer->getContext().getDwarfFormat(); +} + +void DwarfDebugSectionImpl::writeIntValue(uint64_t Value, unsigned Size) { + OutStreamer->emitIntValue(Value, Size); +} + +bool DwarfDebugSectionImpl::doesDwarfUseRelocationsAcrossSections() const { + return MAI->doesDwarfUseRelocationsAcrossSections(); +} + +void DwarfDebugSectionImpl::addBlankLine() { OutStreamer->AddBlankLine(); } + +void DwarfDebugSectionImpl::writeDebugValue(const MCExpr *Value, + unsigned Size) { + OutStreamer->emitValue(Value, Size); +} + +void DwarfDebugSectionImpl::writeLabelPlusOffset(const MCSymbol *Label, + uint64_t Offset, unsigned Size, + bool IsSectionRelative) { + if (MAI->needsDwarfSectionOffsetDirective() && IsSectionRelative) { + OutStreamer->EmitCOFFSecRel32(Label, Offset); + if (Size > 4) + OutStreamer->emitZeros(Size - 4); + return; + } + + // Emit Label+Offset (or just Label if Offset is zero) + const MCExpr *Expr = MCSymbolRefExpr::create(Label, AP->OutContext); + if (Offset) + Expr = MCBinaryExpr::createAdd( + Expr, MCConstantExpr::create(Offset, AP->OutContext), AP->OutContext); + + OutStreamer->emitValue(Expr, Size); +} + +void DwarfDebugSectionImpl::writeLabelReference(const MCSymbol *Label, + unsigned Size, + bool IsSectionRelative) { + writeLabelPlusOffset(Label, 0, Size, IsSectionRelative); +} + +void DwarfDebugSectionImpl::writeLabelDifference(const MCSymbol *Hi, + const MCSymbol *Lo, + unsigned Size) { + OutStreamer->emitAbsoluteSymbolDiff(Hi, Lo, Size); +} + +void DwarfDebugSectionImpl::writeDwarfSymbolReference(const MCSymbol *Label, + bool ForceOffset) { + if (!ForceOffset) { + // On COFF targets, we have to emit the special .secrel32 directive. + if (MAI->needsDwarfSectionOffsetDirective()) { + OutStreamer->EmitCOFFSecRel32(Label, /*Offset=*/0); + return; + } + + // If the format uses relocations with dwarf, refer to the symbol directly. + if (MAI->doesDwarfUseRelocationsAcrossSections()) { + OutStreamer->emitSymbolValue(Label, 4); + return; + } + } + + // Otherwise, emit it as a label difference from the start of the section. + writeLabelDifference(Label, Label->getSection().getBeginSymbol(), 4); +} 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 @@ -177,7 +177,7 @@ } // Just emit the offset directly; no need for symbol math. - emitInt32(S.Offset); + getCurDwarfDebugSection()->writeInt32(S.Offset); } void AsmPrinter::emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const { @@ -196,7 +196,7 @@ void AsmPrinter::emitCallSiteValue(uint64_t Value, unsigned Encoding) const { // The least significant 3 bits specify the width of the encoding if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128) - emitULEB128(Value); + getCurDwarfDebugSection()->writeULEB128(Value); else OutStreamer->emitIntValue(Value, GetSizeOfEncodedValue(Encoding)); } @@ -273,7 +273,7 @@ } // Emit an attribute using the defined form. - V.emitValue(this); + V.emitValue(getCurDwarfDebugSection()); } // Emit the DIE children if any. @@ -282,14 +282,15 @@ emitDwarfDIE(Child); OutStreamer->AddComment("End Of Children Mark"); - emitInt8(0); + getCurDwarfDebugSection()->writeInt8(0); } } void AsmPrinter::emitDwarfAbbrev(const DIEAbbrev &Abbrev) const { // Emit the abbreviations code (base 1 index.) - emitULEB128(Abbrev.getNumber(), "Abbreviation Code"); + const_cast(this)->emitULEB128(Abbrev.getNumber(), + "Abbreviation Code"); // Emit the abbreviations data. - Abbrev.Emit(this); + Abbrev.Emit(getCurDwarfDebugSection()); } 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 @@ -65,44 +65,45 @@ /// Emit - Print the abbreviation using the specified asm printer. /// -void DIEAbbrev::Emit(const AsmPrinter *AP) const { +void DIEAbbrev::Emit(DwarfDebugSection *Dwarf) const { // Emit its Dwarf tag type. - AP->emitULEB128(Tag, dwarf::TagString(Tag).data()); + Dwarf->writeULEB128(Tag, dwarf::TagString(Tag).data()); // Emit whether it has children DIEs. - AP->emitULEB128((unsigned)Children, dwarf::ChildrenString(Children).data()); + Dwarf->writeULEB128((unsigned)Children, + dwarf::ChildrenString(Children).data()); // For each attribute description. for (unsigned i = 0, N = Data.size(); i < N; ++i) { const DIEAbbrevData &AttrData = Data[i]; // Emit attribute type. - AP->emitULEB128(AttrData.getAttribute(), - dwarf::AttributeString(AttrData.getAttribute()).data()); + Dwarf->writeULEB128(AttrData.getAttribute(), + dwarf::AttributeString(AttrData.getAttribute()).data()); // Emit form type. #ifndef NDEBUG // Could be an assertion, but this way we can see the failing form code // easily, which helps track down where it came from. if (!dwarf::isValidFormForVersion(AttrData.getForm(), - AP->getDwarfVersion())) { + Dwarf->getDwarfVersion())) { LLVM_DEBUG(dbgs() << "Invalid form " << format("0x%x", AttrData.getForm()) - << " for DWARF version " << AP->getDwarfVersion() + << " for DWARF version " << Dwarf->getDwarfVersion() << "\n"); llvm_unreachable("Invalid form for specified DWARF version"); } #endif - AP->emitULEB128(AttrData.getForm(), - dwarf::FormEncodingString(AttrData.getForm()).data()); + Dwarf->writeULEB128(AttrData.getForm(), + dwarf::FormEncodingString(AttrData.getForm()).data()); // Emit value for DW_FORM_implicit_const. if (AttrData.getForm() == dwarf::DW_FORM_implicit_const) - AP->emitSLEB128(AttrData.getValue()); + Dwarf->writeSLEB128(AttrData.getValue()); } // Mark end of abbreviation. - AP->emitULEB128(0, "EOM(1)"); - AP->emitULEB128(0, "EOM(2)"); + Dwarf->writeULEB128(0, "EOM(1)"); + Dwarf->writeULEB128(0, "EOM(2)"); } LLVM_DUMP_METHOD @@ -274,7 +275,7 @@ } #endif -unsigned DIE::computeOffsetsAndAbbrevs(const AsmPrinter *AP, +unsigned DIE::computeOffsetsAndAbbrevs(DwarfDebugSection *Dwarf, DIEAbbrevSet &AbbrevSet, unsigned CUOffset) { // Unique the abbreviation and fill in the abbreviation number so this DIE @@ -289,7 +290,7 @@ // Add the byte size of all the DIE attribute values. for (const auto &V : values()) - CUOffset += V.SizeOf(AP); + CUOffset += V.SizeOf(Dwarf); // Let the children compute their offsets and abbreviation numbers. if (hasChildren()) { @@ -297,7 +298,7 @@ assert(Abbrev.hasChildren() && "Children flag not set"); for (auto &Child : children()) - CUOffset = Child.computeOffsetsAndAbbrevs(AP, AbbrevSet, CUOffset); + CUOffset = Child.computeOffsetsAndAbbrevs(Dwarf, AbbrevSet, CUOffset); // Each child chain is terminated with a zero byte, adjust the offset. CUOffset += sizeof(int8_t); @@ -325,25 +326,25 @@ "expected a unit TAG"); } -void DIEValue::emitValue(const AsmPrinter *AP) const { +void DIEValue::emitValue(DwarfDebugSection *Dwarf) const { switch (Ty) { case isNone: llvm_unreachable("Expected valid DIEValue"); #define HANDLE_DIEVALUE(T) \ case is##T: \ - getDIE##T().emitValue(AP, Form); \ + getDIE##T().emitValue(Dwarf, Form); \ break; #include "llvm/CodeGen/DIEValue.def" } } -unsigned DIEValue::SizeOf(const AsmPrinter *AP) const { +unsigned DIEValue::SizeOf(const DwarfDebugSection *Dwarf) const { switch (Ty) { case isNone: llvm_unreachable("Expected valid DIEValue"); #define HANDLE_DIEVALUE(T) \ case is##T: \ - return getDIE##T().SizeOf(AP, Form); + return getDIE##T().SizeOf(Dwarf, Form); #include "llvm/CodeGen/DIEValue.def" } llvm_unreachable("Unknown DIE kind"); @@ -374,13 +375,14 @@ /// EmitValue - Emit integer of appropriate size. /// -void DIEInteger::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const { +void DIEInteger::emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const { switch (Form) { case dwarf::DW_FORM_implicit_const: case dwarf::DW_FORM_flag_present: // Emit something to keep the lines and comments in sync. // FIXME: Is there a better way to do this? - Asm->OutStreamer->AddBlankLine(); + if (Dwarf->isAsm()) + static_cast(Dwarf)->addBlankLine(); return; case dwarf::DW_FORM_flag: case dwarf::DW_FORM_ref1: @@ -409,7 +411,7 @@ case dwarf::DW_FORM_strp_sup: case dwarf::DW_FORM_addr: case dwarf::DW_FORM_ref_addr: - Asm->OutStreamer->emitIntValue(Integer, SizeOf(Asm, Form)); + Dwarf->writeIntValue(Integer, SizeOf(Dwarf, Form)); return; case dwarf::DW_FORM_GNU_str_index: case dwarf::DW_FORM_GNU_addr_index: @@ -418,22 +420,24 @@ case dwarf::DW_FORM_addrx: case dwarf::DW_FORM_rnglistx: case dwarf::DW_FORM_udata: - Asm->emitULEB128(Integer); + Dwarf->writeULEB128(Integer); return; case dwarf::DW_FORM_sdata: - Asm->emitSLEB128(Integer); + Dwarf->writeSLEB128(Integer); return; - default: llvm_unreachable("DIE Value form not supported yet"); + default: + llvm_unreachable("DIE Value form not supported yet"); } } /// SizeOf - Determine size of integer value in bytes. /// -unsigned DIEInteger::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIEInteger::SizeOf(const DwarfDebugSection *Dwarf, + dwarf::Form Form) const { dwarf::FormParams Params = {0, 0, dwarf::DWARF32}; - if (AP) - Params = {AP->getDwarfVersion(), uint8_t(AP->getPointerSize()), - AP->OutStreamer->getContext().getDwarfFormat()}; + if (Dwarf) + Params = {Dwarf->getDwarfVersion(), uint8_t(Dwarf->getAddressSize()), + Dwarf->getDwarfFormat()}; if (Optional FixedSize = dwarf::getFixedFormByteSize(Form, Params)) return *FixedSize; @@ -465,17 +469,24 @@ /// EmitValue - Emit expression value. /// -void DIEExpr::emitValue(const AsmPrinter *AP, dwarf::Form Form) const { - AP->emitDebugValue(Expr, SizeOf(AP, Form)); +void DIEExpr::emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const { + if (Dwarf->isAsm()) { + static_cast(Dwarf)->writeDebugValue( + Expr, SizeOf(Dwarf, Form)); + } else { + llvm_unreachable( + "DIEExpr::emitValue for DwarfDebugSectionBin is not implemented yet."); + } } /// SizeOf - Determine size of expression value in bytes. /// -unsigned DIEExpr::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIEExpr::SizeOf(const DwarfDebugSection *Dwarf, + dwarf::Form Form) const { if (Form == dwarf::DW_FORM_data4) return 4; if (Form == dwarf::DW_FORM_sec_offset) return 4; if (Form == dwarf::DW_FORM_strp) return 4; - return AP->getPointerSize(); + return Dwarf->getAddressSize(); } LLVM_DUMP_METHOD @@ -487,20 +498,26 @@ /// EmitValue - Emit label value. /// -void DIELabel::emitValue(const AsmPrinter *AP, dwarf::Form Form) const { - AP->emitLabelReference( - Label, SizeOf(AP, Form), - Form == dwarf::DW_FORM_strp || Form == dwarf::DW_FORM_sec_offset || - Form == dwarf::DW_FORM_ref_addr || Form == dwarf::DW_FORM_data4); +void DIELabel::emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const { + if (Dwarf->isAsm()) { + static_cast(Dwarf)->writeLabelReference( + Label, SizeOf(Dwarf, Form), + Form == dwarf::DW_FORM_strp || Form == dwarf::DW_FORM_sec_offset || + Form == dwarf::DW_FORM_ref_addr || Form == dwarf::DW_FORM_data4); + } else { + llvm_unreachable( + "DIELabel::emitValue for DwarfDebugSectionBin is not implemented yet."); + } } /// SizeOf - Determine size of label value in bytes. /// -unsigned DIELabel::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIELabel::SizeOf(const DwarfDebugSection *Dwarf, + dwarf::Form Form) const { if (Form == dwarf::DW_FORM_data4) return 4; if (Form == dwarf::DW_FORM_sec_offset) return 4; if (Form == dwarf::DW_FORM_strp) return 4; - return AP->MAI->getCodePointerSize(); + return Dwarf->getAddressSize(); } LLVM_DUMP_METHOD @@ -510,13 +527,13 @@ // DIEBaseTypeRef Implementation //===----------------------------------------------------------------------===// -void DIEBaseTypeRef::emitValue(const AsmPrinter *AP, dwarf::Form Form) const { +void DIEBaseTypeRef::emitValue(DwarfDebugSection *Dwarf, dwarf::Form) const { uint64_t Offset = CU->ExprRefedBaseTypes[Index].Die->getOffset(); assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit"); - AP->emitULEB128(Offset, nullptr, ULEB128PadSize); + Dwarf->writeULEB128(Offset, nullptr, ULEB128PadSize); } -unsigned DIEBaseTypeRef::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIEBaseTypeRef::SizeOf(const DwarfDebugSection *, dwarf::Form) const { return ULEB128PadSize; } @@ -529,17 +546,24 @@ /// EmitValue - Emit delta value. /// -void DIEDelta::emitValue(const AsmPrinter *AP, dwarf::Form Form) const { - AP->emitLabelDifference(LabelHi, LabelLo, SizeOf(AP, Form)); +void DIEDelta::emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const { + if (Dwarf->isAsm()) { + static_cast(Dwarf)->writeLabelDifference( + LabelHi, LabelLo, SizeOf(Dwarf, Form)); + } else { + llvm_unreachable( + "DIEDelta::emitValue for DwarfDebugSectionBin is not implemented yet."); + } } /// SizeOf - Determine size of delta value in bytes. /// -unsigned DIEDelta::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIEDelta::SizeOf(const DwarfDebugSection *Dwarf, + dwarf::Form Form) const { if (Form == dwarf::DW_FORM_data4) return 4; if (Form == dwarf::DW_FORM_sec_offset) return 4; if (Form == dwarf::DW_FORM_strp) return 4; - return AP->MAI->getCodePointerSize(); + return Dwarf->getAddressSize(); } LLVM_DUMP_METHOD @@ -553,7 +577,7 @@ /// EmitValue - Emit string value. /// -void DIEString::emitValue(const AsmPrinter *AP, dwarf::Form Form) const { +void DIEString::emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const { // Index of string in symbol table. switch (Form) { case dwarf::DW_FORM_GNU_str_index: @@ -562,13 +586,13 @@ case dwarf::DW_FORM_strx2: case dwarf::DW_FORM_strx3: case dwarf::DW_FORM_strx4: - DIEInteger(S.getIndex()).emitValue(AP, Form); + DIEInteger(S.getIndex()).emitValue(Dwarf, Form); return; case dwarf::DW_FORM_strp: - if (AP->MAI->doesDwarfUseRelocationsAcrossSections()) - DIELabel(S.getSymbol()).emitValue(AP, Form); + if (Dwarf->doesDwarfUseRelocationsAcrossSections()) + DIELabel(S.getSymbol()).emitValue(Dwarf, Form); else - DIEInteger(S.getOffset()).emitValue(AP, Form); + DIEInteger(S.getOffset()).emitValue(Dwarf, Form); return; default: llvm_unreachable("Expected valid string form"); @@ -577,7 +601,8 @@ /// SizeOf - Determine size of delta value in bytes. /// -unsigned DIEString::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIEString::SizeOf(const DwarfDebugSection *Dwarf, + dwarf::Form Form) const { // Index of string in symbol table. switch (Form) { case dwarf::DW_FORM_GNU_str_index: @@ -586,11 +611,11 @@ case dwarf::DW_FORM_strx2: case dwarf::DW_FORM_strx3: case dwarf::DW_FORM_strx4: - return DIEInteger(S.getIndex()).SizeOf(AP, Form); + return DIEInteger(S.getIndex()).SizeOf(Dwarf, Form); case dwarf::DW_FORM_strp: - if (AP->MAI->doesDwarfUseRelocationsAcrossSections()) - return DIELabel(S.getSymbol()).SizeOf(AP, Form); - return DIEInteger(S.getOffset()).SizeOf(AP, Form); + if (Dwarf->doesDwarfUseRelocationsAcrossSections()) + return DIELabel(S.getSymbol()).SizeOf(Dwarf, Form); + return DIEInteger(S.getOffset()).SizeOf(Dwarf, Form); default: llvm_unreachable("Expected valid string form"); } @@ -604,16 +629,17 @@ //===----------------------------------------------------------------------===// // DIEInlineString Implementation //===----------------------------------------------------------------------===// -void DIEInlineString::emitValue(const AsmPrinter *AP, dwarf::Form Form) const { +void DIEInlineString::emitValue(DwarfDebugSection *Dwarf, + dwarf::Form Form) const { if (Form == dwarf::DW_FORM_string) { - AP->OutStreamer->emitBytes(S); - AP->emitInt8(0); + Dwarf->writeBytes(S); + Dwarf->writeInt8(0); return; } llvm_unreachable("Expected valid string form"); } -unsigned DIEInlineString::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIEInlineString::SizeOf(const DwarfDebugSection *, dwarf::Form) const { // Emit string bytes + NULL byte. return S.size() + 1; } @@ -629,18 +655,18 @@ /// EmitValue - Emit debug information entry offset. /// -void DIEEntry::emitValue(const AsmPrinter *AP, dwarf::Form Form) const { +void DIEEntry::emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const { switch (Form) { case dwarf::DW_FORM_ref1: case dwarf::DW_FORM_ref2: case dwarf::DW_FORM_ref4: case dwarf::DW_FORM_ref8: - AP->OutStreamer->emitIntValue(Entry->getOffset(), SizeOf(AP, Form)); + Dwarf->writeIntValue(Entry->getOffset(), SizeOf(Dwarf, Form)); return; case dwarf::DW_FORM_ref_udata: - AP->emitULEB128(Entry->getOffset()); + Dwarf->writeULEB128(Entry->getOffset()); return; case dwarf::DW_FORM_ref_addr: { @@ -648,11 +674,18 @@ unsigned Addr = Entry->getDebugSectionOffset(); if (const MCSymbol *SectionSym = Entry->getUnit()->getCrossSectionRelativeBaseAddress()) { - AP->emitLabelPlusOffset(SectionSym, Addr, SizeOf(AP, Form), true); + if (Dwarf->isAsm()) { + static_cast(Dwarf)->writeLabelPlusOffset( + SectionSym, Addr, SizeOf(Dwarf, Form), true); + } else { + llvm_unreachable("DIEDelta::emitValue for DwarfDebugSectionBin is not " + "implemented yet."); + } + return; } - AP->OutStreamer->emitIntValue(Addr, SizeOf(AP, Form)); + Dwarf->writeIntValue(Addr, SizeOf(Dwarf, Form)); return; } default: @@ -660,7 +693,8 @@ } } -unsigned DIEEntry::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIEEntry::SizeOf(const DwarfDebugSection *Dwarf, + dwarf::Form Form) const { switch (Form) { case dwarf::DW_FORM_ref1: return 1; @@ -673,9 +707,9 @@ case dwarf::DW_FORM_ref_udata: return getULEB128Size(Entry->getOffset()); case dwarf::DW_FORM_ref_addr: - if (AP->getDwarfVersion() == 2) - return AP->MAI->getCodePointerSize(); - switch (AP->OutStreamer->getContext().getDwarfFormat()) { + if (Dwarf->getDwarfVersion() == 2) + return Dwarf->getAddressSize(); + switch (Dwarf->getDwarfFormat()) { case dwarf::DWARF32: return 4; case dwarf::DWARF64: @@ -699,10 +733,10 @@ /// ComputeSize - calculate the size of the location expression. /// -unsigned DIELoc::ComputeSize(const AsmPrinter *AP) const { +unsigned DIELoc::ComputeSize(const DwarfDebugSection *Dwarf) const { if (!Size) { for (const auto &V : values()) - Size += V.SizeOf(AP); + Size += V.SizeOf(Dwarf); } return Size; @@ -710,25 +744,31 @@ /// EmitValue - Emit location data. /// -void DIELoc::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const { +void DIELoc::emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const { switch (Form) { default: llvm_unreachable("Improper form for block"); - case dwarf::DW_FORM_block1: Asm->emitInt8(Size); break; - case dwarf::DW_FORM_block2: Asm->emitInt16(Size); break; - case dwarf::DW_FORM_block4: Asm->emitInt32(Size); break; + case dwarf::DW_FORM_block1: + Dwarf->writeInt8(Size); + break; + case dwarf::DW_FORM_block2: + Dwarf->writeInt16(Size); + break; + case dwarf::DW_FORM_block4: + Dwarf->writeInt32(Size); + break; case dwarf::DW_FORM_block: case dwarf::DW_FORM_exprloc: - Asm->emitULEB128(Size); + Dwarf->writeULEB128(Size); break; } for (const auto &V : values()) - V.emitValue(Asm); + V.emitValue(Dwarf); } /// SizeOf - Determine size of location data in bytes. /// -unsigned DIELoc::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIELoc::SizeOf(const DwarfDebugSection *, dwarf::Form Form) const { switch (Form) { case dwarf::DW_FORM_block1: return Size + sizeof(int8_t); case dwarf::DW_FORM_block2: return Size + sizeof(int16_t); @@ -751,10 +791,10 @@ /// ComputeSize - calculate the size of the block. /// -unsigned DIEBlock::ComputeSize(const AsmPrinter *AP) const { +unsigned DIEBlock::ComputeSize(const DwarfDebugSection *Dwarf) const { if (!Size) { for (const auto &V : values()) - Size += V.SizeOf(AP); + Size += V.SizeOf(Dwarf); } return Size; @@ -762,26 +802,32 @@ /// EmitValue - Emit block data. /// -void DIEBlock::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const { +void DIEBlock::emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const { switch (Form) { default: llvm_unreachable("Improper form for block"); - case dwarf::DW_FORM_block1: Asm->emitInt8(Size); break; - case dwarf::DW_FORM_block2: Asm->emitInt16(Size); break; - case dwarf::DW_FORM_block4: Asm->emitInt32(Size); break; + case dwarf::DW_FORM_block1: + Dwarf->writeInt8(Size); + break; + case dwarf::DW_FORM_block2: + Dwarf->writeInt16(Size); + break; + case dwarf::DW_FORM_block4: + Dwarf->writeInt32(Size); + break; case dwarf::DW_FORM_block: - Asm->emitULEB128(Size); + Dwarf->writeULEB128(Size); break; case dwarf::DW_FORM_string: break; case dwarf::DW_FORM_data16: break; } for (const auto &V : values()) - V.emitValue(Asm); + V.emitValue(Dwarf); } /// SizeOf - Determine size of block data in bytes. /// -unsigned DIEBlock::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIEBlock::SizeOf(const DwarfDebugSection *, dwarf::Form Form) const { switch (Form) { case dwarf::DW_FORM_block1: return Size + sizeof(int8_t); case dwarf::DW_FORM_block2: return Size + sizeof(int16_t); @@ -801,26 +847,37 @@ // DIELocList Implementation //===----------------------------------------------------------------------===// -unsigned DIELocList::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIELocList::SizeOf(const DwarfDebugSection *Dwarf, + dwarf::Form Form) const { if (Form == dwarf::DW_FORM_loclistx) return getULEB128Size(Index); if (Form == dwarf::DW_FORM_data4) return 4; if (Form == dwarf::DW_FORM_sec_offset) return 4; - return AP->MAI->getCodePointerSize(); + return Dwarf->getAddressSize(); } /// EmitValue - Emit label value. /// -void DIELocList::emitValue(const AsmPrinter *AP, dwarf::Form Form) const { +void DIELocList::emitValue(DwarfDebugSection *Dwarf, dwarf::Form Form) const { if (Form == dwarf::DW_FORM_loclistx) { - AP->emitULEB128(Index); + Dwarf->writeULEB128(Index); return; } - DwarfDebug *DD = AP->getDwarfDebug(); - MCSymbol *Label = DD->getDebugLocs().getList(Index).Label; - AP->emitDwarfSymbolReference(Label, /*ForceOffset*/ DD->useSplitDwarf()); + + if (Dwarf->isAsm()) { + DwarfDebug *DD = static_cast(Dwarf) + ->getAsmPrinter() + ->getDwarfDebug(); + MCSymbol *Label = DD->getDebugLocs().getList(Index).Label; + static_cast(Dwarf)->writeDwarfSymbolReference( + Label, + /*ForceOffset*/ DD->useSplitDwarf()); + } else { + llvm_unreachable("DIELocList::emitValue for DwarfDebugSectionBin is not " + "implemented yet."); + } } LLVM_DUMP_METHOD diff --git a/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp b/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp @@ -295,10 +295,12 @@ addULEB128(Attribute); addULEB128(dwarf::DW_FORM_block); if (Value.getType() == DIEValue::isBlock) { - addULEB128(Value.getDIEBlock().ComputeSize(AP)); + addULEB128(Value.getDIEBlock().ComputeSize( + AP ? AP->getCurDwarfDebugSection() : nullptr)); hashBlockData(Value.getDIEBlock().values()); } else if (Value.getType() == DIEValue::isLoc) { - addULEB128(Value.getDIELoc().ComputeSize(AP)); + addULEB128(Value.getDIELoc().ComputeSize( + AP ? AP->getCurDwarfDebugSection() : nullptr)); hashBlockData(Value.getDIELoc().values()); } else { // We could add the block length, but that would take diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp @@ -90,7 +90,8 @@ // 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) { - return Die.computeOffsetsAndAbbrevs(Asm, Abbrevs, Offset); + return Die.computeOffsetsAndAbbrevs(Asm->getCurDwarfDebugSection(), Abbrevs, + Offset); } void DwarfFile::emitAbbrevs(MCSection *Section) { Abbrevs.Emit(Asm, Section); } 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 @@ -78,7 +78,7 @@ void DIEDwarfExpression::disableTemporaryBuffer() { IsBuffering = false; } unsigned DIEDwarfExpression::getTemporaryBufferSize() { - return TmpDIE.ComputeSize(&AP); + return TmpDIE.ComputeSize(AP.getCurDwarfDebugSection()); } void DIEDwarfExpression::commitTemporaryBuffer() { OutDIE.takeValues(TmpDIE); } @@ -399,7 +399,7 @@ } void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Loc) { - Loc->ComputeSize(Asm); + Loc->ComputeSize(Asm->getCurDwarfDebugSection()); DIELocs.push_back(Loc); // Memoize so we can call the destructor later on. Die.addValue(DIEValueAllocator, Attribute, Loc->BestForm(DD->getDwarfVersion()), Loc); @@ -407,7 +407,7 @@ void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute, DIEBlock *Block) { - Block->ComputeSize(Asm); + Block->ComputeSize(Asm->getCurDwarfDebugSection()); DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on. Die.addValue(DIEValueAllocator, Attribute, Block->BestForm(), Block); } diff --git a/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp b/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp --- a/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp @@ -46,8 +46,8 @@ //===----------------------------------------------------------------------===// unsigned dwarfgen::DIE::computeSizeAndOffsets(unsigned Offset) { auto &DG = CU->getGenerator(); - return Die->computeOffsetsAndAbbrevs(DG.getAsmPrinter(), DG.getAbbrevSet(), - Offset); + return Die->computeOffsetsAndAbbrevs( + DG.getAsmPrinter()->getCurDwarfDebugSection(), DG.getAbbrevSet(), Offset); } void dwarfgen::DIE::addAttribute(uint16_t A, dwarf::Form Form, uint64_t U) { @@ -111,7 +111,7 @@ DIEInteger( (const_cast(static_cast(P)))[I])); - Block->ComputeSize(DG.getAsmPrinter()); + Block->ComputeSize(DG.getAsmPrinter()->getCurDwarfDebugSection()); Die->addValue(DG.getAllocator(), static_cast(A), Form, Block); }