| 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 | |