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