[Lldb-commits] [lldb] r283849 - Add a second, more complicated, arm64 example program to

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Mon Oct 10 20:44:49 PDT 2016


Author: jmolenda
Date: Mon Oct 10 22:44:48 2016
New Revision: 283849

URL: http://llvm.org/viewvc/llvm-project?rev=283849&view=rev
Log:
Add a second, more complicated, arm64 example program to
the arm64 assembly unwind tests.

Modified:
    lldb/trunk/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp

Modified: lldb/trunk/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp?rev=283849&r1=283848&r2=283849&view=diff
==============================================================================
--- lldb/trunk/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp (original)
+++ lldb/trunk/unittests/UnwindAssembly/InstEmulation/TestArm64InstEmulation.cpp Mon Oct 10 22:44:48 2016
@@ -56,7 +56,7 @@ static void terminate() {
   EmulateInstructionARM64::Terminate();
 }
 
-TEST_F(TestArm64InstEmulation, TestSimpleFunction) {
+TEST_F(TestArm64InstEmulation, TestSimpleDarwinFunction) {
 
   init();
 
@@ -64,16 +64,14 @@ TEST_F(TestArm64InstEmulation, TestSimpl
   UnwindAssemblyInstEmulation *engine =
       static_cast<UnwindAssemblyInstEmulation *>(
           UnwindAssemblyInstEmulation::CreateInstance(arch));
-  EXPECT_TRUE(engine != nullptr);
-  if (engine == nullptr)
-    return;
+  ASSERT_NE(engine, nullptr);
 
   UnwindPlan::RowSP row_sp;
   AddressRange sample_range;
   UnwindPlan unwind_plan(eRegisterKindLLDB);
   UnwindPlan::Row::RegisterLocation regloc;
 
-  // 'int main() { }' compiled for arm64-apple-macosx with clang
+  // 'int main() { }' compiled for arm64-apple-ios with clang
   uint8_t data[] = {
       0xfd, 0x7b, 0xbf, 0xa9, // 0xa9bf7bfd :  stp x29, x30, [sp, #-0x10]!
       0xfd, 0x03, 0x00, 0x91, // 0x910003fd :  mov x29, sp
@@ -92,12 +90,6 @@ TEST_F(TestArm64InstEmulation, TestSimpl
   // row[2]:   16: CFA=sp+16 => fp=[CFA-16] lr=[CFA-8]
   // row[3]:   20: CFA=sp +0 => fp= <same> lr= <same>
 
-  // But this is missing the setup of the frame pointer register (x29) and
-  // restore of the same.  This is a bug in the instruction profiler --
-  // it won't work if we have a stack frame with a variable length array, or
-  // an alloca style call where the stack frame size is not fixed.  We need
-  // to recognize the setup of the frame pointer register.
-
   sample_range = AddressRange(0x1000, sizeof(data));
 
   EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(
@@ -164,3 +156,169 @@ TEST_F(TestArm64InstEmulation, TestSimpl
 
   terminate();
 }
+
+TEST_F(TestArm64InstEmulation, TestMediumDarwinFunction) {
+  init();
+
+  ArchSpec arch("arm64-apple-ios10", nullptr);
+  UnwindAssemblyInstEmulation *engine =
+      static_cast<UnwindAssemblyInstEmulation *>(
+          UnwindAssemblyInstEmulation::CreateInstance(arch));
+  ASSERT_NE(engine, nullptr);
+
+  UnwindPlan::RowSP row_sp;
+  AddressRange sample_range;
+  UnwindPlan unwind_plan(eRegisterKindLLDB);
+  UnwindPlan::Row::RegisterLocation regloc;
+
+  // disassembly of -[NSPlaceholderString initWithBytes:length:encoding:]
+  // from Foundation for iOS.
+  uint8_t data[] = {
+      0xf6, 0x57, 0xbd, 0xa9, // 0:  0xa9bd57f6 stp x22, x21, [sp, #-48]!
+      0xf4, 0x4f, 0x01, 0xa9, // 4:  0xa9014ff4 stp x20, x19, [sp, #16]
+      0xfd, 0x7b, 0x02, 0xa9, // 8:  0xa9027bfd stp x29, x30, [sp, #32]
+      0xfd, 0x83, 0x00, 0x91, // 12: 0x910083fd add x29, sp, #32
+      0xff, 0x43, 0x00, 0xd1, // 16: 0xd10043ff sub sp, sp, #16
+
+      // [... function body ...]
+      0x1f, 0x20, 0x03, 0xd5, // 20: 0xd503201f nop
+
+      0xbf, 0x83, 0x00, 0xd1, // 24: 0xd10083bf sub sp, x29, #32
+      0xfd, 0x7b, 0x42, 0xa9, // 28: 0xa9427bfd ldp x29, x30, [sp, #32]
+      0xf4, 0x4f, 0x41, 0xa9, // 32: 0xa9414ff4 ldp x20, x19, [sp, #16]
+      0xf6, 0x57, 0xc3, 0xa8, // 36: 0xa8c357f6 ldp x22, x21, [sp], #48
+      0x01, 0x16, 0x09, 0x14, // 40: 0x14091601 b   0x18f640524 ; symbol stub
+                              // for: CFStringCreateWithBytes
+  };
+
+  // UnwindPlan we expect:
+  //  0: CFA=sp +0 =>
+  //  4: CFA=sp+48 => x21=[CFA-40] x22=[CFA-48]
+  //  8: CFA=sp+48 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48]
+  // 12: CFA=sp+48 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48]
+  // fp=[CFA-16] lr=[CFA-8]
+  // 16: CFA=fp+16 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48]
+  // fp=[CFA-16] lr=[CFA-8]
+
+  // [... function body ...]
+
+  // 28: CFA=sp+48 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48]
+  // fp=[CFA-16] lr=[CFA-8]
+  // 32: CFA=sp+48 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] fp=
+  // <same> lr= <same>
+  // 36: CFA=sp+48 => x19= <same> x20= <same> x21=[CFA-40] x22=[CFA-48] fp=
+  // <same> lr= <same>
+  // 40: CFA=sp +0 => x19= <same> x20= <same> x21= <same> x22= <same> fp= <same>
+  // lr= <same>
+
+  sample_range = AddressRange(0x1000, sizeof(data));
+
+  EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(
+      sample_range, data, sizeof(data), unwind_plan));
+
+  // 0: CFA=sp +0 =>
+  row_sp = unwind_plan.GetRowForFunctionOffset(0);
+  EXPECT_EQ(0, row_sp->GetOffset());
+  EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+  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(4, row_sp->GetOffset());
+  EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+  EXPECT_EQ(48, row_sp->GetCFAValue().GetOffset());
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x21, regloc));
+  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+  EXPECT_EQ(-40, regloc.GetOffset());
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x22, 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(8, row_sp->GetOffset());
+  EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+  EXPECT_EQ(48, row_sp->GetCFAValue().GetOffset());
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x19, regloc));
+  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+  EXPECT_EQ(-24, regloc.GetOffset());
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x20, regloc));
+  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+  EXPECT_EQ(-32, regloc.GetOffset());
+
+  // 12: CFA=sp+48 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48]
+  // fp=[CFA-16] lr=[CFA-8]
+  row_sp = unwind_plan.GetRowForFunctionOffset(12);
+  EXPECT_EQ(12, row_sp->GetOffset());
+  EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+  EXPECT_EQ(48, row_sp->GetCFAValue().GetOffset());
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::fp, regloc));
+  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+  EXPECT_EQ(-16, regloc.GetOffset());
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::lr, regloc));
+  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+  EXPECT_EQ(-8, regloc.GetOffset());
+
+  // 16: CFA=fp+16 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48]
+  // fp=[CFA-16] lr=[CFA-8]
+  row_sp = unwind_plan.GetRowForFunctionOffset(16);
+  EXPECT_EQ(16, 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());
+
+  // 28: CFA=sp+48 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48]
+  // fp=[CFA-16] lr=[CFA-8]
+  row_sp = unwind_plan.GetRowForFunctionOffset(28);
+  EXPECT_EQ(28, row_sp->GetOffset());
+  EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+  EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
+  EXPECT_EQ(48, row_sp->GetCFAValue().GetOffset());
+
+  // 32: CFA=sp+48 => x19=[CFA-24] x20=[CFA-32] x21=[CFA-40] x22=[CFA-48] fp=
+  // <same> lr= <same>
+  row_sp = unwind_plan.GetRowForFunctionOffset(32);
+  EXPECT_EQ(32, row_sp->GetOffset());
+
+  // 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(regloc.IsSame());
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::lr, regloc));
+  EXPECT_TRUE(regloc.IsSame());
+
+  // 36: CFA=sp+48 => x19= <same> x20= <same> x21=[CFA-40] x22=[CFA-48] fp=
+  // <same> lr= <same>
+  row_sp = unwind_plan.GetRowForFunctionOffset(36);
+  EXPECT_EQ(36, row_sp->GetOffset());
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x19, regloc));
+  EXPECT_TRUE(regloc.IsSame());
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x20, 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(40, row_sp->GetOffset());
+  EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == arm64_dwarf::sp);
+  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(regloc.IsSame());
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(arm64_dwarf::x22, regloc));
+  EXPECT_TRUE(regloc.IsSame());
+
+  terminate();
+}




More information about the lldb-commits mailing list