forked from OSchip/llvm-project
Add an arm64 unit test where the function saves x20 in the
prologue, then loads & stores x20 on the stack from a different location in the middle of the function, and then restores the reg in the epilogue. The saving/restoring of x20 in the middle of the function should be ignored. llvm-svn: 283969
This commit is contained in:
parent
8d89c3c6f7
commit
c4be4be5dd
|
@ -342,7 +342,7 @@ TEST_F(TestArm64InstEmulation, TestFramelessThreeEpilogueFunction) {
|
|||
0x89, 0x01, 0x09, 0xca, // 36: 0xca090189 eor x9, x12, x9
|
||||
|
||||
// [...]
|
||||
|
||||
|
||||
0x08, 0x05, 0x00, 0x11, // 40: 0x11000508 add w8, w8, #0x1
|
||||
0x48, 0x00, 0x00, 0xb9, // 44: 0xb9000048 str w8, [x2]
|
||||
0xe0, 0x03, 0x00, 0x32, // 48: 0x320003e0 orr w0, wzr, #0x1
|
||||
|
@ -407,4 +407,104 @@ TEST_F(TestArm64InstEmulation, TestFramelessThreeEpilogueFunction) {
|
|||
EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset());
|
||||
}
|
||||
|
||||
TEST_F(TestArm64InstEmulation, TestRegisterSavedTwice) {
|
||||
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;
|
||||
|
||||
// disassembly of mach_msg_sever_once from libsystem_kernel.dylib for iOS.
|
||||
uint8_t data[] = {
|
||||
|
||||
0xfc, 0x6f, 0xba, 0xa9, // 0: 0xa9ba6ffc stp x28, x27, [sp, #-0x60]!
|
||||
0xfa, 0x67, 0x01, 0xa9, // 4: 0xa90167fa stp x26, x25, [sp, #0x10]
|
||||
0xf8, 0x5f, 0x02, 0xa9, // 8: 0xa9025ff8 stp x24, x23, [sp, #0x20]
|
||||
0xf6, 0x57, 0x03, 0xa9, // 12: 0xa90357f6 stp x22, x21, [sp, #0x30]
|
||||
0xf4, 0x4f, 0x04, 0xa9, // 16: 0xa9044ff4 stp x20, x19, [sp, #0x40]
|
||||
0xfd, 0x7b, 0x05, 0xa9, // 20: 0xa9057bfd stp x29, x30, [sp, #0x50]
|
||||
0xfd, 0x43, 0x01, 0x91, // 24: 0x910143fd add x29, sp, #0x50
|
||||
0xff, 0xc3, 0x00, 0xd1, // 28: 0xd100c3ff sub sp, sp, #0x30
|
||||
|
||||
// mid-function, store x20 & x24 on the stack at a different location.
|
||||
// this should not show up in the unwind plan; caller's values are not
|
||||
// being saved to stack.
|
||||
0xf8, 0x53, 0x01, 0xa9, // 32: 0xa90153f8 stp x24, x20, [sp, #0x10]
|
||||
|
||||
// mid-function, copy x20 and x19 off of the stack -- but not from
|
||||
// their original locations. unwind plan should ignore this.
|
||||
0xf4, 0x4f, 0x41, 0xa9, // 36: 0xa9414ff4 ldp x20, x19, [sp, #0x10]
|
||||
|
||||
// epilogue
|
||||
0xbf, 0x43, 0x01, 0xd1, // 40: 0xd10143bf sub sp, x29, #0x50
|
||||
0xfd, 0x7b, 0x45, 0xa9, // 44: 0xa9457bfd ldp x29, x30, [sp, #0x50]
|
||||
0xf4, 0x4f, 0x44, 0xa9, // 48: 0xa9444ff4 ldp x20, x19, [sp, #0x40]
|
||||
0xf6, 0x57, 0x43, 0xa9, // 52: 0xa94357f6 ldp x22, x21, [sp, #0x30]
|
||||
0xf8, 0x5f, 0x42, 0xa9, // 56: 0xa9425ff8 ldp x24, x23, [sp, #0x20]
|
||||
0xfa, 0x67, 0x41, 0xa9, // 60: 0xa94167fa ldp x26, x25, [sp, #0x10]
|
||||
0xfc, 0x6f, 0xc6, 0xa8, // 64: 0xa8c66ffc ldp x28, x27, [sp], #0x60
|
||||
0xc0, 0x03, 0x5f, 0xd6, // 68: 0xd65f03c0 ret
|
||||
};
|
||||
|
||||
// UnwindPlan we expect:
|
||||
// 0: CFA=sp +0 =>
|
||||
// 4: CFA=sp+96 => x27=[CFA-88] x28=[CFA-96]
|
||||
// 8: CFA=sp+96 => x25=[CFA-72] x26=[CFA-80] x27=[CFA-88] x28=[CFA-96]
|
||||
// 12: CFA=sp+96 => x23=[CFA-56] x24=[CFA-64] x25=[CFA-72] x26=[CFA-80]
|
||||
// x27=[CFA-88] x28=[CFA-96]
|
||||
// 16: CFA=sp+96 => x21=[CFA-40] x22=[CFA-48] x23=[CFA-56] x24=[CFA-64]
|
||||
// x25=[CFA-72] x26=[CFA-80] x27=[CFA-88] x28=[CFA-96]
|
||||
// 20: CFA=sp+96 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48]
|
||||
// x23=[CFA-56] x24=[CFA-64] x25=[CFA-72] x26=[CFA-80] x27=[CFA-88]
|
||||
// x28=[CFA-96]
|
||||
// 24: CFA=sp+96 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48]
|
||||
// x23=[CFA-56] x24=[CFA-64] x25=[CFA-72] x26=[CFA-80] x27=[CFA-88]
|
||||
// x28=[CFA-96] fp=[CFA-16] lr=[CFA-8]
|
||||
// 28: CFA=fp+16 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48]
|
||||
// x23=[CFA-56] x24=[CFA-64] x25=[CFA-72] x26=[CFA-80] x27=[CFA-88]
|
||||
// x28=[CFA-96] fp=[CFA-16] lr=[CFA-8]
|
||||
|
||||
// 44: CFA=sp+96 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48]
|
||||
// x23=[CFA-56] x24=[CFA-64] x25=[CFA-72] x26=[CFA-80] x27=[CFA-88]
|
||||
// x28=[CFA-96] fp=[CFA-16] lr=[CFA-8]
|
||||
// 48: CFA=sp+96 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48]
|
||||
// x23=[CFA-56] x24=[CFA-64] x25=[CFA-72] x26=[CFA-80] x27=[CFA-88]
|
||||
// x28=[CFA-96]
|
||||
// 52: CFA=sp+96 => x21=[CFA-40] x22=[CFA-48] x23=[CFA-56] x24=[CFA-64]
|
||||
// x25=[CFA-72] x26=[CFA-80] x27=[CFA-88] x28=[CFA-96]
|
||||
// 56: CFA=sp+96 => x23=[CFA-56] x24=[CFA-64] x25=[CFA-72] x26=[CFA-80]
|
||||
// x27=[CFA-88] x28=[CFA-96]
|
||||
// 60: CFA=sp+96 => x25=[CFA-72] x26=[CFA-80] x27=[CFA-88] x28=[CFA-96]
|
||||
// 64: CFA=sp+96 => x27=[CFA-88] x28=[CFA-96]
|
||||
// 68: CFA=sp +0 =>
|
||||
|
||||
sample_range = AddressRange(0x1000, sizeof(data));
|
||||
|
||||
EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(
|
||||
sample_range, data, sizeof(data), unwind_plan));
|
||||
|
||||
row_sp = unwind_plan.GetRowForFunctionOffset(36);
|
||||
EXPECT_EQ(28, row_sp->GetOffset());
|
||||
EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::fp);
|
||||
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(regloc.IsAtCFAPlusOffset());
|
||||
EXPECT_EQ(-32, regloc.GetOffset());
|
||||
|
||||
row_sp = unwind_plan.GetRowForFunctionOffset(40);
|
||||
EXPECT_EQ(28, row_sp->GetOffset());
|
||||
EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::fp);
|
||||
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(regloc.IsAtCFAPlusOffset());
|
||||
EXPECT_EQ(-32, regloc.GetOffset());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue