[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