1 //===- MCCodeView.h - Machine Code CodeView support -------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Holds state from .cv_file and .cv_loc directives for later emission.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_MC_MCCODEVIEW_H
15 #define LLVM_MC_MCCODEVIEW_H
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/ADT/StringMap.h"
19 #include "llvm/MC/MCObjectStreamer.h"
20 #include "llvm/MC/MCFragment.h"
26 class MCObjectStreamer;
29 /// \brief Instances of this class represent the information from a
30 /// .cv_loc directive.
36 uint16_t PrologueEnd : 1;
39 private: // MCContext manages these
40 friend class MCContext;
41 MCCVLoc(unsigned functionid, unsigned fileNum, unsigned line, unsigned column,
42 bool prologueend, bool isstmt)
43 : FunctionId(functionid), FileNum(fileNum), Line(line), Column(column),
44 PrologueEnd(prologueend), IsStmt(isstmt) {}
46 // Allow the default copy constructor and assignment operator to be used
47 // for an MCCVLoc object.
50 unsigned getFunctionId() const { return FunctionId; }
52 /// \brief Get the FileNum of this MCCVLoc.
53 unsigned getFileNum() const { return FileNum; }
55 /// \brief Get the Line of this MCCVLoc.
56 unsigned getLine() const { return Line; }
58 /// \brief Get the Column of this MCCVLoc.
59 unsigned getColumn() const { return Column; }
61 bool isPrologueEnd() const { return PrologueEnd; }
62 bool isStmt() const { return IsStmt; }
64 void setFunctionId(unsigned FID) { FunctionId = FID; }
66 /// \brief Set the FileNum of this MCCVLoc.
67 void setFileNum(unsigned fileNum) { FileNum = fileNum; }
69 /// \brief Set the Line of this MCCVLoc.
70 void setLine(unsigned line) { Line = line; }
72 /// \brief Set the Column of this MCCVLoc.
73 void setColumn(unsigned column) {
74 assert(column <= UINT16_MAX);
78 void setPrologueEnd(bool PE) { PrologueEnd = PE; }
79 void setIsStmt(bool IS) { IsStmt = IS; }
82 /// \brief Instances of this class represent the line information for
83 /// the CodeView line table entries. Which is created after a machine
84 /// instruction is assembled and uses an address from a temporary label
85 /// created at the current address in the current section and the info from
86 /// the last .cv_loc directive seen as stored in the context.
87 class MCCVLineEntry : public MCCVLoc {
88 const MCSymbol *Label;
91 // Allow the default copy constructor and assignment operator to be used
92 // for an MCCVLineEntry object.
95 // Constructor to create an MCCVLineEntry given a symbol and the dwarf loc.
96 MCCVLineEntry(const MCSymbol *Label, const MCCVLoc loc)
97 : MCCVLoc(loc), Label(Label) {}
99 const MCSymbol *getLabel() const { return Label; }
101 // This is called when an instruction is assembled into the specified
102 // section and if there is information from the last .cv_loc directive that
103 // has yet to have a line entry made for it is made.
104 static void Make(MCObjectStreamer *MCOS);
107 /// Holds state from .cv_file and .cv_loc directives for later emission.
108 class CodeViewContext {
113 bool isValidFileNumber(unsigned FileNumber) const;
114 bool addFile(unsigned FileNumber, StringRef Filename);
115 ArrayRef<StringRef> getFilenames() { return Filenames; }
117 /// \brief Add a line entry.
118 void addLineEntry(const MCCVLineEntry &LineEntry) {
119 size_t Offset = MCCVLines.size();
120 auto I = MCCVLineStartStop.insert(
121 {LineEntry.getFunctionId(), {Offset, Offset + 1}});
123 I.first->second.second = Offset + 1;
124 MCCVLines.push_back(LineEntry);
127 std::vector<MCCVLineEntry> getFunctionLineEntries(unsigned FuncId) {
128 std::vector<MCCVLineEntry> FilteredLines;
130 auto I = MCCVLineStartStop.find(FuncId);
131 if (I != MCCVLineStartStop.end())
132 for (size_t Idx = I->second.first, End = I->second.second; Idx != End;
134 if (MCCVLines[Idx].getFunctionId() == FuncId)
135 FilteredLines.push_back(MCCVLines[Idx]);
136 return FilteredLines;
139 std::pair<size_t, size_t> getLineExtent(unsigned FuncId) {
140 auto I = MCCVLineStartStop.find(FuncId);
141 // Return an empty extent if there are no cv_locs for this function id.
142 if (I == MCCVLineStartStop.end())
147 ArrayRef<MCCVLineEntry> getLinesForExtent(size_t L, size_t R) {
150 if (L >= MCCVLines.size())
152 return makeArrayRef(&MCCVLines[L], R - L);
155 /// Emits a line table substream.
156 void emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId,
157 const MCSymbol *FuncBegin,
158 const MCSymbol *FuncEnd);
160 void emitInlineLineTableForFunction(
161 MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId,
162 unsigned SourceLineNum, const MCSymbol *FnStartSym,
163 const MCSymbol *FnEndSym, ArrayRef<unsigned> SecondaryFunctionIds);
165 /// Encodes the binary annotations once we have a layout.
166 void encodeInlineLineTable(MCAsmLayout &Layout,
167 MCCVInlineLineTableFragment &F);
170 emitDefRange(MCObjectStreamer &OS,
171 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
172 StringRef FixedSizePortion);
174 void encodeDefRange(MCAsmLayout &Layout, MCCVDefRangeFragment &F);
176 /// Emits the string table substream.
177 void emitStringTable(MCObjectStreamer &OS);
179 /// Emits the file checksum substream.
180 void emitFileChecksums(MCObjectStreamer &OS);
183 /// Map from string to string table offset.
184 StringMap<unsigned> StringTable;
186 /// The fragment that ultimately holds our strings.
187 MCDataFragment *StrTabFragment = nullptr;
188 bool InsertedStrTabFragment = false;
190 MCDataFragment *getStringTableFragment();
192 /// Add something to the string table.
193 StringRef addToStringTable(StringRef S);
195 /// Get a string table offset.
196 unsigned getStringTableOffset(StringRef S);
198 /// An array of absolute paths. Eventually this may include the file checksum.
199 SmallVector<StringRef, 4> Filenames;
201 /// The offset of the first and last .cv_loc directive for a given function
203 std::map<unsigned, std::pair<size_t, size_t>> MCCVLineStartStop;
205 /// A collection of MCCVLineEntry for each section.
206 std::vector<MCCVLineEntry> MCCVLines;
209 } // end namespace llvm