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/ADT/StringRef.h" 21 #include "llvm/CodeGen/AsmPrinter.h" 22 #include "llvm/CodeGen/MachineFunction.h" 23 #include "llvm/CodeGen/MachineModuleInfo.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 LexicalScope; 33 34 /// \brief Collects and handles line tables information in a CodeView format. 35 class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { 36 MCStreamer &OS; 37 38 /// Represents the most general definition range. 39 struct LocalVarDefRange { 40 /// Indicates that variable data is stored in memory relative to the 41 /// specified register. 42 int InMemory : 1; 43 44 /// Offset of variable data in memory. 45 int DataOffset : 31; 46 47 /// Offset of the data into the user level struct. If zero, no splitting 48 /// occurred. 49 uint16_t StructOffset; 50 51 /// Register containing the data or the register base of the memory 52 /// location containing the data. 53 uint16_t CVRegister; 54 55 /// Compares all location fields. This includes all fields except the label 56 /// ranges. 57 bool isDifferentLocation(LocalVarDefRange &O) { 58 return InMemory != O.InMemory || DataOffset != O.DataOffset || 59 StructOffset != O.StructOffset || CVRegister != O.CVRegister; 60 } 61 62 SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 1> Ranges; 63 }; 64 65 static LocalVarDefRange createDefRangeMem(uint16_t CVRegister, int Offset); 66 static LocalVarDefRange createDefRangeReg(uint16_t CVRegister); 67 68 /// Similar to DbgVariable in DwarfDebug, but not dwarf-specific. 69 struct LocalVariable { 70 const DILocalVariable *DIVar = nullptr; 71 SmallVector<LocalVarDefRange, 1> DefRanges; 72 }; 73 74 struct InlineSite { 75 SmallVector<LocalVariable, 1> InlinedLocals; 76 SmallVector<const DILocation *, 1> ChildSites; 77 const DISubprogram *Inlinee = nullptr; 78 unsigned SiteFuncId = 0; 79 }; 80 81 // For each function, store a vector of labels to its instructions, as well as 82 // to the end of the function. 83 struct FunctionInfo { 84 /// Map from inlined call site to inlined instructions and child inlined 85 /// call sites. Listed in program order. 86 std::unordered_map<const DILocation *, InlineSite> InlineSites; 87 88 /// Ordered list of top-level inlined call sites. 89 SmallVector<const DILocation *, 1> ChildSites; 90 91 SmallVector<LocalVariable, 1> Locals; 92 93 DebugLoc LastLoc; 94 const MCSymbol *Begin = nullptr; 95 const MCSymbol *End = nullptr; 96 unsigned FuncId = 0; 97 unsigned LastFileId = 0; 98 bool HaveLineInfo = false; 99 }; 100 FunctionInfo *CurFn; 101 102 /// The next available function index for use with our .cv_* directives. Not 103 /// to be confused with type indices for LF_FUNC_ID records. 104 unsigned NextFuncId = 0; 105 106 /// The next available type index. 107 unsigned NextTypeIndex = llvm::codeview::TypeIndex::FirstNonSimpleIndex; 108 109 /// Get the next type index and reserve it. Can be used to reserve more than 110 /// one type index. 111 unsigned getNextTypeIndex(unsigned NumRecords = 1) { 112 unsigned Result = NextTypeIndex; 113 NextTypeIndex += NumRecords; 114 return Result; 115 } 116 117 InlineSite &getInlineSite(const DILocation *InlinedAt, 118 const DISubprogram *Inlinee); 119 120 static void collectInlineSiteChildren(SmallVectorImpl<unsigned> &Children, 121 const FunctionInfo &FI, 122 const InlineSite &Site); 123 124 /// Remember some debug info about each function. Keep it in a stable order to 125 /// emit at the end of the TU. 126 MapVector<const Function *, FunctionInfo> FnDebugInfo; 127 128 /// Map from DIFile to .cv_file id. 129 DenseMap<const DIFile *, unsigned> FileIdMap; 130 131 /// Map from subprogram to index in InlinedSubprograms. 132 DenseMap<const DISubprogram *, size_t> SubprogramIndices; 133 134 /// All inlined subprograms in the order they should be emitted. 135 SmallVector<const DISubprogram *, 4> InlinedSubprograms; 136 137 /// The first type index that refers to an LF_FUNC_ID record. We have one 138 /// record per inlined subprogram. 139 /// FIXME: Keep in sync with emitTypeInformation until we buffer type records 140 /// on the side as we go. Once we buffer type records, we can allocate type 141 /// indices on demand without interleaving our assembly output. 142 unsigned FuncIdTypeIndexStart = NextTypeIndex + 2; 143 144 typedef std::map<const DIFile *, std::string> FileToFilepathMapTy; 145 FileToFilepathMapTy FileToFilepathMap; 146 StringRef getFullFilepath(const DIFile *S); 147 148 unsigned maybeRecordFile(const DIFile *F); 149 150 void maybeRecordLocation(DebugLoc DL, const MachineFunction *MF); 151 152 void clear() { 153 assert(CurFn == nullptr); 154 FileIdMap.clear(); 155 FnDebugInfo.clear(); 156 FileToFilepathMap.clear(); 157 } 158 159 void emitTypeInformation(); 160 161 void emitInlineeFuncIdsAndLines(); 162 163 void emitDebugInfoForFunction(const Function *GV, FunctionInfo &FI); 164 165 void emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt, 166 const InlineSite &Site); 167 168 typedef DbgValueHistoryMap::InlinedVariable InlinedVariable; 169 170 void collectVariableInfo(const DISubprogram *SP); 171 172 void collectVariableInfoFromMMITable(DenseSet<InlinedVariable> &Processed); 173 174 /// Records information about a local variable in the appropriate scope. In 175 /// particular, locals from inlined code live inside the inlining site. 176 void recordLocalVariable(LocalVariable &&Var, const DILocation *Loc); 177 178 void emitLocalVariable(const LocalVariable &Var); 179 180 public: 181 CodeViewDebug(AsmPrinter *Asm); 182 183 void setSymbolSize(const llvm::MCSymbol *, uint64_t) override {} 184 185 /// \brief Emit the COFF section that holds the line table information. 186 void endModule() override; 187 188 /// \brief Gather pre-function debug information. 189 void beginFunction(const MachineFunction *MF) override; 190 191 /// \brief Gather post-function debug information. 192 void endFunction(const MachineFunction *) override; 193 194 /// \brief Process beginning of an instruction. 195 void beginInstruction(const MachineInstr *MI) override; 196 }; 197 } // End of namespace llvm 198 199 #endif 200