[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