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