Skip to content

Commit adabc83

Browse files
authored
[lldb] Merge/unify ABI-provided AArch64 unwind plans (#139545)
The macos and sysv ABIs return functionally equivalent unwind plans, so they can be implemented in the base AArch64 class. The only difference between them was that the macos plan provided a "pc=lr" rule whereas the sysv plan called SetReturnAddressRegister (which causes the unwind machinery to act as if that rule was present). This difference was enough to cause `CompareUnwindPlansForIdenticalInitialPCLocation` to return a different value and break the (temporarily reverted) TestUnwindFramelessFaulted test. While merging the two functions, I couldn't stop myself from simplifying them to use the generic register number schemes -- which exposed another bug in CompareUnwindPlansForIdenticalInitialPCLocation, namely that it was expecting all unwind plans to use the LLDB numbering scheme. This patch fixes that as well.
1 parent 019d769 commit adabc83

File tree

7 files changed

+63
-118
lines changed

7 files changed

+63
-118
lines changed

lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <optional>
2020

2121
using namespace lldb;
22+
using namespace lldb_private;
2223

2324
LLDB_PLUGIN_DEFINE(ABIAArch64)
2425

@@ -200,3 +201,44 @@ void ABIAArch64::AugmentRegisterInfo(
200201
lldb::eEncodingIEEE754, lldb::eFormatFloat);
201202
}
202203
}
204+
205+
UnwindPlanSP ABIAArch64::CreateFunctionEntryUnwindPlan() {
206+
UnwindPlan::Row row;
207+
208+
// Our previous Call Frame Address is the stack pointer
209+
row.GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, 0);
210+
211+
// Our previous PC is in the LR, all other registers are the same.
212+
row.SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC,
213+
LLDB_REGNUM_GENERIC_RA, true);
214+
215+
auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindGeneric);
216+
plan_sp->AppendRow(std::move(row));
217+
plan_sp->SetSourceName("arm64 at-func-entry default");
218+
plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
219+
plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
220+
plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
221+
return plan_sp;
222+
}
223+
224+
UnwindPlanSP ABIAArch64::CreateDefaultUnwindPlan() {
225+
UnwindPlan::Row row;
226+
const int32_t ptr_size = 8;
227+
228+
row.GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP,
229+
2 * ptr_size);
230+
row.SetUnspecifiedRegistersAreUndefined(true);
231+
232+
row.SetRegisterLocationToAtCFAPlusOffset(LLDB_REGNUM_GENERIC_FP,
233+
ptr_size * -2, true);
234+
row.SetRegisterLocationToAtCFAPlusOffset(LLDB_REGNUM_GENERIC_PC,
235+
ptr_size * -1, true);
236+
237+
auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindGeneric);
238+
plan_sp->AppendRow(std::move(row));
239+
plan_sp->SetSourceName("arm64 default unwind plan");
240+
plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
241+
plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
242+
plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
243+
return plan_sp;
244+
}

lldb/source/Plugins/ABI/AArch64/ABIAArch64.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ class ABIAArch64 : public lldb_private::MCBasedABI {
1919
lldb::addr_t FixCodeAddress(lldb::addr_t pc) override;
2020
lldb::addr_t FixDataAddress(lldb::addr_t pc) override;
2121

22+
lldb::UnwindPlanSP CreateFunctionEntryUnwindPlan() override;
23+
lldb::UnwindPlanSP CreateDefaultUnwindPlan() override;
24+
2225
protected:
2326
virtual lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) {
2427
return pc;

lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "lldb/Core/Module.h"
1818
#include "lldb/Core/PluginManager.h"
1919
#include "lldb/Core/Value.h"
20-
#include "lldb/Symbol/UnwindPlan.h"
2120
#include "lldb/Target/Process.h"
2221
#include "lldb/Target/RegisterContext.h"
2322
#include "lldb/Target/Target.h"
@@ -30,8 +29,6 @@
3029
#include "lldb/Utility/Status.h"
3130
#include "lldb/ValueObject/ValueObjectConstResult.h"
3231

33-
#include "Utility/ARM64_DWARF_Registers.h"
34-
3532
using namespace lldb;
3633
using namespace lldb_private;
3734

@@ -344,48 +341,6 @@ ABIMacOSX_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
344341
return error;
345342
}
346343

347-
UnwindPlanSP ABIMacOSX_arm64::CreateFunctionEntryUnwindPlan() {
348-
uint32_t lr_reg_num = arm64_dwarf::lr;
349-
uint32_t sp_reg_num = arm64_dwarf::sp;
350-
uint32_t pc_reg_num = arm64_dwarf::pc;
351-
352-
UnwindPlan::Row row;
353-
354-
// Our previous Call Frame Address is the stack pointer
355-
row.GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
356-
357-
// Our previous PC is in the LR, all other registers are the same.
358-
row.SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
359-
360-
auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
361-
plan_sp->AppendRow(std::move(row));
362-
plan_sp->SetSourceName("arm64 at-func-entry default");
363-
plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
364-
return plan_sp;
365-
}
366-
367-
UnwindPlanSP ABIMacOSX_arm64::CreateDefaultUnwindPlan() {
368-
uint32_t fp_reg_num = arm64_dwarf::fp;
369-
uint32_t pc_reg_num = arm64_dwarf::pc;
370-
371-
UnwindPlan::Row row;
372-
const int32_t ptr_size = 8;
373-
374-
row.GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
375-
row.SetUnspecifiedRegistersAreUndefined(true);
376-
377-
row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
378-
row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
379-
380-
auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
381-
plan_sp->AppendRow(std::move(row));
382-
plan_sp->SetSourceName("arm64-apple-darwin default unwind plan");
383-
plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
384-
plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
385-
plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
386-
return plan_sp;
387-
}
388-
389344
// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says
390345
// registers x19 through x28 and sp are callee preserved. v8-v15 are non-
391346
// volatile (and specifically only the lower 8 bytes of these regs), the rest

lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ class ABIMacOSX_arm64 : public ABIAArch64 {
2727
bool GetArgumentValues(lldb_private::Thread &thread,
2828
lldb_private::ValueList &values) const override;
2929

30-
lldb::UnwindPlanSP CreateFunctionEntryUnwindPlan() override;
31-
32-
lldb::UnwindPlanSP CreateDefaultUnwindPlan() override;
33-
3430
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
3531

3632
// The arm64 ABI requires that stack frames be 16 byte aligned.

lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
#include "lldb/Utility/Status.h"
3131
#include "lldb/ValueObject/ValueObjectConstResult.h"
3232

33-
#include "Utility/ARM64_DWARF_Registers.h"
34-
3533
using namespace lldb;
3634
using namespace lldb_private;
3735

@@ -385,48 +383,6 @@ Status ABISysV_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
385383
return error;
386384
}
387385

388-
UnwindPlanSP ABISysV_arm64::CreateFunctionEntryUnwindPlan() {
389-
uint32_t lr_reg_num = arm64_dwarf::lr;
390-
uint32_t sp_reg_num = arm64_dwarf::sp;
391-
392-
UnwindPlan::Row row;
393-
394-
// Our previous Call Frame Address is the stack pointer, all other registers
395-
// are the same.
396-
row.GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
397-
398-
auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
399-
plan_sp->AppendRow(std::move(row));
400-
plan_sp->SetReturnAddressRegister(lr_reg_num);
401-
plan_sp->SetSourceName("arm64 at-func-entry default");
402-
plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
403-
plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
404-
plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
405-
return plan_sp;
406-
}
407-
408-
UnwindPlanSP ABISysV_arm64::CreateDefaultUnwindPlan() {
409-
uint32_t fp_reg_num = arm64_dwarf::fp;
410-
uint32_t pc_reg_num = arm64_dwarf::pc;
411-
412-
UnwindPlan::Row row;
413-
const int32_t ptr_size = 8;
414-
415-
row.GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
416-
row.SetUnspecifiedRegistersAreUndefined(true);
417-
418-
row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
419-
row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
420-
421-
auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
422-
plan_sp->AppendRow(std::move(row));
423-
plan_sp->SetSourceName("arm64 default unwind plan");
424-
plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
425-
plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
426-
plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
427-
return plan_sp;
428-
}
429-
430386
// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says
431387
// registers x19 through x28 and sp are callee preserved. v8-v15 are non-
432388
// volatile (and specifically only the lower 8 bytes of these regs), the rest

lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,6 @@ class ABISysV_arm64 : public ABIAArch64 {
3030
SetReturnValueObject(lldb::StackFrameSP &frame_sp,
3131
lldb::ValueObjectSP &new_value) override;
3232

33-
lldb::UnwindPlanSP CreateFunctionEntryUnwindPlan() override;
34-
35-
lldb::UnwindPlanSP CreateDefaultUnwindPlan() override;
36-
3733
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
3834

3935
// The arm64 ABI requires that stack frames be 16 byte aligned.

lldb/source/Symbol/FuncUnwinders.cpp

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -365,33 +365,30 @@ FuncUnwinders::GetAssemblyUnwindPlan(Target &target, Thread &thread) {
365365
LazyBool FuncUnwinders::CompareUnwindPlansForIdenticalInitialPCLocation(
366366
Thread &thread, const std::shared_ptr<const UnwindPlan> &a,
367367
const std::shared_ptr<const UnwindPlan> &b) {
368-
LazyBool plans_are_identical = eLazyBoolCalculate;
368+
if (!a || !b)
369+
return eLazyBoolCalculate;
369370

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

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

377-
if (a_first_row && b_first_row) {
378-
UnwindPlan::Row::AbstractRegisterLocation a_pc_regloc;
379-
UnwindPlan::Row::AbstractRegisterLocation b_pc_regloc;
380+
UnwindPlan::Row::AbstractRegisterLocation a_pc_regloc;
381+
UnwindPlan::Row::AbstractRegisterLocation b_pc_regloc;
380382

381-
a_first_row->GetRegisterInfo(pc_reg_lldb_regnum, a_pc_regloc);
382-
b_first_row->GetRegisterInfo(pc_reg_lldb_regnum, b_pc_regloc);
383+
a_first_row->GetRegisterInfo(a_pc_regnum, a_pc_regloc);
384+
b_first_row->GetRegisterInfo(b_pc_regnum, b_pc_regloc);
383385

384-
plans_are_identical = eLazyBoolYes;
386+
if (a_first_row->GetCFAValue() != b_first_row->GetCFAValue())
387+
return eLazyBoolNo;
388+
if (a_pc_regloc != b_pc_regloc)
389+
return eLazyBoolNo;
385390

386-
if (a_first_row->GetCFAValue() != b_first_row->GetCFAValue()) {
387-
plans_are_identical = eLazyBoolNo;
388-
}
389-
if (a_pc_regloc != b_pc_regloc) {
390-
plans_are_identical = eLazyBoolNo;
391-
}
392-
}
393-
}
394-
return plans_are_identical;
391+
return eLazyBoolYes;
395392
}
396393

397394
std::shared_ptr<const UnwindPlan>

0 commit comments

Comments
 (0)