LLVM  6.0.0svn
MCCodeView.h
Go to the documentation of this file.
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"
21 #include <map>
22 #include <vector>
23 
24 namespace llvm {
25 class MCContext;
26 class MCObjectStreamer;
27 class MCStreamer;
28 class CodeViewContext;
29 
30 /// \brief 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  /// \brief Get the FileNum of this MCCVLoc.
54  unsigned getFileNum() const { return FileNum; }
55 
56  /// \brief Get the Line of this MCCVLoc.
57  unsigned getLine() const { return Line; }
58 
59  /// \brief 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  /// \brief Set the FileNum of this MCCVLoc.
68  void setFileNum(unsigned fileNum) { FileNum = fileNum; }
69 
70  /// \brief Set the Line of this MCCVLoc.
71  void setLine(unsigned line) { Line = line; }
72 
73  /// \brief 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 /// \brief 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.
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 
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.
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.
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.
181  if (FuncId >= Functions.size())
182  return nullptr;
183  if (Functions[FuncId].isUnallocatedFunctionInfo())
184  return nullptr;
185  return &Functions[FuncId];
186  }
187 
188  /// Saves the information from the currently parsed .cv_loc directive
189  /// and sets CVLocSeen. When the next instruction is assembled an entry
190  /// in the line number table with this information and the address of the
191  /// instruction will be created.
192  void setCurrentCVLoc(unsigned FunctionId, unsigned FileNo, unsigned Line,
193  unsigned Column, bool PrologueEnd, bool IsStmt) {
194  CurrentCVLoc.setFunctionId(FunctionId);
195  CurrentCVLoc.setFileNum(FileNo);
196  CurrentCVLoc.setLine(Line);
197  CurrentCVLoc.setColumn(Column);
198  CurrentCVLoc.setPrologueEnd(PrologueEnd);
199  CurrentCVLoc.setIsStmt(IsStmt);
200  CVLocSeen = true;
201  }
202  void clearCVLocSeen() { CVLocSeen = false; }
203 
204  bool getCVLocSeen() { return CVLocSeen; }
205  const MCCVLoc &getCurrentCVLoc() { return CurrentCVLoc; }
206 
207  bool isValidCVFileNumber(unsigned FileNumber);
208 
209  /// \brief Add a line entry.
210  void addLineEntry(const MCCVLineEntry &LineEntry) {
211  size_t Offset = MCCVLines.size();
212  auto I = MCCVLineStartStop.insert(
213  {LineEntry.getFunctionId(), {Offset, Offset + 1}});
214  if (!I.second)
215  I.first->second.second = Offset + 1;
216  MCCVLines.push_back(LineEntry);
217  }
218 
219  std::vector<MCCVLineEntry> getFunctionLineEntries(unsigned FuncId) {
220  std::vector<MCCVLineEntry> FilteredLines;
221 
222  auto I = MCCVLineStartStop.find(FuncId);
223  if (I != MCCVLineStartStop.end())
224  for (size_t Idx = I->second.first, End = I->second.second; Idx != End;
225  ++Idx)
226  if (MCCVLines[Idx].getFunctionId() == FuncId)
227  FilteredLines.push_back(MCCVLines[Idx]);
228  return FilteredLines;
229  }
230 
231  std::pair<size_t, size_t> getLineExtent(unsigned FuncId) {
232  auto I = MCCVLineStartStop.find(FuncId);
233  // Return an empty extent if there are no cv_locs for this function id.
234  if (I == MCCVLineStartStop.end())
235  return {~0ULL, 0};
236  return I->second;
237  }
238 
240  if (R <= L)
241  return None;
242  if (L >= MCCVLines.size())
243  return None;
244  return makeArrayRef(&MCCVLines[L], R - L);
245  }
246 
247  /// Emits a line table substream.
248  void emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId,
249  const MCSymbol *FuncBegin,
250  const MCSymbol *FuncEnd);
251 
252  void emitInlineLineTableForFunction(MCObjectStreamer &OS,
253  unsigned PrimaryFunctionId,
254  unsigned SourceFileId,
255  unsigned SourceLineNum,
256  const MCSymbol *FnStartSym,
257  const MCSymbol *FnEndSym);
258 
259  /// Encodes the binary annotations once we have a layout.
260  void encodeInlineLineTable(MCAsmLayout &Layout,
262 
263  void
264  emitDefRange(MCObjectStreamer &OS,
265  ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
266  StringRef FixedSizePortion);
267 
268  void encodeDefRange(MCAsmLayout &Layout, MCCVDefRangeFragment &F);
269 
270  /// Emits the string table substream.
271  void emitStringTable(MCObjectStreamer &OS);
272 
273  /// Emits the file checksum substream.
274  void emitFileChecksums(MCObjectStreamer &OS);
275 
276  /// Emits the offset into the checksum table of the given file number.
277  void emitFileChecksumOffset(MCObjectStreamer &OS, unsigned FileNo);
278 
279  /// Add something to the string table. Returns the final string as well as
280  /// offset into the string table.
281  std::pair<StringRef, unsigned> addToStringTable(StringRef S);
282 
283 private:
284  /// The current CodeView line information from the last .cv_loc directive.
285  MCCVLoc CurrentCVLoc = MCCVLoc(0, 0, 0, 0, false, true);
286  bool CVLocSeen = false;
287 
288  /// Map from string to string table offset.
289  StringMap<unsigned> StringTable;
290 
291  /// The fragment that ultimately holds our strings.
292  MCDataFragment *StrTabFragment = nullptr;
293  bool InsertedStrTabFragment = false;
294 
295  MCDataFragment *getStringTableFragment();
296 
297  /// Get a string table offset.
298  unsigned getStringTableOffset(StringRef S);
299 
300  struct FileInfo {
301  unsigned StringTableOffset;
302 
303  // Indicates if this FileInfo corresponds to an actual file, or hasn't been
304  // set yet.
305  bool Assigned = false;
306 
307  uint8_t ChecksumKind;
308 
309  ArrayRef<uint8_t> Checksum;
310 
311  // Checksum offset stored as a symbol because it might be requested
312  // before it has been calculated, so a fixup may be needed.
313  MCSymbol *ChecksumTableOffset;
314  };
315 
316  /// Array storing added file information.
318 
319  /// The offset of the first and last .cv_loc directive for a given function
320  /// id.
321  std::map<unsigned, std::pair<size_t, size_t>> MCCVLineStartStop;
322 
323  /// A collection of MCCVLineEntry for each section.
324  std::vector<MCCVLineEntry> MCCVLines;
325 
326  /// All known functions and inlined call sites, indexed by function id.
327  std::vector<MCCVFunctionInfo> Functions;
328 
329  /// Indicate whether we have already laid out the checksum table addresses or
330  /// not.
331  bool ChecksumOffsetsAssigned = false;
332 };
333 
334 } // end namespace llvm
335 #endif
Instances of this class represent a uniqued identifier for a section in the current translation unit...
Definition: MCSection.h:39
Instances of this class represent the information from a .cv_loc directive.
Definition: MCCodeView.h:32
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
bool isPrologueEnd() const
Definition: MCCodeView.h:62
F(f)
DenseMap< unsigned, LineInfo > InlinedAtMap
Map from inlined call site id to the inlined at location to use for that call site.
Definition: MCCodeView.h:138
void setColumn(unsigned column)
Set the Column of this MCCVLoc.
Definition: MCCodeView.h:74
bool isStmt() const
Definition: MCCodeView.h:63
void setIsStmt(bool IS)
Definition: MCCodeView.h:80
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:451
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:29
unsigned getLine() const
Get the Line of this MCCVLoc.
Definition: MCCodeView.h:57
void setCurrentCVLoc(unsigned FunctionId, unsigned FileNo, unsigned Line, unsigned Column, bool PrologueEnd, bool IsStmt)
Saves the information from the currently parsed .cv_loc directive and sets CVLocSeen.
Definition: MCCodeView.h:192
Streaming object file generation interface.
bool isInlinedCallSite() const
Returns true if this represents an inlined call site, meaning ParentFuncIdPlusOne is neither zero nor...
Definition: MCCodeView.h:146
unsigned getParentFuncId() const
Definition: MCCodeView.h:151
const MCCVLoc & getCurrentCVLoc()
Definition: MCCodeView.h:205
friend class CodeViewContext
Definition: MCCodeView.h:41
Streaming machine code generation interface.
Definition: MCStreamer.h:169
MCCVFunctionInfo * getCVFunctionInfo(unsigned FuncId)
Retreive the function info if this is a valid function id, or nullptr.
Definition: MCCodeView.h:180
std::vector< MCCVLineEntry > getFunctionLineEntries(unsigned FuncId)
Definition: MCCodeView.h:219
static const unsigned End
void setFunctionId(unsigned FID)
Definition: MCCodeView.h:65
void setFileNum(unsigned fileNum)
Set the FileNum of this MCCVLoc.
Definition: MCCodeView.h:68
ArrayRef< MCCVLineEntry > getLinesForExtent(size_t L, size_t R)
Definition: MCCodeView.h:239
Fragment representing the .cv_def_range directive.
Definition: MCFragment.h:627
void setLine(unsigned line)
Set the Line of this MCCVLoc.
Definition: MCCodeView.h:71
void addLineEntry(const MCCVLineEntry &LineEntry)
Add a line entry.
Definition: MCCodeView.h:210
unsigned getFileNum() const
Get the FileNum of this MCCVLoc.
Definition: MCCodeView.h:54
std::pair< size_t, size_t > getLineExtent(unsigned FuncId)
Definition: MCCodeView.h:231
MCCVLineEntry(const MCSymbol *Label, const MCCVLoc loc)
Definition: MCCodeView.h:97
Fragment representing the binary annotations produced by the .cv_inline_linetable directive...
Definition: MCFragment.h:589
static void addToStringTable(raw_ostream &Out, StringRef ArcName, const NewArchiveMember &M, bool Thin)
bool isUnallocatedFunctionInfo() const
Returns true if this is function info has not yet been used in a .cv_func_id or .cv_inline_site_id di...
Definition: MCCodeView.h:142
#define I(x, y, z)
Definition: MD5.cpp:58
void setPrologueEnd(bool PE)
Definition: MCCodeView.h:79
Instances of this class represent the line information for the CodeView line table entries...
Definition: MCCodeView.h:88
Fragment for data and encoded instructions.
Definition: MCFragment.h:226
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MCSymbol * getLabel() const
Definition: MCCodeView.h:100
unsigned getColumn() const
Get the Column of this MCCVLoc.
Definition: MCCodeView.h:60
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
Information describing a function or inlined call site introduced by .cv_func_id or ...
Definition: MCCodeView.h:112
unsigned getFunctionId() const
Definition: MCCodeView.h:51
Holds state from .cv_file and .cv_loc directives for later emission.
Definition: MCCodeView.h:158