LCOV - code coverage report
Current view: top level - include/llvm/MC - MCCodeView.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 16 16 100.0 %
Date: 2018-05-20 00:06:23 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- MCCodeView.h - Machine Code CodeView support -------------*- 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             : // Holds state from .cv_file and .cv_loc directives for later emission.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #ifndef LLVM_MC_MCCODEVIEW_H
      15             : #define LLVM_MC_MCCODEVIEW_H
      16             : 
      17             : #include "llvm/ADT/StringMap.h"
      18             : #include "llvm/ADT/StringRef.h"
      19             : #include "llvm/MC/MCFragment.h"
      20             : #include "llvm/MC/MCObjectStreamer.h"
      21             : #include <map>
      22             : #include <vector>
      23             : 
      24             : namespace llvm {
      25             : class MCContext;
      26             : class MCObjectStreamer;
      27             : class MCStreamer;
      28             : class CodeViewContext;
      29             : 
      30             : /// Instances of this class represent the information from a
      31             : /// .cv_loc directive.
      32             : class MCCVLoc {
      33             :   uint32_t FunctionId;
      34             :   uint32_t FileNum;
      35             :   uint32_t Line;
      36             :   uint16_t Column;
      37             :   uint16_t PrologueEnd : 1;
      38             :   uint16_t IsStmt : 1;
      39             : 
      40             : private: // CodeViewContext manages these
      41             :   friend class CodeViewContext;
      42             :   MCCVLoc(unsigned functionid, unsigned fileNum, unsigned line, unsigned column,
      43             :           bool prologueend, bool isstmt)
      44        6988 :       : FunctionId(functionid), FileNum(fileNum), Line(line), Column(column),
      45        6995 :         PrologueEnd(prologueend), IsStmt(isstmt) {}
      46             : 
      47             :   // Allow the default copy constructor and assignment operator to be used
      48             :   // for an MCCVLoc object.
      49             : 
      50             : public:
      51             :   unsigned getFunctionId() const { return FunctionId; }
      52             : 
      53             :   /// Get the FileNum of this MCCVLoc.
      54             :   unsigned getFileNum() const { return FileNum; }
      55             : 
      56             :   /// Get the Line of this MCCVLoc.
      57             :   unsigned getLine() const { return Line; }
      58             : 
      59             :   /// Get the Column of this MCCVLoc.
      60          17 :   unsigned getColumn() const { return Column; }
      61             : 
      62             :   bool isPrologueEnd() const { return PrologueEnd; }
      63         854 :   bool isStmt() const { return IsStmt; }
      64             : 
      65         888 :   void setFunctionId(unsigned FID) { FunctionId = FID; }
      66             : 
      67             :   /// Set the FileNum of this MCCVLoc.
      68         888 :   void setFileNum(unsigned fileNum) { FileNum = fileNum; }
      69             : 
      70             :   /// Set the Line of this MCCVLoc.
      71         888 :   void setLine(unsigned line) { Line = line; }
      72             : 
      73             :   /// Set the Column of this MCCVLoc.
      74             :   void setColumn(unsigned column) {
      75             :     assert(column <= UINT16_MAX);
      76         888 :     Column = column;
      77             :   }
      78             : 
      79         888 :   void setPrologueEnd(bool PE) { PrologueEnd = PE; }
      80         888 :   void setIsStmt(bool IS) { IsStmt = IS; }
      81             : };
      82             : 
      83             : /// Instances of this class represent the line information for
      84             : /// the CodeView line table entries.  Which is created after a machine
      85             : /// instruction is assembled and uses an address from a temporary label
      86             : /// created at the current address in the current section and the info from
      87             : /// the last .cv_loc directive seen as stored in the context.
      88             : class MCCVLineEntry : public MCCVLoc {
      89             :   const MCSymbol *Label;
      90             : 
      91             : private:
      92             :   // Allow the default copy constructor and assignment operator to be used
      93             :   // for an MCCVLineEntry object.
      94             : 
      95             : public:
      96             :   // Constructor to create an MCCVLineEntry given a symbol and the dwarf loc.
      97             :   MCCVLineEntry(const MCSymbol *Label, const MCCVLoc loc)
      98         479 :       : MCCVLoc(loc), Label(Label) {}
      99             : 
     100             :   const MCSymbol *getLabel() const { return Label; }
     101             : 
     102             :   // This is called when an instruction is assembled into the specified
     103             :   // section and if there is information from the last .cv_loc directive that
     104             :   // has yet to have a line entry made for it is made.
     105             :   static void Make(MCObjectStreamer *MCOS);
     106             : };
     107             : 
     108             : /// Information describing a function or inlined call site introduced by
     109             : /// .cv_func_id or .cv_inline_site_id. Accumulates information from .cv_loc
     110             : /// directives used with this function's id or the id of an inlined call site
     111             : /// within this function or inlined call site.
     112         948 : struct MCCVFunctionInfo {
     113             :   /// If this represents an inlined call site, then ParentFuncIdPlusOne will be
     114             :   /// the parent function id plus one. If this represents a normal function,
     115             :   /// then there is no parent, and ParentFuncIdPlusOne will be FunctionSentinel.
     116             :   /// If this struct is an unallocated slot in the function info vector, then
     117             :   /// ParentFuncIdPlusOne will be zero.
     118             :   unsigned ParentFuncIdPlusOne = 0;
     119             : 
     120             :   enum : unsigned { FunctionSentinel = ~0U };
     121             : 
     122             :   struct LineInfo {
     123             :     unsigned File;
     124             :     unsigned Line;
     125             :     unsigned Col;
     126             :   };
     127             : 
     128             :   LineInfo InlinedAt;
     129             : 
     130             :   /// The section of the first .cv_loc directive used for this function, or null
     131             :   /// if none has been seen yet.
     132             :   MCSection *Section = nullptr;
     133             : 
     134             :   /// Map from inlined call site id to the inlined at location to use for that
     135             :   /// call site. Call chains are collapsed, so for the call chain 'f -> g -> h',
     136             :   /// the InlinedAtMap of 'f' will contain entries for 'g' and 'h' that both
     137             :   /// list the line info for the 'g' call site.
     138             :   DenseMap<unsigned, LineInfo> InlinedAtMap;
     139             : 
     140             :   /// Returns true if this is function info has not yet been used in a
     141             :   /// .cv_func_id or .cv_inline_site_id directive.
     142             :   bool isUnallocatedFunctionInfo() const { return ParentFuncIdPlusOne == 0; }
     143             : 
     144             :   /// Returns true if this represents an inlined call site, meaning
     145             :   /// ParentFuncIdPlusOne is neither zero nor ~0U.
     146             :   bool isInlinedCallSite() const {
     147          70 :     return !isUnallocatedFunctionInfo() &&
     148             :            ParentFuncIdPlusOne != FunctionSentinel;
     149             :   }
     150             : 
     151             :   unsigned getParentFuncId() const {
     152             :     assert(isInlinedCallSite());
     153          39 :     return ParentFuncIdPlusOne - 1;
     154             :   }
     155             : };
     156             : 
     157             : /// Holds state from .cv_file and .cv_loc directives for later emission.
     158             : class CodeViewContext {
     159             : public:
     160             :   CodeViewContext();
     161             :   ~CodeViewContext();
     162             : 
     163             :   bool isValidFileNumber(unsigned FileNumber) const;
     164             :   bool addFile(MCStreamer &OS, unsigned FileNumber, StringRef Filename,
     165             :                ArrayRef<uint8_t> ChecksumBytes, uint8_t ChecksumKind);
     166             : 
     167             :   /// Records the function id of a normal function. Returns false if the
     168             :   /// function id has already been used, and true otherwise.
     169             :   bool recordFunctionId(unsigned FuncId);
     170             : 
     171             :   /// Records the function id of an inlined call site. Records the "inlined at"
     172             :   /// location info of the call site, including what function or inlined call
     173             :   /// site it was inlined into. Returns false if the function id has already
     174             :   /// been used, and true otherwise.
     175             :   bool recordInlinedCallSiteId(unsigned FuncId, unsigned IAFunc,
     176             :                                unsigned IAFile, unsigned IALine,
     177             :                                unsigned IACol);
     178             : 
     179             :   /// Retreive the function info if this is a valid function id, or nullptr.
     180             :   MCCVFunctionInfo *getCVFunctionInfo(unsigned FuncId);
     181             : 
     182             :   /// Saves the information from the currently parsed .cv_loc directive
     183             :   /// and sets CVLocSeen.  When the next instruction is assembled an entry
     184             :   /// in the line number table with this information and the address of the
     185             :   /// instruction will be created.
     186             :   void setCurrentCVLoc(unsigned FunctionId, unsigned FileNo, unsigned Line,
     187             :                        unsigned Column, bool PrologueEnd, bool IsStmt) {
     188             :     CurrentCVLoc.setFunctionId(FunctionId);
     189             :     CurrentCVLoc.setFileNum(FileNo);
     190             :     CurrentCVLoc.setLine(Line);
     191             :     CurrentCVLoc.setColumn(Column);
     192             :     CurrentCVLoc.setPrologueEnd(PrologueEnd);
     193             :     CurrentCVLoc.setIsStmt(IsStmt);
     194         888 :     CVLocSeen = true;
     195             :   }
     196             : 
     197             :   bool getCVLocSeen() { return CVLocSeen; }
     198      208457 :   void clearCVLocSeen() { CVLocSeen = false; }
     199             : 
     200             :   const MCCVLoc &getCurrentCVLoc() { return CurrentCVLoc; }
     201             : 
     202             :   bool isValidCVFileNumber(unsigned FileNumber);
     203             : 
     204             :   /// Add a line entry.
     205             :   void addLineEntry(const MCCVLineEntry &LineEntry);
     206             : 
     207             :   std::vector<MCCVLineEntry> getFunctionLineEntries(unsigned FuncId);
     208             : 
     209             :   std::pair<size_t, size_t> getLineExtent(unsigned FuncId);
     210             : 
     211             :   ArrayRef<MCCVLineEntry> getLinesForExtent(size_t L, size_t R);
     212             : 
     213             :   /// Emits a line table substream.
     214             :   void emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId,
     215             :                                 const MCSymbol *FuncBegin,
     216             :                                 const MCSymbol *FuncEnd);
     217             : 
     218             :   void emitInlineLineTableForFunction(MCObjectStreamer &OS,
     219             :                                       unsigned PrimaryFunctionId,
     220             :                                       unsigned SourceFileId,
     221             :                                       unsigned SourceLineNum,
     222             :                                       const MCSymbol *FnStartSym,
     223             :                                       const MCSymbol *FnEndSym);
     224             : 
     225             :   /// Encodes the binary annotations once we have a layout.
     226             :   void encodeInlineLineTable(MCAsmLayout &Layout,
     227             :                              MCCVInlineLineTableFragment &F);
     228             : 
     229             :   void
     230             :   emitDefRange(MCObjectStreamer &OS,
     231             :                ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
     232             :                StringRef FixedSizePortion);
     233             : 
     234             :   void encodeDefRange(MCAsmLayout &Layout, MCCVDefRangeFragment &F);
     235             : 
     236             :   /// Emits the string table substream.
     237             :   void emitStringTable(MCObjectStreamer &OS);
     238             : 
     239             :   /// Emits the file checksum substream.
     240             :   void emitFileChecksums(MCObjectStreamer &OS);
     241             : 
     242             :   /// Emits the offset into the checksum table of the given file number.
     243             :   void emitFileChecksumOffset(MCObjectStreamer &OS, unsigned FileNo);
     244             : 
     245             :   /// Add something to the string table.  Returns the final string as well as
     246             :   /// offset into the string table.
     247             :   std::pair<StringRef, unsigned> addToStringTable(StringRef S);
     248             : 
     249             : private:
     250             :   /// The current CodeView line information from the last .cv_loc directive.
     251             :   MCCVLoc CurrentCVLoc = MCCVLoc(0, 0, 0, 0, false, true);
     252             :   bool CVLocSeen = false;
     253             : 
     254             :   /// Map from string to string table offset.
     255             :   StringMap<unsigned> StringTable;
     256             : 
     257             :   /// The fragment that ultimately holds our strings.
     258             :   MCDataFragment *StrTabFragment = nullptr;
     259             :   bool InsertedStrTabFragment = false;
     260             : 
     261             :   MCDataFragment *getStringTableFragment();
     262             : 
     263             :   /// Get a string table offset.
     264             :   unsigned getStringTableOffset(StringRef S);
     265             : 
     266             :   struct FileInfo {
     267             :     unsigned StringTableOffset;
     268             : 
     269             :     // Indicates if this FileInfo corresponds to an actual file, or hasn't been
     270             :     // set yet.
     271             :     bool Assigned = false;
     272             : 
     273             :     uint8_t ChecksumKind;
     274             : 
     275             :     ArrayRef<uint8_t> Checksum;
     276             : 
     277             :     // Checksum offset stored as a symbol because it might be requested
     278             :     // before it has been calculated, so a fixup may be needed.
     279             :     MCSymbol *ChecksumTableOffset;
     280             :   };
     281             : 
     282             :   /// Array storing added file information.
     283             :   SmallVector<FileInfo, 4> Files;
     284             : 
     285             :   /// The offset of the first and last .cv_loc directive for a given function
     286             :   /// id.
     287             :   std::map<unsigned, std::pair<size_t, size_t>> MCCVLineStartStop;
     288             : 
     289             :   /// A collection of MCCVLineEntry for each section.
     290             :   std::vector<MCCVLineEntry> MCCVLines;
     291             : 
     292             :   /// All known functions and inlined call sites, indexed by function id.
     293             :   std::vector<MCCVFunctionInfo> Functions;
     294             : 
     295             :   /// Indicate whether we have already laid out the checksum table addresses or
     296             :   /// not.
     297             :   bool ChecksumOffsetsAssigned = false;
     298             : };
     299             : 
     300             : } // end namespace llvm
     301             : #endif

Generated by: LCOV version 1.13