236 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H10#define LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H11 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 19namespace lldb_private {20namespace breakpad {21 22class Record {23public:24 enum Kind {25 Module,26 Info,27 File,28 Func,29 Inline,30 InlineOrigin,31 Line,32 Public,33 StackCFI,34 StackWin35 };36 37 /// Attempt to guess the kind of the record present in the argument without38 /// doing a full parse. The returned kind will always be correct for valid39 /// records, but the full parse can still fail in case of corrupted input.40 static std::optional<Kind> classify(llvm::StringRef Line);41 42protected:43 Record(Kind K) : TheKind(K) {}44 45 ~Record() = default;46 47public:48 Kind getKind() { return TheKind; }49 50private:51 Kind TheKind;52};53 54llvm::StringRef toString(Record::Kind K);55inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Record::Kind K) {56 OS << toString(K);57 return OS;58}59 60class ModuleRecord : public Record {61public: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 71inline bool operator==(const ModuleRecord &L, const ModuleRecord &R) {72 return L.OS == R.OS && L.Arch == R.Arch && L.ID == R.ID;73}74llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const ModuleRecord &R);75 76class InfoRecord : public Record {77public: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 84inline bool operator==(const InfoRecord &L, const InfoRecord &R) {85 return L.ID == R.ID;86}87llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const InfoRecord &R);88 89class FileRecord : public Record {90public: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 99inline bool operator==(const FileRecord &L, const FileRecord &R) {100 return L.Number == R.Number && L.Name == R.Name;101}102llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const FileRecord &R);103 104class InlineOriginRecord : public Record {105public: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 114inline bool operator==(const InlineOriginRecord &L,115 const InlineOriginRecord &R) {116 return L.Number == R.Number && L.Name == R.Name;117}118llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,119 const InlineOriginRecord &R);120 121class FuncRecord : public Record {122public: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 136bool operator==(const FuncRecord &L, const FuncRecord &R);137llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const FuncRecord &R);138 139class InlineRecord : public Record {140public: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 inline153 std::vector<std::pair<lldb::addr_t, lldb::addr_t>> Ranges;154};155 156bool operator==(const InlineRecord &L, const InlineRecord &R);157llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const InlineRecord &R);158 159class LineRecord : public Record {160public: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 173bool operator==(const LineRecord &L, const LineRecord &R);174llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const LineRecord &R);175 176class PublicRecord : public Record {177public: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 190bool operator==(const PublicRecord &L, const PublicRecord &R);191llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const PublicRecord &R);192 193class StackCFIRecord : public Record {194public: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 206bool operator==(const StackCFIRecord &L, const StackCFIRecord &R);207llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackCFIRecord &R);208 209class StackWinRecord : public Record {210public: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 229bool operator==(const StackWinRecord &L, const StackWinRecord &R);230llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackWinRecord &R);231 232} // namespace breakpad233} // namespace lldb_private234 235#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H236