diff options
| author | Jason Molenda <jmolenda@apple.com> | 2016-10-12 03:53:01 +0000 | 
|---|---|---|
| committer | Jason Molenda <jmolenda@apple.com> | 2016-10-12 03:53:01 +0000 | 
| commit | c4be4be5ddae96114e09244ad1ffcbe60741f879 (patch) | |
| tree | b0ecc11012d7dcfb721c56d02b209cbe6095aac3 /lldb/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp | |
| parent | 8d89c3c6f7f731662d9e6af3ad82069e380c8355 (diff) | |
| download | bcm5719-llvm-c4be4be5ddae96114e09244ad1ffcbe60741f879.tar.gz bcm5719-llvm-c4be4be5ddae96114e09244ad1ffcbe60741f879.zip | |
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
Diffstat (limited to 'lldb/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp')
| -rw-r--r-- | lldb/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp | 102 | 
1 files changed, 101 insertions, 1 deletions
| diff --git a/lldb/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp b/lldb/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp index 9adcf477960..3ccd70f0a04 100644 --- a/lldb/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp +++ b/lldb/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp @@ -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()); +} | 

