136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===-- llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h ----*- C++ -*--===// 236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// The LLVM Compiler Infrastructure 436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file is distributed under the University of Illinois Open Source 636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// License. See LICENSE.TXT for details. 736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===// 936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file contains support for writing line tables info into COFF files. 1136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===// 1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#ifndef CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H__ 1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H__ 1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "AsmPrinterHandler.h" 1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/DenseMap.h" 1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/StringMap.h" 2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/StringRef.h" 2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/AsmPrinter.h" 2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/LexicalScopes.h" 2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineFunction.h" 2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineModuleInfo.h" 2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DebugInfo.h" 2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DebugLoc.h" 2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCStreamer.h" 2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Target/TargetLoweringObjectFile.h" 2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace llvm { 3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Collects and handles line tables information in a CodeView format. 3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass WinCodeViewLineTables : public AsmPrinterHandler { 3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AsmPrinter *Asm; 3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DebugLoc PrevInstLoc; 3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // For each function, store a vector of labels to its instructions, as well as 3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // to the end of the function. 3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines struct FunctionInfo { 3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<MCSymbol *, 10> Instrs; 4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCSymbol *End; 41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FunctionInfo() : End(nullptr) {} 4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } *CurFn; 4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typedef DenseMap<const Function *, FunctionInfo> FnDebugInfoTy; 4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FnDebugInfoTy FnDebugInfo; 4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Store the functions we've visited in a vector so we can maintain a stable 4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // order while emitting subsections. 4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<const Function *, 10> VisitedFunctions; 4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // InstrInfoTy - Holds the Filename:LineNumber information for every 5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // instruction with a unique debug location. 5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines struct InstrInfoTy { 5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef Filename; 5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned LineNumber; 5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines InstrInfoTy() : LineNumber(0) {} 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines InstrInfoTy(StringRef Filename, unsigned LineNumber) 5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : Filename(Filename), LineNumber(LineNumber) {} 6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines }; 6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DenseMap<MCSymbol *, InstrInfoTy> InstrInfo; 6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // FileNameRegistry - Manages filenames observed while generating debug info 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // by filtering out duplicates and bookkeeping the offsets in the string 6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // table to be generated. 6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines struct FileNameRegistryTy { 6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<StringRef, 10> Filenames; 6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines struct PerFileInfo { 6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t FilenameID, StartOffset; 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines }; 7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringMap<PerFileInfo> Infos; 7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The offset in the string table where we'll write the next unique 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // filename. 7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t LastOffset; 7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FileNameRegistryTy() { 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines clear(); 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Add Filename to the registry, if it was not observed before. 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void add(StringRef Filename) { 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Infos.count(Filename)) 8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t OldSize = Infos.size(); 8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Infos[Filename].FilenameID = OldSize; 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Infos[Filename].StartOffset = LastOffset; 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LastOffset += Filename.size() + 1; 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Filenames.push_back(Filename); 9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void clear() { 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LastOffset = 1; 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Infos.clear(); 9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Filenames.clear(); 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } FileNameRegistry; 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typedef std::map<std::pair<StringRef, StringRef>, char *> 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DirAndFilenameToFilepathMapTy; 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DirAndFilenameToFilepathMapTy DirAndFilenameToFilepathMap; 10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef getFullFilepath(const MDNode *S); 10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void maybeRecordLocation(DebugLoc DL, const MachineFunction *MF); 10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void clear() { 107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(CurFn == nullptr); 10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FileNameRegistry.clear(); 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines InstrInfo.clear(); 11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitDebugInfoForFunction(const Function *GV); 11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic: 11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines WinCodeViewLineTables(AsmPrinter *Asm); 11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ~WinCodeViewLineTables() { 11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (DirAndFilenameToFilepathMapTy::iterator 11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I = DirAndFilenameToFilepathMap.begin(), 12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines E = DirAndFilenameToFilepathMap.end(); 12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I != E; ++I) 12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines free(I->second); 12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void setSymbolSize(const llvm::MCSymbol *, uint64_t) override {} 12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// \brief Emit the COFF section that holds the line table information. 12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void endModule() override; 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// \brief Gather pre-function debug information. 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void beginFunction(const MachineFunction *MF) override; 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// \brief Gather post-function debug information. 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void endFunction(const MachineFunction *) override; 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// \brief Process beginning of an instruction. 13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void beginInstruction(const MachineInstr *MI) override; 13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// \brief Process end of an instruction. 14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void endInstruction() override {} 14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} // End of namespace llvm 14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif 145