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