/src/keystone/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/StringRef.h" |
18 | | #include "llvm/ADT/StringMap.h" |
19 | | #include "llvm/MC/MCObjectStreamer.h" |
20 | | #include "llvm/MC/MCFragment.h" |
21 | | #include <map> |
22 | | #include <vector> |
23 | | |
24 | | namespace llvm_ks { |
25 | | class MCContext; |
26 | | class MCObjectStreamer; |
27 | | class MCStreamer; |
28 | | |
29 | | /// \brief Instances of this class represent the information from a |
30 | | /// .cv_loc directive. |
31 | | class MCCVLoc { |
32 | | uint32_t FunctionId; |
33 | | uint32_t FileNum; |
34 | | uint32_t Line; |
35 | | uint16_t Column; |
36 | | uint16_t PrologueEnd : 1; |
37 | | uint16_t IsStmt : 1; |
38 | | |
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 | 129k | : FunctionId(functionid), FileNum(fileNum), Line(line), Column(column), |
44 | 129k | PrologueEnd(prologueend), IsStmt(isstmt) {} |
45 | | |
46 | | // Allow the default copy constructor and assignment operator to be used |
47 | | // for an MCCVLoc object. |
48 | | |
49 | | public: |
50 | 0 | unsigned getFunctionId() const { return FunctionId; } |
51 | | |
52 | | /// \brief Get the FileNum of this MCCVLoc. |
53 | 0 | unsigned getFileNum() const { return FileNum; } |
54 | | |
55 | | /// \brief Get the Line of this MCCVLoc. |
56 | 0 | unsigned getLine() const { return Line; } |
57 | | |
58 | | /// \brief Get the Column of this MCCVLoc. |
59 | 0 | unsigned getColumn() const { return Column; } |
60 | | |
61 | 0 | bool isPrologueEnd() const { return PrologueEnd; } |
62 | 0 | bool isStmt() const { return IsStmt; } |
63 | | |
64 | 0 | void setFunctionId(unsigned FID) { FunctionId = FID; } |
65 | | |
66 | | /// \brief Set the FileNum of this MCCVLoc. |
67 | 0 | void setFileNum(unsigned fileNum) { FileNum = fileNum; } |
68 | | |
69 | | /// \brief Set the Line of this MCCVLoc. |
70 | 0 | void setLine(unsigned line) { Line = line; } |
71 | | |
72 | | /// \brief Set the Column of this MCCVLoc. |
73 | 0 | void setColumn(unsigned column) { |
74 | 0 | assert(column <= UINT16_MAX); |
75 | 0 | Column = column; |
76 | 0 | } |
77 | | |
78 | 0 | void setPrologueEnd(bool PE) { PrologueEnd = PE; } |
79 | 0 | void setIsStmt(bool IS) { IsStmt = IS; } |
80 | | }; |
81 | | |
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 | | MCSymbol *Label; |
89 | | |
90 | | private: |
91 | | // Allow the default copy constructor and assignment operator to be used |
92 | | // for an MCCVLineEntry object. |
93 | | |
94 | | public: |
95 | | // Constructor to create an MCCVLineEntry given a symbol and the dwarf loc. |
96 | | MCCVLineEntry(MCSymbol *label, const MCCVLoc loc) |
97 | 0 | : MCCVLoc(loc), Label(label) {} |
98 | | |
99 | 0 | MCSymbol *getLabel() const { return Label; } |
100 | | |
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); |
105 | | }; |
106 | | |
107 | | /// Holds state from .cv_file and .cv_loc directives for later emission. |
108 | | class CodeViewContext { |
109 | | public: |
110 | | CodeViewContext(); |
111 | | ~CodeViewContext(); |
112 | | |
113 | | bool isValidFileNumber(unsigned FileNumber) const; |
114 | | bool addFile(unsigned FileNumber, StringRef Filename); |
115 | 0 | ArrayRef<StringRef> getFilenames() { return Filenames; } |
116 | | |
117 | | /// \brief Add a line entry. |
118 | 0 | void addLineEntry(const MCCVLineEntry &LineEntry) { |
119 | 0 | size_t Offset = MCCVLines.size(); |
120 | 0 | auto I = |
121 | 0 | MCCVLineStartStop.insert({LineEntry.getFunctionId(), {Offset, Offset}}); |
122 | 0 | if (!I.second) |
123 | 0 | I.first->second.second = Offset; |
124 | 0 | MCCVLines.push_back(LineEntry); |
125 | 0 | } |
126 | | |
127 | 0 | std::vector<MCCVLineEntry> getFunctionLineEntries(unsigned FuncId) { |
128 | 0 | std::vector<MCCVLineEntry> FilteredLines; |
129 | 0 |
|
130 | 0 | auto I = MCCVLineStartStop.find(FuncId); |
131 | 0 | if (I != MCCVLineStartStop.end()) |
132 | 0 | for (size_t Idx = I->second.first, End = I->second.second + 1; Idx != End; |
133 | 0 | ++Idx) |
134 | 0 | if (MCCVLines[Idx].getFunctionId() == FuncId) |
135 | 0 | FilteredLines.push_back(MCCVLines[Idx]); |
136 | 0 | return FilteredLines; |
137 | 0 | } |
138 | | |
139 | | /// Emits a line table substream. |
140 | | void emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId, |
141 | | const MCSymbol *FuncBegin, |
142 | | const MCSymbol *FuncEnd); |
143 | | |
144 | | void emitInlineLineTableForFunction(MCObjectStreamer &OS, |
145 | | unsigned PrimaryFunctionId, |
146 | | unsigned SourceFileId, |
147 | | unsigned SourceLineNum, |
148 | | ArrayRef<unsigned> SecondaryFunctionIds); |
149 | | |
150 | | /// Emits the string table substream. |
151 | | void emitStringTable(MCObjectStreamer &OS); |
152 | | |
153 | | /// Emits the file checksum substream. |
154 | | void emitFileChecksums(MCObjectStreamer &OS); |
155 | | |
156 | | private: |
157 | | /// Map from string to string table offset. |
158 | | StringMap<unsigned> StringTable; |
159 | | |
160 | | /// The fragment that ultimately holds our strings. |
161 | | MCDataFragment *StrTabFragment = nullptr; |
162 | | bool InsertedStrTabFragment = false; |
163 | | |
164 | | MCDataFragment *getStringTableFragment(); |
165 | | |
166 | | /// Add something to the string table. |
167 | | StringRef addToStringTable(StringRef S); |
168 | | |
169 | | /// Get a string table offset. |
170 | | unsigned getStringTableOffset(StringRef S); |
171 | | |
172 | | /// An array of absolute paths. Eventually this may include the file checksum. |
173 | | SmallVector<StringRef, 4> Filenames; |
174 | | |
175 | | /// The offset of the first and last .cv_loc directive for a given function |
176 | | /// id. |
177 | | std::map<unsigned, std::pair<size_t, size_t>> MCCVLineStartStop; |
178 | | |
179 | | /// A collection of MCCVLineEntry for each section. |
180 | | std::vector<MCCVLineEntry> MCCVLines; |
181 | | }; |
182 | | |
183 | | } // end namespace llvm_ks |
184 | | #endif |