]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/MC/MCCodeView.h
Merge clang 7.0.1 and several follow-up changes
[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/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       : FunctionId(functionid), FileNum(fileNum), Line(line), Column(column),
45         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   unsigned getColumn() const { return Column; }
61
62   bool isPrologueEnd() const { return PrologueEnd; }
63   bool isStmt() const { return IsStmt; }
64
65   void setFunctionId(unsigned FID) { FunctionId = FID; }
66
67   /// Set the FileNum of this MCCVLoc.
68   void setFileNum(unsigned fileNum) { FileNum = fileNum; }
69
70   /// Set the Line of this MCCVLoc.
71   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     Column = column;
77   }
78
79   void setPrologueEnd(bool PE) { PrologueEnd = PE; }
80   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       : 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 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     return !isUnallocatedFunctionInfo() &&
148            ParentFuncIdPlusOne != FunctionSentinel;
149   }
150
151   unsigned getParentFuncId() const {
152     assert(isInlinedCallSite());
153     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     CVLocSeen = true;
195   }
196
197   bool getCVLocSeen() { return CVLocSeen; }
198   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