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