summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp')
-rw-r--r--lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp50
1 files changed, 40 insertions, 10 deletions
diff --git a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
index 4aa9fb634b61..1bc071c2b161 100644
--- a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
+++ b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
@@ -1,4 +1,4 @@
-//===-- UnwindAssemblyInstEmulation.cpp --------------------------*- C++-*-===//
+//===-- UnwindAssemblyInstEmulation.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -28,6 +28,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(UnwindAssemblyInstEmulation)
+
// UnwindAssemblyInstEmulation method definitions
bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
@@ -123,18 +125,12 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
// Add the initial state to the save list with offset 0.
saved_unwind_states.insert({0, {last_row, m_register_values}});
- // cache the pc register number (in whatever register numbering this
- // UnwindPlan uses) for quick reference during instruction parsing.
- RegisterInfo pc_reg_info;
- m_inst_emulator_up->GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc_reg_info);
-
- // cache the return address register number (in whatever register
+ // cache the stack pointer register number (in whatever register
// numbering this UnwindPlan uses) for quick reference during
// instruction parsing.
- RegisterInfo ra_reg_info;
+ RegisterInfo sp_reg_info;
m_inst_emulator_up->GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, ra_reg_info);
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp_reg_info);
// The architecture dependent condition code of the last processed
// instruction.
@@ -165,6 +161,23 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
*newrow = *it->second.first;
m_curr_row.reset(newrow);
m_register_values = it->second.second;
+ // re-set the CFA register ivars to match the
+ // new m_curr_row.
+ if (sp_reg_info.name &&
+ m_curr_row->GetCFAValue().IsRegisterPlusOffset()) {
+ uint32_t row_cfa_regnum =
+ m_curr_row->GetCFAValue().GetRegisterNumber();
+ lldb::RegisterKind row_kind =
+ m_unwind_plan_ptr->GetRegisterKind();
+ // set m_cfa_reg_info to the row's CFA reg.
+ m_inst_emulator_up->GetRegisterInfo(row_kind, row_cfa_regnum,
+ m_cfa_reg_info);
+ // set m_fp_is_cfa.
+ if (sp_reg_info.kinds[row_kind] == row_cfa_regnum)
+ m_fp_is_cfa = false;
+ else
+ m_fp_is_cfa = true;
+ }
}
m_inst_emulator_up->SetInstruction(inst->GetOpcode(),
@@ -195,6 +208,23 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
std::make_shared<UnwindPlan::Row>(*saved_state.first);
m_curr_row->SetOffset(current_offset);
m_register_values = saved_state.second;
+ // re-set the CFA register ivars to match the
+ // new m_curr_row.
+ if (sp_reg_info.name &&
+ m_curr_row->GetCFAValue().IsRegisterPlusOffset()) {
+ uint32_t row_cfa_regnum =
+ m_curr_row->GetCFAValue().GetRegisterNumber();
+ lldb::RegisterKind row_kind =
+ m_unwind_plan_ptr->GetRegisterKind();
+ // set m_cfa_reg_info to the row's CFA reg.
+ m_inst_emulator_up->GetRegisterInfo(row_kind, row_cfa_regnum,
+ m_cfa_reg_info);
+ // set m_fp_is_cfa.
+ if (sp_reg_info.kinds[row_kind] == row_cfa_regnum)
+ m_fp_is_cfa = false;
+ else
+ m_fp_is_cfa = true;
+ }
bool replace_existing =
true; // The last instruction might already
// created a row for this offset and