//===--- unittests/DebugInfo/DWARF/DwarfGenerator.h -------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // A file that can generate DWARF debug info for unit tests. // //===----------------------------------------------------------------------===// #ifndef LLVM_UNITTESTS_DEBUG_INFO_DWARF_DWARFGENERATOR_H #define LLVM_UNITTESTS_DEBUG_INFO_DWARF_DWARFGENERATOR_H #include "llvm/ADT/StringRef.h" #include "llvm/CodeGen/DIE.h" #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" #include "llvm/Support/Error.h" #include #include #include #include namespace llvm { class AsmPrinter; class DIE; class DIEAbbrev; class DwarfStringPool; class MCAsmBackend; class MCAsmInfo; class MCCodeEmitter; class MCContext; struct MCDwarfLineTableParams; class MCInstrInfo; class MCObjectFileInfo; class MCRegisterInfo; class MCStreamer; class MCSubtargetInfo; class raw_fd_ostream; class TargetMachine; class Triple; namespace dwarfgen { class Generator; class CompileUnit; /// A DWARF debug information entry class used to generate DWARF DIEs. /// /// This class is used to quickly generate DWARF debug information by creating /// child DIEs or adding attributes to the current DIE. Instances of this class /// are created from the compile unit (dwarfgen::CompileUnit::getUnitDIE()) or /// by calling dwarfgen::DIE::addChild(...) and using the returned DIE object. class DIE { dwarfgen::CompileUnit *CU; llvm::DIE *Die; protected: friend class Generator; friend class CompileUnit; DIE(CompileUnit *U = nullptr, llvm::DIE *D = nullptr) : CU(U), Die(D) {} /// Called with a compile/type unit relative offset prior to generating the /// DWARF debug info. /// /// \param CUOffset the compile/type unit relative offset where the /// abbreviation code for this DIE will be encoded. unsigned computeSizeAndOffsets(unsigned CUOffset); public: /// Add an attribute value that has no value. /// /// \param Attr a dwarf::Attribute enumeration value or any uint16_t that /// represents a user defined DWARF attribute. /// \param Form the dwarf::Form to use when encoding the attribute. This is /// only used with the DW_FORM_flag_present form encoding. void addAttribute(uint16_t Attr, dwarf::Form Form); /// Add an attribute value to be encoded as a DIEInteger /// /// \param Attr a dwarf::Attribute enumeration value or any uint16_t that /// represents a user defined DWARF attribute. /// \param Form the dwarf::Form to use when encoding the attribute. /// \param U the unsigned integer to encode. void addAttribute(uint16_t Attr, dwarf::Form Form, uint64_t U); /// Add an attribute value to be encoded as a DIEString or DIEInlinedString. /// /// \param Attr a dwarf::Attribute enumeration value or any uint16_t that /// represents a user defined DWARF attribute. /// \param Form the dwarf::Form to use when encoding the attribute. The form /// must be one of DW_FORM_strp or DW_FORM_string. /// \param String the string to encode. void addAttribute(uint16_t Attr, dwarf::Form Form, StringRef String); /// Add an attribute value to be encoded as a DIEEntry. /// /// DIEEntry attributes refer to other llvm::DIE objects that have been /// created. /// /// \param Attr a dwarf::Attribute enumeration value or any uint16_t that /// represents a user defined DWARF attribute. /// \param Form the dwarf::Form to use when encoding the attribute. The form /// must be one of DW_FORM_strp or DW_FORM_string. /// \param RefDie the DIE that this attriute refers to. void addAttribute(uint16_t Attr, dwarf::Form Form, dwarfgen::DIE &RefDie); /// Add an attribute value to be encoded as a DIEBlock. /// /// DIEBlock attributes refers to binary data that is stored as the /// attribute's value. /// /// \param Attr a dwarf::Attribute enumeration value or any uint16_t that /// represents a user defined DWARF attribute. /// \param Form the dwarf::Form to use when encoding the attribute. The form /// must be one of DW_FORM_strp or DW_FORM_string. /// \param P a pointer to the data to store as the attribute value. /// \param S the size in bytes of the data pointed to by P . void addAttribute(uint16_t Attr, dwarf::Form Form, const void *P, size_t S); /// Add a new child to this DIE object. /// /// \param Tag the dwarf::Tag to assing to the llvm::DIE object. /// \returns the newly created DIE object that is now a child owned by this /// object. dwarfgen::DIE addChild(dwarf::Tag Tag); }; /// A DWARF compile unit used to generate DWARF compile/type units. /// /// Instances of these classes are created by instances of the Generator /// class. All information required to generate a DWARF compile unit is /// contained inside this class. class CompileUnit { Generator &DG; BasicDIEUnit DU; public: CompileUnit(Generator &D, uint16_t V, uint8_t A) : DG(D), DU(V, A, dwarf::DW_TAG_compile_unit) {} DIE getUnitDIE(); Generator &getGenerator() { return DG; } uint64_t getOffset() const { return DU.getDebugSectionOffset(); } uint64_t getLength() const { return DU.getLength(); } uint16_t getVersion() const { return DU.getDwarfVersion(); } uint16_t getAddressSize() const { return DU.getAddressSize(); } void setOffset(uint64_t Offset) { DU.setDebugSectionOffset(Offset); } void setLength(uint64_t Length) { DU.setLength(Length); } }; /// A DWARF generator. /// /// Generate DWARF for unit tests by creating any instance of this class and /// calling Generator::addCompileUnit(), and then getting the dwarfgen::DIE from /// the returned compile unit and adding attributes and children to each DIE. class Generator { std::unique_ptr MRI; std::unique_ptr MAI; std::unique_ptr MOFI; std::unique_ptr MC; MCAsmBackend *MAB; // Owned by MCStreamer std::unique_ptr MII; std::unique_ptr MSTI; MCCodeEmitter *MCE; // Owned by MCStreamer MCStreamer *MS; // Owned by AsmPrinter std::unique_ptr TM; std::unique_ptr Asm; BumpPtrAllocator Allocator; std::unique_ptr StringPool; // Entries owned by Allocator. std::vector> CompileUnits; DIEAbbrevSet Abbreviations; SmallString<4096> FileBytes; /// The stream we use to generate the DWARF into as an ELF file. std::unique_ptr Stream; /// The DWARF version to generate. uint16_t Version; /// Private constructor, call Generator::Create(...) to get a DWARF generator /// expected. Generator(); /// Create the streamer and setup the output buffer. llvm::Error init(Triple TheTriple, uint16_t DwarfVersion); public: /// Create a DWARF generator or get an appropriate error. /// /// \param TheTriple the triple to use when creating any required support /// classes needed to emit the DWARF. /// \param DwarfVersion the version of DWARF to emit. /// /// \returns a llvm::Expected that either contains a unique_ptr to a Generator /// or a llvm::Error. static llvm::Expected> create(Triple TheTriple, uint16_t DwarfVersion); ~Generator(); /// Generate all DWARF sections and return a memory buffer that /// contains an ELF file that contains the DWARF. StringRef generate(); /// Add a compile unit to be generated. /// /// \returns a dwarfgen::CompileUnit that can be used to retrieve the compile /// unit dwarfgen::DIE that can be used to add attributes and add child DIE /// objedts to. dwarfgen::CompileUnit &addCompileUnit(); BumpPtrAllocator &getAllocator() { return Allocator; } AsmPrinter *getAsmPrinter() const { return Asm.get(); } DIEAbbrevSet &getAbbrevSet() { return Abbreviations; } DwarfStringPool &getStringPool() { return *StringPool; } /// Save the generated DWARF file to disk. /// /// \param Path the path to save the ELF file to. bool saveFile(StringRef Path); }; } // end namespace dwarfgen } // end namespace llvm #endif // LLVM_UNITTESTS_DEBUG_INFO_DWARF_DWARFGENERATOR_H