]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/MC/MCCodeView.h
MFV: r313101
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / MC / MCCodeView.h
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