mgorny created this revision.
mgorny added reviewers: labath, krytarowski, emaste.
Herald added a subscriber: pengfei.
mgorny requested review of this revision.

The FXSAVE/XSAVE data can have two different layouts on x86_64.  When
called as FXSAVE/XSAVE..., the Instruction Pointer and Address Pointer
registers are reported using a 16-bit segment identifier and a 32-bit
offset.  When called as FXSAVE64/XSAVE64..., they are reported using
a complete 64-bit offsets instead.

LLDB has historically followed GDB and unconditionally used to assume
the 32-bit layout, with the slight modification of possibly
using a 32-bit segment register (i.e. extending the register into
the reserved 16 upper bits).  When the underlying operating system used
FXSAVE64/XSAVE64..., the pointer was split into two halves,
with the upper half repored as the segment registers.  While
reconstructing the full address was possible on the user end (and e.g.
the FPU register tests did that), it certainly was not the most
convenient option.

Introduce a two additional 'fip' and 'fdp' registers that overlap
with 'fiseg'/'fioff' and 'foseg'/'foff' respectively, and report
the complete 64-bit address.


https://reviews.llvm.org/D91497

Files:
  
lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp
  lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
  lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
  lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
  lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
  lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
  lldb/test/Shell/Register/x86-64-fp-read.test
  lldb/test/Shell/Register/x86-fp-read.test
  lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp

Index: lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
===================================================================
--- lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
+++ lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
@@ -83,8 +83,10 @@
   // are reserved.  However, we use them to access/recombine 64-bit FIP/FDP.
   EXPECT_OFF(fioff_x86_64, 0x08, 4);
   EXPECT_OFF(fiseg_x86_64, 0x0C, 4);
+  EXPECT_OFF(fip_x86_64, 0x08, 8);
   EXPECT_OFF(fooff_x86_64, 0x10, 4);
   EXPECT_OFF(foseg_x86_64, 0x14, 4);
+  EXPECT_OFF(fdp_x86_64, 0x10, 8);
   EXPECT_OFF(mxcsr_x86_64, 0x18, 4);
   EXPECT_OFF(mxcsrmask_x86_64, 0x1C, 4);
   EXPECT_OFF(st0_x86_64, 0x20, 10);
Index: lldb/test/Shell/Register/x86-fp-read.test
===================================================================
--- lldb/test/Shell/Register/x86-fp-read.test
+++ lldb/test/Shell/Register/x86-fp-read.test
@@ -1,5 +1,5 @@
 # XFAIL: system-windows
-# REQUIRES: native && (target-x86 || target-x86_64)
+# REQUIRES: native && target-x86
 # RUN: %clangxx_host -g %p/Inputs/x86-fp-read.cpp -o %t
 # RUN: %lldb -b -s %s %t | FileCheck %s
 process launch
Index: lldb/test/Shell/Register/x86-64-fp-read.test
===================================================================
--- /dev/null
+++ lldb/test/Shell/Register/x86-64-fp-read.test
@@ -0,0 +1,38 @@
+# XFAIL: system-windows
+# REQUIRES: native && target-x86_64
+# RUN: %clangxx_host -g %p/Inputs/x86-fp-read.cpp -o %t
+# RUN: %lldb -b -s %s %t | FileCheck %s
+process launch
+# CHECK: Process {{.*}} stopped
+
+# fdiv (%rbx) gets encoded into 2 bytes, int3 into 1 byte
+print (void*)($pc-3)
+# CHECK: (void *) $0 = [[FDIV:0x[0-9a-f]*]]
+print (void*)($fiseg*0x100000000 + $fioff)
+# CHECK: (void *) $1 = [[FDIV]]
+print &zero
+# CHECK: (uint32_t *) $2 = [[ZERO:0x[0-9a-f]*]]
+print (uint32_t*)($foseg * 0x100000000 + $fooff)
+# CHECK: (uint32_t *) $3 = [[ZERO]]
+
+register read --all
+# CHECK-DAG: fctrl = 0x037b
+# CHECK-DAG: fstat = 0x8084
+# TODO: the following value is incorrect, it's a bug in the way
+# FXSAVE/XSAVE is interpreted
+# CHECK-DAG: ftag = 0x007f
+# CHECK-DAG: fop = 0x0033
+# CHECK-DAG: fip = [[FDIV]]
+# CHECK-DAG: fdp = [[ZERO]]
+
+# CHECK-DAG: st{{(mm)?}}0 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x00 0x40}
+# CHECK-DAG: st{{(mm)?}}1 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x3f 0x00 0x00}
+# CHECK-DAG: st{{(mm)?}}2 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}
+# CHECK-DAG: st{{(mm)?}}3 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80}
+# CHECK-DAG: st{{(mm)?}}4 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0xff 0x7f}
+# CHECK-DAG: st{{(mm)?}}5 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0xff 0xff}
+# CHECK-DAG: st{{(mm)?}}6 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xc0 0xff 0xff}
+# CHECK-DAG: st{{(mm)?}}7 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}
+
+process continue
+# CHECK: Process {{[0-9]+}} exited with status = 0
Index: lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
===================================================================
--- lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
+++ lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
@@ -228,8 +228,10 @@
   lldb_fop_x86_64,
   lldb_fiseg_x86_64,
   lldb_fioff_x86_64,
+  lldb_fip_x86_64,
   lldb_foseg_x86_64,
   lldb_fooff_x86_64,
+  lldb_fdp_x86_64,
   lldb_mxcsr_x86_64,
   lldb_mxcsrmask_x86_64,
   lldb_st0_x86_64,
Index: lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
===================================================================
--- lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
+++ lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
@@ -259,8 +259,10 @@
     DEFINE_FPR(fop,       fop,             LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
     DEFINE_FPR(fiseg,     ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
     DEFINE_FPR(fioff,     ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+    DEFINE_FPR(fip,       ptr.x86_64.fip,  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
     DEFINE_FPR(foseg,     ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
     DEFINE_FPR(fooff,     ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+    DEFINE_FPR(fdp,       ptr.x86_64.fdp,  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
     DEFINE_FPR(mxcsr,     mxcsr,           dwarf_mxcsr_x86_64,  dwarf_mxcsr_x86_64,  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
     DEFINE_FPR(mxcsrmask, mxcsrmask,       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
 
Index: lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
===================================================================
--- lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
+++ lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
@@ -120,8 +120,8 @@
 
 static const uint32_t g_lldb_regnums_x86_64[] = {
     lldb_fctrl_x86_64,     lldb_fstat_x86_64, lldb_ftag_x86_64,
-    lldb_fop_x86_64,       lldb_fiseg_x86_64, lldb_fioff_x86_64,
-    lldb_foseg_x86_64,     lldb_fooff_x86_64, lldb_mxcsr_x86_64,
+    lldb_fop_x86_64,       lldb_fiseg_x86_64, lldb_fioff_x86_64, lldb_fip_x86_64,
+    lldb_foseg_x86_64,     lldb_fooff_x86_64, lldb_fdp_x86_64, lldb_mxcsr_x86_64,
     lldb_mxcsrmask_x86_64, lldb_st0_x86_64,   lldb_st1_x86_64,
     lldb_st2_x86_64,       lldb_st3_x86_64,   lldb_st4_x86_64,
     lldb_st5_x86_64,       lldb_st6_x86_64,   lldb_st7_x86_64,
Index: lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
===================================================================
--- lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
+++ lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
@@ -84,8 +84,8 @@
 // x86 64-bit registers available via XState.
 static const uint32_t g_xstate_regnums_x86_64[] = {
     lldb_fctrl_x86_64,     lldb_fstat_x86_64, lldb_ftag_x86_64,
-    lldb_fop_x86_64,       lldb_fiseg_x86_64, lldb_fioff_x86_64,
-    lldb_foseg_x86_64,     lldb_fooff_x86_64, lldb_mxcsr_x86_64,
+    lldb_fop_x86_64,       lldb_fiseg_x86_64, lldb_fioff_x86_64, lldb_fip_x86_64,
+    lldb_foseg_x86_64,     lldb_fooff_x86_64, lldb_fdp_x86_64, lldb_mxcsr_x86_64,
     lldb_mxcsrmask_x86_64, lldb_st0_x86_64,   lldb_st1_x86_64,
     lldb_st2_x86_64,       lldb_st3_x86_64,   lldb_st4_x86_64,
     lldb_st5_x86_64,       lldb_st6_x86_64,   lldb_st7_x86_64,
@@ -621,12 +621,18 @@
   case lldb_fioff_x86_64:
     reg_value = (uint32_t)m_xstate.xs_fxsave.fx_ip.fa_32.fa_off;
     break;
+  case lldb_fip_x86_64:
+    reg_value = (uint64_t)m_xstate.xs_fxsave.fx_ip.fa_64;
+    break;
   case lldb_foseg_x86_64:
     reg_value = (uint32_t)m_xstate.xs_fxsave.fx_dp.fa_32.fa_seg;
     break;
   case lldb_fooff_x86_64:
     reg_value = (uint32_t)m_xstate.xs_fxsave.fx_dp.fa_32.fa_off;
     break;
+  case lldb_fdp_x86_64:
+    reg_value = (uint64_t)m_xstate.xs_fxsave.fx_dp.fa_64;
+    break;
   case lldb_mxcsr_x86_64:
     reg_value = (uint32_t)m_xstate.xs_fxsave.fx_mxcsr;
     break;
@@ -912,12 +918,18 @@
   case lldb_fioff_x86_64:
     m_xstate.xs_fxsave.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32();
     break;
+  case lldb_fip_x86_64:
+    m_xstate.xs_fxsave.fx_ip.fa_64 = reg_value.GetAsUInt64();
+    break;
   case lldb_foseg_x86_64:
     m_xstate.xs_fxsave.fx_dp.fa_32.fa_seg = reg_value.GetAsUInt32();
     break;
   case lldb_fooff_x86_64:
     m_xstate.xs_fxsave.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32();
     break;
+  case lldb_fdp_x86_64:
+    m_xstate.xs_fxsave.fx_dp.fa_64 = reg_value.GetAsUInt64();
+    break;
   case lldb_mxcsr_x86_64:
     m_xstate.xs_fxsave.fx_mxcsr = reg_value.GetAsUInt32();
     new_xstate_bv = XCR0_SSE;
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -150,8 +150,8 @@
 // x86 64-bit floating point registers.
 static const uint32_t g_fpu_regnums_x86_64[] = {
     lldb_fctrl_x86_64,     lldb_fstat_x86_64, lldb_ftag_x86_64,
-    lldb_fop_x86_64,       lldb_fiseg_x86_64, lldb_fioff_x86_64,
-    lldb_foseg_x86_64,     lldb_fooff_x86_64, lldb_mxcsr_x86_64,
+    lldb_fop_x86_64,       lldb_fiseg_x86_64, lldb_fioff_x86_64, lldb_fip_x86_64,
+    lldb_foseg_x86_64,     lldb_fooff_x86_64, lldb_fdp_x86_64, lldb_mxcsr_x86_64,
     lldb_mxcsrmask_x86_64, lldb_st0_x86_64,   lldb_st1_x86_64,
     lldb_st2_x86_64,       lldb_st3_x86_64,   lldb_st4_x86_64,
     lldb_st5_x86_64,       lldb_st6_x86_64,   lldb_st7_x86_64,
Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp
===================================================================
--- lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp
+++ lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp
@@ -81,8 +81,8 @@
 // x86 64-bit floating point registers.
 static const uint32_t g_fpu_regnums_x86_64[] = {
     lldb_fctrl_x86_64,     lldb_fstat_x86_64, lldb_ftag_x86_64,
-    lldb_fop_x86_64,       lldb_fiseg_x86_64, lldb_fioff_x86_64,
-    lldb_foseg_x86_64,     lldb_fooff_x86_64, lldb_mxcsr_x86_64,
+    lldb_fop_x86_64,       lldb_fiseg_x86_64, lldb_fioff_x86_64, lldb_fip_x86_64,
+    lldb_foseg_x86_64,     lldb_fooff_x86_64, lldb_fdp_x86_64, lldb_mxcsr_x86_64,
     lldb_mxcsrmask_x86_64, lldb_st0_x86_64,   lldb_st1_x86_64,
     lldb_st2_x86_64,       lldb_st3_x86_64,   lldb_st4_x86_64,
     lldb_st5_x86_64,       lldb_st6_x86_64,   lldb_st7_x86_64,
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to