Skip to content

[lldb] Merge/unify ABI-provided AArch64 unwind plans #139545

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
May 14, 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
42 changes: 42 additions & 0 deletions lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <optional>

using namespace lldb;
using namespace lldb_private;

LLDB_PLUGIN_DEFINE(ABIAArch64)

Expand Down Expand Up @@ -200,3 +201,44 @@ void ABIAArch64::AugmentRegisterInfo(
lldb::eEncodingIEEE754, lldb::eFormatFloat);
}
}

UnwindPlanSP ABIAArch64::CreateFunctionEntryUnwindPlan() {
UnwindPlan::Row row;

// Our previous Call Frame Address is the stack pointer
row.GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, 0);

// Our previous PC is in the LR, all other registers are the same.
row.SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC,
LLDB_REGNUM_GENERIC_RA, true);

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

UnwindPlanSP ABIAArch64::CreateDefaultUnwindPlan() {
UnwindPlan::Row row;
const int32_t ptr_size = 8;

row.GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP,
2 * ptr_size);
row.SetUnspecifiedRegistersAreUndefined(true);

row.SetRegisterLocationToAtCFAPlusOffset(LLDB_REGNUM_GENERIC_FP,
ptr_size * -2, true);
row.SetRegisterLocationToAtCFAPlusOffset(LLDB_REGNUM_GENERIC_PC,
ptr_size * -1, true);

auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindGeneric);
plan_sp->AppendRow(std::move(row));
plan_sp->SetSourceName("arm64 default unwind plan");
plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
return plan_sp;
}
3 changes: 3 additions & 0 deletions lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ class ABIAArch64 : public lldb_private::MCBasedABI {
lldb::addr_t FixCodeAddress(lldb::addr_t pc) override;
lldb::addr_t FixDataAddress(lldb::addr_t pc) override;

lldb::UnwindPlanSP CreateFunctionEntryUnwindPlan() override;
lldb::UnwindPlanSP CreateDefaultUnwindPlan() override;

protected:
virtual lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) {
return pc;
Expand Down
45 changes: 0 additions & 45 deletions lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Value.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
Expand All @@ -30,8 +29,6 @@
#include "lldb/Utility/Status.h"
#include "lldb/ValueObject/ValueObjectConstResult.h"

#include "Utility/ARM64_DWARF_Registers.h"

using namespace lldb;
using namespace lldb_private;

Expand Down Expand Up @@ -344,48 +341,6 @@ ABIMacOSX_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
return error;
}

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;

UnwindPlan::Row row;

// Our previous Call Frame Address is the stack pointer
row.GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);

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

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

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

UnwindPlan::Row row;
const int32_t ptr_size = 8;

row.GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
row.SetUnspecifiedRegistersAreUndefined(true);

row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);

auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
plan_sp->AppendRow(std::move(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
// registers x19 through x28 and sp are callee preserved. v8-v15 are non-
// volatile (and specifically only the lower 8 bytes of these regs), the rest
Expand Down
4 changes: 0 additions & 4 deletions lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ class ABIMacOSX_arm64 : public ABIAArch64 {
bool GetArgumentValues(lldb_private::Thread &thread,
lldb_private::ValueList &values) const override;

lldb::UnwindPlanSP CreateFunctionEntryUnwindPlan() override;

lldb::UnwindPlanSP CreateDefaultUnwindPlan() override;

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

// The arm64 ABI requires that stack frames be 16 byte aligned.
Expand Down
44 changes: 0 additions & 44 deletions lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
#include "lldb/Utility/Status.h"
#include "lldb/ValueObject/ValueObjectConstResult.h"

#include "Utility/ARM64_DWARF_Registers.h"

using namespace lldb;
using namespace lldb_private;

Expand Down Expand Up @@ -385,48 +383,6 @@ Status ABISysV_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
return error;
}

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

UnwindPlan::Row row;

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

auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
plan_sp->AppendRow(std::move(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;
}

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

UnwindPlan::Row row;
const int32_t ptr_size = 8;

row.GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
row.SetUnspecifiedRegistersAreUndefined(true);

row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);

auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
plan_sp->AppendRow(std::move(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
// registers x19 through x28 and sp are callee preserved. v8-v15 are non-
// volatile (and specifically only the lower 8 bytes of these regs), the rest
Expand Down
4 changes: 0 additions & 4 deletions lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ class ABISysV_arm64 : public ABIAArch64 {
SetReturnValueObject(lldb::StackFrameSP &frame_sp,
lldb::ValueObjectSP &new_value) override;

lldb::UnwindPlanSP CreateFunctionEntryUnwindPlan() override;

lldb::UnwindPlanSP CreateDefaultUnwindPlan() override;

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

// The arm64 ABI requires that stack frames be 16 byte aligned.
Expand Down
39 changes: 18 additions & 21 deletions lldb/source/Symbol/FuncUnwinders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,33 +365,30 @@ FuncUnwinders::GetAssemblyUnwindPlan(Target &target, Thread &thread) {
LazyBool FuncUnwinders::CompareUnwindPlansForIdenticalInitialPCLocation(
Thread &thread, const std::shared_ptr<const UnwindPlan> &a,
const std::shared_ptr<const UnwindPlan> &b) {
LazyBool plans_are_identical = eLazyBoolCalculate;
if (!a || !b)
return eLazyBoolCalculate;

RegisterNumber pc_reg(thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
uint32_t pc_reg_lldb_regnum = pc_reg.GetAsKind(eRegisterKindLLDB);
const UnwindPlan::Row *a_first_row = a->GetRowAtIndex(0);
const UnwindPlan::Row *b_first_row = b->GetRowAtIndex(0);
if (!a_first_row || !b_first_row)
return eLazyBoolCalculate;

if (a && b) {
const UnwindPlan::Row *a_first_row = a->GetRowAtIndex(0);
const UnwindPlan::Row *b_first_row = b->GetRowAtIndex(0);
RegisterNumber pc_reg(thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
uint32_t a_pc_regnum = pc_reg.GetAsKind(a->GetRegisterKind());
uint32_t b_pc_regnum = pc_reg.GetAsKind(b->GetRegisterKind());

if (a_first_row && b_first_row) {
UnwindPlan::Row::AbstractRegisterLocation a_pc_regloc;
UnwindPlan::Row::AbstractRegisterLocation b_pc_regloc;
UnwindPlan::Row::AbstractRegisterLocation a_pc_regloc;
UnwindPlan::Row::AbstractRegisterLocation b_pc_regloc;

a_first_row->GetRegisterInfo(pc_reg_lldb_regnum, a_pc_regloc);
b_first_row->GetRegisterInfo(pc_reg_lldb_regnum, b_pc_regloc);
a_first_row->GetRegisterInfo(a_pc_regnum, a_pc_regloc);
b_first_row->GetRegisterInfo(b_pc_regnum, b_pc_regloc);

plans_are_identical = eLazyBoolYes;
if (a_first_row->GetCFAValue() != b_first_row->GetCFAValue())
return eLazyBoolNo;
if (a_pc_regloc != b_pc_regloc)
return eLazyBoolNo;

if (a_first_row->GetCFAValue() != b_first_row->GetCFAValue()) {
plans_are_identical = eLazyBoolNo;
}
if (a_pc_regloc != b_pc_regloc) {
plans_are_identical = eLazyBoolNo;
}
}
}
return plans_are_identical;
return eLazyBoolYes;
}

std::shared_ptr<const UnwindPlan>
Expand Down
Loading