zequanwu created this revision.
zequanwu added reviewers: labath, clayborg, jasonmolenda.
Herald added subscribers: atanasyan, jrtc27, kbarton, nemanjai, sdardis.
Herald added a project: All.
zequanwu requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.
This adds stack scanning as fallback unwind plan to find a value that looks like
return address. If the return address is not valid, continue scanning from next
locatoin on stack when trying fallback unwind and the active row is `raSearch`.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D124198
Files:
lldb/include/lldb/Symbol/UnwindPlan.h
lldb/include/lldb/Target/ABI.h
lldb/include/lldb/Target/RegisterContextUnwind.h
lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
lldb/source/Plugins/ABI/ARC/ABISysV_arc.h
lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h
lldb/source/Plugins/ABI/ARM/ABISysV_arm.h
lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h
lldb/source/Plugins/ABI/Mips/ABISysV_mips.h
lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h
lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h
lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h
lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h
lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h
lldb/source/Plugins/ABI/X86/ABISysV_i386.h
lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h
lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp
lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h
lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
lldb/source/Symbol/UnwindPlan.cpp
lldb/source/Target/RegisterContextUnwind.cpp
lldb/test/Shell/SymbolFile/Breakpad/unwind-via-raSearch.test
Index: lldb/test/Shell/SymbolFile/Breakpad/unwind-via-raSearch.test
===================================================================
--- lldb/test/Shell/SymbolFile/Breakpad/unwind-via-raSearch.test
+++ lldb/test/Shell/SymbolFile/Breakpad/unwind-via-raSearch.test
@@ -16,13 +16,13 @@
# CHECK: This UnwindPlan is valid at all instruction locations: no.
# CHECK: This UnwindPlan is for a trap handler function: no.
# CHECK: Address range of this UnwindPlan: [unwind-via-stack-win.exe..module_image + 4112-0x0000107d)
-# CHECK: row[0]: 0: CFA=RaSearch@SP+0 => esp=DW_OP_pick 0x0, DW_OP_consts +4, DW_OP_plus eip=DW_OP_pick 0x0, DW_OP_deref
+# CHECK: row[0]: 0: CFA=RaSearch@SP+0, offset=+0 => esp=DW_OP_pick 0x0, DW_OP_consts +4, DW_OP_plus eip=DW_OP_pick 0x0, DW_OP_deref
image show-unwind -n nonzero_frame_size
# CHECK-LABEL: image show-unwind -n nonzero_frame_size
# CHECK: UNWIND PLANS for unwind-via-stack-win.exe`nonzero_frame_size
# CHECK: Symbol file UnwindPlan:
-# CHECK: row[0]: 0: CFA=RaSearch@SP+12 => esp=DW_OP_pick 0x0, DW_OP_consts +4, DW_OP_plus eip=DW_OP_pick 0x0, DW_OP_deref
+# CHECK: row[0]: 0: CFA=RaSearch@SP+12, offset=+0 => esp=DW_OP_pick 0x0, DW_OP_consts +4, DW_OP_plus eip=DW_OP_pick 0x0, DW_OP_deref
# Then, some invalid rules.
image show-unwind -n complex_rasearch
Index: lldb/source/Target/RegisterContextUnwind.cpp
===================================================================
--- lldb/source/Target/RegisterContextUnwind.cpp
+++ lldb/source/Target/RegisterContextUnwind.cpp
@@ -285,7 +285,18 @@
cfa_status = true;
}
if (!cfa_status) {
- UnwindLogMsg("could not read CFA value for first frame.");
+ UnwindLogMsg("could not read CFA value for first frame. Trying stack "
+ "walking unwind plan.");
+ if (abi) {
+ UnwindPlanSP stack_walk_unwind_plan =
+ std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+ if (abi->CreateStackWalkingUnwindPlan(*stack_walk_unwind_plan)) {
+ m_fallback_unwind_plan_sp = stack_walk_unwind_plan;
+ cfa_status = TryFallbackUnwindPlan();
+ }
+ }
+ }
+ if (!cfa_status) {
m_frame_type = eNotAValidFrame;
return;
}
@@ -384,7 +395,7 @@
// symbol/function information - just stick in some reasonable defaults and
// hope we can unwind past this frame. If we're above a trap handler,
// we may be at a bogus address because we jumped through a bogus function
- // pointer and trapped, so don't force the arch default unwind plan in that
+ // pointer and trapped, so don't force the arch default unwind plan in that
// case.
ModuleSP pc_module_sp(m_current_pc.GetModule());
if ((!m_current_pc.IsValid() || !pc_module_sp) &&
@@ -660,9 +671,20 @@
}
if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) {
- UnwindLogMsg("failed to get cfa");
- m_frame_type = eNotAValidFrame;
- return;
+ UnwindLogMsg("failed to get cfa. Trying stack walking unwind plan.");
+ bool cfa_status = false;
+ if (abi) {
+ UnwindPlanSP stack_walk_unwind_plan =
+ std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+ if (abi->CreateStackWalkingUnwindPlan(*stack_walk_unwind_plan)) {
+ m_fallback_unwind_plan_sp = stack_walk_unwind_plan;
+ cfa_status = TryFallbackUnwindPlan();
+ }
+ }
+ if (!cfa_status) {
+ m_frame_type = eNotAValidFrame;
+ return;
+ }
}
ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa);
@@ -1287,7 +1309,7 @@
// arch default unwind plan is used as the Fast Unwind Plan, we
// need to recognize this & switch over to the Full Unwind Plan
// to see what unwind rule that (more knoweldgeable, probably)
- // UnwindPlan has. If the full UnwindPlan says the register
+ // UnwindPlan has. If the full UnwindPlan says the register
// location is Undefined, then it really is.
if (active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind),
unwindplan_regloc) &&
@@ -1335,14 +1357,14 @@
m_full_unwind_plan_sp->GetReturnAddressRegister() !=
LLDB_INVALID_REGNUM) {
// If this is a trap handler frame, we should have access to
- // the complete register context when the interrupt/async
+ // the complete register context when the interrupt/async
// signal was received, we should fetch the actual saved $pc
// value instead of the Return Address register.
// If $pc is not available, fall back to the RA reg.
UnwindPlan::Row::RegisterLocation scratch;
if (m_frame_type == eTrapHandlerFrame &&
- active_row->GetRegisterInfo
- (pc_regnum.GetAsKind (unwindplan_registerkind), scratch)) {
+ active_row->GetRegisterInfo(
+ pc_regnum.GetAsKind(unwindplan_registerkind), scratch)) {
UnwindLogMsg("Providing pc register instead of rewriting to "
"RA reg because this is a trap handler and there is "
"a location for the saved pc register value.");
@@ -1710,12 +1732,6 @@
if (m_full_unwind_plan_sp.get() == nullptr)
return false;
- if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() ||
- m_full_unwind_plan_sp->GetSourceName() ==
- m_fallback_unwind_plan_sp->GetSourceName()) {
- return false;
- }
-
// If a compiler generated unwind plan failed, trying the arch default
// unwindplan isn't going to do any better.
if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes)
@@ -1771,71 +1787,86 @@
UnwindPlan::RowSP active_row =
m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
-
+ UnwindPlan::Row::FAValue &fa = active_row->GetCFAValue();
if (active_row &&
- active_row->GetCFAValue().GetValueType() !=
- UnwindPlan::Row::FAValue::unspecified) {
+ fa.GetValueType() != UnwindPlan::Row::FAValue::unspecified) {
addr_t new_cfa;
- if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
- active_row->GetCFAValue(), new_cfa) ||
- new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) {
- UnwindLogMsg("failed to get cfa with fallback unwindplan");
- m_fallback_unwind_plan_sp.reset();
- m_full_unwind_plan_sp = original_full_unwind_plan_sp;
- return false;
+ // If itn's not first attempt and ra search, update ra search offset before
+ // searching for cfa. Previous attempts may fail due to bad pc.
+ if (fa.IsRaSearch() && old_cfa != LLDB_INVALID_ADDRESS) {
+ addr_t sp;
+ if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp)) {
+ UnwindLogMsg("failed to get cfa with fallback unwindplan");
+ m_fallback_unwind_plan_sp.reset();
+ m_full_unwind_plan_sp = original_full_unwind_plan_sp;
+ return false;
+ }
+ Process &process = *m_thread.GetProcess();
+ // It's the next stack offset location so that sp + next_search_offset ==
+ // old_cfa + process.GetAddressByteSize().
+ addr_t next_search_offset =
+ old_cfa - sp - fa.GetOffset() + process.GetAddressByteSize();
+ fa.SetRaSearch(next_search_offset, fa.GetOffset());
}
- m_cfa = new_cfa;
-
- ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
- active_row->GetAFAValue(), m_afa);
+ if (ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), fa,
+ new_cfa) ||
+ new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) {
- if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB),
- regloc) ==
- UnwindLLDB::RegisterSearchResult::eRegisterFound) {
- const RegisterInfo *reg_info =
- GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB));
- if (reg_info) {
- RegisterValue reg_value;
- if (ReadRegisterValueFromRegisterLocation(regloc, reg_info,
- reg_value)) {
- new_caller_pc_value = reg_value.GetAsUInt64();
- if (ProcessSP process_sp = m_thread.GetProcess()) {
- if (ABISP abi = process_sp->GetABI())
- new_caller_pc_value = abi->FixCodeAddress(new_caller_pc_value);
+ m_cfa = new_cfa;
+
+ ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
+ active_row->GetAFAValue(), m_afa);
+
+ if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB),
+ regloc) ==
+ UnwindLLDB::RegisterSearchResult::eRegisterFound) {
+ const RegisterInfo *reg_info =
+ GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB));
+ if (reg_info) {
+ RegisterValue reg_value;
+ if (ReadRegisterValueFromRegisterLocation(regloc, reg_info,
+ reg_value)) {
+ new_caller_pc_value = reg_value.GetAsUInt64();
+ if (ProcessSP process_sp = m_thread.GetProcess()) {
+ if (ABISP abi = process_sp->GetABI())
+ new_caller_pc_value = abi->FixCodeAddress(new_caller_pc_value);
+ }
}
}
}
- }
- if (new_caller_pc_value == LLDB_INVALID_ADDRESS) {
- UnwindLogMsg("failed to get a pc value for the caller frame with the "
- "fallback unwind plan");
- m_fallback_unwind_plan_sp.reset();
- m_full_unwind_plan_sp = original_full_unwind_plan_sp;
- m_cfa = old_cfa;
- m_afa = old_afa;
- return false;
- }
+ if (new_caller_pc_value == LLDB_INVALID_ADDRESS) {
+ UnwindLogMsg("failed to get a pc value for the caller frame with the "
+ "fallback unwind plan");
+ m_fallback_unwind_plan_sp.reset();
+ m_full_unwind_plan_sp = original_full_unwind_plan_sp;
+ m_cfa = old_cfa;
+ m_afa = old_afa;
+ return false;
+ }
+
+ if (old_caller_pc_value == new_caller_pc_value && m_cfa == old_cfa &&
+ m_afa == old_afa) {
+ UnwindLogMsg("fallback unwind plan got the same values for this frame "
+ "CFA and caller frame pc, not using");
+ m_fallback_unwind_plan_sp.reset();
+ m_full_unwind_plan_sp = original_full_unwind_plan_sp;
+ return false;
+ }
+
+ UnwindLogMsg(
+ "trying to unwind from this function with the UnwindPlan '%s' "
+ "because UnwindPlan '%s' failed.",
+ m_fallback_unwind_plan_sp->GetSourceName().GetCString(),
+ original_full_unwind_plan_sp->GetSourceName().GetCString());
- if (old_caller_pc_value == new_caller_pc_value &&
- m_cfa == old_cfa &&
- m_afa == old_afa) {
- UnwindLogMsg("fallback unwind plan got the same values for this frame "
- "CFA and caller frame pc, not using");
+ PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
+ } else {
+ UnwindLogMsg("failed to get cfa with fallback unwindplan");
m_fallback_unwind_plan_sp.reset();
m_full_unwind_plan_sp = original_full_unwind_plan_sp;
return false;
}
-
- UnwindLogMsg("trying to unwind from this function with the UnwindPlan '%s' "
- "because UnwindPlan '%s' failed.",
- m_fallback_unwind_plan_sp->GetSourceName().GetCString(),
- original_full_unwind_plan_sp->GetSourceName().GetCString());
-
- // We've copied the fallback unwind plan into the full - now clear the
- // fallback.
- m_fallback_unwind_plan_sp.reset();
- PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
}
return true;
@@ -2025,16 +2056,21 @@
}
case UnwindPlan::Row::FAValue::isRaSearch: {
Process &process = *m_thread.GetProcess();
- lldb::addr_t return_address_hint = GetReturnAddressHint(fa.GetOffset());
- if (return_address_hint == LLDB_INVALID_ADDRESS)
+ addr_t sp;
+ if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp))
return false;
+ addr_t return_address_hint = sp + fa.GetRaSearchOffset();
+ if (fa.IsFirstRaSearch())
+ return_address_hint += GetParameterStackSize();
const unsigned max_iterations = 256;
for (unsigned i = 0; i < max_iterations; ++i) {
Status st;
- lldb::addr_t candidate_addr =
+ addr_t candidate_addr =
return_address_hint + i * process.GetAddressByteSize();
- lldb::addr_t candidate =
- process.ReadPointerFromMemory(candidate_addr, st);
+ if (!process.GetABI()->CallFrameAddressIsValid(candidate_addr +
+ fa.GetOffset()))
+ continue;
+ addr_t candidate = process.ReadPointerFromMemory(candidate_addr, st);
if (st.Fail()) {
UnwindLogMsg("Cannot read memory at 0x%" PRIx64 ": %s", candidate_addr,
st.AsCString());
@@ -2044,7 +2080,7 @@
uint32_t permissions;
if (process.GetLoadAddressPermissions(candidate, permissions) &&
permissions & lldb::ePermissionsExecutable) {
- address = candidate_addr;
+ address = candidate_addr + fa.GetOffset();
UnwindLogMsg("Heuristically found CFA: 0x%" PRIx64, address);
return true;
}
@@ -2058,29 +2094,21 @@
return false;
}
-lldb::addr_t RegisterContextUnwind::GetReturnAddressHint(int32_t plan_offset) {
- addr_t hint;
- if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, hint))
- return LLDB_INVALID_ADDRESS;
- if (!m_sym_ctx.module_sp || !m_sym_ctx.symbol)
- return LLDB_INVALID_ADDRESS;
-
- hint += plan_offset;
-
+addr_t RegisterContextUnwind::GetParameterStackSize() {
if (auto next = GetNextFrame()) {
if (!next->m_sym_ctx.module_sp || !next->m_sym_ctx.symbol)
- return LLDB_INVALID_ADDRESS;
+ return 0;
if (auto expected_size =
next->m_sym_ctx.module_sp->GetSymbolFile()->GetParameterStackSize(
*next->m_sym_ctx.symbol))
- hint += *expected_size;
+ return *expected_size;
else {
UnwindLogMsgVerbose("Could not retrieve parameter size: %s",
llvm::toString(expected_size.takeError()).c_str());
- return LLDB_INVALID_ADDRESS;
+ return 0;
}
}
- return hint;
+ return 0;
}
// Retrieve a general purpose register value for THIS frame, as saved by the
Index: lldb/source/Symbol/UnwindPlan.cpp
===================================================================
--- lldb/source/Symbol/UnwindPlan.cpp
+++ lldb/source/Symbol/UnwindPlan.cpp
@@ -169,8 +169,11 @@
if (m_type == rhs.m_type) {
switch (m_type) {
case unspecified:
+ return true;
case isRaSearch:
- return m_value.ra_search_offset == rhs.m_value.ra_search_offset;
+ return m_value.ra_search.search_offset ==
+ rhs.m_value.ra_search.search_offset &&
+ m_value.ra_search.cfa_offset == rhs.m_value.ra_search.cfa_offset;
case isRegisterPlusOffset:
return m_value.reg.offset == rhs.m_value.reg.offset;
@@ -209,7 +212,7 @@
s.PutCString("unspecified");
break;
case isRaSearch:
- s.Printf("RaSearch@SP%+d", m_value.ra_search_offset);
+ s.Printf("RaSearch@SP%+d, offset=%+d", GetRaSearchOffset(), GetOffset());
break;
}
}
Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -1255,7 +1255,7 @@
auto begin = scope.begin();
auto end = scope.end();
std::vector<clang::ParmVarDecl *> params;
- while (begin != end && param_count > 0) {
+ for (uint32_t i = 0; i < param_count && begin != end;) {
uint32_t record_offset = begin.offset();
CVSymbol sym = *begin++;
@@ -1307,10 +1307,10 @@
m_uid_to_decl[toOpaqueUid(param_uid)] = param;
params.push_back(param);
- --param_count;
+ ++i;
}
- if (!params.empty())
+ if (!params.empty() && params.size() == param_count)
m_clang.SetFunctionParameters(&function_decl, params);
}
Index: lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -740,8 +740,8 @@
// clang will use T1, if it needs to realign the stack.
auto *symbol = llvm::dyn_cast<postfix::SymbolNode>(it->second);
if (symbol && symbol->GetName() == ".raSearch") {
- row_sp->GetCFAValue().SetRaSearch(record->LocalSize +
- record->SavedRegisterSize);
+ row_sp->GetCFAValue().SetRaSearch(
+ record->LocalSize + record->SavedRegisterSize, 0);
} else {
if (!postfix::ResolveSymbols(it->second, symbol_resolver)) {
LLDB_LOG(log, "Resolving symbols in `{0}` failed.",
Index: lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h
===================================================================
--- lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h
+++ lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h
@@ -33,6 +33,9 @@
GetReturnValueObjectImpl(lldb_private::Thread &thread,
lldb_private::CompilerType &type) const override;
+ bool
+ CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
Index: lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp
===================================================================
--- lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp
+++ lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp
@@ -731,6 +731,27 @@
return return_valobj_sp;
}
+bool ABIWindows_x86_64::CreateStackWalkingUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindLLDB);
+
+ uint32_t sp_reg_num = dwarf_rsp;
+ uint32_t pc_reg_num = dwarf_rip;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ row->GetCFAValue().SetRaSearch(0, 8);
+ row->SetUnspecifiedRegistersAreUndefined(true);
+
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, true);
+ row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("x86_64 stack-walking unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
+ return true;
+}
+
// This defines the CFA as rsp+8
// the saved pc is at CFA-8 (i.e. rsp+0)
// The saved rsp is CFA+0
Index: lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h
===================================================================
--- lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h
+++ lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h
@@ -33,6 +33,11 @@
GetReturnValueObjectImpl(lldb_private::Thread &thread,
lldb_private::CompilerType &type) const override;
+ bool
+ CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override {
+ return false;
+ }
+
bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
Index: lldb/source/Plugins/ABI/X86/ABISysV_i386.h
===================================================================
--- lldb/source/Plugins/ABI/X86/ABISysV_i386.h
+++ lldb/source/Plugins/ABI/X86/ABISysV_i386.h
@@ -36,6 +36,11 @@
GetReturnValueObjectImpl(lldb_private::Thread &thread,
lldb_private::CompilerType &type) const override;
+ bool
+ CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override {
+ return false;
+ }
+
bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
Index: lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h
===================================================================
--- lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h
+++ lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h
@@ -30,6 +30,11 @@
SetReturnValueObject(lldb::StackFrameSP &frame_sp,
lldb::ValueObjectSP &new_value) override;
+ bool
+ CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override {
+ return false;
+ }
+
bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
Index: lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h
===================================================================
--- lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h
+++ lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h
@@ -34,6 +34,11 @@
GetReturnValueObjectImpl(lldb_private::Thread &thread,
lldb_private::CompilerType &type) const override;
+ bool
+ CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override {
+ return false;
+ }
+
bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
Index: lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h
===================================================================
--- lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h
+++ lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h
@@ -34,6 +34,11 @@
GetReturnValueObjectImpl(lldb_private::Thread &thread,
lldb_private::CompilerType &type) const override;
+ bool
+ CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override {
+ return false;
+ }
+
bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
Index: lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h
===================================================================
--- lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h
+++ lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h
@@ -34,6 +34,11 @@
GetReturnValueObjectImpl(lldb_private::Thread &thread,
lldb_private::CompilerType &type) const override;
+ bool
+ CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override {
+ return false;
+ }
+
bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
Index: lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h
===================================================================
--- lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h
+++ lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h
@@ -34,6 +34,11 @@
GetReturnValueObjectImpl(lldb_private::Thread &thread,
lldb_private::CompilerType &type) const override;
+ bool
+ CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override {
+ return false;
+ }
+
bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
Index: lldb/source/Plugins/ABI/Mips/ABISysV_mips.h
===================================================================
--- lldb/source/Plugins/ABI/Mips/ABISysV_mips.h
+++ lldb/source/Plugins/ABI/Mips/ABISysV_mips.h
@@ -34,6 +34,11 @@
GetReturnValueObjectImpl(lldb_private::Thread &thread,
lldb_private::CompilerType &type) const override;
+ bool
+ CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override {
+ return false;
+ }
+
bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
Index: lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h
===================================================================
--- lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h
+++ lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h
@@ -46,6 +46,11 @@
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread,
llvm::Type &type) const override;
+ bool
+ CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override {
+ return false;
+ }
+
bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
Index: lldb/source/Plugins/ABI/ARM/ABISysV_arm.h
===================================================================
--- lldb/source/Plugins/ABI/ARM/ABISysV_arm.h
+++ lldb/source/Plugins/ABI/ARM/ABISysV_arm.h
@@ -29,6 +29,11 @@
SetReturnValueObject(lldb::StackFrameSP &frame_sp,
lldb::ValueObjectSP &new_value) override;
+ bool
+ CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override {
+ return false;
+ }
+
bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
Index: lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h
===================================================================
--- lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h
+++ lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h
@@ -29,6 +29,11 @@
SetReturnValueObject(lldb::StackFrameSP &frame_sp,
lldb::ValueObjectSP &new_value) override;
+ bool
+ CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override {
+ return false;
+ }
+
bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
Index: lldb/source/Plugins/ABI/ARC/ABISysV_arc.h
===================================================================
--- lldb/source/Plugins/ABI/ARC/ABISysV_arc.h
+++ lldb/source/Plugins/ABI/ARC/ABISysV_arc.h
@@ -49,6 +49,11 @@
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread,
llvm::Type &type) const override;
+ bool
+ CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override {
+ return false;
+ }
+
bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
Index: lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
===================================================================
--- lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
+++ lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
@@ -30,6 +30,11 @@
SetReturnValueObject(lldb::StackFrameSP &frame_sp,
lldb::ValueObjectSP &new_value) override;
+ bool
+ CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override {
+ return false;
+ }
+
bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
Index: lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
===================================================================
--- lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
+++ lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
@@ -27,6 +27,11 @@
bool GetArgumentValues(lldb_private::Thread &thread,
lldb_private::ValueList &values) const override;
+ bool
+ CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override {
+ return false;
+ }
+
bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
Index: lldb/include/lldb/Target/RegisterContextUnwind.h
===================================================================
--- lldb/include/lldb/Target/RegisterContextUnwind.h
+++ lldb/include/lldb/Target/RegisterContextUnwind.h
@@ -206,7 +206,7 @@
bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp,
int &valid_pc_offset);
- lldb::addr_t GetReturnAddressHint(int32_t plan_offset);
+ lldb::addr_t GetParameterStackSize();
lldb_private::Thread &m_thread;
Index: lldb/include/lldb/Target/ABI.h
===================================================================
--- lldb/include/lldb/Target/ABI.h
+++ lldb/include/lldb/Target/ABI.h
@@ -96,6 +96,8 @@
lldb::ProcessSP GetProcessSP() const { return m_process_wp.lock(); }
public:
+ virtual bool CreateStackWalkingUnwindPlan(UnwindPlan &unwind_plan) = 0;
+
virtual bool CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) = 0;
virtual bool CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) = 0;
Index: lldb/include/lldb/Symbol/UnwindPlan.h
===================================================================
--- lldb/include/lldb/Symbol/UnwindPlan.h
+++ lldb/include/lldb/Symbol/UnwindPlan.h
@@ -215,9 +215,16 @@
bool IsUnspecified() const { return m_type == unspecified; }
- void SetRaSearch(int32_t offset) {
+ bool IsRaSearch() const { return m_type == isRaSearch; }
+
+ void SetRaSearch(int32_t search_offset, int32_t cfa_offset) {
+ m_value.ra_search.search_offset = search_offset;
+ m_value.ra_search.cfa_offset = cfa_offset;
+ if (m_type == isRaSearch) {
+ // Not the first search.
+ m_value.ra_search.search_offset |= 1;
+ }
m_type = isRaSearch;
- m_value.ra_search_offset = offset;
}
bool IsRegisterPlusOffset() const {
@@ -255,12 +262,20 @@
ValueType GetValueType() const { return m_type; }
+ int32_t GetRaSearchOffset() const {
+ return m_type == isRaSearch ? m_value.ra_search.search_offset & ~1 : 0;
+ }
+
+ bool IsFirstRaSearch() const {
+ return m_value.ra_search.search_offset % 2 == 0;
+ }
+
int32_t GetOffset() const {
switch (m_type) {
case isRegisterPlusOffset:
return m_value.reg.offset;
case isRaSearch:
- return m_value.ra_search_offset;
+ return m_value.ra_search.cfa_offset;
default:
return 0;
}
@@ -316,7 +331,12 @@
uint16_t length;
} expr;
// For m_type == isRaSearch
- int32_t ra_search_offset;
+ struct {
+ // If last bit of search_offset is 0, it's the first try in this
+ // ra_search.
+ int32_t search_offset;
+ int32_t cfa_offset;
+ } ra_search;
} m_value;
}; // class FAValue
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits