Home | History | Annotate | Download | only in MC
      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/StringRef.h"
     18 #include "llvm/ADT/StringMap.h"
     19 #include "llvm/MC/MCObjectStreamer.h"
     20 #include "llvm/MC/MCFragment.h"
     21 #include <map>
     22 #include <vector>
     23 
     24 namespace llvm {
     25 class MCContext;
     26 class MCObjectStreamer;
     27 class MCStreamer;
     28 
     29 /// \brief Instances of this class represent the information from a
     30 /// .cv_loc directive.
     31 class MCCVLoc {
     32   uint32_t FunctionId;
     33   uint32_t FileNum;
     34   uint32_t Line;
     35   uint16_t Column;
     36   uint16_t PrologueEnd : 1;
     37   uint16_t IsStmt : 1;
     38 
     39 private: // MCContext manages these
     40   friend class MCContext;
     41   MCCVLoc(unsigned functionid, unsigned fileNum, unsigned line, unsigned column,
     42           bool prologueend, bool isstmt)
     43       : FunctionId(functionid), FileNum(fileNum), Line(line), Column(column),
     44         PrologueEnd(prologueend), IsStmt(isstmt) {}
     45 
     46   // Allow the default copy constructor and assignment operator to be used
     47   // for an MCCVLoc object.
     48 
     49 public:
     50   unsigned getFunctionId() const { return FunctionId; }
     51 
     52   /// \brief Get the FileNum of this MCCVLoc.
     53   unsigned getFileNum() const { return FileNum; }
     54 
     55   /// \brief Get the Line of this MCCVLoc.
     56   unsigned getLine() const { return Line; }
     57 
     58   /// \brief Get the Column of this MCCVLoc.
     59   unsigned getColumn() const { return Column; }
     60 
     61   bool isPrologueEnd() const { return PrologueEnd; }
     62   bool isStmt() const { return IsStmt; }
     63 
     64   void setFunctionId(unsigned FID) { FunctionId = FID; }
     65 
     66   /// \brief Set the FileNum of this MCCVLoc.
     67   void setFileNum(unsigned fileNum) { FileNum = fileNum; }
     68 
     69   /// \brief Set the Line of this MCCVLoc.
     70   void setLine(unsigned line) { Line = line; }
     71 
     72   /// \brief Set the Column of this MCCVLoc.
     73   void setColumn(unsigned column) {
     74     assert(column <= UINT16_MAX);
     75     Column = column;
     76   }
     77 
     78   void setPrologueEnd(bool PE) { PrologueEnd = PE; }
     79   void setIsStmt(bool IS) { IsStmt = IS; }
     80 };
     81 
     82 /// \brief Instances of this class represent the line information for
     83 /// the CodeView line table entries.  Which is created after a machine
     84 /// instruction is assembled and uses an address from a temporary label
     85 /// created at the current address in the current section and the info from
     86 /// the last .cv_loc directive seen as stored in the context.
     87 class MCCVLineEntry : public MCCVLoc {
     88   const MCSymbol *Label;
     89 
     90 private:
     91   // Allow the default copy constructor and assignment operator to be used
     92   // for an MCCVLineEntry object.
     93 
     94 public:
     95   // Constructor to create an MCCVLineEntry given a symbol and the dwarf loc.
     96   MCCVLineEntry(const MCSymbol *Label, const MCCVLoc loc)
     97       : MCCVLoc(loc), Label(Label) {}
     98 
     99   const MCSymbol *getLabel() const { return Label; }
    100 
    101   // This is called when an instruction is assembled into the specified
    102   // section and if there is information from the last .cv_loc directive that
    103   // has yet to have a line entry made for it is made.
    104   static void Make(MCObjectStreamer *MCOS);
    105 };
    106 
    107 /// Holds state from .cv_file and .cv_loc directives for later emission.
    108 class CodeViewContext {
    109 public:
    110   CodeViewContext();
    111   ~CodeViewContext();
    112 
    113   bool isValidFileNumber(unsigned FileNumber) const;
    114   bool addFile(unsigned FileNumber, StringRef Filename);
    115   ArrayRef<StringRef> getFilenames() { return Filenames; }
    116 
    117   /// \brief Add a line entry.
    118   void addLineEntry(const MCCVLineEntry &LineEntry) {
    119     size_t Offset = MCCVLines.size();
    120     auto I = MCCVLineStartStop.insert(
    121         {LineEntry.getFunctionId(), {Offset, Offset + 1}});
    122     if (!I.second)
    123       I.first->second.second = Offset + 1;
    124     MCCVLines.push_back(LineEntry);
    125   }
    126 
    127   std::vector<MCCVLineEntry> getFunctionLineEntries(unsigned FuncId) {
    128     std::vector<MCCVLineEntry> FilteredLines;
    129 
    130     auto I = MCCVLineStartStop.find(FuncId);
    131     if (I != MCCVLineStartStop.end())
    132       for (size_t Idx = I->second.first, End = I->second.second; Idx != End;
    133            ++Idx)
    134         if (MCCVLines[Idx].getFunctionId() == FuncId)
    135           FilteredLines.push_back(MCCVLines[Idx]);
    136     return FilteredLines;
    137   }
    138 
    139   std::pair<size_t, size_t> getLineExtent(unsigned FuncId) {
    140     auto I = MCCVLineStartStop.find(FuncId);
    141     // Return an empty extent if there are no cv_locs for this function id.
    142     if (I == MCCVLineStartStop.end())
    143       return {~0ULL, 0};
    144     return I->second;
    145   }
    146 
    147   ArrayRef<MCCVLineEntry> getLinesForExtent(size_t L, size_t R) {
    148     if (R <= L)
    149       return None;
    150     if (L >= MCCVLines.size())
    151       return None;
    152     return makeArrayRef(&MCCVLines[L], R - L);
    153   }
    154 
    155   /// Emits a line table substream.
    156   void emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId,
    157                                 const MCSymbol *FuncBegin,
    158                                 const MCSymbol *FuncEnd);
    159 
    160   void emitInlineLineTableForFunction(
    161       MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId,
    162       unsigned SourceLineNum, const MCSymbol *FnStartSym,
    163       const MCSymbol *FnEndSym, ArrayRef<unsigned> SecondaryFunctionIds);
    164 
    165   /// Encodes the binary annotations once we have a layout.
    166   void encodeInlineLineTable(MCAsmLayout &Layout,
    167                              MCCVInlineLineTableFragment &F);
    168 
    169   void
    170   emitDefRange(MCObjectStreamer &OS,
    171                ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
    172                StringRef FixedSizePortion);
    173 
    174   void encodeDefRange(MCAsmLayout &Layout, MCCVDefRangeFragment &F);
    175 
    176   /// Emits the string table substream.
    177   void emitStringTable(MCObjectStreamer &OS);
    178 
    179   /// Emits the file checksum substream.
    180   void emitFileChecksums(MCObjectStreamer &OS);
    181 
    182 private:
    183   /// Map from string to string table offset.
    184   StringMap<unsigned> StringTable;
    185 
    186   /// The fragment that ultimately holds our strings.
    187   MCDataFragment *StrTabFragment = nullptr;
    188   bool InsertedStrTabFragment = false;
    189 
    190   MCDataFragment *getStringTableFragment();
    191 
    192   /// Add something to the string table.
    193   StringRef addToStringTable(StringRef S);
    194 
    195   /// Get a string table offset.
    196   unsigned getStringTableOffset(StringRef S);
    197 
    198   /// An array of absolute paths. Eventually this may include the file checksum.
    199   SmallVector<StringRef, 4> Filenames;
    200 
    201   /// The offset of the first and last .cv_loc directive for a given function
    202   /// id.
    203   std::map<unsigned, std::pair<size_t, size_t>> MCCVLineStartStop;
    204 
    205   /// A collection of MCCVLineEntry for each section.
    206   std::vector<MCCVLineEntry> MCCVLines;
    207 };
    208 
    209 } // end namespace llvm
    210 #endif
    211