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