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