[Lldb-commits] [lldb] r285662 - Fix a bug where the EmulateInstructionARM64 handling of STP/LDP instructions
Jason Molenda via lldb-commits
lldb-commits at lists.llvm.org
Mon Oct 31 18:26:55 PDT 2016
Author: jmolenda
Date: Mon Oct 31 20:26:54 2016
New Revision: 285662
URL: http://llvm.org/viewvc/llvm-project?rev=285662&view=rev
Log:
Fix a bug where the EmulateInstructionARM64 handling of STP/LDP instructions
for floating point registers was not recording them correctly. I needed to
change the EmulateInstructionARM64 unwind plans from using the DWARF
register numbering scheme to using the LLDB register numbering scheme
(because dwarf doesn't define register numbers for the 64-bit "d" registers).
Updated the EmulateInstructionARM64 unit tests to work with the LLDB
register numbering scheme and added a unit test to check the floating
point register spills & restores are correctly recorded.
https://reviews.llvm.org/D25864
<rdar://problem/28745483>
Modified:
lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
lldb/trunk/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp
Modified: lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp?rev=285662&r1=285661&r2=285662&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp Mon Oct 31 20:26:54 2016
@@ -21,7 +21,24 @@
#include "Plugins/Process/Utility/ARMDefines.h"
#include "Plugins/Process/Utility/ARMUtils.h"
-#include "Utility/ARM64_DWARF_Registers.h"
+#include "Plugins/Process/Utility/lldb-arm64-register-enums.h"
+
+#define GPR_OFFSET(idx) ((idx)*8)
+#define GPR_OFFSET_NAME(reg) 0
+#define FPU_OFFSET(idx) ((idx)*16)
+#define FPU_OFFSET_NAME(reg) 0
+#define EXC_OFFSET_NAME(reg) 0
+#define DBG_OFFSET_NAME(reg) 0
+#define DBG_OFFSET_NAME(reg) 0
+#define DEFINE_DBG(re, y) \
+ "na", nullptr, 8, 0, lldb::eEncodingUint, lldb::eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, \
+ nullptr, nullptr, nullptr, 0
+
+#define DECLARE_REGISTER_INFOS_ARM64_STRUCT
+
+#include "Plugins/Process/Utility/RegisterInfos_arm64.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
@@ -32,6 +49,13 @@
using namespace lldb;
using namespace lldb_private;
+static bool LLDBTableGetRegisterInfo(uint32_t reg_num, RegisterInfo ®_info) {
+ if (reg_num >= llvm::array_lengthof(g_register_infos_arm64_le))
+ return false;
+ reg_info = g_register_infos_arm64_le[reg_num];
+ return true;
+}
+
#define No_VFP 0
#define VFPv1 (1u << 1)
#define VFPv2 (1u << 2)
@@ -168,41 +192,33 @@ bool EmulateInstructionARM64::GetRegiste
if (reg_kind == eRegisterKindGeneric) {
switch (reg_num) {
case LLDB_REGNUM_GENERIC_PC:
- reg_kind = eRegisterKindDWARF;
- reg_num = arm64_dwarf::pc;
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_pc_arm64;
break;
case LLDB_REGNUM_GENERIC_SP:
- reg_kind = eRegisterKindDWARF;
- reg_num = arm64_dwarf::sp;
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_sp_arm64;
break;
case LLDB_REGNUM_GENERIC_FP:
- reg_kind = eRegisterKindDWARF;
- reg_num = arm64_dwarf::fp;
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_fp_arm64;
break;
case LLDB_REGNUM_GENERIC_RA:
- reg_kind = eRegisterKindDWARF;
- reg_num = arm64_dwarf::lr;
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_lr_arm64;
break;
case LLDB_REGNUM_GENERIC_FLAGS:
- // There is no DWARF register number for the CPSR right now...
- reg_info.name = "cpsr";
- reg_info.alt_name = NULL;
- reg_info.byte_size = 4;
- reg_info.byte_offset = 0;
- reg_info.encoding = eEncodingUint;
- reg_info.format = eFormatHex;
- for (uint32_t i = 0; i < lldb::kNumRegisterKinds; ++i)
- reg_info.kinds[reg_kind] = LLDB_INVALID_REGNUM;
- reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
- return true;
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_cpsr_arm64;
+ break;
default:
return false;
}
}
- if (reg_kind == eRegisterKindDWARF)
- return arm64_dwarf::GetRegisterInfo(reg_num, reg_info);
+ if (reg_kind == eRegisterKindLLDB)
+ return LLDBTableGetRegisterInfo(reg_num, reg_info);
return false;
}
@@ -429,12 +445,8 @@ bool EmulateInstructionARM64::EvaluateIn
bool success = false;
// if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
// {
- // m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric,
- // // use eRegisterKindDWARF is we ever get a cpsr DWARF register
- // number
- // LLDB_REGNUM_GENERIC_FLAGS,
- // // use arm64_dwarf::cpsr if we
- // ever get one
+ // m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindLLDB,
+ // gpr_cpsr_arm64,
// 0,
// &success);
// }
@@ -447,7 +459,7 @@ bool EmulateInstructionARM64::EvaluateIn
uint32_t orig_pc_value = 0;
if (auto_advance_pc) {
orig_pc_value =
- ReadRegisterUnsigned(eRegisterKindDWARF, arm64_dwarf::pc, 0, &success);
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_pc_arm64, 0, &success);
if (!success)
return false;
}
@@ -459,7 +471,7 @@ bool EmulateInstructionARM64::EvaluateIn
if (auto_advance_pc) {
uint32_t new_pc_value =
- ReadRegisterUnsigned(eRegisterKindDWARF, arm64_dwarf::pc, 0, &success);
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_pc_arm64, 0, &success);
if (!success)
return false;
@@ -467,7 +479,7 @@ bool EmulateInstructionARM64::EvaluateIn
EmulateInstruction::Context context;
context.type = eContextAdvancePC;
context.SetNoArgs();
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, arm64_dwarf::pc,
+ if (!WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_pc_arm64,
orig_pc_value + 4))
return false;
}
@@ -478,18 +490,18 @@ bool EmulateInstructionARM64::EvaluateIn
bool EmulateInstructionARM64::CreateFunctionEntryUnwind(
UnwindPlan &unwind_plan) {
unwind_plan.Clear();
- unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+ unwind_plan.SetRegisterKind(eRegisterKindLLDB);
UnwindPlan::RowSP row(new UnwindPlan::Row);
// Our previous Call Frame Address is the stack pointer
- row->GetCFAValue().SetIsRegisterPlusOffset(arm64_dwarf::sp, 0);
+ row->GetCFAValue().SetIsRegisterPlusOffset(gpr_sp_arm64, 0);
unwind_plan.AppendRow(row);
unwind_plan.SetSourceName("EmulateInstructionARM64");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
- unwind_plan.SetReturnAddressRegister(arm64_dwarf::lr);
+ unwind_plan.SetReturnAddressRegister(gpr_lr_arm64);
return true;
}
@@ -497,7 +509,7 @@ uint32_t EmulateInstructionARM64::GetFra
if (m_arch.GetTriple().isAndroid())
return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
- return arm64_dwarf::fp;
+ return gpr_fp_arm64;
}
bool EmulateInstructionARM64::UsingAArch32() {
@@ -664,8 +676,8 @@ bool EmulateInstructionARM64::EmulateADD
return false; // UNDEFINED;
}
uint64_t result;
- uint64_t operand1 = ReadRegisterUnsigned(eRegisterKindDWARF,
- arm64_dwarf::x0 + n, 0, &success);
+ uint64_t operand1 =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + n, 0, &success);
uint64_t operand2 = imm;
bit carry_in;
@@ -690,28 +702,26 @@ bool EmulateInstructionARM64::EmulateADD
Context context;
RegisterInfo reg_info_Rn;
- if (arm64_dwarf::GetRegisterInfo(n, reg_info_Rn))
+ if (GetRegisterInfo(eRegisterKindLLDB, n, reg_info_Rn))
context.SetRegisterPlusOffset(reg_info_Rn, imm);
- if (n == GetFramePointerRegisterNumber() && d == arm64_dwarf::sp &&
- !setflags) {
+ if (n == GetFramePointerRegisterNumber() && d == gpr_sp_arm64 && !setflags) {
// 'mov sp, fp' - common epilogue instruction, CFA is now in terms
// of the stack pointer, instead of frame pointer.
context.type = EmulateInstruction::eContextRestoreStackPointer;
- } else if ((n == arm64_dwarf::sp || n == GetFramePointerRegisterNumber()) &&
- d == arm64_dwarf::sp && !setflags) {
+ } else if ((n == gpr_sp_arm64 || n == GetFramePointerRegisterNumber()) &&
+ d == gpr_sp_arm64 && !setflags) {
context.type = EmulateInstruction::eContextAdjustStackPointer;
- } else if (d == GetFramePointerRegisterNumber() && n == arm64_dwarf::sp &&
+ } else if (d == GetFramePointerRegisterNumber() && n == gpr_sp_arm64 &&
!setflags) {
context.type = EmulateInstruction::eContextSetFramePointer;
} else {
context.type = EmulateInstruction::eContextImmediate;
}
- // If setflags && d == arm64_dwarf::sp then d = WZR/XZR. See CMN, CMP
- if (!setflags || d != arm64_dwarf::sp)
- WriteRegisterUnsigned(context, eRegisterKindDWARF, arm64_dwarf::x0 + d,
- result);
+ // If setflags && d == gpr_sp_arm64 then d = WZR/XZR. See CMN, CMP
+ if (!setflags || d != gpr_sp_arm64)
+ WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_x0_arm64 + d, result);
return false;
}
@@ -804,19 +814,18 @@ bool EmulateInstructionARM64::EmulateLDP
RegisterInfo reg_info_base;
RegisterInfo reg_info_Rt;
RegisterInfo reg_info_Rt2;
- if (!GetRegisterInfo(eRegisterKindDWARF, arm64_dwarf::x0 + n, reg_info_base))
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + n, reg_info_base))
return false;
if (vector) {
- if (!GetRegisterInfo(eRegisterKindDWARF, arm64_dwarf::v0 + n, reg_info_Rt))
+ if (!GetRegisterInfo(eRegisterKindLLDB, fpu_d0_arm64 + t, reg_info_Rt))
return false;
- if (!GetRegisterInfo(eRegisterKindDWARF, arm64_dwarf::v0 + n, reg_info_Rt2))
+ if (!GetRegisterInfo(eRegisterKindLLDB, fpu_d0_arm64 + t2, reg_info_Rt2))
return false;
} else {
- if (!GetRegisterInfo(eRegisterKindDWARF, arm64_dwarf::x0 + t, reg_info_Rt))
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + t, reg_info_Rt))
return false;
- if (!GetRegisterInfo(eRegisterKindDWARF, arm64_dwarf::x0 + t2,
- reg_info_Rt2))
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + t2, reg_info_Rt2))
return false;
}
@@ -824,10 +833,10 @@ bool EmulateInstructionARM64::EmulateLDP
if (n == 31) {
// CheckSPAlignment();
address =
- ReadRegisterUnsigned(eRegisterKindDWARF, arm64_dwarf::sp, 0, &success);
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_sp_arm64, 0, &success);
} else
- address = ReadRegisterUnsigned(eRegisterKindDWARF, arm64_dwarf::x0 + n, 0,
- &success);
+ address =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + n, 0, &success);
wb_address = address + idx;
if (a_mode != AddrMode_POST)
@@ -991,10 +1000,10 @@ bool EmulateInstructionARM64::EmulateLDR
if (n == 31)
address =
- ReadRegisterUnsigned(eRegisterKindDWARF, arm64_dwarf::sp, 0, &success);
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_sp_arm64, 0, &success);
else
- address = ReadRegisterUnsigned(eRegisterKindDWARF, arm64_dwarf::x0 + n, 0,
- &success);
+ address =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + n, 0, &success);
if (!success)
return false;
@@ -1003,11 +1012,11 @@ bool EmulateInstructionARM64::EmulateLDR
address += offset;
RegisterInfo reg_info_base;
- if (!GetRegisterInfo(eRegisterKindDWARF, arm64_dwarf::x0 + n, reg_info_base))
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + n, reg_info_base))
return false;
RegisterInfo reg_info_Rt;
- if (!GetRegisterInfo(eRegisterKindDWARF, arm64_dwarf::x0 + t, reg_info_Rt))
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + t, reg_info_Rt))
return false;
Context context;
@@ -1096,8 +1105,7 @@ bool EmulateInstructionARM64::EmulateB(c
switch (branch_type) {
case BranchType_CALL: {
addr_t x30 = pc + 4;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, arm64_dwarf::x30,
- x30))
+ if (!WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_lr_arm64, x30))
return false;
} break;
case BranchType_JMP:
@@ -1158,8 +1166,8 @@ bool EmulateInstructionARM64::EmulateCBZ
bool is_zero = Bit32(opcode, 24) == 0;
int32_t offset = llvm::SignExtend64<21>(Bits32(opcode, 23, 5) << 2);
- const uint64_t operand = ReadRegisterUnsigned(
- eRegisterKindDWARF, arm64_dwarf::x0 + t, 0, &success);
+ const uint64_t operand =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + t, 0, &success);
if (!success)
return false;
@@ -1194,8 +1202,8 @@ bool EmulateInstructionARM64::EmulateTBZ
uint32_t bit_val = Bit32(opcode, 24);
int64_t offset = llvm::SignExtend64<16>(Bits32(opcode, 18, 5) << 2);
- const uint64_t operand = ReadRegisterUnsigned(
- eRegisterKindDWARF, arm64_dwarf::x0 + t, 0, &success);
+ const uint64_t operand =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + t, 0, &success);
if (!success)
return false;
Modified: lldb/trunk/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp?rev=285662&r1=285661&r2=285662&view=diff
==============================================================================
--- lldb/trunk/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp (original)
+++ lldb/trunk/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp Mon Oct 31 20:26:54 2016
@@ -14,7 +14,6 @@
#include <vector>
#include "Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h"
-#include "Utility/ARM64_DWARF_Registers.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h"
@@ -24,6 +23,7 @@
#include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h"
#include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h"
+#include "Plugins/Process/Utility/lldb-arm64-register-enums.h"
#include "llvm/Support/TargetSelect.h"
using namespace lldb;
@@ -93,59 +93,59 @@ TEST_F(TestArm64InstEmulation, TestSimpl
// CFA=sp +0
row_sp = unwind_plan.GetRowForFunctionOffset(0);
EXPECT_EQ(0ull, row_sp->GetOffset());
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset());
// CFA=sp+16 => fp=[CFA-16] lr=[CFA-8]
row_sp = unwind_plan.GetRowForFunctionOffset(4);
EXPECT_EQ(4ull, row_sp->GetOffset());
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::fp, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_fp_arm64, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-16, regloc.GetOffset());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::lr, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_lr_arm64, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-8, regloc.GetOffset());
// CFA=fp+16 => fp=[CFA-16] lr=[CFA-8]
row_sp = unwind_plan.GetRowForFunctionOffset(8);
EXPECT_EQ(8ull, row_sp->GetOffset());
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::fp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_fp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::fp, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_fp_arm64, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-16, regloc.GetOffset());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::lr, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_lr_arm64, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-8, regloc.GetOffset());
// CFA=sp+16 => fp=[CFA-16] lr=[CFA-8]
row_sp = unwind_plan.GetRowForFunctionOffset(16);
EXPECT_EQ(16ull, row_sp->GetOffset());
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::fp, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_fp_arm64, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-16, regloc.GetOffset());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::lr, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_lr_arm64, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-8, regloc.GetOffset());
// CFA=sp +0 => fp= <same> lr= <same>
row_sp = unwind_plan.GetRowForFunctionOffset(20);
EXPECT_EQ(20ull, row_sp->GetOffset());
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset());
}
@@ -210,35 +210,35 @@ TEST_F(TestArm64InstEmulation, TestMediu
// 0: CFA=sp +0 =>
row_sp = unwind_plan.GetRowForFunctionOffset(0);
EXPECT_EQ(0ull, row_sp->GetOffset());
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset());
// 4: CFA=sp+48 => x21=[CFA-40] x22=[CFA-48]
row_sp = unwind_plan.GetRowForFunctionOffset(4);
EXPECT_EQ(4ull, row_sp->GetOffset());
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
EXPECT_EQ(48, row_sp->GetCFAValue().GetOffset());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x21, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x21_arm64, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-40, regloc.GetOffset());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x22, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x22_arm64, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-48, regloc.GetOffset());
// 8: CFA=sp+48 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48]
row_sp = unwind_plan.GetRowForFunctionOffset(8);
EXPECT_EQ(8ull, row_sp->GetOffset());
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
EXPECT_EQ(48, row_sp->GetCFAValue().GetOffset());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x19, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x19_arm64, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-24, regloc.GetOffset());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x20, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x20_arm64, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-32, regloc.GetOffset());
@@ -246,14 +246,14 @@ TEST_F(TestArm64InstEmulation, TestMediu
// fp=[CFA-16] lr=[CFA-8]
row_sp = unwind_plan.GetRowForFunctionOffset(12);
EXPECT_EQ(12ull, row_sp->GetOffset());
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
EXPECT_EQ(48, row_sp->GetCFAValue().GetOffset());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::fp, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_fp_arm64, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-16, regloc.GetOffset());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::lr, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_lr_arm64, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-8, regloc.GetOffset());
@@ -261,7 +261,7 @@ TEST_F(TestArm64InstEmulation, TestMediu
// fp=[CFA-16] lr=[CFA-8]
row_sp = unwind_plan.GetRowForFunctionOffset(16);
EXPECT_EQ(16ull, row_sp->GetOffset());
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::fp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_fp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset());
@@ -269,7 +269,7 @@ TEST_F(TestArm64InstEmulation, TestMediu
// fp=[CFA-16] lr=[CFA-8]
row_sp = unwind_plan.GetRowForFunctionOffset(28);
EXPECT_EQ(28ull, row_sp->GetOffset());
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(48, row_sp->GetCFAValue().GetOffset());
@@ -280,10 +280,10 @@ TEST_F(TestArm64InstEmulation, TestMediu
// I'd prefer if these restored registers were cleared entirely instead of set
// to IsSame...
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::fp, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_fp_arm64, regloc));
EXPECT_TRUE(regloc.IsSame());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::lr, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_lr_arm64, regloc));
EXPECT_TRUE(regloc.IsSame());
// 36: CFA=sp+48 => x19= <same> x20= <same> x21=[CFA-40] x22=[CFA-48] fp=
@@ -291,24 +291,24 @@ TEST_F(TestArm64InstEmulation, TestMediu
row_sp = unwind_plan.GetRowForFunctionOffset(36);
EXPECT_EQ(36ull, row_sp->GetOffset());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x19, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x19_arm64, regloc));
EXPECT_TRUE(regloc.IsSame());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x20, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x20_arm64, regloc));
EXPECT_TRUE(regloc.IsSame());
// 40: CFA=sp +0 => x19= <same> x20= <same> x21= <same> x22= <same> fp= <same>
// lr= <same>
row_sp = unwind_plan.GetRowForFunctionOffset(40);
EXPECT_EQ(40ull, row_sp->GetOffset());
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x21, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x21_arm64, regloc));
EXPECT_TRUE(regloc.IsSame());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x22, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x22_arm64, regloc));
EXPECT_TRUE(regloc.IsSame());
}
@@ -364,45 +364,45 @@ TEST_F(TestArm64InstEmulation, TestFrame
// 0: CFA=sp +0 =>
row_sp = unwind_plan.GetRowForFunctionOffset(0);
EXPECT_EQ(0ull, row_sp->GetOffset());
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset());
row_sp = unwind_plan.GetRowForFunctionOffset(32);
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset());
- EXPECT_FALSE(row_sp->GetRegisterInfo(arm64_dwarf::x19, regloc));
- EXPECT_FALSE(row_sp->GetRegisterInfo(arm64_dwarf::x20, regloc));
- EXPECT_FALSE(row_sp->GetRegisterInfo(arm64_dwarf::x21, regloc));
- EXPECT_FALSE(row_sp->GetRegisterInfo(arm64_dwarf::x22, regloc));
- EXPECT_FALSE(row_sp->GetRegisterInfo(arm64_dwarf::x23, regloc));
- EXPECT_FALSE(row_sp->GetRegisterInfo(arm64_dwarf::x24, regloc));
- EXPECT_FALSE(row_sp->GetRegisterInfo(arm64_dwarf::x25, regloc));
- EXPECT_FALSE(row_sp->GetRegisterInfo(arm64_dwarf::x26, regloc));
- EXPECT_FALSE(row_sp->GetRegisterInfo(arm64_dwarf::x27, regloc));
- EXPECT_FALSE(row_sp->GetRegisterInfo(arm64_dwarf::x28, regloc));
- EXPECT_FALSE(row_sp->GetRegisterInfo(arm64_dwarf::fp, regloc));
- EXPECT_FALSE(row_sp->GetRegisterInfo(arm64_dwarf::lr, regloc));
+ EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x19_arm64, regloc));
+ EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x20_arm64, regloc));
+ EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x21_arm64, regloc));
+ EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x22_arm64, regloc));
+ EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x23_arm64, regloc));
+ EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x24_arm64, regloc));
+ EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x25_arm64, regloc));
+ EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x26_arm64, regloc));
+ EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x27_arm64, regloc));
+ EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_x28_arm64, regloc));
+ EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_fp_arm64, regloc));
+ EXPECT_FALSE(row_sp->GetRegisterInfo(gpr_lr_arm64, regloc));
row_sp = unwind_plan.GetRowForFunctionOffset(36);
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset());
row_sp = unwind_plan.GetRowForFunctionOffset(52);
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset());
row_sp = unwind_plan.GetRowForFunctionOffset(56);
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset());
row_sp = unwind_plan.GetRowForFunctionOffset(60);
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset());
}
@@ -490,21 +490,183 @@ TEST_F(TestArm64InstEmulation, TestRegis
row_sp = unwind_plan.GetRowForFunctionOffset(36);
EXPECT_EQ(28ull, row_sp->GetOffset());
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::fp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_fp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x20, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x20_arm64, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-32, regloc.GetOffset());
row_sp = unwind_plan.GetRowForFunctionOffset(40);
EXPECT_EQ(28ull, row_sp->GetOffset());
- EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::fp);
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_fp_arm64);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset());
- EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x20, regloc));
+ EXPECT_TRUE(row_sp->GetRegisterInfo(gpr_x20_arm64, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-32, regloc.GetOffset());
}
+
+TEST_F(TestArm64InstEmulation, TestRegisterDoubleSpills) {
+ ArchSpec arch("arm64-apple-ios10", nullptr);
+ UnwindAssemblyInstEmulation *engine =
+ static_cast<UnwindAssemblyInstEmulation *>(
+ UnwindAssemblyInstEmulation::CreateInstance(arch));
+ ASSERT_NE(nullptr, engine);
+
+ UnwindPlan::RowSP row_sp;
+ AddressRange sample_range;
+ UnwindPlan unwind_plan(eRegisterKindLLDB);
+ UnwindPlan::Row::RegisterLocation regloc;
+
+ // this file built with clang for iOS arch arm64 optimization -Os
+ // #include <stdio.h>
+ // double foo(double in) {
+ // double arr[32];
+ // for (int i = 0; i < 32; i++)
+ // arr[i] = in + i;
+ // for (int i = 2; i < 30; i++)
+ // arr[i] = ((((arr[i - 1] * arr[i - 2] * 0.2) + (0.7 * arr[i])) /
+ // ((((arr[i] * 0.73) + 0.65) * (arr[i - 1] + 0.2)) - ((arr[i + 1] + (arr[i]
+ // * 0.32) + 0.52) / 0.3) + (0.531 * arr[i - 2]))) + ((arr[i - 1] + 5) /
+ // ((arr[i + 2] + 0.4) / arr[i])) + (arr[5] * (0.17 + arr[7] * arr[i])) +
+ // ((i > 5 ? (arr[i - 3]) : arr[i - 1]) * 0.263) + (((arr[i - 2] + arr[i -
+ // 1]) * 0.3252) + 3.56) - (arr[i + 1] * 0.852311)) * ((arr[i] * 85234.1345)
+ // + (77342.451324 / (arr[i - 2] + arr[i - 1] - 73425341.33455))) + (arr[i]
+ // * 875712013.55) - (arr[i - 1] * 0.5555) - ((arr[i] * (arr[i + 1] +
+ // 17342834.44) / 8688200123.555)) + (arr[i - 2] + 8888.888);
+ // return arr[16];
+ //}
+ // int main(int argc, char **argv) { printf("%g\n", foo(argc)); }
+
+ // so function foo() uses enough registers that it spills the callee-saved
+ // floating point registers.
+ uint8_t data[] = {
+ // prologue
+ 0xef, 0x3b, 0xba, 0x6d, // 0: 0x6dba3bef stp d15, d14, [sp, #-0x60]!
+ 0xed, 0x33, 0x01, 0x6d, // 4: 0x6d0133ed stp d13, d12, [sp, #0x10]
+ 0xeb, 0x2b, 0x02, 0x6d, // 8: 0x6d022beb stp d11, d10, [sp, #0x20]
+ 0xe9, 0x23, 0x03, 0x6d, // 12: 0x6d0323e9 stp d9, d8, [sp, #0x30]
+ 0xfc, 0x6f, 0x04, 0xa9, // 16: 0xa9046ffc stp x28, x27, [sp, #0x40]
+ 0xfd, 0x7b, 0x05, 0xa9, // 20: 0xa9057bfd stp x29, x30, [sp, #0x50]
+ 0xfd, 0x43, 0x01, 0x91, // 24: 0x910143fd add x29, sp, #0x50
+ 0xff, 0x43, 0x04, 0xd1, // 28: 0xd10443ff sub sp, sp, #0x110
+
+ // epilogue
+ 0xbf, 0x43, 0x01, 0xd1, // 32: 0xd10143bf sub sp, x29, #0x50
+ 0xfd, 0x7b, 0x45, 0xa9, // 36: 0xa9457bfd ldp x29, x30, [sp, #0x50]
+ 0xfc, 0x6f, 0x44, 0xa9, // 40: 0xa9446ffc ldp x28, x27, [sp, #0x40]
+ 0xe9, 0x23, 0x43, 0x6d, // 44: 0x6d4323e9 ldp d9, d8, [sp, #0x30]
+ 0xeb, 0x2b, 0x42, 0x6d, // 48: 0x6d422beb ldp d11, d10, [sp, #0x20]
+ 0xed, 0x33, 0x41, 0x6d, // 52: 0x6d4133ed ldp d13, d12, [sp, #0x10]
+ 0xef, 0x3b, 0xc6, 0x6c, // 56: 0x6cc63bef ldp d15, d14, [sp], #0x60
+ 0xc0, 0x03, 0x5f, 0xd6, // 60: 0xd65f03c0 ret
+ };
+
+ // UnwindPlan we expect:
+ // 0: CFA=sp +0 =>
+ // 4: CFA=sp+96 => d14=[CFA-88] d15=[CFA-96]
+ // 8: CFA=sp+96 => d12=[CFA-72] d13=[CFA-80] d14=[CFA-88] d15=[CFA-96]
+ // 12: CFA=sp+96 => d10=[CFA-56] d11=[CFA-64] d12=[CFA-72] d13=[CFA-80]
+ // d14=[CFA-88] d15=[CFA-96]
+ // 16: CFA=sp+96 => d8=[CFA-40] d9=[CFA-48] d10=[CFA-56] d11=[CFA-64]
+ // d12=[CFA-72] d13=[CFA-80] d14=[CFA-88] d15=[CFA-96]
+ // 20: CFA=sp+96 => x27=[CFA-24] x28=[CFA-32] d8=[CFA-40] d9=[CFA-48]
+ // d10=[CFA-56] d11=[CFA-64] d12=[CFA-72] d13=[CFA-80] d14=[CFA-88]
+ // d15=[CFA-96]
+ // 24: CFA=sp+96 => x27=[CFA-24] x28=[CFA-32] fp=[CFA-16] lr=[CFA-8]
+ // d8=[CFA-40] d9=[CFA-48] d10=[CFA-56] d11=[CFA-64] d12=[CFA-72]
+ // d13=[CFA-80] d14=[CFA-88] d15=[CFA-96]
+ // 28: CFA=fp+16 => x27=[CFA-24] x28=[CFA-32] fp=[CFA-16] lr=[CFA-8]
+ // d8=[CFA-40] d9=[CFA-48] d10=[CFA-56] d11=[CFA-64] d12=[CFA-72]
+ // d13=[CFA-80] d14=[CFA-88] d15=[CFA-96]
+ // 36: CFA=sp+96 => x27=[CFA-24] x28=[CFA-32] fp=[CFA-16] lr=[CFA-8]
+ // d8=[CFA-40] d9=[CFA-48] d10=[CFA-56] d11=[CFA-64] d12=[CFA-72]
+ // d13=[CFA-80] d14=[CFA-88] d15=[CFA-96]
+ // 40: CFA=sp+96 => x27=[CFA-24] x28=[CFA-32] d8=[CFA-40] d9=[CFA-48]
+ // d10=[CFA-56] d11=[CFA-64] d12=[CFA-72] d13=[CFA-80] d14=[CFA-88]
+ // d15=[CFA-96]
+ // 44: CFA=sp+96 => d8=[CFA-40] d9=[CFA-48] d10=[CFA-56] d11=[CFA-64]
+ // d12=[CFA-72] d13=[CFA-80] d14=[CFA-88] d15=[CFA-96]
+ // 48: CFA=sp+96 => d10=[CFA-56] d11=[CFA-64] d12=[CFA-72] d13=[CFA-80]
+ // d14=[CFA-88] d15=[CFA-96]
+ // 52: CFA=sp+96 => d12=[CFA-72] d13=[CFA-80] d14=[CFA-88] d15=[CFA-96]
+ // 56: CFA=sp+96 => d14=[CFA-88] d15=[CFA-96]
+ // 60: CFA=sp +0 =>
+
+ sample_range = AddressRange(0x1000, sizeof(data));
+
+ EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(
+ sample_range, data, sizeof(data), unwind_plan));
+
+ // 28: CFA=fp+16 => x27=[CFA-24] x28=[CFA-32] fp=[CFA-16] lr=[CFA-8]
+ // d8=[CFA-40] d9=[CFA-48] d10=[CFA-56] d11=[CFA-64] d12=[CFA-72]
+ // d13=[CFA-80] d14=[CFA-88] d15=[CFA-96]
+ row_sp = unwind_plan.GetRowForFunctionOffset(28);
+ EXPECT_EQ(28ull, row_sp->GetOffset());
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_fp_arm64);
+ EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
+ EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset());
+
+ EXPECT_TRUE(row_sp->GetRegisterInfo(fpu_d15_arm64, regloc));
+ EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+ EXPECT_EQ(-96, regloc.GetOffset());
+
+ EXPECT_TRUE(row_sp->GetRegisterInfo(fpu_d14_arm64, regloc));
+ EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+ EXPECT_EQ(-88, regloc.GetOffset());
+
+ EXPECT_TRUE(row_sp->GetRegisterInfo(fpu_d13_arm64, regloc));
+ EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+ EXPECT_EQ(-80, regloc.GetOffset());
+
+ EXPECT_TRUE(row_sp->GetRegisterInfo(fpu_d12_arm64, regloc));
+ EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+ EXPECT_EQ(-72, regloc.GetOffset());
+
+ EXPECT_TRUE(row_sp->GetRegisterInfo(fpu_d11_arm64, regloc));
+ EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+ EXPECT_EQ(-64, regloc.GetOffset());
+
+ EXPECT_TRUE(row_sp->GetRegisterInfo(fpu_d10_arm64, regloc));
+ EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+ EXPECT_EQ(-56, regloc.GetOffset());
+
+ EXPECT_TRUE(row_sp->GetRegisterInfo(fpu_d9_arm64, regloc));
+ EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+ EXPECT_EQ(-48, regloc.GetOffset());
+
+ EXPECT_TRUE(row_sp->GetRegisterInfo(fpu_d8_arm64, regloc));
+ EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+ EXPECT_EQ(-40, regloc.GetOffset());
+
+ // 60: CFA=sp +0 =>
+ row_sp = unwind_plan.GetRowForFunctionOffset(60);
+ EXPECT_EQ(60ull, row_sp->GetOffset());
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64);
+ EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
+ EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset());
+
+ if (row_sp->GetRegisterInfo(fpu_d8_arm64, regloc))
+ EXPECT_TRUE(regloc.IsSame());
+ if (row_sp->GetRegisterInfo(fpu_d9_arm64, regloc))
+ EXPECT_TRUE(regloc.IsSame());
+ if (row_sp->GetRegisterInfo(fpu_d10_arm64, regloc))
+ EXPECT_TRUE(regloc.IsSame());
+ if (row_sp->GetRegisterInfo(fpu_d11_arm64, regloc))
+ EXPECT_TRUE(regloc.IsSame());
+ if (row_sp->GetRegisterInfo(fpu_d12_arm64, regloc))
+ EXPECT_TRUE(regloc.IsSame());
+ if (row_sp->GetRegisterInfo(fpu_d13_arm64, regloc))
+ EXPECT_TRUE(regloc.IsSame());
+ if (row_sp->GetRegisterInfo(fpu_d14_arm64, regloc))
+ EXPECT_TRUE(regloc.IsSame());
+ if (row_sp->GetRegisterInfo(fpu_d15_arm64, regloc))
+ EXPECT_TRUE(regloc.IsSame());
+ if (row_sp->GetRegisterInfo(gpr_x27_arm64, regloc))
+ EXPECT_TRUE(regloc.IsSame());
+ if (row_sp->GetRegisterInfo(gpr_x28_arm64, regloc))
+ EXPECT_TRUE(regloc.IsSame());
+}
More information about the lldb-commits
mailing list