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 unsigned NextFuncId = 0; 103 104 InlineSite &getInlineSite(const DILocation *InlinedAt, 105 const DISubprogram *Inlinee); 106 107 static void collectInlineSiteChildren(SmallVectorImpl<unsigned> &Children, 108 const FunctionInfo &FI, 109 const InlineSite &Site); 110 111 /// Remember some debug info about each function. Keep it in a stable order to 112 /// emit at the end of the TU. 113 MapVector<const Function *, FunctionInfo> FnDebugInfo; 114 115 /// Map from DIFile to .cv_file id. 116 DenseMap<const DIFile *, unsigned> FileIdMap; 117 118 SmallSetVector<const DISubprogram *, 4> InlinedSubprograms; 119 120 DenseMap<const DISubprogram *, codeview::TypeIndex> SubprogramToFuncId; 121 122 unsigned TypeCount = 0; 123 124 /// Gets the next type index and increments the count of types streamed so 125 /// far. 126 codeview::TypeIndex getNextTypeIndex() { 127 return codeview::TypeIndex(codeview::TypeIndex::FirstNonSimpleIndex + TypeCount++); 128 } 129 130 typedef std::map<const DIFile *, std::string> FileToFilepathMapTy; 131 FileToFilepathMapTy FileToFilepathMap; 132 StringRef getFullFilepath(const DIFile *S); 133 134 unsigned maybeRecordFile(const DIFile *F); 135 136 void maybeRecordLocation(DebugLoc DL, const MachineFunction *MF); 137 138 void clear() { 139 assert(CurFn == nullptr); 140 FileIdMap.clear(); 141 FnDebugInfo.clear(); 142 FileToFilepathMap.clear(); 143 } 144 145 void emitTypeInformation(); 146 147 void emitInlineeLinesSubsection(); 148 149 void emitDebugInfoForFunction(const Function *GV, FunctionInfo &FI); 150 151 void emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt, 152 const InlineSite &Site); 153 154 typedef DbgValueHistoryMap::InlinedVariable InlinedVariable; 155 156 void collectVariableInfo(const DISubprogram *SP); 157 158 void collectVariableInfoFromMMITable(DenseSet<InlinedVariable> &Processed); 159 160 /// Records information about a local variable in the appropriate scope. In 161 /// particular, locals from inlined code live inside the inlining site. 162 void recordLocalVariable(LocalVariable &&Var, const DILocation *Loc); 163 164 void emitLocalVariable(const LocalVariable &Var); 165 166 public: 167 CodeViewDebug(AsmPrinter *Asm); 168 169 void setSymbolSize(const llvm::MCSymbol *, uint64_t) override {} 170 171 /// \brief Emit the COFF section that holds the line table information. 172 void endModule() override; 173 174 /// \brief Gather pre-function debug information. 175 void beginFunction(const MachineFunction *MF) override; 176 177 /// \brief Gather post-function debug information. 178 void endFunction(const MachineFunction *) override; 179 180 /// \brief Process beginning of an instruction. 181 void beginInstruction(const MachineInstr *MI) override; 182 }; 183 } // End of namespace llvm 184 185 #endif 186