[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