[Lldb-commits] [lldb] r369892 - Breakpad: Add support for parsing STACK WIN records
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Mon Aug 26 04:25:28 PDT 2019
Author: labath
Date: Mon Aug 26 04:25:28 2019
New Revision: 369892
URL: http://llvm.org/viewvc/llvm-project?rev=369892&view=rev
Log:
Breakpad: Add support for parsing STACK WIN records
Summary: The fields that aren't useful for us right now are simply ignored.
Reviewers: amccarth, markmentovai
Subscribers: rnk, lldb-commits
Differential Revision: https://reviews.llvm.org/D66633
Modified:
lldb/trunk/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
lldb/trunk/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
lldb/trunk/unittests/ObjectFile/Breakpad/BreakpadRecordsTest.cpp
Modified: lldb/trunk/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp?rev=369892&r1=369891&r2=369892&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp Mon Aug 26 04:25:28 2019
@@ -16,7 +16,19 @@ using namespace lldb_private;
using namespace lldb_private::breakpad;
namespace {
-enum class Token { Unknown, Module, Info, CodeID, File, Func, Public, Stack, CFI, Init };
+enum class Token {
+ Unknown,
+ Module,
+ Info,
+ CodeID,
+ File,
+ Func,
+ Public,
+ Stack,
+ CFI,
+ Init,
+ Win,
+};
}
template<typename T>
@@ -33,6 +45,7 @@ template <> Token stringTo<Token>(llvm::
.Case("STACK", Token::Stack)
.Case("CFI", Token::CFI)
.Case("INIT", Token::Init)
+ .Case("WIN", Token::Win)
.Default(Token::Unknown);
}
@@ -127,6 +140,8 @@ llvm::Optional<Record::Kind> Record::cla
switch (Tok) {
case Token::CFI:
return Record::StackCFI;
+ case Token::Win:
+ return Record::StackWin;
default:
return llvm::None;
}
@@ -134,13 +149,13 @@ llvm::Optional<Record::Kind> Record::cla
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
- // hex number. CODE_ID should never be at the start of a line, but if it
- // is, it can be treated the same way as a garbled line record.
+ // hex number.
return Record::Line;
case Token::CodeID:
case Token::CFI:
case Token::Init:
+ case Token::Win:
// These should never appear at the start of a valid record.
return llvm::None;
}
@@ -390,6 +405,81 @@ llvm::raw_ostream &breakpad::operator<<(
return OS << " " << R.UnwindRules;
}
+llvm::Optional<StackWinRecord> StackWinRecord::parse(llvm::StringRef Line) {
+ // STACK WIN type rva code_size prologue_size epilogue_size parameter_size
+ // saved_register_size local_size max_stack_size has_program_string
+ // program_string_OR_allocates_base_pointer
+
+ if (consume<Token>(Line) != Token::Stack)
+ return llvm::None;
+ if (consume<Token>(Line) != Token::Win)
+ return llvm::None;
+
+ llvm::StringRef Str;
+ uint8_t Type;
+ std::tie(Str, Line) = getToken(Line);
+ // Right now we only support the "FrameData" frame type.
+ if (!to_integer(Str, Type) || FrameType(Type) != FrameType::FrameData)
+ return llvm::None;
+
+ lldb::addr_t RVA;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, RVA, 16))
+ return llvm::None;
+
+ lldb::addr_t CodeSize;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, CodeSize, 16))
+ return llvm::None;
+
+ // Skip fields which we aren't using right now.
+ std::tie(Str, Line) = getToken(Line); // prologue_size
+ std::tie(Str, Line) = getToken(Line); // epilogue_size
+
+ lldb::addr_t ParameterSize;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, ParameterSize, 16))
+ return llvm::None;
+
+ lldb::addr_t SavedRegisterSize;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, SavedRegisterSize, 16))
+ return llvm::None;
+
+ lldb::addr_t LocalSize;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, LocalSize, 16))
+ return llvm::None;
+
+ std::tie(Str, Line) = getToken(Line); // max_stack_size
+
+ uint8_t HasProgramString;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, HasProgramString))
+ return llvm::None;
+ // FrameData records should always have a program string.
+ if (!HasProgramString)
+ return llvm::None;
+
+ return StackWinRecord(RVA, CodeSize, ParameterSize, SavedRegisterSize,
+ LocalSize, Line.trim());
+}
+
+bool breakpad::operator==(const StackWinRecord &L, const StackWinRecord &R) {
+ return L.RVA == R.RVA && L.CodeSize == R.CodeSize &&
+ L.ParameterSize == R.ParameterSize &&
+ L.SavedRegisterSize == R.SavedRegisterSize &&
+ L.LocalSize == R.LocalSize && L.ProgramString == R.ProgramString;
+}
+
+llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS,
+ const StackWinRecord &R) {
+ return OS << llvm::formatv(
+ "STACK WIN 4 {0:x-} {1:x-} ? ? {2} {3} {4} ? 1 {5}", R.RVA,
+ R.CodeSize, R.ParameterSize, R.SavedRegisterSize, R.LocalSize,
+ R.ProgramString);
+}
+
llvm::StringRef breakpad::toString(Record::Kind K) {
switch (K) {
case Record::Module:
@@ -406,6 +496,8 @@ llvm::StringRef breakpad::toString(Recor
return "PUBLIC";
case Record::StackCFI:
return "STACK CFI";
+ case Record::StackWin:
+ return "STACK WIN";
}
llvm_unreachable("Unknown record kind!");
}
Modified: lldb/trunk/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h?rev=369892&r1=369891&r2=369892&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h Mon Aug 26 04:25:28 2019
@@ -20,7 +20,7 @@ namespace breakpad {
class Record {
public:
- enum Kind { Module, Info, File, Func, Line, Public, StackCFI };
+ enum Kind { Module, Info, File, Func, 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
@@ -157,6 +157,29 @@ public:
bool operator==(const StackCFIRecord &L, const StackCFIRecord &R);
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackCFIRecord &R);
+class StackWinRecord : public Record {
+public:
+ static llvm::Optional<StackWinRecord> parse(llvm::StringRef Line);
+
+ StackWinRecord(lldb::addr_t RVA, lldb::addr_t CodeSize,
+ lldb::addr_t ParameterSize, lldb::addr_t SavedRegisterSize,
+ lldb::addr_t LocalSize, llvm::StringRef ProgramString)
+ : Record(StackWin), RVA(RVA), CodeSize(CodeSize),
+ ParameterSize(ParameterSize), SavedRegisterSize(SavedRegisterSize),
+ LocalSize(LocalSize), ProgramString(ProgramString) {}
+
+ enum class FrameType : uint8_t { FPO = 0, FrameData = 4 };
+ lldb::addr_t RVA;
+ lldb::addr_t CodeSize;
+ lldb::addr_t ParameterSize;
+ lldb::addr_t SavedRegisterSize;
+ lldb::addr_t LocalSize;
+ llvm::StringRef ProgramString;
+};
+
+bool operator==(const StackWinRecord &L, const StackWinRecord &R);
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackWinRecord &R);
+
} // namespace breakpad
} // namespace lldb_private
Modified: lldb/trunk/unittests/ObjectFile/Breakpad/BreakpadRecordsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/ObjectFile/Breakpad/BreakpadRecordsTest.cpp?rev=369892&r1=369891&r2=369892&view=diff
==============================================================================
--- lldb/trunk/unittests/ObjectFile/Breakpad/BreakpadRecordsTest.cpp (original)
+++ lldb/trunk/unittests/ObjectFile/Breakpad/BreakpadRecordsTest.cpp Mon Aug 26 04:25:28 2019
@@ -20,6 +20,7 @@ TEST(Record, classify) {
EXPECT_EQ(Record::Func, Record::classify("FUNC"));
EXPECT_EQ(Record::Public, Record::classify("PUBLIC"));
EXPECT_EQ(Record::StackCFI, Record::classify("STACK CFI"));
+ EXPECT_EQ(Record::StackWin, Record::classify("STACK WIN"));
// Any obviously incorrect lines will be classified as such.
EXPECT_EQ(llvm::None, Record::classify("STACK"));
@@ -119,3 +120,34 @@ TEST(StackCFIRecord, parse) {
EXPECT_EQ(llvm::None, StackCFIRecord::parse("FILE 47 foo"));
EXPECT_EQ(llvm::None, StackCFIRecord::parse("42 47"));
}
+
+TEST(StackWinRecord, parse) {
+ EXPECT_EQ(
+ StackWinRecord(0x47, 0x8, 3, 4, 5, llvm::StringRef("$eip $esp ^ =")),
+ StackWinRecord::parse("STACK WIN 4 47 8 1 2 3 4 5 6 1 $eip $esp ^ ="));
+
+ EXPECT_EQ(llvm::None, StackWinRecord::parse(
+ "STACK WIN 0 47 8 1 0 0 0 0 0 1 $eip $esp ^ ="));
+ EXPECT_EQ(llvm::None,
+ StackWinRecord::parse("STACK WIN 4 47 8 1 0 0 0 0 0 0 1"));
+ EXPECT_EQ(llvm::None, StackWinRecord::parse(
+ "STACK WIN 3 47 8 1 0 0 0 0 0 1 $eip $esp ^ ="));
+ EXPECT_EQ(llvm::None,
+ StackWinRecord::parse("STACK WIN 3 47 8 1 0 0 0 0 0 0 1"));
+ EXPECT_EQ(llvm::None, StackWinRecord::parse(
+ "STACK WIN 4 47 8 1 0 0 0 0 1 $eip $esp ^ ="));
+ EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0 0 0 0 0"));
+ EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0 0 0 0"));
+ EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0 0 0"));
+ EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0 0"));
+ EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0"));
+ EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1"));
+ EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8"));
+ EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47"));
+ EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4"));
+ EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN"));
+ EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK"));
+ EXPECT_EQ(llvm::None, StackWinRecord::parse(""));
+ EXPECT_EQ(llvm::None, StackCFIRecord::parse("FILE 47 foo"));
+ EXPECT_EQ(llvm::None, StackCFIRecord::parse("42 47"));
+}
More information about the lldb-commits
mailing list