aleksandr.urakov created this revision.
aleksandr.urakov added reviewers: jasonmolenda, labath.
aleksandr.urakov added a project: LLDB.
Herald added subscribers: lldb-commits, abidh.

This patch makes `x86AssemblyInspectionEngine` to process zero value of the `B` 
field of the `REX` prefix in a correct way for `PUSH` and `POP` instructions. 
MSVC sometimes emits `pushq %rbp` instruction as `0x40 0x55`, and it was not 
parsed correctly before.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D57745

Files:
  source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
  unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp

Index: unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp
===================================================================
--- unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp
+++ unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp
@@ -325,27 +325,27 @@
   // compiled 'clang -fomit-frame-pointer -Os' for x86_64-apple-macosx
 
   uint8_t data[] = {
-      0x55,       // offset 0  -- pushq %rbp
-      0x41, 0x57, // offset 1  -- pushq %r15
-      0x41, 0x56, // offset 3  -- pushq %r14
-      0x41, 0x55, // offset 5  -- pushq %r13
-      0x41, 0x54, // offset 7  -- pushq %r12
-      0x53,       // offset 9  -- pushq %rbx
+      0x40, 0x55, // offset 0  -- pushq %rbp
+      0x41, 0x57, // offset 2  -- pushq %r15
+      0x41, 0x56, // offset 4  -- pushq %r14
+      0x41, 0x55, // offset 6  -- pushq %r13
+      0x41, 0x54, // offset 8  -- pushq %r12
+      0x53,       // offset 10 -- pushq %rbx
       0x48, 0x81, 0xec, 0x68, 0x38, 0x00,
-      0x00, // offset 10 -- subq $0x3868, %rsp
+      0x00, // offset 11 -- subq $0x3868, %rsp
 
       // ....
 
       0x48, 0x81, 0xc4, 0x68, 0x38, 0x00,
-      0x00,                        // offset 17 -- addq $0x3868, %rsp
-      0x5b,                        // offset 24 -- popq %rbx
-      0x41, 0x5c,                  // offset 25 -- popq %r12
-      0x41, 0x5d,                  // offset 27 -- popq %r13
-      0x41, 0x5e,                  // offset 29 -- popq %r14
-      0x41, 0x5f,                  // offset 31 -- popq %r15
-      0x5d,                        // offset 33 -- popq %rbp
-      0xc3,                        // offset 34 -- retq
-      0xe8, 0x12, 0x34, 0x56, 0x78 // offset 35 -- callq whatever
+      0x00,                        // offset 18 -- addq $0x3868, %rsp
+      0x5b,                        // offset 25 -- popq %rbx
+      0x41, 0x5c,                  // offset 26 -- popq %r12
+      0x41, 0x5d,                  // offset 28 -- popq %r13
+      0x41, 0x5e,                  // offset 30 -- popq %r14
+      0x41, 0x5f,                  // offset 32 -- popq %r15
+      0x40, 0x5d,                  // offset 34 -- popq %rbp
+      0xc3,                        // offset 36 -- retq
+      0xe8, 0x12, 0x34, 0x56, 0x78 // offset 37 -- callq whatever
   };
 
   AddressRange sample_range(0x1000, sizeof(data));
@@ -356,40 +356,40 @@
 
   // Unwind rules should look like
   // 0: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8]
-  // 1: CFA=rsp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8]
-  // 3: CFA=rsp+24 => rbp=[CFA-16] rsp=CFA+0 r15=[CFA-24] rip=[CFA-8]
-  // 5: CFA=rsp+32 => rbp=[CFA-16] rsp=CFA+0 r14=[CFA-32] r15=[CFA-24]
+  // 2: CFA=rsp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8]
+  // 4: CFA=rsp+24 => rbp=[CFA-16] rsp=CFA+0 r15=[CFA-24] rip=[CFA-8]
+  // 6: CFA=rsp+32 => rbp=[CFA-16] rsp=CFA+0 r14=[CFA-32] r15=[CFA-24]
   // rip=[CFA-8
-  // 7: CFA=rsp+40 => rbp=[CFA-16] rsp=CFA+0 r13=[CFA-40] r14=[CFA-32]
+  // 8: CFA=rsp+40 => rbp=[CFA-16] rsp=CFA+0 r13=[CFA-40] r14=[CFA-32]
   // r15=[CFA-24] rip=[CFA-8]
-  // 9: CFA=rsp+48 => rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48] r13=[CFA-40]
+  // 10: CFA=rsp+48 => rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48] r13=[CFA-40]
   // r14=[CFA-32] r15=[CFA-24] rip=[CFA-8]
-  // 10: CFA=rsp+56 => rbx=[CFA-56] rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48]
+  // 11: CFA=rsp+56 => rbx=[CFA-56] rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48]
   // r13=[CFA-40] r14=[CFA-32] r15=[CFA-24] rip=[CFA-8]
-  // 17: CFA=rsp+14496 => rbx=[CFA-56] rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48]
+  // 18: CFA=rsp+14496 => rbx=[CFA-56] rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48]
   // r13=[CFA-40] r14=[CFA-32] r15=[CFA-24] rip=[CFA-8]
 
-  // 24: CFA=rsp+56 => rbx=[CFA-56] rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48]
+  // 25: CFA=rsp+56 => rbx=[CFA-56] rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48]
   // r13=[CFA-40] r14=[CFA-32] r15=[CFA-24] rip=[CFA-8]
-  // 25: CFA=rsp+48 => rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48] r13=[CFA-40]
+  // 26: CFA=rsp+48 => rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48] r13=[CFA-40]
   // r14=[CFA-32] r15=[CFA-24] rip=[CFA-8]
-  // 27: CFA=rsp+40 => rbp=[CFA-16] rsp=CFA+0 r13=[CFA-40] r14=[CFA-32]
+  // 28: CFA=rsp+40 => rbp=[CFA-16] rsp=CFA+0 r13=[CFA-40] r14=[CFA-32]
   // r15=[CFA-24] rip=[CFA-8]
-  // 29: CFA=rsp+32 => rbp=[CFA-16] rsp=CFA+0 r14=[CFA-32] r15=[CFA-24]
+  // 30: CFA=rsp+32 => rbp=[CFA-16] rsp=CFA+0 r14=[CFA-32] r15=[CFA-24]
   // rip=[CFA-8]
-  // 31: CFA=rsp+24 => rbp=[CFA-16] rsp=CFA+0 r15=[CFA-24] rip=[CFA-8]
-  // 33: CFA=rsp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8]
-  // 34: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8]
+  // 32: CFA=rsp+24 => rbp=[CFA-16] rsp=CFA+0 r15=[CFA-24] rip=[CFA-8]
+  // 34: CFA=rsp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8]
+  // 36: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8]
 
   UnwindPlan::Row::RegisterLocation regloc;
 
   // grab the Row for when the prologue has finished executing:
-  // 17: CFA=rsp+14496 => rbx=[CFA-56] rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48]
+  // 18: CFA=rsp+14496 => rbx=[CFA-56] rbp=[CFA-16] rsp=CFA+0 r12=[CFA-48]
   // r13=[CFA-40] r14=[CFA-32] r15=[CFA-24] rip=[CFA-8]
 
-  UnwindPlan::RowSP row_sp = unwind_plan.GetRowForFunctionOffset(17);
+  UnwindPlan::RowSP row_sp = unwind_plan.GetRowForFunctionOffset(18);
 
-  EXPECT_EQ(17ull, row_sp->GetOffset());
+  EXPECT_EQ(18ull, row_sp->GetOffset());
   EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp);
   EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
   EXPECT_EQ(14496, row_sp->GetCFAValue().GetOffset());
@@ -423,11 +423,11 @@
   EXPECT_EQ(-56, regloc.GetOffset());
 
   // grab the Row for when the epilogue has finished executing:
-  // 34: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8]
+  // 36: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8]
 
-  row_sp = unwind_plan.GetRowForFunctionOffset(34);
+  row_sp = unwind_plan.GetRowForFunctionOffset(36);
 
-  EXPECT_EQ(34ull, row_sp->GetOffset());
+  EXPECT_EQ(36ull, 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());
Index: source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
===================================================================
--- source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
+++ source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
@@ -364,8 +364,8 @@
   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;
+  if (m_wordsize == 8 && (*p & 0xfe) == 0x40) {
+    regno_prefix_bit = (*p & 1) << 3;
     p++;
   }
   if (*p >= 0x50 && *p <= 0x57) {
@@ -562,8 +562,8 @@
   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;
+  if (m_wordsize == 8 && (*p & 0xfe) == 0x40) {
+    regno_prefix_bit = (*p & 1) << 3;
     p++;
   }
   if (*p >= 0x58 && *p <= 0x5f) {
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to