1 | //===-- BreakpadRecords.h ------------------------------------- -*- 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 | #ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H |
10 | #define LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H |
11 | |
12 | #include "lldb/Utility/UUID.h" |
13 | #include "lldb/lldb-types.h" |
14 | #include "llvm/ADT/StringRef.h" |
15 | #include "llvm/Support/FormatProviders.h" |
16 | #include "llvm/TargetParser/Triple.h" |
17 | #include <optional> |
18 | |
19 | namespace lldb_private { |
20 | namespace breakpad { |
21 | |
22 | class Record { |
23 | public: |
24 | enum Kind { |
25 | Module, |
26 | Info, |
27 | File, |
28 | Func, |
29 | Inline, |
30 | InlineOrigin, |
31 | Line, |
32 | Public, |
33 | StackCFI, |
34 | StackWin |
35 | }; |
36 | |
37 | /// Attempt to guess the kind of the record present in the argument without |
38 | /// doing a full parse. The returned kind will always be correct for valid |
39 | /// records, but the full parse can still fail in case of corrupted input. |
40 | static std::optional<Kind> classify(llvm::StringRef Line); |
41 | |
42 | protected: |
43 | Record(Kind K) : TheKind(K) {} |
44 | |
45 | ~Record() = default; |
46 | |
47 | public: |
48 | Kind getKind() { return TheKind; } |
49 | |
50 | private: |
51 | Kind TheKind; |
52 | }; |
53 | |
54 | llvm::StringRef toString(Record::Kind K); |
55 | inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Record::Kind K) { |
56 | OS << toString(K); |
57 | return OS; |
58 | } |
59 | |
60 | class ModuleRecord : public Record { |
61 | public: |
62 | static std::optional<ModuleRecord> parse(llvm::StringRef Line); |
63 | ModuleRecord(llvm::Triple::OSType OS, llvm::Triple::ArchType Arch, UUID ID) |
64 | : Record(Module), OS(OS), Arch(Arch), ID(std::move(ID)) {} |
65 | |
66 | llvm::Triple::OSType OS; |
67 | llvm::Triple::ArchType Arch; |
68 | UUID ID; |
69 | }; |
70 | |
71 | inline bool operator==(const ModuleRecord &L, const ModuleRecord &R) { |
72 | return L.OS == R.OS && L.Arch == R.Arch && L.ID == R.ID; |
73 | } |
74 | llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const ModuleRecord &R); |
75 | |
76 | class InfoRecord : public Record { |
77 | public: |
78 | static std::optional<InfoRecord> parse(llvm::StringRef Line); |
79 | InfoRecord(UUID ID) : Record(Info), ID(std::move(ID)) {} |
80 | |
81 | UUID ID; |
82 | }; |
83 | |
84 | inline bool operator==(const InfoRecord &L, const InfoRecord &R) { |
85 | return L.ID == R.ID; |
86 | } |
87 | llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const InfoRecord &R); |
88 | |
89 | class FileRecord : public Record { |
90 | public: |
91 | static std::optional<FileRecord> parse(llvm::StringRef Line); |
92 | FileRecord(size_t Number, llvm::StringRef Name) |
93 | : Record(File), Number(Number), Name(Name) {} |
94 | |
95 | size_t Number; |
96 | llvm::StringRef Name; |
97 | }; |
98 | |
99 | inline bool operator==(const FileRecord &L, const FileRecord &R) { |
100 | return L.Number == R.Number && L.Name == R.Name; |
101 | } |
102 | llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const FileRecord &R); |
103 | |
104 | class InlineOriginRecord : public Record { |
105 | public: |
106 | static std::optional<InlineOriginRecord> parse(llvm::StringRef Line); |
107 | InlineOriginRecord(size_t Number, llvm::StringRef Name) |
108 | : Record(InlineOrigin), Number(Number), Name(Name) {} |
109 | |
110 | size_t Number; |
111 | llvm::StringRef Name; |
112 | }; |
113 | |
114 | inline bool operator==(const InlineOriginRecord &L, |
115 | const InlineOriginRecord &R) { |
116 | return L.Number == R.Number && L.Name == R.Name; |
117 | } |
118 | llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, |
119 | const InlineOriginRecord &R); |
120 | |
121 | class FuncRecord : public Record { |
122 | public: |
123 | static std::optional<FuncRecord> parse(llvm::StringRef Line); |
124 | FuncRecord(bool Multiple, lldb::addr_t Address, lldb::addr_t Size, |
125 | lldb::addr_t ParamSize, llvm::StringRef Name) |
126 | : Record(Module), Multiple(Multiple), Address(Address), Size(Size), |
127 | ParamSize(ParamSize), Name(Name) {} |
128 | |
129 | bool Multiple; |
130 | lldb::addr_t Address; |
131 | lldb::addr_t Size; |
132 | lldb::addr_t ParamSize; |
133 | llvm::StringRef Name; |
134 | }; |
135 | |
136 | bool operator==(const FuncRecord &L, const FuncRecord &R); |
137 | llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const FuncRecord &R); |
138 | |
139 | class InlineRecord : public Record { |
140 | public: |
141 | static std::optional<InlineRecord> parse(llvm::StringRef Line); |
142 | InlineRecord(size_t InlineNestLevel, uint32_t CallSiteLineNum, |
143 | size_t CallSiteFileNum, size_t OriginNum) |
144 | : Record(Inline), InlineNestLevel(InlineNestLevel), |
145 | CallSiteLineNum(CallSiteLineNum), CallSiteFileNum(CallSiteFileNum), |
146 | OriginNum(OriginNum) {} |
147 | |
148 | size_t InlineNestLevel; |
149 | uint32_t CallSiteLineNum; |
150 | size_t CallSiteFileNum; |
151 | size_t OriginNum; |
152 | // A vector of address range covered by this inline |
153 | std::vector<std::pair<lldb::addr_t, lldb::addr_t>> Ranges; |
154 | }; |
155 | |
156 | bool operator==(const InlineRecord &L, const InlineRecord &R); |
157 | llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const InlineRecord &R); |
158 | |
159 | class LineRecord : public Record { |
160 | public: |
161 | static std::optional<LineRecord> parse(llvm::StringRef Line); |
162 | LineRecord(lldb::addr_t Address, lldb::addr_t Size, uint32_t LineNum, |
163 | size_t FileNum) |
164 | : Record(Line), Address(Address), Size(Size), LineNum(LineNum), |
165 | FileNum(FileNum) {} |
166 | |
167 | lldb::addr_t Address; |
168 | lldb::addr_t Size; |
169 | uint32_t LineNum; |
170 | size_t FileNum; |
171 | }; |
172 | |
173 | bool operator==(const LineRecord &L, const LineRecord &R); |
174 | llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const LineRecord &R); |
175 | |
176 | class PublicRecord : public Record { |
177 | public: |
178 | static std::optional<PublicRecord> parse(llvm::StringRef Line); |
179 | PublicRecord(bool Multiple, lldb::addr_t Address, lldb::addr_t ParamSize, |
180 | llvm::StringRef Name) |
181 | : Record(Module), Multiple(Multiple), Address(Address), |
182 | ParamSize(ParamSize), Name(Name) {} |
183 | |
184 | bool Multiple; |
185 | lldb::addr_t Address; |
186 | lldb::addr_t ParamSize; |
187 | llvm::StringRef Name; |
188 | }; |
189 | |
190 | bool operator==(const PublicRecord &L, const PublicRecord &R); |
191 | llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const PublicRecord &R); |
192 | |
193 | class StackCFIRecord : public Record { |
194 | public: |
195 | static std::optional<StackCFIRecord> parse(llvm::StringRef Line); |
196 | StackCFIRecord(lldb::addr_t Address, std::optional<lldb::addr_t> Size, |
197 | llvm::StringRef UnwindRules) |
198 | : Record(StackCFI), Address(Address), Size(Size), |
199 | UnwindRules(UnwindRules) {} |
200 | |
201 | lldb::addr_t Address; |
202 | std::optional<lldb::addr_t> Size; |
203 | llvm::StringRef UnwindRules; |
204 | }; |
205 | |
206 | bool operator==(const StackCFIRecord &L, const StackCFIRecord &R); |
207 | llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackCFIRecord &R); |
208 | |
209 | class StackWinRecord : public Record { |
210 | public: |
211 | static std::optional<StackWinRecord> parse(llvm::StringRef Line); |
212 | |
213 | StackWinRecord(lldb::addr_t RVA, lldb::addr_t CodeSize, |
214 | lldb::addr_t ParameterSize, lldb::addr_t SavedRegisterSize, |
215 | lldb::addr_t LocalSize, llvm::StringRef ProgramString) |
216 | : Record(StackWin), RVA(RVA), CodeSize(CodeSize), |
217 | ParameterSize(ParameterSize), SavedRegisterSize(SavedRegisterSize), |
218 | LocalSize(LocalSize), ProgramString(ProgramString) {} |
219 | |
220 | enum class FrameType : uint8_t { FPO = 0, FrameData = 4 }; |
221 | lldb::addr_t RVA; |
222 | lldb::addr_t CodeSize; |
223 | lldb::addr_t ParameterSize; |
224 | lldb::addr_t SavedRegisterSize; |
225 | lldb::addr_t LocalSize; |
226 | llvm::StringRef ProgramString; |
227 | }; |
228 | |
229 | bool operator==(const StackWinRecord &L, const StackWinRecord &R); |
230 | llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackWinRecord &R); |
231 | |
232 | } // namespace breakpad |
233 | } // namespace lldb_private |
234 | |
235 | #endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H |
236 | |