Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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