Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

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