LLVM 23.0.0git
MCCodeView.h
Go to the documentation of this file.
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"
19#include "llvm/ADT/StringMap.h"
20#include "llvm/ADT/StringRef.h"
21#include <deque>
22#include <map>
23#include <vector>
24
25namespace llvm {
26class MCAssembler;
29class MCFragment;
30class MCSection;
31class MCSymbol;
32class MCContext;
34class MCStreamer;
35
36/// Instances of this class represent the information from a
37/// .cv_loc directive.
38class 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
47private: // 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
57public:
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.
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.
105
106 enum : unsigned { FunctionSentinel = ~0U };
107
108 struct LineInfo {
109 unsigned File;
110 unsigned Line;
111 unsigned Col;
112 };
113
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.
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.
136
137 unsigned getParentFuncId() const {
139 return ParentFuncIdPlusOne - 1;
140 }
141};
142
143/// Holds state from .cv_file and .cv_loc directives for later emission.
145public:
146 CodeViewContext(MCContext *MCCtx) : MCCtx(MCCtx) {}
147
149 CodeViewContext(const CodeViewContext &other) = delete;
150
151 LLVM_ABI void finish();
152
153 LLVM_ABI bool isValidFileNumber(unsigned FileNumber) const;
154 LLVM_ABI bool addFile(MCStreamer &OS, unsigned FileNumber, StringRef Filename,
155 ArrayRef<uint8_t> ChecksumBytes, uint8_t ChecksumKind);
156
157 /// Records the function id of a normal function. Returns false if the
158 /// function id has already been used, and true otherwise.
159 LLVM_ABI bool recordFunctionId(unsigned FuncId);
160
161 /// Records the function id of an inlined call site. Records the "inlined at"
162 /// location info of the call site, including what function or inlined call
163 /// site it was inlined into. Returns false if the function id has already
164 /// been used, and true otherwise.
165 LLVM_ABI bool recordInlinedCallSiteId(unsigned FuncId, unsigned IAFunc,
166 unsigned IAFile, unsigned IALine,
167 unsigned IACol);
168
169 /// Retreive the function info if this is a valid function id, or nullptr.
171
172 /// Saves the information from the currently parsed .cv_loc directive
173 /// and sets CVLocSeen. When the next instruction is assembled an entry
174 /// in the line number table with this information and the address of the
175 /// instruction will be created.
176 LLVM_ABI void recordCVLoc(MCContext &Ctx, const MCSymbol *Label,
177 unsigned FunctionId, unsigned FileNo, unsigned Line,
178 unsigned Column, bool PrologueEnd, bool IsStmt);
179
180 /// Add a line entry.
181 LLVM_ABI void addLineEntry(const MCCVLoc &LineEntry);
182
183 LLVM_ABI std::vector<MCCVLoc> getFunctionLineEntries(unsigned FuncId);
184
185 LLVM_ABI std::pair<size_t, size_t> getLineExtent(unsigned FuncId);
186 LLVM_ABI std::pair<size_t, size_t>
187 getLineExtentIncludingInlinees(unsigned FuncId);
188
189 LLVM_ABI ArrayRef<MCCVLoc> getLinesForExtent(size_t L, size_t R);
190
191 /// Emits a line table substream.
192 LLVM_ABI void emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId,
193 const MCSymbol *FuncBegin,
194 const MCSymbol *FuncEnd);
195
197 unsigned PrimaryFunctionId,
198 unsigned SourceFileId,
199 unsigned SourceLineNum,
200 const MCSymbol *FnStartSym,
201 const MCSymbol *FnEndSym);
202
203 /// Encodes the binary annotations once we have a layout.
206
207 LLVM_ABI void
209 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
210 StringRef FixedSizePortion);
211
213
214 /// Emits the string table substream.
216
217 /// Emits the file checksum substream.
219
220 /// Emits the offset into the checksum table of the given file number.
221 LLVM_ABI void emitFileChecksumOffset(MCObjectStreamer &OS, unsigned FileNo);
222
223 /// Add something to the string table. Returns the final string as well as
224 /// offset into the string table.
225 LLVM_ABI std::pair<StringRef, unsigned> addToStringTable(StringRef S);
226
227private:
228 MCContext *MCCtx;
229
230 /// Map from string to string table offset.
231 StringMap<unsigned> StringTable;
232
233 /// The fragment that ultimately holds our strings.
234 MCFragment *StrTabFragment = nullptr;
235 SmallVector<char, 0> StrTab = {'\0'};
236
237 /// Get a string table offset.
238 unsigned getStringTableOffset(StringRef S);
239
240 struct FileInfo {
241 unsigned StringTableOffset;
242
243 // Indicates if this FileInfo corresponds to an actual file, or hasn't been
244 // set yet.
245 bool Assigned = false;
246
247 uint8_t ChecksumKind;
248
249 ArrayRef<uint8_t> Checksum;
250
251 // Checksum offset stored as a symbol because it might be requested
252 // before it has been calculated, so a fixup may be needed.
253 MCSymbol *ChecksumTableOffset;
254 };
255
256 /// Array storing added file information.
257 SmallVector<FileInfo, 4> Files;
258
259 /// The offset of the first and last .cv_loc directive for a given function
260 /// id.
261 std::map<unsigned, std::pair<size_t, size_t>> MCCVLineStartStop;
262
263 /// A collection of MCCVLoc for each section.
264 std::vector<MCCVLoc> MCCVLines;
265
266 /// All known functions and inlined call sites, indexed by function id.
267 std::vector<MCCVFunctionInfo> Functions;
268
269 /// Indicate whether we have already laid out the checksum table addresses or
270 /// not.
271 bool ChecksumOffsetsAssigned = false;
272
273 /// Append-only storage of MCCVDefRangeFragment::Ranges.
274 std::deque<SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 0>>
275 DefRangeStorage;
276};
277
278} // end namespace llvm
279#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
#define LLVM_ABI
Definition Compiler.h:213
This file defines the DenseMap class.
#define F(x, y, z)
Definition MD5.cpp:54
static constexpr StringLiteral Filename
This file defines the SmallVector class.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM_ABI ArrayRef< MCCVLoc > getLinesForExtent(size_t L, size_t R)
LLVM_ABI std::pair< size_t, size_t > getLineExtent(unsigned FuncId)
LLVM_ABI void encodeInlineLineTable(const MCAssembler &Asm, MCCVInlineLineTableFragment &F)
Encodes the binary annotations once we have a layout.
LLVM_ABI void emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId, const MCSymbol *FuncBegin, const MCSymbol *FuncEnd)
Emits a line table substream.
LLVM_ABI void emitFileChecksums(MCObjectStreamer &OS)
Emits the file checksum substream.
LLVM_ABI void recordCVLoc(MCContext &Ctx, const MCSymbol *Label, 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.
LLVM_ABI void emitDefRange(MCObjectStreamer &OS, ArrayRef< std::pair< const MCSymbol *, const MCSymbol * > > Ranges, StringRef FixedSizePortion)
CodeViewContext & operator=(const CodeViewContext &other)=delete
LLVM_ABI bool addFile(MCStreamer &OS, unsigned FileNumber, StringRef Filename, ArrayRef< uint8_t > ChecksumBytes, uint8_t ChecksumKind)
CodeViewContext(MCContext *MCCtx)
Definition MCCodeView.h:146
LLVM_ABI MCCVFunctionInfo * getCVFunctionInfo(unsigned FuncId)
Retreive the function info if this is a valid function id, or nullptr.
LLVM_ABI bool recordFunctionId(unsigned FuncId)
Records the function id of a normal function.
LLVM_ABI void emitFileChecksumOffset(MCObjectStreamer &OS, unsigned FileNo)
Emits the offset into the checksum table of the given file number.
LLVM_ABI std::vector< MCCVLoc > getFunctionLineEntries(unsigned FuncId)
LLVM_ABI void addLineEntry(const MCCVLoc &LineEntry)
Add a line entry.
LLVM_ABI bool recordInlinedCallSiteId(unsigned FuncId, unsigned IAFunc, unsigned IAFile, unsigned IALine, unsigned IACol)
Records the function id of an inlined call site.
CodeViewContext(const CodeViewContext &other)=delete
LLVM_ABI std::pair< size_t, size_t > getLineExtentIncludingInlinees(unsigned FuncId)
LLVM_ABI void emitInlineLineTableForFunction(MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, const MCSymbol *FnStartSym, const MCSymbol *FnEndSym)
LLVM_ABI void finish()
LLVM_ABI void emitStringTable(MCObjectStreamer &OS)
Emits the string table substream.
LLVM_ABI bool isValidFileNumber(unsigned FileNumber) const
This is a valid number for use with .cv_loc if we've already seen a .cv_file for it.
LLVM_ABI void encodeDefRange(const MCAssembler &Asm, MCCVDefRangeFragment &F)
LLVM_ABI std::pair< StringRef, unsigned > addToStringTable(StringRef S)
Add something to the string table.
Fragment representing the .cv_def_range directive.
Definition MCSection.h:510
Fragment representing the binary annotations produced by the .cv_inline_linetable directive.
Definition MCSection.h:482
Instances of this class represent the information from a .cv_loc directive.
Definition MCCodeView.h:38
void setFileNum(unsigned fileNum)
Set the FileNum of this MCCVLoc.
Definition MCCodeView.h:79
void setPrologueEnd(bool PE)
Definition MCCodeView.h:90
unsigned getLine() const
Get the Line of this MCCVLoc.
Definition MCCodeView.h:66
void setColumn(unsigned column)
Set the Column of this MCCVLoc.
Definition MCCodeView.h:85
unsigned getFileNum() const
Get the FileNum of this MCCVLoc.
Definition MCCodeView.h:63
friend class CodeViewContext
Definition MCCodeView.h:48
void setFunctionId(unsigned FID)
Definition MCCodeView.h:76
bool isPrologueEnd() const
Definition MCCodeView.h:71
void setIsStmt(bool IS)
Definition MCCodeView.h:91
bool isStmt() const
Definition MCCodeView.h:72
const MCSymbol * getLabel() const
Definition MCCodeView.h:58
void setLabel(const MCSymbol *L)
Definition MCCodeView.h:74
unsigned getColumn() const
Get the Column of this MCCVLoc.
Definition MCCodeView.h:69
unsigned getFunctionId() const
Definition MCCodeView.h:60
void setLine(unsigned line)
Set the Line of this MCCVLoc.
Definition MCCodeView.h:82
Context object for machine code objects.
Definition MCContext.h:83
Streaming object file generation interface.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition MCSection.h:573
Streaming machine code generation interface.
Definition MCStreamer.h:222
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:128
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
This class represents a function that is read from a sample profile.
Definition FunctionId.h:36
This is an optimization pass for GlobalISel generic memory operations.
Information describing a function or inlined call site introduced by .cv_func_id or ....
Definition MCCodeView.h:98
bool isInlinedCallSite() const
Returns true if this represents an inlined call site, meaning ParentFuncIdPlusOne is neither zero nor...
Definition MCCodeView.h:132
MCSection * Section
The section of the first .cv_loc directive used for this function, or null if none has been seen yet.
Definition MCCodeView.h:118
unsigned ParentFuncIdPlusOne
If this represents an inlined call site, then ParentFuncIdPlusOne will be the parent function id plus...
Definition MCCodeView.h:104
unsigned getParentFuncId() const
Definition MCCodeView.h:137
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:128
DenseMap< unsigned, LineInfo > InlinedAtMap
Map from inlined call site id to the inlined at location to use for that call site.
Definition MCCodeView.h:124