[Lldb-commits] [lldb] r371017 - Breakpad: Basic support for STACK WIN unwinding

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Thu Sep 5 00:05:15 PDT 2019


Author: labath
Date: Thu Sep  5 00:05:15 2019
New Revision: 371017

URL: http://llvm.org/viewvc/llvm-project?rev=371017&view=rev
Log:
Breakpad: Basic support for STACK WIN unwinding

Summary:
This patch makes it possible to unwind via breakpad STACK WIN records.
It is "basic" because two important features are missing:
- support for the .raSearch keyword
- support for multiple STACK WIN records within a single function
Right now, we just reject the .raSearch records, and always pick the
first record for the whole function
SymbolFileBreakpad, and so I think it can serve as a good example of
what is needed of the symbol file and unwinding machinery to make this
work.

However, it is already useful for unwinding in some situations, and it
sets up the general framework for the parsing of these kinds of records,
which reduces the size of the followup patches implementing the two
other components.

Reviewers: amccarth, rnk, markmentovai

Subscribers: lldb-commits

Differential Revision: https://reviews.llvm.org/D67067

Added:
    lldb/trunk/lit/SymbolFile/Breakpad/Inputs/unwind-via-stack-win.syms
    lldb/trunk/lit/SymbolFile/Breakpad/Inputs/unwind-via-stack-win.yaml
    lldb/trunk/lit/SymbolFile/Breakpad/unwind-via-stack-win.test
Modified:
    lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
    lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h

Added: lldb/trunk/lit/SymbolFile/Breakpad/Inputs/unwind-via-stack-win.syms
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/Breakpad/Inputs/unwind-via-stack-win.syms?rev=371017&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/Breakpad/Inputs/unwind-via-stack-win.syms (added)
+++ lldb/trunk/lit/SymbolFile/Breakpad/Inputs/unwind-via-stack-win.syms Thu Sep  5 00:05:15 2019
@@ -0,0 +1,17 @@
+MODULE windows x86 897DD83EA8C8411897F3A925EE4BF7411 unwind-via-stack-win.pdb
+INFO CODE_ID 5D499B5C5000 unwind-via-stack-win.exe
+PUBLIC  0 0 dummy
+PUBLIC 10 0 call_many
+PUBLIC 80 0 main
+PUBLIC 90 0 many_pointer_args
+PUBLIC 100 0 bogus_rule
+PUBLIC 110 0 bogus_cfa_rhs
+PUBLIC 120 0 bogus_esp_rhs
+PUBLIC 130 0 temporary_var
+STACK WIN 4 10 6d 0 0 0 0 0 0 1 $T0 $esp 80 + = $eip $T0 ^ = $esp $T0 4 + =
+STACK WIN 4 80 8 0 0 0 0 0 0 1 $T0 $esp = $eip $T0 ^ = $esp $T0 4 + =
+STACK WIN 4 90 5 0 0 50 0 0 0 1 $T0 $esp = $eip $T0 ^ = $esp $T0 4 + =
+STACK WIN 4 100 4 0 0 0 0 0 0 1 bogus
+STACK WIN 4 110 4 0 0 0 0 0 0 1 $T0 $bogus = $eip $T0 ^ = $esp $T0 4 + =
+STACK WIN 4 120 4 0 0 0 0 0 0 1 $T0 $esp = $eip $T0 ^ = $esp $bogus 4 + =
+STACK WIN 4 130 4 0 0 0 0 0 0 1 $T0 $esp = $bogus $T0 = $eip $bogus ^ = $esp $T0 4 + =

Added: lldb/trunk/lit/SymbolFile/Breakpad/Inputs/unwind-via-stack-win.yaml
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/Breakpad/Inputs/unwind-via-stack-win.yaml?rev=371017&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/Breakpad/Inputs/unwind-via-stack-win.yaml (added)
+++ lldb/trunk/lit/SymbolFile/Breakpad/Inputs/unwind-via-stack-win.yaml Thu Sep  5 00:05:15 2019
@@ -0,0 +1,35 @@
+--- !minidump
+Streams:
+  - Type:            ThreadList
+    Threads:
+      - Thread Id:       0x0000290C
+        Priority Class:  0x00000020
+        Environment Block: 0x0000000000A98000
+        Context:         3F0001000000000000000000000000000000000000000000000000007F02000000000000FFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002B000000530000002B0000002B00000080100B0080100B000050A90080100B0080100B0000000000E4FECF0092100B0023000000440301007CFECF002B0000007F0200000000000000000000000000000000000000000000801F0000FFFF020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000144E3D6C2000000001000000EA1E00F4C000E50700000000FC0100002CE3C014D8E202010000E507880F401D839DC60100000000400000007F00000000000000880F401D0A000000900F401D0000000000000100EA1E00009808E5077F00000000000000000000009008E507990100006002E5072CABC87708346474B42300000100000044E3C014200000000000000020532777A80F401D4F346474D00F401D6F378CCC5C4CD5010000000000000000000000000000000000000000000000003AFCD72F90E3C01418CE3470B4230000B80F401DC00F401DC80F401DD00F401D
+        Stack:
+          Start of Memory Range: 0x0000000000CFFE78
+          Content:         0000000079100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0085100B0094842777
+  - Type:            ModuleList
+    Modules:
+      - Base of Image:   0x00000000000B1000
+        Size of Image:   0x00004000
+        Module Name:     'unwind-via-stack-win.exe'
+        CodeView Record: 525344533ED87D89C8A8184197F3A925EE4BF74101000000433A5C70726F6A656374735C746573745F6170705C436F6E736F6C654170706C69636174696F6E315C44656275675C436F6E736F6C654170706C69636174696F6E312E70646200
+      - Base of Image:   0x0000000077260000
+        Size of Image:   0x000E0000
+        Module Name:     'C:\Windows\System32\kernel32.dll'
+        CodeView Record: 5253445300F90A57CF8DED8A463A90390318CD4401000000776B65726E656C33322EFFFFFFFF
+  - Type:            MemoryList
+    Memory Ranges:
+      - Start of Memory Range: 0x0000000000CFFE78
+        Content:         0000000079100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0000100B0085100B0094842777
+  - Type:            SystemInfo
+    Processor Arch:  X86
+    Platform ID:     Win32NT
+    CPU:
+      Vendor ID:       AuthenticAMD
+      Version Info:    0x00800F82
+      Feature Info:    0x178BFBFF
+  - Type:            MiscInfo
+    Content:         54050000F703000008290000C883495D0000000000000000AC0D000098080000AC0D00000200000002000000002000000D0000000000000002000000C4FFFFFF430065006E007400720061006C0020004500750072006F007000650020005300740061006E0064006100720064002000540069006D006500000000000000000000000A0000000500030000000000000000000000430065006E007400720061006C0020004500750072006F00700065002000530075006D006D00650072002000540069006D00650000000000000000000000000000000300000005000200000000000000C4FFFFFF310037003100330034002E0031002E007800380036006600720065002E007200730034005F00720065006C0065006100730065002E003100380030003400310030002D00310038003000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064006200670063006F00720065002E0069003300380036002C00310030002E0030002E00310037003100330034002E0031000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C816B92
+...

Added: lldb/trunk/lit/SymbolFile/Breakpad/unwind-via-stack-win.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/Breakpad/unwind-via-stack-win.test?rev=371017&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/Breakpad/unwind-via-stack-win.test (added)
+++ lldb/trunk/lit/SymbolFile/Breakpad/unwind-via-stack-win.test Thu Sep  5 00:05:15 2019
@@ -0,0 +1,54 @@
+# RUN: yaml2obj %S/Inputs/unwind-via-stack-win.yaml > %t
+# RUN: %lldb -c %t \
+# RUN:   -o "target symbols add %S/Inputs/unwind-via-stack-win.syms" \
+# RUN:   -s %s -b | FileCheck %s
+
+# First check that unwind plan generation works correctly.
+# This function has a "typical" unwind rule.
+image show-unwind -n call_many
+# CHECK-LABEL: image show-unwind -n call_many
+# CHECK: UNWIND PLANS for unwind-via-stack-win.exe`call_many
+# CHECK: Symbol file UnwindPlan:
+# CHECK: This UnwindPlan originally sourced from breakpad STACK WIN
+# CHECK: This UnwindPlan is sourced from the compiler: yes.
+# CHECK: This UnwindPlan is valid at all instruction locations: no.
+# CHECK: Address range of this UnwindPlan: [unwind-via-stack-win.exe..module_image + 16-0x0000007d)
+# CHECK: row[0]:    0: CFA=DW_OP_breg7 +0, DW_OP_consts +80, DW_OP_plus  => esp=DW_OP_pick 0x00, DW_OP_consts +4, DW_OP_plus  eip=DW_OP_pick 0x00, DW_OP_deref
+
+# Then, some invalid rules.
+image show-unwind -n bogus_rule
+# CHECK-LABEL: image show-unwind -n bogus_rule
+# CHECK: UNWIND PLANS for unwind-via-stack-win.exe`bogus_rule
+# CHECK-NOT: Symbol file
+
+image show-unwind -n bogus_cfa_rhs
+# CHECK-LABEL: image show-unwind -n bogus_cfa_rhs
+# CHECK: UNWIND PLANS for unwind-via-stack-win.exe`bogus_cfa_rhs
+# CHECK-NOT: Symbol file
+
+image show-unwind -n bogus_esp_rhs
+# CHECK-LABEL: image show-unwind -n bogus_esp_rhs
+# CHECK: UNWIND PLANS for unwind-via-stack-win.exe`bogus_esp_rhs
+# CHECK-NOT: Symbol file
+
+# We don't treat unknown lhs as an error, as it can be just a temporary
+# variable used in other rules.
+image show-unwind -n temporary_var
+# CHECK-LABEL: image show-unwind -n temporary_var
+# CHECK: UNWIND PLANS for unwind-via-stack-win.exe`temporary_var
+# CHECK: Symbol file UnwindPlan:
+# CHECK: This UnwindPlan originally sourced from breakpad STACK WIN
+# CHECK: This UnwindPlan is sourced from the compiler: yes.
+# CHECK: This UnwindPlan is valid at all instruction locations: no.
+# CHECK: Address range of this UnwindPlan: [unwind-via-stack-win.exe..module_image + 304-0x00000134)
+# CHECK: row[0]:    0: CFA=DW_OP_breg7 +0 => esp=DW_OP_pick 0x00, DW_OP_consts +4, DW_OP_plus  eip=DW_OP_pick 0x00, DW_OP_deref
+
+# And finally, check that backtracing works as a whole by unwinding a simple
+# stack.
+thread backtrace
+# CHECK-LABEL: thread backtrace
+# CHECK: frame #0: 0x000b1092 unwind-via-stack-win.exe`many_pointer_args
+# CHECK: frame #1: 0x000b1079 unwind-via-stack-win.exe`call_many + 105
+# CHECK: frame #2: 0x000b1085 unwind-via-stack-win.exe`main + 5
+# CHECK: frame #3: 0x77278494 kernel32.dll
+# CHECK-NOT: frame

Modified: lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp?rev=371017&r1=371016&r2=371017&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp Thu Sep  5 00:05:15 2019
@@ -15,7 +15,6 @@
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/PostfixExpression.h"
 #include "lldb/Symbol/SymbolVendor.h"
 #include "lldb/Symbol/TypeMap.h"
 #include "lldb/Utility/Log.h"
@@ -421,7 +420,17 @@ ResolveRegisterOrRA(const SymbolFile::Re
   return ResolveRegister(resolver, name);
 }
 
-bool SymbolFileBreakpad::ParseUnwindRow(llvm::StringRef unwind_rules,
+llvm::ArrayRef<uint8_t> SymbolFileBreakpad::SaveAsDWARF(postfix::Node &node) {
+  ArchSpec arch = m_objfile_sp->GetArchitecture();
+  StreamString dwarf(Stream::eBinary, arch.GetAddressByteSize(),
+                     arch.GetByteOrder());
+  ToDWARF(node, dwarf);
+  uint8_t *saved = m_allocator.Allocate<uint8_t>(dwarf.GetSize());
+  std::memcpy(saved, dwarf.GetData(), dwarf.GetSize());
+  return {saved, dwarf.GetSize()};
+}
+
+bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules,
                                         const RegisterInfoResolver &resolver,
                                         UnwindPlan::Row &row) {
   Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
@@ -454,18 +463,12 @@ bool SymbolFileBreakpad::ParseUnwindRow(
       return false;
     }
 
-    ArchSpec arch = m_objfile_sp->GetArchitecture();
-    StreamString dwarf(Stream::eBinary, arch.GetAddressByteSize(),
-                       arch.GetByteOrder());
-    ToDWARF(*rhs, dwarf);
-    uint8_t *saved = m_allocator.Allocate<uint8_t>(dwarf.GetSize());
-    std::memcpy(saved, dwarf.GetData(), dwarf.GetSize());
-
+    llvm::ArrayRef<uint8_t> saved = SaveAsDWARF(*rhs);
     if (lhs == ".cfa") {
-      row.GetCFAValue().SetIsDWARFExpression(saved, dwarf.GetSize());
+      row.GetCFAValue().SetIsDWARFExpression(saved.data(), saved.size());
     } else if (const RegisterInfo *info = ResolveRegisterOrRA(resolver, lhs)) {
       UnwindPlan::Row::RegisterLocation loc;
-      loc.SetIsDWARFExpression(saved, dwarf.GetSize());
+      loc.SetIsDWARFExpression(saved.data(), saved.size());
       row.SetRegisterInfo(info->kinds[eRegisterKindLLDB], loc);
     } else
       LLDB_LOG(log, "Invalid register `{0}` in unwind rule.", lhs);
@@ -481,20 +484,27 @@ UnwindPlanSP
 SymbolFileBreakpad::GetUnwindPlan(const Address &address,
                                   const RegisterInfoResolver &resolver) {
   ParseUnwindData();
-  const UnwindMap::Entry *entry =
-      m_unwind_data->FindEntryThatContains(address.GetFileAddress());
-  if (!entry)
-    return nullptr;
+  if (auto *entry =
+          m_unwind_data->cfi.FindEntryThatContains(address.GetFileAddress()))
+    return ParseCFIUnwindPlan(entry->data, resolver);
+  if (auto *entry =
+          m_unwind_data->win.FindEntryThatContains(address.GetFileAddress()))
+    return ParseWinUnwindPlan(entry->data, resolver);
+  return nullptr;
+}
 
+UnwindPlanSP
+SymbolFileBreakpad::ParseCFIUnwindPlan(const Bookmark &bookmark,
+                                       const RegisterInfoResolver &resolver) {
   addr_t base = GetBaseFileAddress();
   if (base == LLDB_INVALID_ADDRESS)
     return nullptr;
 
-  LineIterator It(*m_objfile_sp, Record::StackCFI, entry->data),
+  LineIterator It(*m_objfile_sp, Record::StackCFI, bookmark),
       End(*m_objfile_sp);
   llvm::Optional<StackCFIRecord> init_record = StackCFIRecord::parse(*It);
-  assert(init_record.hasValue());
-  assert(init_record->Size.hasValue());
+  assert(init_record.hasValue() && init_record->Size.hasValue() &&
+         "Record already parsed successfully in ParseUnwindData!");
 
   auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindLLDB);
   plan_sp->SetSourceName("breakpad STACK CFI");
@@ -507,7 +517,7 @@ SymbolFileBreakpad::GetUnwindPlan(const
 
   auto row_sp = std::make_shared<UnwindPlan::Row>();
   row_sp->SetOffset(0);
-  if (!ParseUnwindRow(init_record->UnwindRules, resolver, *row_sp))
+  if (!ParseCFIUnwindRow(init_record->UnwindRules, resolver, *row_sp))
     return nullptr;
   plan_sp->AppendRow(row_sp);
   for (++It; It != End; ++It) {
@@ -519,13 +529,98 @@ SymbolFileBreakpad::GetUnwindPlan(const
 
     row_sp = std::make_shared<UnwindPlan::Row>(*row_sp);
     row_sp->SetOffset(record->Address - init_record->Address);
-    if (!ParseUnwindRow(record->UnwindRules, resolver, *row_sp))
+    if (!ParseCFIUnwindRow(record->UnwindRules, resolver, *row_sp))
       return nullptr;
     plan_sp->AppendRow(row_sp);
   }
   return plan_sp;
 }
 
+UnwindPlanSP
+SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark,
+                                       const RegisterInfoResolver &resolver) {
+  Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
+  addr_t base = GetBaseFileAddress();
+  if (base == LLDB_INVALID_ADDRESS)
+    return nullptr;
+
+  LineIterator It(*m_objfile_sp, Record::StackWin, bookmark);
+  llvm::Optional<StackWinRecord> record = StackWinRecord::parse(*It);
+  assert(record.hasValue() &&
+         "Record already parsed successfully in ParseUnwindData!");
+
+  auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindLLDB);
+  plan_sp->SetSourceName("breakpad STACK WIN");
+  plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+  plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
+  plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
+  plan_sp->SetPlanValidAddressRange(
+      AddressRange(base + record->RVA, record->CodeSize,
+                   m_objfile_sp->GetModule()->GetSectionList()));
+
+  auto row_sp = std::make_shared<UnwindPlan::Row>();
+  row_sp->SetOffset(0);
+
+  llvm::BumpPtrAllocator node_alloc;
+  std::vector<std::pair<llvm::StringRef, postfix::Node *>> program =
+      postfix::ParseFPOProgram(record->ProgramString, node_alloc);
+
+  if (program.empty()) {
+    LLDB_LOG(log, "Invalid unwind rule: {0}.", record->ProgramString);
+    return nullptr;
+  }
+  auto it = program.begin();
+  const auto &symbol_resolver =
+      [&](postfix::SymbolNode &symbol) -> postfix::Node * {
+    llvm::StringRef name = symbol.GetName();
+    for (const auto &rule : llvm::make_range(program.begin(), it)) {
+      if (rule.first == name)
+        return rule.second;
+    }
+    if (const RegisterInfo *info = ResolveRegister(resolver, name))
+      return postfix::MakeNode<postfix::RegisterNode>(
+          node_alloc, info->kinds[eRegisterKindLLDB]);
+    return nullptr;
+  };
+
+  // We assume the first value will be the CFA. It is usually called T0, but
+  // clang will use T1, if it needs to realign the stack.
+  if (!postfix::ResolveSymbols(it->second, symbol_resolver)) {
+    LLDB_LOG(log, "Resolving symbols in `{0}` failed.", record->ProgramString);
+    return nullptr;
+  }
+  llvm::ArrayRef<uint8_t> saved = SaveAsDWARF(*it->second);
+  row_sp->GetCFAValue().SetIsDWARFExpression(saved.data(), saved.size());
+
+  // Replace the node value with InitialValueNode, so that subsequent
+  // expressions refer to the CFA value instead of recomputing the whole
+  // expression.
+  it->second = postfix::MakeNode<postfix::InitialValueNode>(node_alloc);
+
+
+  // Now process the rest of the assignments.
+  for (++it; it != program.end(); ++it) {
+    const RegisterInfo *info = ResolveRegister(resolver, it->first);
+    // It is not an error if the resolution fails because the program may
+    // contain temporary variables.
+    if (!info)
+      continue;
+    if (!postfix::ResolveSymbols(it->second, symbol_resolver)) {
+      LLDB_LOG(log, "Resolving symbols in `{0}` failed.",
+               record->ProgramString);
+      return nullptr;
+    }
+
+    llvm::ArrayRef<uint8_t> saved = SaveAsDWARF(*it->second);
+    UnwindPlan::Row::RegisterLocation loc;
+    loc.SetIsDWARFExpression(saved.data(), saved.size());
+    row_sp->SetRegisterInfo(info->kinds[eRegisterKindLLDB], loc);
+  }
+
+  plan_sp->AppendRow(row_sp);
+  return plan_sp;
+}
+
 addr_t SymbolFileBreakpad::GetBaseFileAddress() {
   return m_objfile_sp->GetModule()
       ->GetObjectFile()
@@ -633,8 +728,8 @@ void SymbolFileBreakpad::ParseLineTableA
 void SymbolFileBreakpad::ParseUnwindData() {
   if (m_unwind_data)
     return;
-
   m_unwind_data.emplace();
+
   Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
   addr_t base = GetBaseFileAddress();
   if (base == LLDB_INVALID_ADDRESS) {
@@ -646,10 +741,20 @@ void SymbolFileBreakpad::ParseUnwindData
        It != End; ++It) {
     if (auto record = StackCFIRecord::parse(*It)) {
       if (record->Size)
-        m_unwind_data->Append(UnwindMap::Entry(
+        m_unwind_data->cfi.Append(UnwindMap::Entry(
             base + record->Address, *record->Size, It.GetBookmark()));
     } else
       LLDB_LOG(log, "Failed to parse: {0}. Skipping record.", *It);
   }
-  m_unwind_data->Sort();
+  m_unwind_data->cfi.Sort();
+
+  for (LineIterator It(*m_objfile_sp, Record::StackWin), End(*m_objfile_sp);
+       It != End; ++It) {
+    if (auto record = StackWinRecord::parse(*It)) {
+      m_unwind_data->win.Append(UnwindMap::Entry(
+          base + record->RVA, record->CodeSize, It.GetBookmark()));
+    } else
+      LLDB_LOG(log, "Failed to parse: {0}. Skipping record.", *It);
+  }
+  m_unwind_data->win.Sort();
 }

Modified: lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h?rev=371017&r1=371016&r2=371017&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h Thu Sep  5 00:05:15 2019
@@ -12,6 +12,7 @@
 #include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h"
 #include "lldb/Core/FileSpecList.h"
 #include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/PostfixExpression.h"
 #include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/UnwindPlan.h"
 
@@ -204,9 +205,14 @@ private:
   void ParseCUData();
   void ParseLineTableAndSupportFiles(CompileUnit &cu, CompUnitData &data);
   void ParseUnwindData();
-  bool ParseUnwindRow(llvm::StringRef unwind_rules,
-                      const RegisterInfoResolver &resolver,
-                      UnwindPlan::Row &row);
+  llvm::ArrayRef<uint8_t> SaveAsDWARF(postfix::Node &node);
+  lldb::UnwindPlanSP ParseCFIUnwindPlan(const Bookmark &bookmark,
+                                        const RegisterInfoResolver &resolver);
+  bool ParseCFIUnwindRow(llvm::StringRef unwind_rules,
+                         const RegisterInfoResolver &resolver,
+                         UnwindPlan::Row &row);
+  lldb::UnwindPlanSP ParseWinUnwindPlan(const Bookmark &bookmark,
+                                        const RegisterInfoResolver &resolver);
 
   using CompUnitMap = RangeDataVector<lldb::addr_t, lldb::addr_t, CompUnitData>;
 
@@ -214,7 +220,11 @@ private:
   llvm::Optional<CompUnitMap> m_cu_data;
 
   using UnwindMap = RangeDataVector<lldb::addr_t, lldb::addr_t, Bookmark>;
-  llvm::Optional<UnwindMap> m_unwind_data;
+  struct UnwindData {
+    UnwindMap cfi;
+    UnwindMap win;
+  };
+  llvm::Optional<UnwindData> m_unwind_data;
   llvm::BumpPtrAllocator m_allocator;
 };
 




More information about the lldb-commits mailing list