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
19namespace lldb_private {
20namespace breakpad {
21
22class Record {
23public:
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
42protected:
43 Record(Kind K) : TheKind(K) {}
44
45 ~Record() = default;
46
47public:
48 Kind getKind() { return TheKind; }
49
50private:
51 Kind TheKind;
52};
53
54llvm::StringRef toString(Record::Kind K);
55inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Record::Kind K) {
56 OS << toString(K);
57 return OS;
58}
59
60class ModuleRecord : public Record {
61public:
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
71inline bool operator==(const ModuleRecord &L, const ModuleRecord &R) {
72 return L.OS == R.OS && L.Arch == R.Arch && L.ID == R.ID;
73}
74llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const ModuleRecord &R);
75
76class InfoRecord : public Record {
77public:
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
84inline bool operator==(const InfoRecord &L, const InfoRecord &R) {
85 return L.ID == R.ID;
86}
87llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const InfoRecord &R);
88
89class FileRecord : public Record {
90public:
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
99inline bool operator==(const FileRecord &L, const FileRecord &R) {
100 return L.Number == R.Number && L.Name == R.Name;
101}
102llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const FileRecord &R);
103
104class InlineOriginRecord : public Record {
105public:
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
114inline bool operator==(const InlineOriginRecord &L,
115 const InlineOriginRecord &R) {
116 return L.Number == R.Number && L.Name == R.Name;
117}
118llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
119 const InlineOriginRecord &R);
120
121class FuncRecord : public Record {
122public:
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
136bool operator==(const FuncRecord &L, const FuncRecord &R);
137llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const FuncRecord &R);
138
139class InlineRecord : public Record {
140public:
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
156bool operator==(const InlineRecord &L, const InlineRecord &R);
157llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const InlineRecord &R);
158
159class LineRecord : public Record {
160public:
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
173bool operator==(const LineRecord &L, const LineRecord &R);
174llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const LineRecord &R);
175
176class PublicRecord : public Record {
177public:
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
190bool operator==(const PublicRecord &L, const PublicRecord &R);
191llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const PublicRecord &R);
192
193class StackCFIRecord : public Record {
194public:
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
206bool operator==(const StackCFIRecord &L, const StackCFIRecord &R);
207llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackCFIRecord &R);
208
209class StackWinRecord : public Record {
210public:
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
229bool operator==(const StackWinRecord &L, const StackWinRecord &R);
230llvm::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

source code of lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h