1 //===-- llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.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 line tables info into COFF files. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H 15 #define LLVM_LIB_CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H 16 17 #include "AsmPrinterHandler.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/LexicalScopes.h" 23 #include "llvm/CodeGen/MachineFunction.h" 24 #include "llvm/CodeGen/MachineModuleInfo.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 /// \brief Collects and handles line tables information in a CodeView format. 32 class WinCodeViewLineTables : public AsmPrinterHandler { 33 AsmPrinter *Asm; 34 DebugLoc PrevInstLoc; 35 36 // For each function, store a vector of labels to its instructions, as well as 37 // to the end of the function. 38 struct FunctionInfo { 39 SmallVector<MCSymbol *, 10> Instrs; 40 MCSymbol *End; FunctionInfoFunctionInfo41 FunctionInfo() : End(nullptr) {} 42 } *CurFn; 43 44 typedef DenseMap<const Function *, FunctionInfo> FnDebugInfoTy; 45 FnDebugInfoTy FnDebugInfo; 46 // Store the functions we've visited in a vector so we can maintain a stable 47 // order while emitting subsections. 48 SmallVector<const Function *, 10> VisitedFunctions; 49 50 // InstrInfoTy - Holds the Filename:LineNumber information for every 51 // instruction with a unique debug location. 52 struct InstrInfoTy { 53 StringRef Filename; 54 unsigned LineNumber; 55 InstrInfoTyInstrInfoTy56 InstrInfoTy() : LineNumber(0) {} 57 InstrInfoTyInstrInfoTy58 InstrInfoTy(StringRef Filename, unsigned LineNumber) 59 : Filename(Filename), LineNumber(LineNumber) {} 60 }; 61 DenseMap<MCSymbol *, InstrInfoTy> InstrInfo; 62 63 // FileNameRegistry - Manages filenames observed while generating debug info 64 // by filtering out duplicates and bookkeeping the offsets in the string 65 // table to be generated. 66 struct FileNameRegistryTy { 67 SmallVector<StringRef, 10> Filenames; 68 struct PerFileInfo { 69 size_t FilenameID, StartOffset; 70 }; 71 StringMap<PerFileInfo> Infos; 72 73 // The offset in the string table where we'll write the next unique 74 // filename. 75 size_t LastOffset; 76 FileNameRegistryTyFileNameRegistryTy77 FileNameRegistryTy() { 78 clear(); 79 } 80 81 // Add Filename to the registry, if it was not observed before. addFileNameRegistryTy82 void add(StringRef Filename) { 83 if (Infos.count(Filename)) 84 return; 85 size_t OldSize = Infos.size(); 86 Infos[Filename].FilenameID = OldSize; 87 Infos[Filename].StartOffset = LastOffset; 88 LastOffset += Filename.size() + 1; 89 Filenames.push_back(Filename); 90 } 91 clearFileNameRegistryTy92 void clear() { 93 LastOffset = 1; 94 Infos.clear(); 95 Filenames.clear(); 96 } 97 } FileNameRegistry; 98 99 typedef std::map<std::pair<StringRef, StringRef>, char *> 100 DirAndFilenameToFilepathMapTy; 101 DirAndFilenameToFilepathMapTy DirAndFilenameToFilepathMap; 102 StringRef getFullFilepath(const MDNode *S); 103 104 void maybeRecordLocation(DebugLoc DL, const MachineFunction *MF); 105 clear()106 void clear() { 107 assert(CurFn == nullptr); 108 FileNameRegistry.clear(); 109 InstrInfo.clear(); 110 } 111 112 void emitDebugInfoForFunction(const Function *GV); 113 114 public: 115 WinCodeViewLineTables(AsmPrinter *Asm); 116 ~WinCodeViewLineTables()117 ~WinCodeViewLineTables() override { 118 for (DirAndFilenameToFilepathMapTy::iterator 119 I = DirAndFilenameToFilepathMap.begin(), 120 E = DirAndFilenameToFilepathMap.end(); 121 I != E; ++I) 122 free(I->second); 123 } 124 setSymbolSize(const llvm::MCSymbol *,uint64_t)125 void setSymbolSize(const llvm::MCSymbol *, uint64_t) override {} 126 127 /// \brief Emit the COFF section that holds the line table information. 128 void endModule() override; 129 130 /// \brief Gather pre-function debug information. 131 void beginFunction(const MachineFunction *MF) override; 132 133 /// \brief Gather post-function debug information. 134 void endFunction(const MachineFunction *) override; 135 136 /// \brief Process beginning of an instruction. 137 void beginInstruction(const MachineInstr *MI) override; 138 139 /// \brief Process end of an instruction. endInstruction()140 void endInstruction() override {} 141 }; 142 } // End of namespace llvm 143 144 #endif 145