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: Record(Kind K)43 Record(Kind K) : TheKind(K) {} 44 45 ~Record() = default; 46 47 public: getKind()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); ModuleRecord(llvm::Triple::OSType OS,llvm::Triple::ArchType Arch,UUID ID)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); InfoRecord(UUID ID)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); FileRecord(size_t Number,llvm::StringRef Name)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); InlineOriginRecord(size_t Number,llvm::StringRef Name)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); FuncRecord(bool Multiple,lldb::addr_t Address,lldb::addr_t Size,lldb::addr_t ParamSize,llvm::StringRef Name)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); InlineRecord(size_t InlineNestLevel,uint32_t CallSiteLineNum,size_t CallSiteFileNum,size_t OriginNum)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); LineRecord(lldb::addr_t Address,lldb::addr_t Size,uint32_t LineNum,size_t FileNum)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); PublicRecord(bool Multiple,lldb::addr_t Address,lldb::addr_t ParamSize,llvm::StringRef Name)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); StackCFIRecord(lldb::addr_t Address,std::optional<lldb::addr_t> Size,llvm::StringRef UnwindRules)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 StackWinRecord(lldb::addr_t RVA,lldb::addr_t CodeSize,lldb::addr_t ParameterSize,lldb::addr_t SavedRegisterSize,lldb::addr_t LocalSize,llvm::StringRef ProgramString)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