[Lldb-commits] [lldb] r283404 - Add i386/x86_64 tests of the eh_frame augmentation code in the x86
Jason Molenda via lldb-commits
lldb-commits at lists.llvm.org
Wed Oct 5 15:37:01 PDT 2016
Author: jmolenda
Date: Wed Oct 5 17:37:01 2016
New Revision: 283404
URL: http://llvm.org/viewvc/llvm-project?rev=283404&view=rev
Log:
Add i386/x86_64 tests of the eh_frame augmentation code in the x86
insturction profiling. Add a test that verifies that we reject a
32-bit only instruction in 64-bit (long) mode.
This wraps up all the testing I want to add for
x86AssemblyInspectionEngine.
Modified:
lldb/trunk/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp
Modified: lldb/trunk/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp?rev=283404&r1=283403&r2=283404&view=diff
==============================================================================
--- lldb/trunk/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp (original)
+++ lldb/trunk/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp Wed Oct 5 17:37:01 2016
@@ -958,7 +958,7 @@ TEST_F(Testx86AssemblyInspectionEngine,
UnwindPlan::RowSP row_sp;
uint8_t data[] = {
- 0x55, // pushq $rbp
+ 0x55, // pushq %rbp
0x90 // nop
};
@@ -1583,7 +1583,7 @@ TEST_F(Testx86AssemblyInspectionEngine,
std::unique_ptr<x86AssemblyInspectionEngine> engine32 = Geti386Inspector();
uint8_t data1[] = {
- 0x81, 0xec, 0x00, 0x01, 0x00, 0x00, // subq $0x100, $esp
+ 0x81, 0xec, 0x00, 0x01, 0x00, 0x00, // subl $0x100, %esp
0x90 // nop
};
@@ -2110,11 +2110,11 @@ TEST_F(Testx86AssemblyInspectionEngine,
std::unique_ptr<x86AssemblyInspectionEngine> engine32 = Geti386Inspector();
uint8_t data[] = {
- 0x55, // pushq %ebp
- 0x89, 0xe5, // movq %esp, %ebp
+ 0x55, // pushl %ebp
+ 0x89, 0xe5, // movl %esp, %ebp
0x89, 0x9d, 0xb0, 0xfe, 0xff, 0xff, // movl %ebx, -0x150(%ebp)
0x89, 0x75, 0xe0, // movl %esi, -0x20(%ebp)
- 0x90 // nop
+ 0x90 // nop
};
sample_range = AddressRange(0x1000, sizeof(data));
@@ -2135,3 +2135,206 @@ TEST_F(Testx86AssemblyInspectionEngine,
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-40, regloc.GetOffset());
}
+
+TEST_F(Testx86AssemblyInspectionEngine, TestSimplex86_64Augmented) {
+ UnwindPlan::Row::RegisterLocation regloc;
+ UnwindPlan::RowSP row_sp;
+ AddressRange sample_range;
+ UnwindPlan unwind_plan(eRegisterKindLLDB);
+ std::unique_ptr<x86AssemblyInspectionEngine> engine64 = Getx86_64Inspector();
+
+ uint8_t data[] = {
+ 0x55, // pushq %rbp
+ 0x48, 0x89, 0xe5, // movq %rsp, %rbp
+
+ // x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite
+ // has a bug where it can't augment a function that is just
+ // prologue+epilogue - it needs at least one other instruction
+ // in between.
+ 0x90, // nop
+
+ 0x5d, // popq %rbp
+ 0xc3 // retq
+ };
+
+ sample_range = AddressRange(0x1000, sizeof(data));
+
+ unwind_plan.SetSourceName("unit testing hand-created unwind plan");
+ unwind_plan.SetPlanValidAddressRange(sample_range);
+ unwind_plan.SetRegisterKind(eRegisterKindLLDB);
+
+ row_sp.reset(new UnwindPlan::Row);
+
+ // Describe offset 0
+ row_sp->SetOffset(0);
+ row_sp->GetCFAValue().SetIsRegisterPlusOffset(k_rsp, 8);
+
+ regloc.SetAtCFAPlusOffset(-8);
+ row_sp->SetRegisterInfo(k_rip, regloc);
+
+ unwind_plan.AppendRow(row_sp);
+
+ // Allocate a new Row, populate it with the existing Row contents.
+ UnwindPlan::Row *new_row = new UnwindPlan::Row;
+ *new_row = *row_sp.get();
+ row_sp.reset(new_row);
+
+ // Describe offset 1
+ row_sp->SetOffset(1);
+ row_sp->GetCFAValue().SetIsRegisterPlusOffset(k_rsp, 16);
+ regloc.SetAtCFAPlusOffset(-16);
+ row_sp->SetRegisterInfo(k_rbp, regloc);
+ unwind_plan.AppendRow(row_sp);
+
+ // Allocate a new Row, populate it with the existing Row contents.
+ new_row = new UnwindPlan::Row;
+ *new_row = *row_sp.get();
+ row_sp.reset(new_row);
+
+ // Describe offset 4
+ row_sp->SetOffset(4);
+ row_sp->GetCFAValue().SetIsRegisterPlusOffset(k_rbp, 16);
+ unwind_plan.AppendRow(row_sp);
+
+ RegisterContextSP reg_ctx_sp;
+ EXPECT_TRUE(engine64->AugmentUnwindPlanFromCallSite(
+ data, sizeof(data), sample_range, unwind_plan, reg_ctx_sp));
+
+ row_sp = unwind_plan.GetRowForFunctionOffset(6);
+ EXPECT_EQ(6, row_sp->GetOffset());
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp);
+ EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset());
+
+ // x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite
+ // doesn't track register restores (pop'ing a reg value back from
+ // the stack) - it was just written to make stepping work correctly.
+ // Technically we should be able to do the following test, but it
+ // won't work today - the unwind plan will still say that the caller's
+ // rbp is on the stack.
+ // EXPECT_FALSE(row_sp->GetRegisterInfo(k_rbp, regloc));
+}
+
+TEST_F(Testx86AssemblyInspectionEngine, TestSimplei386ugmented) {
+ UnwindPlan::Row::RegisterLocation regloc;
+ UnwindPlan::RowSP row_sp;
+ AddressRange sample_range;
+ UnwindPlan unwind_plan(eRegisterKindLLDB);
+ std::unique_ptr<x86AssemblyInspectionEngine> engine32 = Geti386Inspector();
+
+ uint8_t data[] = {
+ 0x55, // pushl %ebp
+ 0x89, 0xe5, // movl %esp, %ebp
+
+ // x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite
+ // has a bug where it can't augment a function that is just
+ // prologue+epilogue - it needs at least one other instruction
+ // in between.
+ 0x90, // nop
+
+ 0x5d, // popl %ebp
+ 0xc3 // retl
+ };
+
+ sample_range = AddressRange(0x1000, sizeof(data));
+
+ unwind_plan.SetSourceName("unit testing hand-created unwind plan");
+ unwind_plan.SetPlanValidAddressRange(sample_range);
+ unwind_plan.SetRegisterKind(eRegisterKindLLDB);
+
+ row_sp.reset(new UnwindPlan::Row);
+
+ // Describe offset 0
+ row_sp->SetOffset(0);
+ row_sp->GetCFAValue().SetIsRegisterPlusOffset(k_esp, 4);
+
+ regloc.SetAtCFAPlusOffset(-4);
+ row_sp->SetRegisterInfo(k_eip, regloc);
+
+ unwind_plan.AppendRow(row_sp);
+
+ // Allocate a new Row, populate it with the existing Row contents.
+ UnwindPlan::Row *new_row = new UnwindPlan::Row;
+ *new_row = *row_sp.get();
+ row_sp.reset(new_row);
+
+ // Describe offset 1
+ row_sp->SetOffset(1);
+ row_sp->GetCFAValue().SetIsRegisterPlusOffset(k_esp, 8);
+ regloc.SetAtCFAPlusOffset(-8);
+ row_sp->SetRegisterInfo(k_ebp, regloc);
+ unwind_plan.AppendRow(row_sp);
+
+ // Allocate a new Row, populate it with the existing Row contents.
+ new_row = new UnwindPlan::Row;
+ *new_row = *row_sp.get();
+ row_sp.reset(new_row);
+
+ // Describe offset 3
+ row_sp->SetOffset(3);
+ row_sp->GetCFAValue().SetIsRegisterPlusOffset(k_ebp, 8);
+ unwind_plan.AppendRow(row_sp);
+
+ RegisterContextSP reg_ctx_sp;
+ EXPECT_TRUE(engine32->AugmentUnwindPlanFromCallSite(
+ data, sizeof(data), sample_range, unwind_plan, reg_ctx_sp));
+
+ row_sp = unwind_plan.GetRowForFunctionOffset(5);
+ EXPECT_EQ(5, row_sp->GetOffset());
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp);
+ EXPECT_EQ(4, row_sp->GetCFAValue().GetOffset());
+
+ // x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite
+ // doesn't track register restores (pop'ing a reg value back from
+ // the stack) - it was just written to make stepping work correctly.
+ // Technically we should be able to do the following test, but it
+ // won't work today - the unwind plan will still say that the caller's
+ // ebp is on the stack.
+ // EXPECT_FALSE(row_sp->GetRegisterInfo(k_ebp, regloc));
+}
+
+// Check that the i386 disassembler disassembles past an opcode that
+// is only valid in 32-bit mode (non-long mode), and the x86_64 disassembler
+// stops
+// disassembling at that point (long-mode).
+TEST_F(Testx86AssemblyInspectionEngine, Test32BitOnlyInstruction) {
+ UnwindPlan::Row::RegisterLocation regloc;
+ UnwindPlan::RowSP row_sp;
+ AddressRange sample_range;
+ UnwindPlan unwind_plan(eRegisterKindLLDB);
+ std::unique_ptr<x86AssemblyInspectionEngine> engine32 = Geti386Inspector();
+ std::unique_ptr<x86AssemblyInspectionEngine> engine64 = Getx86_64Inspector();
+
+ uint8_t data[] = {
+ 0x43, // incl $ebx --- an invalid opcode in 64-bit mode
+ 0x55, // pushl %ebp
+ 0x90 // nop
+ };
+
+ sample_range = AddressRange(0x1000, sizeof(data));
+
+ EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly(
+ data, sizeof(data), sample_range, unwind_plan));
+
+ row_sp = unwind_plan.GetRowForFunctionOffset(2);
+ EXPECT_EQ(2, row_sp->GetOffset());
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp);
+ EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
+ EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset());
+
+ EXPECT_TRUE(row_sp->GetRegisterInfo(k_ebp, regloc));
+ EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+ EXPECT_EQ(-8, regloc.GetOffset());
+
+ unwind_plan.Clear();
+
+ EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly(
+ data, sizeof(data), sample_range, unwind_plan));
+
+ row_sp = unwind_plan.GetRowForFunctionOffset(2);
+ EXPECT_EQ(0, row_sp->GetOffset());
+ EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp);
+ EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
+ EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset());
+
+ EXPECT_FALSE(row_sp->GetRegisterInfo(k_rbp, regloc));
+}
More information about the lldb-commits
mailing list