[Lldb-commits] [lldb] r282991 - Add support for some extended push instructions in i386/x86_64 like

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Fri Sep 30 17:19:27 PDT 2016


Author: jmolenda
Date: Fri Sep 30 19:19:26 2016
New Revision: 282991

URL: http://llvm.org/viewvc/llvm-project?rev=282991&view=rev
Log:
Add support for some extended push instructions in i386/x86_64 like
'push 0x20(%esp)' which clang can generate when emitting
-fomit-frame-pointer code for 32-bit.

Add a unit test program which includes this instruction.

Also fix a bug in the refactoring/rewrite of the x86 assembly
instruction profiler where I'd hard coded it as a 64-bit disassembler
instead of using the ArchSpec to pick a 32-bit or 64-bit disassembler
from llvm.  When the disassembler would hit an instruction
that is invalid in 64-bit mode, it would stop disassembling the function.
This likely led to the TestSBData testsuite failure on linux with 32-bit
i386 and gcc-4.9; I'll test that in a bit.

The newly added unit test program is 32-bit i386 code and it includes
an instruction which is invalid in 64-bit mode so it will catch this.

<rdar://problem/28557876> 


Modified:
    lldb/trunk/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
    lldb/trunk/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
    lldb/trunk/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp

Modified: lldb/trunk/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp?rev=282991&r1=282990&r2=282991&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp (original)
+++ lldb/trunk/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp Fri Sep 30 19:19:26 2016
@@ -29,10 +29,9 @@ x86AssemblyInspectionEngine::x86Assembly
 
       m_reg_map(), m_arch(arch), m_cpu(k_cpu_unspecified), m_wordsize(-1),
       m_register_map_initialized(false), m_disasm_context() {
-  m_disasm_context = ::LLVMCreateDisasm("x86_64-apple-macosx", nullptr,
-                                        /*TagType=*/1, nullptr, nullptr);
-  //      ::LLVMCreateDisasm(arch.GetTriple().getTriple().c_str(), nullptr,
-  //                         /*TagType=*/1, nullptr, nullptr);
+  m_disasm_context =
+      ::LLVMCreateDisasm(arch.GetTriple().getTriple().c_str(), nullptr,
+                         /*TagType=*/1, nullptr, nullptr);
 }
 
 x86AssemblyInspectionEngine::~x86AssemblyInspectionEngine() {
@@ -320,6 +319,50 @@ bool x86AssemblyInspectionEngine::push_i
   return false;
 }
 
+// pushl imm8(%esp)
+//
+// e.g. 0xff 0x74 0x24 0x20 - 'pushl 0x20(%esp)'
+// (same byte pattern for 'pushq 0x20(%rsp)' in an x86_64 program)
+//
+// 0xff (with opcode bits '6' in next byte, PUSH r/m32)
+// 0x74 (ModR/M byte with three bits used to specify the opcode)
+//      mod == b01, opcode == b110, R/M == b100
+//      "+disp8"
+// 0x24 (SIB byte - scaled index = 0, r32 == esp)
+// 0x20 imm8 value
+
+bool x86AssemblyInspectionEngine::push_extended_pattern_p() {
+  if (*m_cur_insn == 0xff) {
+    // Get the 3 opcode bits from the ModR/M byte
+    uint8_t opcode = (*(m_cur_insn + 1) >> 3) & 7;
+    if (opcode == 6) {
+      // I'm only looking for 0xff /6 here - I
+      // don't really care what value is being pushed,
+      // just that we're pushing a 32/64 bit value on
+      // to the stack is enough.
+      return true;
+    }
+  }
+  return false;
+}
+
+// pushq %rbx
+// pushl %ebx
+bool x86AssemblyInspectionEngine::push_reg_p(int &regno) {
+  uint8_t *p = m_cur_insn;
+  int regno_prefix_bit = 0;
+  // If we have a rex prefix byte, check to see if a B bit is set
+  if (m_wordsize == 8 && *p == 0x41) {
+    regno_prefix_bit = 1 << 3;
+    p++;
+  }
+  if (*p >= 0x50 && *p <= 0x57) {
+    regno = (*p - 0x50) | regno_prefix_bit;
+    return true;
+  }
+  return false;
+}
+
 // movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5]
 // movl %esp, %ebp [0x8b 0xec] or [0x89 0xe5]
 bool x86AssemblyInspectionEngine::mov_rsp_rbp_pattern_p() {
@@ -395,23 +438,6 @@ bool x86AssemblyInspectionEngine::lea_rs
   return false;
 }
 
-// pushq %rbx
-// pushl %ebx
-bool x86AssemblyInspectionEngine::push_reg_p(int &regno) {
-  uint8_t *p = m_cur_insn;
-  int regno_prefix_bit = 0;
-  // If we have a rex prefix byte, check to see if a B bit is set
-  if (m_wordsize == 8 && *p == 0x41) {
-    regno_prefix_bit = 1 << 3;
-    p++;
-  }
-  if (*p >= 0x50 && *p <= 0x57) {
-    regno = (*p - 0x50) | regno_prefix_bit;
-    return true;
-  }
-  return false;
-}
-
 // popq %rbx
 // popl %ebx
 bool x86AssemblyInspectionEngine::pop_reg_p(int &regno) {
@@ -762,6 +788,14 @@ bool x86AssemblyInspectionEngine::GetNon
       in_epilogue = true;
     }
 
+    else if (push_extended_pattern_p() || push_imm_pattern_p()) {
+      current_sp_bytes_offset_from_cfa += m_wordsize;
+      if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
+        row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+        row_updated = true;
+      }
+    }
+
     else if (lea_rsp_pattern_p(stack_offset)) {
       current_sp_bytes_offset_from_cfa -= stack_offset;
       if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
@@ -1002,6 +1036,16 @@ bool x86AssemblyInspectionEngine::Augmen
         continue;
       }
 
+      // push extended
+      if (push_extended_pattern_p()) {
+        row->SetOffset(offset);
+        row->GetCFAValue().IncOffset(m_wordsize);
+        UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+        unwind_plan.InsertRow(new_row);
+        unwind_plan_updated = true;
+        continue;
+      }
+
       // add/sub %rsp/%esp
       int amount;
       if (add_rsp_pattern_p(amount)) {
@@ -1045,16 +1089,16 @@ bool x86AssemblyInspectionEngine::Augmen
       //     [0x5d] pop %rbp/%ebp
       //  => [0xc3] ret
       if (pop_rbp_pattern_p() || leave_pattern_p()) {
-          offset += 1;
-          row->SetOffset(offset);
-          row->GetCFAValue().SetIsRegisterPlusOffset(
-              first_row->GetCFAValue().GetRegisterNumber(), m_wordsize);
+        offset += 1;
+        row->SetOffset(offset);
+        row->GetCFAValue().SetIsRegisterPlusOffset(
+            first_row->GetCFAValue().GetRegisterNumber(), m_wordsize);
 
-          UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
-          unwind_plan.InsertRow(new_row);
-          unwind_plan_updated = true;
-          reinstate_unwind_state = true;
-          continue;
+        UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+        unwind_plan.InsertRow(new_row);
+        unwind_plan_updated = true;
+        reinstate_unwind_state = true;
+        continue;
       }
     } else {
       // CFA register is not sp or fp.

Modified: lldb/trunk/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h?rev=282991&r1=282990&r2=282991&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h (original)
+++ lldb/trunk/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h Fri Sep 30 19:19:26 2016
@@ -96,6 +96,7 @@ private:
   bool push_rbp_pattern_p();
   bool push_0_pattern_p();
   bool push_imm_pattern_p();
+  bool push_extended_pattern_p();
   bool mov_rsp_rbp_pattern_p();
   bool sub_rsp_pattern_p(int &amount);
   bool add_rsp_pattern_p(int &amount);

Modified: lldb/trunk/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp?rev=282991&r1=282990&r2=282991&view=diff
==============================================================================
--- lldb/trunk/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp (original)
+++ lldb/trunk/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp Fri Sep 30 19:19:26 2016
@@ -447,9 +447,304 @@ TEST_F(Testx86AssemblyInspectionEngine,
   EXPECT_FALSE(row_sp->GetRegisterInfo(k_r13, regloc));
   EXPECT_FALSE(row_sp->GetRegisterInfo(k_r14, regloc));
   EXPECT_FALSE(row_sp->GetRegisterInfo(k_r15, regloc));
-
 }
 
+TEST_F(Testx86AssemblyInspectionEngine, Test32bitFramelessBigStackFrame) {
+  std::unique_ptr<x86AssemblyInspectionEngine> engine = Geti386Inspector();
+
+  // this source file:
+  //
+  // #include <stdio.h>
+  // int main (int argc, char **argv)
+  // {
+  //
+  //     const int arrsize = 60;
+  //     int buf[arrsize * arrsize];
+  //     int accum = argc;
+  //     for (int i = 0; i < arrsize; i++)
+  //         for (int j = 0; j < arrsize; j++)
+  //         {
+  //             if (i > 0 && j > 0)
+  //             {
+  //                 int n = buf[(i-1) * (j-1)] * 2;
+  //                 int m = buf[(i-1) * (j-1)] / 2;
+  //                 int j = buf[(i-1) * (j-1)] + 2;
+  //                 int k = buf[(i-1) * (j-1)] - 2;
+  //                 printf ("%d ", n + m + j + k);
+  //                 buf[(i-1) * (j-1)] += n - m + j - k;
+  //             }
+  //             buf[i*j] = accum++;
+  //         }
+  //
+  //     return buf[(arrsize * arrsize) - 2] + printf ("%d\n", buf[(arrsize *
+  //     arrsize) - 3]);
+  // }
+  //
+  // compiled 'clang -arch i386 -fomit-frame-pointer -Os' for i386-apple-macosx
+
+  // simplified assembly version of the above function, which is used as the
+  // input
+  // data:
+  //
+  // 	.section	__TEXT,__text,regular,pure_instructions
+  // 	.macosx_version_min 10, 12
+  // 	.globl	_main
+  // 	.align	4, 0x90
+  // _main:                                  ## @main
+  // ## BB#0:
+  // 	pushl %ebp
+  // 	pushl %ebx
+  // 	pushl %edi
+  // 	pushl %esi
+  // L0$pb:
+  // 	subl $0x386c, %esp
+  //     calll L1
+  // L1:
+  //     popl %ecx
+  //     movl %ecx, 0x8(%esp)
+  //     subl $0x8, %esp
+  //     pushl %eax
+  //     pushl 0x20(%esp)
+  //     calll _puts
+  //     addl $0x10, %esp
+  //     incl %ebx
+  //     addl $0x386c, %esp
+  //     popl %esi
+  //     popl %edi
+  //     popl %ebx
+  //     popl %ebp
+  //     retl
+  //
+  // 	.section	__TEXT,__cstring,cstring_literals
+  // L_.str:                                 ## @.str
+  // 	.asciz	"HI"
+  //
+  //
+  // .subsections_via_symbols
+
+  uint8_t data[] = {
+      0x55,
+      // offset 0 -- pushl %ebp
+
+      0x53,
+      // offset 1 -- pushl %ebx
+
+      0x57,
+      // offset 2 -- pushl %edi
+
+      0x56,
+      // offset 3 -- pushl %esi
+
+      0x81, 0xec, 0x6c, 0x38, 0x00, 0x00,
+      // offset 4 -- subl $0x386c, %esp
+
+      0xe8, 0x00, 0x00, 0x00, 0x00,
+      // offset 10 -- calll 0
+      // call the next instruction, to put the pc on the stack
+
+      0x59,
+      // offset 15 -- popl %ecx
+      // pop the saved pc address into ecx
+
+      0x89, 0x4c, 0x24, 0x08,
+      // offset 16 -- movl %ecx, 0x8(%esp)
+
+      // ....
+
+      0x83, 0xec, 0x08,
+      // offset 20 -- subl $0x8, %esp
+
+      0x50,
+      // offset 23 -- pushl %eax
+
+      0xff, 0x74, 0x24, 0x20,
+      // offset 24 -- pushl 0x20(%esp)
+
+      0xe8, 0x8c, 0x00, 0x00, 0x00,
+      // offset 28 -- calll puts
+
+      0x83, 0xc4, 0x10,
+      // offset 33 -- addl $0x10, %esp
+      // get esp back to the value it was before the
+      // alignment & argument saves for the puts call
+
+      0x43,
+      // offset 36 -- incl %ebx
+
+      // ....
+
+      0x81, 0xc4, 0x6c, 0x38, 0x00, 0x00,
+      // offset 37 -- addl $0x386c, %esp
+
+      0x5e,
+      // offset 43 -- popl %esi
+
+      0x5f,
+      // offset 44 -- popl %edi
+
+      0x5b,
+      // offset 45 -- popl %ebx
+
+      0x5d,
+      // offset 46 -- popl %ebp
+
+      0xc3,
+      // offset 47 -- retl
+
+      0xe8, 0x12, 0x34, 0x56, 0x78,
+      // offset 48 -- calll __stack_chk_fail
+  };
+
+  AddressRange sample_range(0x1000, sizeof(data));
+
+  UnwindPlan unwind_plan(eRegisterKindLLDB);
+  EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(
+      data, sizeof(data), sample_range, unwind_plan));
+
+  // Unwind rules should look like
+  //
+  //   0: CFA=esp +4 => esp=CFA+0 eip=[CFA-4]
+  //   1: CFA=esp +8 => ebp=[CFA-8] esp=CFA+0 eip=[CFA-4]
+  //   2: CFA=esp+12 => ebx=[CFA-12] ebp=[CFA-8] esp=CFA+0 eip=[CFA-4]
+  //   3: CFA=esp+16 => ebx=[CFA-12] edi=[CFA-16] ebp=[CFA-8] esp=CFA+0
+  //   eip=[CFA-4]
+  //   4: CFA=esp+20 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  //   esp=CFA+0 eip=[CFA-4]
+  //  10: CFA=esp+14464 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  //  esp=CFA+0 eip=[CFA-4]
+  //  15: CFA=esp+14468 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  //  esp=CFA+0 eip=[CFA-4]
+  //  16: CFA=esp+14464 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  //  esp=CFA+0 eip=[CFA-4]
+  //
+  //  ....
+  //
+  //  23: CFA=esp+14472 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  //  esp=CFA+0 eip=[CFA-4]
+  //  24: CFA=esp+14476 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  //  esp=CFA+0 eip=[CFA-4]
+  //  28: CFA=esp+14480 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  //  esp=CFA+0 eip=[CFA-4]
+  //  36: CFA=esp+14464 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  //  esp=CFA+0 eip=[CFA-4]
+  //
+  //  .....
+  //
+  //  37: CFA=esp+14464 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  //  esp=CFA+0 eip=[CFA-4]
+  //  43: CFA=esp+20 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  //  esp=CFA+0 eip=[CFA-4]
+  //  44: CFA=esp+16 => ebx=[CFA-12] edi=[CFA-16] ebp=[CFA-8] esp=CFA+0
+  //  eip=[CFA-4]
+  //  45: CFA=esp+12 => ebx=[CFA-12] ebp=[CFA-8] esp=CFA+0 eip=[CFA-4]
+  //  46: CFA=esp +8 => ebp=[CFA-8] esp=CFA+0 eip=[CFA-4]
+  //  47: CFA=esp +4 => esp=CFA+0 eip=[CFA-4]
+  //  48: CFA=esp+14480 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  //  esp=CFA+0 eip=[CFA-4]
+
+  UnwindPlan::Row::RegisterLocation regloc;
+  UnwindPlan::RowSP row_sp;
+
+  // Check that we get the CFA correct for the pic base setup sequence
+
+  // CFA=esp+14464 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  // esp=CFA+0 eip=[CFA-4]
+  row_sp = unwind_plan.GetRowForFunctionOffset(10);
+  EXPECT_EQ(10, row_sp->GetOffset());
+  EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp);
+  EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
+  EXPECT_EQ(14464, row_sp->GetCFAValue().GetOffset());
+
+  // 15: CFA=esp+14468 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  // esp=CFA+0 eip=[CFA-4]
+  row_sp = unwind_plan.GetRowForFunctionOffset(15);
+  EXPECT_EQ(15, row_sp->GetOffset());
+  EXPECT_EQ(14468, row_sp->GetCFAValue().GetOffset());
+
+  // 16: CFA=esp+14464 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  // esp=CFA+0 eip=[CFA-4]
+  row_sp = unwind_plan.GetRowForFunctionOffset(16);
+  EXPECT_EQ(16, row_sp->GetOffset());
+  EXPECT_EQ(14464, row_sp->GetCFAValue().GetOffset());
+
+  // Check that the row for offset 16 has the registers saved that we expect
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(k_eip, regloc));
+  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+  EXPECT_EQ(-4, regloc.GetOffset());
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(k_ebp, regloc));
+  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+  EXPECT_EQ(-8, regloc.GetOffset());
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(k_ebx, regloc));
+  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+  EXPECT_EQ(-12, regloc.GetOffset());
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(k_edi, regloc));
+  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+  EXPECT_EQ(-16, regloc.GetOffset());
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(k_esi, regloc));
+  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+  EXPECT_EQ(-20, regloc.GetOffset());
+
+  //
+  // Check the pushing & popping around the call printf instruction
+
+  // 23: CFA=esp+14472 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  // esp=CFA+0 eip=[CFA-4]
+  row_sp = unwind_plan.GetRowForFunctionOffset(23);
+  EXPECT_EQ(23, row_sp->GetOffset());
+  EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp);
+  EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
+  EXPECT_EQ(14472, row_sp->GetCFAValue().GetOffset());
+
+  // 24: CFA=esp+14476 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  // esp=CFA+0 eip=[CFA-4]
+  row_sp = unwind_plan.GetRowForFunctionOffset(24);
+  EXPECT_EQ(24, row_sp->GetOffset());
+  EXPECT_EQ(14476, row_sp->GetCFAValue().GetOffset());
+
+  // 28: CFA=esp+14480 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  // esp=CFA+0 eip=[CFA-4]
+  row_sp = unwind_plan.GetRowForFunctionOffset(28);
+  EXPECT_EQ(28, row_sp->GetOffset());
+  EXPECT_EQ(14480, row_sp->GetCFAValue().GetOffset());
+
+  // 36: CFA=esp+14464 => ebx=[CFA-12] edi=[CFA-16] esi=[CFA-20] ebp=[CFA-8]
+  // esp=CFA+0 eip=[CFA-4]
+  row_sp = unwind_plan.GetRowForFunctionOffset(36);
+  EXPECT_EQ(36, row_sp->GetOffset());
+  EXPECT_EQ(14464, row_sp->GetCFAValue().GetOffset());
+
+  // Check that the epilogue gets us back to the original unwind state
+
+  //  47: CFA=esp +4 => esp=CFA+0 eip=[CFA-4]
+  row_sp = unwind_plan.GetRowForFunctionOffset(47);
+  EXPECT_EQ(47, row_sp->GetOffset());
+  EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_esp);
+  EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
+  EXPECT_EQ(4, row_sp->GetCFAValue().GetOffset());
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(k_eip, regloc));
+  EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
+  EXPECT_EQ(-4, regloc.GetOffset());
+
+  EXPECT_TRUE(row_sp->GetRegisterInfo(k_esp, regloc));
+  EXPECT_TRUE(regloc.IsCFAPlusOffset());
+  EXPECT_EQ(0, regloc.GetOffset());
+
+  // Check that no unexpected registers were saved
+
+  EXPECT_FALSE(row_sp->GetRegisterInfo(k_eax, regloc));
+  EXPECT_FALSE(row_sp->GetRegisterInfo(k_ebx, regloc));
+  EXPECT_FALSE(row_sp->GetRegisterInfo(k_ecx, regloc));
+  EXPECT_FALSE(row_sp->GetRegisterInfo(k_edx, regloc));
+  EXPECT_FALSE(row_sp->GetRegisterInfo(k_esi, regloc));
+  EXPECT_FALSE(row_sp->GetRegisterInfo(k_edi, regloc));
+  EXPECT_FALSE(row_sp->GetRegisterInfo(k_ebp, regloc));
+}
 
 TEST_F(Testx86AssemblyInspectionEngine, Test64bitFramelessSmallStackFrame) {
   std::unique_ptr<x86AssemblyInspectionEngine> engine = Getx86_64Inspector();
@@ -463,18 +758,18 @@ TEST_F(Testx86AssemblyInspectionEngine,
   // compiled 'clang -fomit-frame-pointer' for x86_64-apple-macosx
 
   uint8_t data[] = {
-      0x50,       
+      0x50,
       // offset 0  -- pushq %rax
 
-      0x48, 0x8d, 0x3d, 0x32, 0x00, 0x00, 0x00, 
+      0x48, 0x8d, 0x3d, 0x32, 0x00, 0x00, 0x00,
       // offset 1 -- leaq 0x32(%rip), %rdi ; "HI"
 
-      0xe8, 0x0b, 0x00, 0x00, 0x00, 
+      0xe8, 0x0b, 0x00, 0x00, 0x00,
       // offset 8 -- callq 0x100000f58 ; puts
 
       0x31, 0xc9,
       // offset 13 -- xorl %ecx, %ecx
-      
+
       0x89, 0x44, 0x24, 0x04,
       // offset 15 -- movl %eax, 0x4(%rsp)
 
@@ -495,14 +790,14 @@ TEST_F(Testx86AssemblyInspectionEngine,
       data, sizeof(data), sample_range, unwind_plan));
 
   // Unwind rules should look like
-  //     0: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] 
-  //     1: CFA=rsp+16 => rsp=CFA+0 rip=[CFA-8] 
-  //    22: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] 
+  //     0: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8]
+  //     1: CFA=rsp+16 => rsp=CFA+0 rip=[CFA-8]
+  //    22: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8]
 
   UnwindPlan::Row::RegisterLocation regloc;
 
   // grab the Row for when the prologue has finished executing:
-  //     1: CFA=rsp+16 => rsp=CFA+0 rip=[CFA-8] 
+  //     1: CFA=rsp+16 => rsp=CFA+0 rip=[CFA-8]
 
   UnwindPlan::RowSP row_sp = unwind_plan.GetRowForFunctionOffset(13);
 
@@ -548,7 +843,6 @@ TEST_F(Testx86AssemblyInspectionEngine,
   EXPECT_EQ(-8, regloc.GetOffset());
 }
 
-
 TEST_F(Testx86AssemblyInspectionEngine, Test32bitFramelessSmallStackFrame) {
   std::unique_ptr<x86AssemblyInspectionEngine> engine = Geti386Inspector();
 
@@ -563,7 +857,7 @@ TEST_F(Testx86AssemblyInspectionEngine,
   uint8_t data[] = {
       0x83, 0xec, 0x0c,
       // offset 0 -- subl $0xc, %esp
-      
+
       0xe8, 0x00, 0x00, 0x00, 0x00,
       // offset 3 -- calll 0 {call the next instruction, to put the pc on
       // the stack}
@@ -603,11 +897,11 @@ TEST_F(Testx86AssemblyInspectionEngine,
       data, sizeof(data), sample_range, unwind_plan));
 
   // Unwind rules should look like
-  // row[0]:    0: CFA=esp +4 => esp=CFA+0 eip=[CFA-4] 
-  // row[1]:    3: CFA=esp+16 => esp=CFA+0 eip=[CFA-4] 
-  // row[2]:    8: CFA=esp+20 => esp=CFA+0 eip=[CFA-4] 
-  // row[3]:    9: CFA=esp+16 => esp=CFA+0 eip=[CFA-4] 
-  // row[4]:   34: CFA=esp +4 => esp=CFA+0 eip=[CFA-4] 
+  // row[0]:    0: CFA=esp +4 => esp=CFA+0 eip=[CFA-4]
+  // row[1]:    3: CFA=esp+16 => esp=CFA+0 eip=[CFA-4]
+  // row[2]:    8: CFA=esp+20 => esp=CFA+0 eip=[CFA-4]
+  // row[3]:    9: CFA=esp+16 => esp=CFA+0 eip=[CFA-4]
+  // row[4]:   34: CFA=esp +4 => esp=CFA+0 eip=[CFA-4]
 
   UnwindPlan::Row::RegisterLocation regloc;
 
@@ -631,7 +925,7 @@ TEST_F(Testx86AssemblyInspectionEngine,
   EXPECT_EQ(20, row_sp->GetCFAValue().GetOffset());
 
   // Check unwind state after we pop the pic base value off the stack
-  // row[3]:    9: CFA=esp+16 => esp=CFA+0 eip=[CFA-4] 
+  // row[3]:    9: CFA=esp+16 => esp=CFA+0 eip=[CFA-4]
 
   row_sp = unwind_plan.GetRowForFunctionOffset(9);
   EXPECT_EQ(9, row_sp->GetOffset());
@@ -650,7 +944,7 @@ TEST_F(Testx86AssemblyInspectionEngine,
   EXPECT_FALSE(row_sp->GetRegisterInfo(k_ebp, regloc));
 
   // verify that we get back to the original unwind state before the ret
-  //  34: CFA=esp +4 => esp=CFA+0 eip=[CFA-4] 
+  //  34: CFA=esp +4 => esp=CFA+0 eip=[CFA-4]
 
   row_sp = unwind_plan.GetRowForFunctionOffset(34);
   EXPECT_EQ(34, row_sp->GetOffset());




More information about the lldb-commits mailing list