1 //===-- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h ----*- 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 // This file contains support for writing Microsoft CodeView debug info. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H 15 #define LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H 16 17 #include "DebugHandlerBase.h" 18 #include "llvm/ADT/DenseMap.h" 19 #include "llvm/ADT/StringMap.h" 20 #include "llvm/CodeGen/AsmPrinter.h" 21 #include "llvm/CodeGen/MachineFunction.h" 22 #include "llvm/CodeGen/MachineModuleInfo.h" 23 #include "llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h" 24 #include "llvm/DebugInfo/CodeView/TypeIndex.h" 25 #include "llvm/IR/DebugInfo.h" 26 #include "llvm/IR/DebugLoc.h" 27 #include "llvm/MC/MCStreamer.h" 28 #include "llvm/Target/TargetLoweringObjectFile.h" 29 30 namespace llvm { 31 32 class StringRef; 33 class LexicalScope; 34 35 /// \brief Collects and handles line tables information in a CodeView format. 36 class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { 37 MCStreamer &OS; 38 codeview::MemoryTypeTableBuilder TypeTable; 39 40 /// Represents the most general definition range. 41 struct LocalVarDefRange { 42 /// Indicates that variable data is stored in memory relative to the 43 /// specified register. 44 int InMemory : 1; 45 46 /// Offset of variable data in memory. 47 int DataOffset : 31; 48 49 /// Offset of the data into the user level struct. If zero, no splitting 50 /// occurred. 51 uint16_t StructOffset; 52 53 /// Register containing the data or the register base of the memory 54 /// location containing the data. 55 uint16_t CVRegister; 56 57 /// Compares all location fields. This includes all fields except the label 58 /// ranges. 59 bool isDifferentLocation(LocalVarDefRange &O) { 60 return InMemory != O.InMemory || DataOffset != O.DataOffset || 61 StructOffset != O.StructOffset || CVRegister != O.CVRegister; 62 } 63 64 SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 1> Ranges; 65 }; 66 67 static LocalVarDefRange createDefRangeMem(uint16_t CVRegister, int Offset); 68 static LocalVarDefRange createDefRangeReg(uint16_t CVRegister); 69 70 /// Similar to DbgVariable in DwarfDebug, but not dwarf-specific. 71 struct LocalVariable { 72 const DILocalVariable *DIVar = nullptr; 73 SmallVector<LocalVarDefRange, 1> DefRanges; 74 }; 75 76 struct InlineSite { 77 SmallVector<LocalVariable, 1> InlinedLocals; 78 SmallVector<const DILocation *, 1> ChildSites; 79 const DISubprogram *Inlinee = nullptr; 80 unsigned SiteFuncId = 0; 81 }; 82 83 // For each function, store a vector of labels to its instructions, as well as 84 // to the end of the function. 85 struct FunctionInfo { 86 /// Map from inlined call site to inlined instructions and child inlined 87 /// call sites. Listed in program order. 88 std::unordered_map<const DILocation *, InlineSite> InlineSites; 89 90 /// Ordered list of top-level inlined call sites. 91 SmallVector<const DILocation *, 1> ChildSites; 92 93 SmallVector<LocalVariable, 1> Locals; 94 95 DebugLoc LastLoc; 96 const MCSymbol *Begin = nullptr; 97 const MCSymbol *End = nullptr; 98 unsigned FuncId = 0; 99 unsigned LastFileId = 0; 100 bool HaveLineInfo = false; 101 }; 102 FunctionInfo *CurFn; 103 104 /// The set of comdat .debug$S sections that we've seen so far. Each section 105 /// must start with a magic version number that must only be emitted once. 106 /// This set tracks which sections we've already opened. 107 DenseSet<MCSectionCOFF *> ComdatDebugSections; 108 109 /// Switch to the appropriate .debug$S section for GVSym. If GVSym, the symbol 110 /// of an emitted global value, is in a comdat COFF section, this will switch 111 /// to a new .debug$S section in that comdat. This method ensures that the 112 /// section starts with the magic version number on first use. If GVSym is 113 /// null, uses the main .debug$S section. 114 void switchToDebugSectionForSymbol(const MCSymbol *GVSym); 115 116 /// The next available function index for use with our .cv_* directives. Not 117 /// to be confused with type indices for LF_FUNC_ID records. 118 unsigned NextFuncId = 0; 119 120 codeview::TypeIndex VoidFnTyIdx; 121 122 /// Get a type index for a generic void function type. 123 codeview::TypeIndex getGenericFunctionTypeIndex(); 124 125 InlineSite &getInlineSite(const DILocation *InlinedAt, 126 const DISubprogram *Inlinee); 127 128 void recordFuncIdForSubprogram(const DISubprogram *SP); 129 130 static void collectInlineSiteChildren(SmallVectorImpl<unsigned> &Children, 131 const FunctionInfo &FI, 132 const InlineSite &Site); 133 134 /// Remember some debug info about each function. Keep it in a stable order to 135 /// emit at the end of the TU. 136 MapVector<const Function *, FunctionInfo> FnDebugInfo; 137 138 /// Map from DIFile to .cv_file id. 139 DenseMap<const DIFile *, unsigned> FileIdMap; 140 141 /// All inlined subprograms in the order they should be emitted. 142 SmallSetVector<const DISubprogram *, 4> InlinedSubprograms; 143 144 /// Map from DI metadata nodes to CodeView type indices. Primarily indexed by 145 /// DIType* and DISubprogram*. 146 DenseMap<const DINode *, codeview::TypeIndex> TypeIndices; 147 148 typedef std::map<const DIFile *, std::string> FileToFilepathMapTy; 149 FileToFilepathMapTy FileToFilepathMap; 150 StringRef getFullFilepath(const DIFile *S); 151 152 unsigned maybeRecordFile(const DIFile *F); 153 154 void maybeRecordLocation(DebugLoc DL, const MachineFunction *MF); 155 156 void clear() { 157 assert(CurFn == nullptr); 158 FileIdMap.clear(); 159 FnDebugInfo.clear(); 160 FileToFilepathMap.clear(); 161 } 162 163 /// Emit the magic version number at the start of a CodeView type or symbol 164 /// section. Appears at the front of every .debug$S or .debug$T section. 165 void emitCodeViewMagicVersion(); 166 167 void emitTypeInformation(); 168 169 void emitInlineeLinesSubsection(); 170 171 void emitDebugInfoForFunction(const Function *GV, FunctionInfo &FI); 172 173 void emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt, 174 const InlineSite &Site); 175 176 typedef DbgValueHistoryMap::InlinedVariable InlinedVariable; 177 178 void collectVariableInfo(const DISubprogram *SP); 179 180 void collectVariableInfoFromMMITable(DenseSet<InlinedVariable> &Processed); 181 182 /// Records information about a local variable in the appropriate scope. In 183 /// particular, locals from inlined code live inside the inlining site. 184 void recordLocalVariable(LocalVariable &&Var, const DILocation *Loc); 185 186 void emitLocalVariable(const LocalVariable &Var); 187 188 /// Translates the DIType to codeview if necessary and returns a type index 189 /// for it. 190 codeview::TypeIndex getTypeIndex(DITypeRef Ty); 191 192 codeview::TypeIndex lowerType(const DIType *Ty); 193 codeview::TypeIndex lowerTypeBasic(const DIBasicType *Ty); 194 codeview::TypeIndex lowerTypePointer(const DIDerivedType *Ty); 195 codeview::TypeIndex lowerTypeMemberPointer(const DIDerivedType *Ty); 196 codeview::TypeIndex lowerTypeModifier(const DIDerivedType *Ty); 197 198 public: 199 CodeViewDebug(AsmPrinter *Asm); 200 201 void setSymbolSize(const llvm::MCSymbol *, uint64_t) override {} 202 203 /// \brief Emit the COFF section that holds the line table information. 204 void endModule() override; 205 206 /// \brief Gather pre-function debug information. 207 void beginFunction(const MachineFunction *MF) override; 208 209 /// \brief Gather post-function debug information. 210 void endFunction(const MachineFunction *) override; 211 212 /// \brief Process beginning of an instruction. 213 void beginInstruction(const MachineInstr *MI) override; 214 }; 215 } // End of namespace llvm 216 217 #endif 218