1 //===- llvm/CodeGen/DwarfFile.h - Dwarf Debug Framework ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFFILE_H 11 #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFFILE_H 12 13 #include "DwarfStringPool.h" 14 #include "llvm/ADT/DenseMap.h" 15 #include "llvm/ADT/SmallVector.h" 16 #include "llvm/ADT/StringRef.h" 17 #include "llvm/CodeGen/DIE.h" 18 #include "llvm/IR/Metadata.h" 19 #include "llvm/Support/Allocator.h" 20 #include <map> 21 #include <memory> 22 #include <utility> 23 24 namespace llvm { 25 26 class AsmPrinter; 27 class DbgEntity; 28 class DbgVariable; 29 class DbgLabel; 30 class DwarfCompileUnit; 31 class DwarfUnit; 32 class LexicalScope; 33 class MCSection; 34 35 // Data structure to hold a range for range lists. 36 class RangeSpan { 37 public: RangeSpan(MCSymbol * S,MCSymbol * E)38 RangeSpan(MCSymbol *S, MCSymbol *E) : Start(S), End(E) {} getStart()39 const MCSymbol *getStart() const { return Start; } getEnd()40 const MCSymbol *getEnd() const { return End; } setEnd(const MCSymbol * E)41 void setEnd(const MCSymbol *E) { End = E; } 42 43 private: 44 const MCSymbol *Start, *End; 45 }; 46 47 class RangeSpanList { 48 private: 49 // Index for locating within the debug_range section this particular span. 50 MCSymbol *RangeSym; 51 const DwarfCompileUnit *CU; 52 // List of ranges. 53 SmallVector<RangeSpan, 2> Ranges; 54 55 public: RangeSpanList(MCSymbol * Sym,const DwarfCompileUnit & CU,SmallVector<RangeSpan,2> Ranges)56 RangeSpanList(MCSymbol *Sym, const DwarfCompileUnit &CU, 57 SmallVector<RangeSpan, 2> Ranges) 58 : RangeSym(Sym), CU(&CU), Ranges(std::move(Ranges)) {} getSym()59 MCSymbol *getSym() const { return RangeSym; } getCU()60 const DwarfCompileUnit &getCU() const { return *CU; } getRanges()61 const SmallVectorImpl<RangeSpan> &getRanges() const { return Ranges; } addRange(RangeSpan Range)62 void addRange(RangeSpan Range) { Ranges.push_back(Range); } 63 }; 64 65 class DwarfFile { 66 // Target of Dwarf emission, used for sizing of abbreviations. 67 AsmPrinter *Asm; 68 69 BumpPtrAllocator AbbrevAllocator; 70 71 // Used to uniquely define abbreviations. 72 DIEAbbrevSet Abbrevs; 73 74 // A pointer to all units in the section. 75 SmallVector<std::unique_ptr<DwarfCompileUnit>, 1> CUs; 76 77 DwarfStringPool StrPool; 78 79 // List of range lists for a given compile unit, separate from the ranges for 80 // the CU itself. 81 SmallVector<RangeSpanList, 1> CURangeLists; 82 83 /// DWARF v5: The symbol that designates the start of the contribution to 84 /// the string offsets table. The contribution is shared by all units. 85 MCSymbol *StringOffsetsStartSym = nullptr; 86 87 /// DWARF v5: The symbol that designates the base of the range list table. 88 /// The table is shared by all units. 89 MCSymbol *RnglistsTableBaseSym = nullptr; 90 91 /// DWARF v5: The symbol that designates the base of the locations list table. 92 /// The table is shared by all units. 93 MCSymbol *LoclistsTableBaseSym = nullptr; 94 95 /// The variables of a lexical scope. 96 struct ScopeVars { 97 /// We need to sort Args by ArgNo and check for duplicates. This could also 98 /// be implemented as a list or vector + std::lower_bound(). 99 std::map<unsigned, DbgVariable *> Args; 100 SmallVector<DbgVariable *, 8> Locals; 101 }; 102 /// Collection of DbgVariables of each lexical scope. 103 DenseMap<LexicalScope *, ScopeVars> ScopeVariables; 104 105 /// Collection of DbgLabels of each lexical scope. 106 using LabelList = SmallVector<DbgLabel *, 4>; 107 DenseMap<LexicalScope *, LabelList> ScopeLabels; 108 109 // Collection of abstract subprogram DIEs. 110 DenseMap<const MDNode *, DIE *> AbstractSPDies; 111 DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities; 112 113 /// Maps MDNodes for type system with the corresponding DIEs. These DIEs can 114 /// be shared across CUs, that is why we keep the map here instead 115 /// of in DwarfCompileUnit. 116 DenseMap<const MDNode *, DIE *> DITypeNodeToDieMap; 117 118 public: 119 DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA); 120 getUnits()121 const SmallVectorImpl<std::unique_ptr<DwarfCompileUnit>> &getUnits() { 122 return CUs; 123 } 124 125 std::pair<uint32_t, RangeSpanList *> addRange(const DwarfCompileUnit &CU, 126 SmallVector<RangeSpan, 2> R); 127 128 /// getRangeLists - Get the vector of range lists. getRangeLists()129 const SmallVectorImpl<RangeSpanList> &getRangeLists() const { 130 return CURangeLists; 131 } 132 133 /// Compute the size and offset of a DIE given an incoming Offset. 134 unsigned computeSizeAndOffset(DIE &Die, unsigned Offset); 135 136 /// Compute the size and offset of all the DIEs. 137 void computeSizeAndOffsets(); 138 139 /// Compute the size and offset of all the DIEs in the given unit. 140 /// \returns The size of the root DIE. 141 unsigned computeSizeAndOffsetsForUnit(DwarfUnit *TheU); 142 143 /// Add a unit to the list of CUs. 144 void addUnit(std::unique_ptr<DwarfCompileUnit> U); 145 146 /// Emit all of the units to the section listed with the given 147 /// abbreviation section. 148 void emitUnits(bool UseOffsets); 149 150 /// Emit the given unit to its section. 151 void emitUnit(DwarfUnit *U, bool UseOffsets); 152 153 /// Emit a set of abbreviations to the specific section. 154 void emitAbbrevs(MCSection *); 155 156 /// Emit all of the strings to the section given. If OffsetSection is 157 /// non-null, emit a table of string offsets to it. If UseRelativeOffsets 158 /// is false, emit absolute offsets to the strings. Otherwise, emit 159 /// relocatable references to the strings if they are supported by the target. 160 void emitStrings(MCSection *StrSection, MCSection *OffsetSection = nullptr, 161 bool UseRelativeOffsets = false); 162 163 /// Returns the string pool. getStringPool()164 DwarfStringPool &getStringPool() { return StrPool; } 165 getStringOffsetsStartSym()166 MCSymbol *getStringOffsetsStartSym() const { return StringOffsetsStartSym; } setStringOffsetsStartSym(MCSymbol * Sym)167 void setStringOffsetsStartSym(MCSymbol *Sym) { StringOffsetsStartSym = Sym; } 168 getRnglistsTableBaseSym()169 MCSymbol *getRnglistsTableBaseSym() const { return RnglistsTableBaseSym; } setRnglistsTableBaseSym(MCSymbol * Sym)170 void setRnglistsTableBaseSym(MCSymbol *Sym) { RnglistsTableBaseSym = Sym; } 171 getLoclistsTableBaseSym()172 MCSymbol *getLoclistsTableBaseSym() const { return LoclistsTableBaseSym; } setLoclistsTableBaseSym(MCSymbol * Sym)173 void setLoclistsTableBaseSym(MCSymbol *Sym) { LoclistsTableBaseSym = Sym; } 174 175 /// \returns false if the variable was merged with a previous one. 176 bool addScopeVariable(LexicalScope *LS, DbgVariable *Var); 177 178 void addScopeLabel(LexicalScope *LS, DbgLabel *Label); 179 getScopeVariables()180 DenseMap<LexicalScope *, ScopeVars> &getScopeVariables() { 181 return ScopeVariables; 182 } 183 getScopeLabels()184 DenseMap<LexicalScope *, LabelList> &getScopeLabels() { 185 return ScopeLabels; 186 } 187 getAbstractSPDies()188 DenseMap<const MDNode *, DIE *> &getAbstractSPDies() { 189 return AbstractSPDies; 190 } 191 getAbstractEntities()192 DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() { 193 return AbstractEntities; 194 } 195 insertDIE(const MDNode * TypeMD,DIE * Die)196 void insertDIE(const MDNode *TypeMD, DIE *Die) { 197 DITypeNodeToDieMap.insert(std::make_pair(TypeMD, Die)); 198 } 199 getDIE(const MDNode * TypeMD)200 DIE *getDIE(const MDNode *TypeMD) { 201 return DITypeNodeToDieMap.lookup(TypeMD); 202 } 203 }; 204 205 } // end namespace llvm 206 207 #endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFFILE_H 208