Coverage Report

Created: 2018-07-12 09:57

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/MC/MCCodeView.h
Line
Count
Source
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
17.7k
        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
1.14k
  unsigned getFunctionId() const { return FunctionId; }
52
53
  /// Get the FileNum of this MCCVLoc.
54
730
  unsigned getFileNum() const { return FileNum; }
55
56
  /// Get the Line of this MCCVLoc.
57
584
  unsigned getLine() const { return Line; }
58
59
  /// Get the Column of this MCCVLoc.
60
638
  unsigned getColumn() const { return Column; }
61
62
  bool isPrologueEnd() const { return PrologueEnd; }
63
862
  bool isStmt() const { return IsStmt; }
64
65
898
  void setFunctionId(unsigned FID) { FunctionId = FID; }
66
67
  /// Set the FileNum of this MCCVLoc.
68
967
  void setFileNum(unsigned fileNum) { FileNum = fileNum; }
69
70
  /// Set the Line of this MCCVLoc.
71
967
  void setLine(unsigned line) { Line = line; }
72
73
  /// Set the Column of this MCCVLoc.
74
898
  void setColumn(unsigned column) {
75
898
    assert(column <= UINT16_MAX);
76
898
    Column = column;
77
898
  }
78
79
898
  void setPrologueEnd(bool PE) { PrologueEnd = PE; }
80
898
  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
558
      : MCCVLoc(loc), Label(Label) {}
99
100
828
  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
1.50k
  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
70
  bool isInlinedCallSite() const {
147
70
    return !isUnallocatedFunctionInfo() &&
148
70
           ParentFuncIdPlusOne != FunctionSentinel;
149
70
  }
150
151
39
  unsigned getParentFuncId() const {
152
39
    assert(isInlinedCallSite());
153
39
    return ParentFuncIdPlusOne - 1;
154
39
  }
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
898
                       unsigned Column, bool PrologueEnd, bool IsStmt) {
188
898
    CurrentCVLoc.setFunctionId(FunctionId);
189
898
    CurrentCVLoc.setFileNum(FileNo);
190
898
    CurrentCVLoc.setLine(Line);
191
898
    CurrentCVLoc.setColumn(Column);
192
898
    CurrentCVLoc.setPrologueEnd(PrologueEnd);
193
898
    CurrentCVLoc.setIsStmt(IsStmt);
194
898
    CVLocSeen = true;
195
898
  }
196
197
27.5M
  bool getCVLocSeen() { return CVLocSeen; }
198
151k
  void clearCVLocSeen() { CVLocSeen = false; }
199
200
898
  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