Skip to content

[lldb] Modernize ABI-based unwind plan creation #128505

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lldb/include/lldb/Symbol/UnwindPlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,11 @@ class UnwindPlan {
for (const RowSP &row_sp : rhs.m_row_list)
m_row_list.emplace_back(new Row(*row_sp));
}
UnwindPlan(UnwindPlan &&rhs) = default;
UnwindPlan &operator=(const UnwindPlan &rhs) {
return *this = UnwindPlan(rhs); // NB: moving from a temporary (deep) copy
}
UnwindPlan &operator=(UnwindPlan &&) = default;

~UnwindPlan() = default;

Expand Down
5 changes: 3 additions & 2 deletions lldb/include/lldb/Target/ABI.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/DynamicRegisterInfo.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"

#include "llvm/ADT/ArrayRef.h"
Expand Down Expand Up @@ -96,9 +97,9 @@ class ABI : public PluginInterface {
lldb::ProcessSP GetProcessSP() const { return m_process_wp.lock(); }

public:
virtual bool CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) = 0;
virtual lldb::UnwindPlanSP CreateFunctionEntryUnwindPlan() = 0;

virtual bool CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) = 0;
virtual lldb::UnwindPlanSP CreateDefaultUnwindPlan() = 0;

virtual bool RegisterIsVolatile(const RegisterInfo *reg_info) = 0;

Expand Down
14 changes: 6 additions & 8 deletions lldb/source/Commands/CommandObjectTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3763,20 +3763,18 @@ class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {

ABISP abi_sp = process->GetABI();
if (abi_sp) {
UnwindPlan arch_default(lldb::eRegisterKindGeneric);
if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
if (UnwindPlanSP plan_sp = abi_sp->CreateDefaultUnwindPlan()) {
result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
arch_default.Dump(result.GetOutputStream(), thread.get(),
LLDB_INVALID_ADDRESS);
plan_sp->Dump(result.GetOutputStream(), thread.get(),
LLDB_INVALID_ADDRESS);
result.GetOutputStream().Printf("\n");
}

UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
if (UnwindPlanSP plan_sp = abi_sp->CreateFunctionEntryUnwindPlan()) {
result.GetOutputStream().Printf(
"Arch default at entry point UnwindPlan:\n");
arch_entry.Dump(result.GetOutputStream(), thread.get(),
LLDB_INVALID_ADDRESS);
plan_sp->Dump(result.GetOutputStream(), thread.get(),
LLDB_INVALID_ADDRESS);
result.GetOutputStream().Printf("\n");
}
}
Expand Down
38 changes: 15 additions & 23 deletions lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,10 +343,7 @@ ABIMacOSX_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
return error;
}

bool ABIMacOSX_arm64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.Clear();
unwind_plan.SetRegisterKind(eRegisterKindDWARF);

UnwindPlanSP ABIMacOSX_arm64::CreateFunctionEntryUnwindPlan() {
uint32_t lr_reg_num = arm64_dwarf::lr;
uint32_t sp_reg_num = arm64_dwarf::sp;
uint32_t pc_reg_num = arm64_dwarf::pc;
Expand All @@ -356,23 +353,17 @@ bool ABIMacOSX_arm64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
// Our previous Call Frame Address is the stack pointer
row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);

// Our previous PC is in the LR
// Our previous PC is in the LR, all other registers are the same.
row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);

unwind_plan.AppendRow(row);

// All other registers are the same.

unwind_plan.SetSourceName("arm64 at-func-entry default");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);

return true;
auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
plan_sp->AppendRow(row);
plan_sp->SetSourceName("arm64 at-func-entry default");
plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
return plan_sp;
}

bool ABIMacOSX_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.Clear();
unwind_plan.SetRegisterKind(eRegisterKindDWARF);

UnwindPlanSP ABIMacOSX_arm64::CreateDefaultUnwindPlan() {
uint32_t fp_reg_num = arm64_dwarf::fp;
uint32_t pc_reg_num = arm64_dwarf::pc;

Expand All @@ -386,12 +377,13 @@ bool ABIMacOSX_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);

unwind_plan.AppendRow(row);
unwind_plan.SetSourceName("arm64-apple-darwin default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
plan_sp->AppendRow(row);
plan_sp->SetSourceName("arm64-apple-darwin default unwind plan");
plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
return plan_sp;
}

// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says
Expand Down
5 changes: 2 additions & 3 deletions lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ class ABIMacOSX_arm64 : public ABIAArch64 {
bool GetArgumentValues(lldb_private::Thread &thread,
lldb_private::ValueList &values) const override;

bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
lldb::UnwindPlanSP CreateFunctionEntryUnwindPlan() override;

bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
lldb::UnwindPlanSP CreateDefaultUnwindPlan() override;

bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;

Expand Down
46 changes: 19 additions & 27 deletions lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,35 +391,27 @@ Status ABISysV_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
return error;
}

bool ABISysV_arm64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.Clear();
unwind_plan.SetRegisterKind(eRegisterKindDWARF);

UnwindPlanSP ABISysV_arm64::CreateFunctionEntryUnwindPlan() {
uint32_t lr_reg_num = arm64_dwarf::lr;
uint32_t sp_reg_num = arm64_dwarf::sp;

UnwindPlan::RowSP row(new UnwindPlan::Row);

// Our previous Call Frame Address is the stack pointer
// Our previous Call Frame Address is the stack pointer, all other registers
// are the same.
row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);

unwind_plan.AppendRow(row);
unwind_plan.SetReturnAddressRegister(lr_reg_num);

// All other registers are the same.

unwind_plan.SetSourceName("arm64 at-func-entry default");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);

return true;
auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
plan_sp->AppendRow(row);
plan_sp->SetReturnAddressRegister(lr_reg_num);
plan_sp->SetSourceName("arm64 at-func-entry default");
plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
return plan_sp;
}

bool ABISysV_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.Clear();
unwind_plan.SetRegisterKind(eRegisterKindDWARF);

UnwindPlanSP ABISysV_arm64::CreateDefaultUnwindPlan() {
uint32_t fp_reg_num = arm64_dwarf::fp;
uint32_t pc_reg_num = arm64_dwarf::pc;

Expand All @@ -433,13 +425,13 @@ bool ABISysV_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);

unwind_plan.AppendRow(row);
unwind_plan.SetSourceName("arm64 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);

return true;
auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
plan_sp->AppendRow(row);
plan_sp->SetSourceName("arm64 default unwind plan");
plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
return plan_sp;
}

// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says
Expand Down
5 changes: 2 additions & 3 deletions lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@ class ABISysV_arm64 : public ABIAArch64 {
SetReturnValueObject(lldb::StackFrameSP &frame_sp,
lldb::ValueObjectSP &new_value) override;

bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
lldb::UnwindPlanSP CreateFunctionEntryUnwindPlan() override;

bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
lldb::UnwindPlanSP CreateDefaultUnwindPlan() override;

bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;

Expand Down
22 changes: 8 additions & 14 deletions lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,29 +555,23 @@ ValueObjectSP ABISysV_arc::GetReturnValueObjectImpl(Thread &thread,
value, ConstString(""));
}

bool ABISysV_arc::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.Clear();
unwind_plan.SetRegisterKind(eRegisterKindDWARF);

UnwindPlanSP ABISysV_arc::CreateFunctionEntryUnwindPlan() {
UnwindPlan::RowSP row(new UnwindPlan::Row);

// Our Call Frame Address is the stack pointer value.
row->GetCFAValue().SetIsRegisterPlusOffset(dwarf::sp, 0);

// The previous PC is in the BLINK.
// The previous PC is in the BLINK, all other registers are the same.
row->SetRegisterLocationToRegister(dwarf::pc, dwarf::blink, true);
unwind_plan.AppendRow(row);

// All other registers are the same.
unwind_plan.SetSourceName("arc at-func-entry default");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);

return true;
auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
plan_sp->AppendRow(row);
plan_sp->SetSourceName("arc at-func-entry default");
plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
return plan_sp;
}

bool ABISysV_arc::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
return false;
}
UnwindPlanSP ABISysV_arc::CreateDefaultUnwindPlan() { return nullptr; }

bool ABISysV_arc::RegisterIsVolatile(const RegisterInfo *reg_info) {
if (nullptr == reg_info)
Expand Down
5 changes: 2 additions & 3 deletions lldb/source/Plugins/ABI/ARC/ABISysV_arc.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,9 @@ class ABISysV_arc : public lldb_private::RegInfoBasedABI {
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread,
llvm::Type &type) const override;

bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
lldb::UnwindPlanSP CreateFunctionEntryUnwindPlan() override;

bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
lldb::UnwindPlanSP CreateDefaultUnwindPlan() override;

bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;

Expand Down
38 changes: 15 additions & 23 deletions lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1781,10 +1781,7 @@ Status ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
return error;
}

bool ABIMacOSX_arm::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.Clear();
unwind_plan.SetRegisterKind(eRegisterKindDWARF);

UnwindPlanSP ABIMacOSX_arm::CreateFunctionEntryUnwindPlan() {
uint32_t lr_reg_num = dwarf_lr;
uint32_t sp_reg_num = dwarf_sp;
uint32_t pc_reg_num = dwarf_pc;
Expand All @@ -1794,22 +1791,17 @@ bool ABIMacOSX_arm::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
// Our Call Frame Address is the stack pointer value
row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);

// The previous PC is in the LR
// The previous PC is in the LR, all other registers are the same.
row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
unwind_plan.AppendRow(row);

// All other registers are the same.

unwind_plan.SetSourceName("arm at-func-entry default");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);

return true;
auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
plan_sp->AppendRow(row);
plan_sp->SetSourceName("arm at-func-entry default");
plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
return plan_sp;
}

bool ABIMacOSX_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.Clear();
unwind_plan.SetRegisterKind(eRegisterKindDWARF);

UnwindPlanSP ABIMacOSX_arm::CreateDefaultUnwindPlan() {
uint32_t fp_reg_num =
dwarf_r7; // apple uses r7 for all frames. Normal arm uses r11
uint32_t pc_reg_num = dwarf_pc;
Expand All @@ -1824,13 +1816,13 @@ bool ABIMacOSX_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);

unwind_plan.AppendRow(row);
unwind_plan.SetSourceName("arm-apple-ios default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);

return true;
auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
plan_sp->AppendRow(row);
plan_sp->SetSourceName("arm-apple-ios default unwind plan");
plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
return plan_sp;
}

// cf. "ARMv6 Function Calling Conventions"
Expand Down
5 changes: 2 additions & 3 deletions lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ class ABIMacOSX_arm : public lldb_private::RegInfoBasedABI {
SetReturnValueObject(lldb::StackFrameSP &frame_sp,
lldb::ValueObjectSP &new_value) override;

bool
CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
lldb::UnwindPlanSP CreateFunctionEntryUnwindPlan() override;

bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
lldb::UnwindPlanSP CreateDefaultUnwindPlan() override;

bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;

Expand Down
Loading