Coverage Report

Created: 2018-11-16 02:38

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