diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-11-19 20:06:13 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-11-19 20:06:13 +0000 |
| commit | c0981da47d5696fe36474fcf86b4ce03ae3ff818 (patch) | |
| tree | f42add1021b9f2ac6a69ac7cf6c4499962739a45 /lldb/source/Plugins/ObjectFile/Breakpad | |
| parent | 344a3780b2e33f6ca763666c380202b18aab72a3 (diff) | |
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/Breakpad')
4 files changed, 140 insertions, 18 deletions
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp index bd8eeedce57d..24941be515de 100644 --- a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp +++ b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp @@ -23,6 +23,8 @@ enum class Token { CodeID, File, Func, + Inline, + InlineOrigin, Public, Stack, CFI, @@ -41,6 +43,8 @@ template <> Token stringTo<Token>(llvm::StringRef Str) { .Case("CODE_ID", Token::CodeID) .Case("FILE", Token::File) .Case("FUNC", Token::Func) + .Case("INLINE", Token::Inline) + .Case("INLINE_ORIGIN", Token::InlineOrigin) .Case("PUBLIC", Token::Public) .Case("STACK", Token::Stack) .Case("CFI", Token::CFI) @@ -145,7 +149,10 @@ llvm::Optional<Record::Kind> Record::classify(llvm::StringRef Line) { default: return llvm::None; } - + case Token::Inline: + return Record::Inline; + case Token::InlineOrigin: + return Record::InlineOrigin; case Token::Unknown: // Optimistically assume that any unrecognised token means this is a line // record, those don't have a special keyword and start directly with a @@ -216,9 +223,11 @@ llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, return OS << "INFO CODE_ID " << R.ID.GetAsString(); } -llvm::Optional<FileRecord> FileRecord::parse(llvm::StringRef Line) { - // FILE number name - if (consume<Token>(Line) != Token::File) +template <typename T> +static llvm::Optional<T> parseNumberName(llvm::StringRef Line, + Token TokenType) { + // TOKEN number name + if (consume<Token>(Line) != TokenType) return llvm::None; llvm::StringRef Str; @@ -231,7 +240,12 @@ llvm::Optional<FileRecord> FileRecord::parse(llvm::StringRef Line) { if (Name.empty()) return llvm::None; - return FileRecord(Number, Name); + return T(Number, Name); +} + +llvm::Optional<FileRecord> FileRecord::parse(llvm::StringRef Line) { + // FILE number name + return parseNumberName<FileRecord>(Line, Token::File); } llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, @@ -239,6 +253,17 @@ llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, return OS << "FILE " << R.Number << " " << R.Name; } +llvm::Optional<InlineOriginRecord> +InlineOriginRecord::parse(llvm::StringRef Line) { + // INLINE_ORIGIN number name + return parseNumberName<InlineOriginRecord>(Line, Token::InlineOrigin); +} + +llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, + const InlineOriginRecord &R) { + return OS << "INLINE_ORIGIN " << R.Number << " " << R.Name; +} + static bool parsePublicOrFunc(llvm::StringRef Line, bool &Multiple, lldb::addr_t &Address, lldb::addr_t *Size, lldb::addr_t &ParamSize, llvm::StringRef &Name) { @@ -299,6 +324,58 @@ llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, R.ParamSize, R.Name); } +llvm::Optional<InlineRecord> InlineRecord::parse(llvm::StringRef Line) { + // INLINE inline_nest_level call_site_line call_site_file_num origin_num + // [address size]+ + if (consume<Token>(Line) != Token::Inline) + return llvm::None; + + llvm::SmallVector<llvm::StringRef> Tokens; + SplitString(Line, Tokens, " "); + if (Tokens.size() < 6 || Tokens.size() % 2 == 1) + return llvm::None; + + size_t InlineNestLevel; + uint32_t CallSiteLineNum; + size_t CallSiteFileNum; + size_t OriginNum; + if (!(to_integer(Tokens[0], InlineNestLevel) && + to_integer(Tokens[1], CallSiteLineNum) && + to_integer(Tokens[2], CallSiteFileNum) && + to_integer(Tokens[3], OriginNum))) + return llvm::None; + + InlineRecord Record = InlineRecord(InlineNestLevel, CallSiteLineNum, + CallSiteFileNum, OriginNum); + for (size_t i = 4; i < Tokens.size(); i += 2) { + lldb::addr_t Address; + if (!to_integer(Tokens[i], Address, 16)) + return llvm::None; + lldb::addr_t Size; + if (!to_integer(Tokens[i + 1].trim(), Size, 16)) + return llvm::None; + Record.Ranges.emplace_back(Address, Size); + } + return Record; +} + +bool breakpad::operator==(const InlineRecord &L, const InlineRecord &R) { + return L.InlineNestLevel == R.InlineNestLevel && + L.CallSiteLineNum == R.CallSiteLineNum && + L.CallSiteFileNum == R.CallSiteFileNum && L.OriginNum == R.OriginNum && + L.Ranges == R.Ranges; +} + +llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, + const InlineRecord &R) { + OS << llvm::formatv("INLINE {0} {1} {2} {3}", R.InlineNestLevel, + R.CallSiteLineNum, R.CallSiteFileNum, R.OriginNum); + for (const auto &range : R.Ranges) { + OS << llvm::formatv(" {0:x-} {1:x-}", range.first, range.second); + } + return OS; +} + llvm::Optional<LineRecord> LineRecord::parse(llvm::StringRef Line) { lldb::addr_t Address; llvm::StringRef Str; @@ -490,6 +567,10 @@ llvm::StringRef breakpad::toString(Record::Kind K) { return "FILE"; case Record::Func: return "FUNC"; + case Record::Inline: + return "INLINE"; + case Record::InlineOrigin: + return "INLINE_ORIGIN"; case Record::Line: return "LINE"; case Record::Public: diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h index 1620a1210b84..8a11323d521c 100644 --- a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h +++ b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h @@ -20,7 +20,18 @@ namespace breakpad { class Record { public: - enum Kind { Module, Info, File, Func, Line, Public, StackCFI, StackWin }; + enum Kind { + Module, + Info, + File, + Func, + Inline, + InlineOrigin, + Line, + Public, + StackCFI, + StackWin + }; /// Attempt to guess the kind of the record present in the argument without /// doing a full parse. The returned kind will always be correct for valid @@ -89,6 +100,23 @@ inline bool operator==(const FileRecord &L, const FileRecord &R) { } llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const FileRecord &R); +class InlineOriginRecord : public Record { +public: + static llvm::Optional<InlineOriginRecord> parse(llvm::StringRef Line); + InlineOriginRecord(size_t Number, llvm::StringRef Name) + : Record(InlineOrigin), Number(Number), Name(Name) {} + + size_t Number; + llvm::StringRef Name; +}; + +inline bool operator==(const InlineOriginRecord &L, + const InlineOriginRecord &R) { + return L.Number == R.Number && L.Name == R.Name; +} +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, + const InlineOriginRecord &R); + class FuncRecord : public Record { public: static llvm::Optional<FuncRecord> parse(llvm::StringRef Line); @@ -107,6 +135,26 @@ public: bool operator==(const FuncRecord &L, const FuncRecord &R); llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const FuncRecord &R); +class InlineRecord : public Record { +public: + static llvm::Optional<InlineRecord> parse(llvm::StringRef Line); + InlineRecord(size_t InlineNestLevel, uint32_t CallSiteLineNum, + size_t CallSiteFileNum, size_t OriginNum) + : Record(Inline), InlineNestLevel(InlineNestLevel), + CallSiteLineNum(CallSiteLineNum), CallSiteFileNum(CallSiteFileNum), + OriginNum(OriginNum) {} + + size_t InlineNestLevel; + uint32_t CallSiteLineNum; + size_t CallSiteFileNum; + size_t OriginNum; + // A vector of address range covered by this inline + std::vector<std::pair<lldb::addr_t, lldb::addr_t>> Ranges; +}; + +bool operator==(const InlineRecord &L, const InlineRecord &R); +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const InlineRecord &R); + class LineRecord : public Record { public: static llvm::Optional<LineRecord> parse(llvm::StringRef Line); diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp index 7a9163ddb880..bad730512ff4 100644 --- a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp +++ b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp @@ -56,11 +56,6 @@ void ObjectFileBreakpad::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -ConstString ObjectFileBreakpad::GetPluginNameStatic() { - static ConstString g_name("breakpad"); - return g_name; -} - ObjectFile *ObjectFileBreakpad::CreateInstance( const ModuleSP &module_sp, DataBufferSP &data_sp, offset_t data_offset, const FileSpec *file, offset_t file_offset, offset_t length) { @@ -153,9 +148,9 @@ void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) { std::tie(line, text) = text.split('\n'); llvm::Optional<Record::Kind> next_section = Record::classify(line); - if (next_section == Record::Line) { - // Line records logically belong to the preceding Func record, so we put - // them in the same section. + if (next_section == Record::Line || next_section == Record::Inline) { + // Line/Inline records logically belong to the preceding Func record, so + // we put them in the same section. next_section = Record::Func; } if (next_section == current_section) diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h index 8724feaa422d..c320c7ad3e2e 100644 --- a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h +++ b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h @@ -21,7 +21,7 @@ public: static void Initialize(); static void Terminate(); - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "breakpad"; } static const char *GetPluginDescriptionStatic() { return "Breakpad object file reader."; } @@ -44,9 +44,7 @@ public: ModuleSpecList &specs); // PluginInterface protocol - ConstString GetPluginName() override { return GetPluginNameStatic(); } - - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } // LLVM RTTI support static char ID; |
