[Lldb-commits] [lldb] d8ff269 - [lldb] Add explicit 64-bit fip/fdp registers on x86_64

Michał Górny via lldb-commits lldb-commits at lists.llvm.org
Thu Nov 19 04:23:22 PST 2020


Author: Michał Górny
Date: 2020-11-19T13:23:12+01:00
New Revision: d8ff269f677621a773d75c79d50bb3f59a6b052e

URL: https://github.com/llvm/llvm-project/commit/d8ff269f677621a773d75c79d50bb3f59a6b052e
DIFF: https://github.com/llvm/llvm-project/commit/d8ff269f677621a773d75c79d50bb3f59a6b052e.diff

LOG: [lldb] Add explicit 64-bit fip/fdp registers on x86_64

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.

Differential Revision: https://reviews.llvm.org/D91497

Added: 
    lldb/test/Shell/Register/x86-64-fp-read.test

Modified: 
    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/RegisterContextPOSIX_x86.h
    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-write.test
    lldb/test/Shell/Register/x86-fp-read.test
    lldb/test/Shell/Register/x86-fp-write.test
    lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp
index 1682a13977d9..ea2494dabf27 100644
--- a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp
+++ b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp
@@ -80,20 +80,21 @@ static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
 
 // 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_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_mm0_x86_64,       lldb_mm1_x86_64,   lldb_mm2_x86_64,
-    lldb_mm3_x86_64,       lldb_mm4_x86_64,   lldb_mm5_x86_64,
-    lldb_mm6_x86_64,       lldb_mm7_x86_64,   lldb_xmm0_x86_64,
-    lldb_xmm1_x86_64,      lldb_xmm2_x86_64,  lldb_xmm3_x86_64,
-    lldb_xmm4_x86_64,      lldb_xmm5_x86_64,  lldb_xmm6_x86_64,
-    lldb_xmm7_x86_64,      lldb_xmm8_x86_64,  lldb_xmm9_x86_64,
-    lldb_xmm10_x86_64,     lldb_xmm11_x86_64, lldb_xmm12_x86_64,
-    lldb_xmm13_x86_64,     lldb_xmm14_x86_64, lldb_xmm15_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_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_mm0_x86_64,
+    lldb_mm1_x86_64,    lldb_mm2_x86_64,   lldb_mm3_x86_64,
+    lldb_mm4_x86_64,    lldb_mm5_x86_64,   lldb_mm6_x86_64,
+    lldb_mm7_x86_64,    lldb_xmm0_x86_64,  lldb_xmm1_x86_64,
+    lldb_xmm2_x86_64,   lldb_xmm3_x86_64,  lldb_xmm4_x86_64,
+    lldb_xmm5_x86_64,   lldb_xmm6_x86_64,  lldb_xmm7_x86_64,
+    lldb_xmm8_x86_64,   lldb_xmm9_x86_64,  lldb_xmm10_x86_64,
+    lldb_xmm11_x86_64,  lldb_xmm12_x86_64, lldb_xmm13_x86_64,
+    lldb_xmm14_x86_64,  lldb_xmm15_x86_64,
     LLDB_INVALID_REGNUM // register sets need to end with this flag
 };
 static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) -
@@ -280,7 +281,7 @@ NativeRegisterContextFreeBSD_x86_64::NativeRegisterContextFreeBSD_x86_64(
     llvm_unreachable("Unhandled target architecture.");
   }
 
-  for (int i: {FPRegSet, DBRegSet})
+  for (int i : {FPRegSet, DBRegSet})
     m_regset_offsets[i] = GetRegisterInfoInterface()
                               .GetRegisterInfo()[first_regnos[i]]
                               .byte_offset;

diff  --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
index 0eb83b44274d..20cd5e3f62ff 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -149,20 +149,21 @@ static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
 
 // 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_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_mm0_x86_64,       lldb_mm1_x86_64,   lldb_mm2_x86_64,
-    lldb_mm3_x86_64,       lldb_mm4_x86_64,   lldb_mm5_x86_64,
-    lldb_mm6_x86_64,       lldb_mm7_x86_64,   lldb_xmm0_x86_64,
-    lldb_xmm1_x86_64,      lldb_xmm2_x86_64,  lldb_xmm3_x86_64,
-    lldb_xmm4_x86_64,      lldb_xmm5_x86_64,  lldb_xmm6_x86_64,
-    lldb_xmm7_x86_64,      lldb_xmm8_x86_64,  lldb_xmm9_x86_64,
-    lldb_xmm10_x86_64,     lldb_xmm11_x86_64, lldb_xmm12_x86_64,
-    lldb_xmm13_x86_64,     lldb_xmm14_x86_64, lldb_xmm15_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_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_mm0_x86_64,
+    lldb_mm1_x86_64,    lldb_mm2_x86_64,   lldb_mm3_x86_64,
+    lldb_mm4_x86_64,    lldb_mm5_x86_64,   lldb_mm6_x86_64,
+    lldb_mm7_x86_64,    lldb_xmm0_x86_64,  lldb_xmm1_x86_64,
+    lldb_xmm2_x86_64,   lldb_xmm3_x86_64,  lldb_xmm4_x86_64,
+    lldb_xmm5_x86_64,   lldb_xmm6_x86_64,  lldb_xmm7_x86_64,
+    lldb_xmm8_x86_64,   lldb_xmm9_x86_64,  lldb_xmm10_x86_64,
+    lldb_xmm11_x86_64,  lldb_xmm12_x86_64, lldb_xmm13_x86_64,
+    lldb_xmm14_x86_64,  lldb_xmm15_x86_64,
     LLDB_INVALID_REGNUM // register sets need to end with this flag
 };
 static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) -

diff  --git a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
index a2e896fbd002..917693884681 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
+++ b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
@@ -83,28 +83,26 @@ static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
 
 // 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_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_mm0_x86_64,       lldb_mm1_x86_64,   lldb_mm2_x86_64,
-    lldb_mm3_x86_64,       lldb_mm4_x86_64,   lldb_mm5_x86_64,
-    lldb_mm6_x86_64,       lldb_mm7_x86_64,   lldb_xmm0_x86_64,
-    lldb_xmm1_x86_64,      lldb_xmm2_x86_64,  lldb_xmm3_x86_64,
-    lldb_xmm4_x86_64,      lldb_xmm5_x86_64,  lldb_xmm6_x86_64,
-    lldb_xmm7_x86_64,      lldb_xmm8_x86_64,  lldb_xmm9_x86_64,
-    lldb_xmm10_x86_64,     lldb_xmm11_x86_64, lldb_xmm12_x86_64,
-    lldb_xmm13_x86_64,     lldb_xmm14_x86_64, lldb_xmm15_x86_64,
-    lldb_ymm0_x86_64,   lldb_ymm1_x86_64,  lldb_ymm2_x86_64,  lldb_ymm3_x86_64,
-    lldb_ymm4_x86_64,   lldb_ymm5_x86_64,  lldb_ymm6_x86_64,  lldb_ymm7_x86_64,
-    lldb_ymm8_x86_64,   lldb_ymm9_x86_64,  lldb_ymm10_x86_64, lldb_ymm11_x86_64,
-    lldb_ymm12_x86_64,  lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_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_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_mm0_x86_64, lldb_mm1_x86_64, lldb_mm2_x86_64,
+    lldb_mm3_x86_64, lldb_mm4_x86_64, lldb_mm5_x86_64, lldb_mm6_x86_64,
+    lldb_mm7_x86_64, lldb_xmm0_x86_64, lldb_xmm1_x86_64, lldb_xmm2_x86_64,
+    lldb_xmm3_x86_64, lldb_xmm4_x86_64, lldb_xmm5_x86_64, lldb_xmm6_x86_64,
+    lldb_xmm7_x86_64, lldb_xmm8_x86_64, lldb_xmm9_x86_64, lldb_xmm10_x86_64,
+    lldb_xmm11_x86_64, lldb_xmm12_x86_64, lldb_xmm13_x86_64, lldb_xmm14_x86_64,
+    lldb_xmm15_x86_64, lldb_ymm0_x86_64, lldb_ymm1_x86_64, lldb_ymm2_x86_64,
+    lldb_ymm3_x86_64, lldb_ymm4_x86_64, lldb_ymm5_x86_64, lldb_ymm6_x86_64,
+    lldb_ymm7_x86_64, lldb_ymm8_x86_64, lldb_ymm9_x86_64, lldb_ymm10_x86_64,
+    lldb_ymm11_x86_64, lldb_ymm12_x86_64, lldb_ymm13_x86_64, lldb_ymm14_x86_64,
+    lldb_ymm15_x86_64,
     // Note: we currently do not provide them but this is needed to avoid
     // unnamed groups in SBFrame::GetRegisterContext().
-    lldb_bnd0_x86_64,    lldb_bnd1_x86_64,    lldb_bnd2_x86_64,
-    lldb_bnd3_x86_64,    lldb_bndcfgu_x86_64, lldb_bndstatus_x86_64,
+    lldb_bnd0_x86_64, lldb_bnd1_x86_64, lldb_bnd2_x86_64, lldb_bnd3_x86_64,
+    lldb_bndcfgu_x86_64, lldb_bndstatus_x86_64,
     LLDB_INVALID_REGNUM // register sets need to end with this flag
 };
 static_assert((sizeof(g_xstate_regnums_x86_64) /
@@ -621,12 +619,18 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
   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 +916,18 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
   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;

diff  --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
index ac271a90d6a1..bf9282d8c0cc 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
@@ -119,20 +119,21 @@ static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
               "g_gpr_regnums_x86_64 has wrong number of register infos");
 
 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_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_mm0_x86_64,       lldb_mm1_x86_64,   lldb_mm2_x86_64,
-    lldb_mm3_x86_64,       lldb_mm4_x86_64,   lldb_mm5_x86_64,
-    lldb_mm6_x86_64,       lldb_mm7_x86_64,   lldb_xmm0_x86_64,
-    lldb_xmm1_x86_64,      lldb_xmm2_x86_64,  lldb_xmm3_x86_64,
-    lldb_xmm4_x86_64,      lldb_xmm5_x86_64,  lldb_xmm6_x86_64,
-    lldb_xmm7_x86_64,      lldb_xmm8_x86_64,  lldb_xmm9_x86_64,
-    lldb_xmm10_x86_64,     lldb_xmm11_x86_64, lldb_xmm12_x86_64,
-    lldb_xmm13_x86_64,     lldb_xmm14_x86_64, lldb_xmm15_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_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_mm0_x86_64,
+    lldb_mm1_x86_64,    lldb_mm2_x86_64,   lldb_mm3_x86_64,
+    lldb_mm4_x86_64,    lldb_mm5_x86_64,   lldb_mm6_x86_64,
+    lldb_mm7_x86_64,    lldb_xmm0_x86_64,  lldb_xmm1_x86_64,
+    lldb_xmm2_x86_64,   lldb_xmm3_x86_64,  lldb_xmm4_x86_64,
+    lldb_xmm5_x86_64,   lldb_xmm6_x86_64,  lldb_xmm7_x86_64,
+    lldb_xmm8_x86_64,   lldb_xmm9_x86_64,  lldb_xmm10_x86_64,
+    lldb_xmm11_x86_64,  lldb_xmm12_x86_64, lldb_xmm13_x86_64,
+    lldb_xmm14_x86_64,  lldb_xmm15_x86_64,
     LLDB_INVALID_REGNUM // Register sets must be terminated with
                         // LLDB_INVALID_REGNUM.
 };
@@ -275,6 +276,16 @@ uint32_t RegisterContextPOSIX_x86::g_invalidate_r15[] = {
     lldb_r15_x86_64, lldb_r15d_x86_64, lldb_r15w_x86_64, lldb_r15l_x86_64,
     LLDB_INVALID_REGNUM};
 
+uint32_t RegisterContextPOSIX_x86::g_contained_fip[] = {lldb_fip_x86_64,
+                                                        LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_fdp[] = {lldb_fdp_x86_64,
+                                                        LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_invalidate_fip[] = {
+    lldb_fip_x86_64, lldb_fioff_x86_64, lldb_fiseg_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_fdp[] = {
+    lldb_fdp_x86_64, lldb_fooff_x86_64, lldb_foseg_x86_64, LLDB_INVALID_REGNUM};
+
 // Number of register sets provided by this context.
 enum { k_num_extended_register_sets = 1, k_num_register_sets = 3 };
 

diff  --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
index 81d467311c4f..7ccf0a94faae 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
@@ -106,6 +106,12 @@ class RegisterContextPOSIX_x86 : public lldb_private::RegisterContext {
   static uint32_t g_invalidate_r14[];
   static uint32_t g_invalidate_r15[];
 
+  static uint32_t g_contained_fip[];
+  static uint32_t g_contained_fdp[];
+
+  static uint32_t g_invalidate_fip[];
+  static uint32_t g_invalidate_fdp[];
+
 protected:
   struct RegInfo {
     uint32_t num_registers;

diff  --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
index af3027afa73c..466248cc1d47 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
@@ -195,6 +195,14 @@
                     RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
   }
 
+#define DEFINE_FPR_32(name, reg, kind1, kind2, kind3, kind4, reg64)            \
+  {                                                                            \
+    #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+    {kind1, kind2, kind3, kind4, lldb_##name##_x86_64 },                       \
+    RegisterContextPOSIX_x86::g_contained_##reg64,                             \
+    RegisterContextPOSIX_x86::g_invalidate_##reg64,           nullptr, 0       \
+  }
+
 // clang-format off
 static RegisterInfo g_register_infos_x86_64[] = {
 // General purpose registers     EH_Frame              DWARF                 Generic                     Process Plugin
@@ -251,16 +259,18 @@ static RegisterInfo g_register_infos_x86_64[] = {
     DEFINE_GPR_PSEUDO_8L(r12l, r12), DEFINE_GPR_PSEUDO_8L(r13l, r13),
     DEFINE_GPR_PSEUDO_8L(r14l, r14), DEFINE_GPR_PSEUDO_8L(r15l, r15),
 
-//  i387 Floating point registers.         EH_frame             DWARF                Generic              Process Plugin
-//  ====================================== ===============      ==================   ===================  ====================
+//  i387 Floating point registers.         EH_frame             DWARF                Generic              Process Plugin       reg64
+//  ====================================== ===============      ==================   ===================  ==================== =====
     DEFINE_FPR(fctrl,     fctrl,           dwarf_fctrl_x86_64,  dwarf_fctrl_x86_64,  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
     DEFINE_FPR(fstat,     fstat,           dwarf_fstat_x86_64,  dwarf_fstat_x86_64,  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
     DEFINE_FPR(ftag,      ftag,            LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
     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(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_32(fiseg,  ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fip),
+    DEFINE_FPR_32(fioff,  ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fip),
+    DEFINE_FPR(fip,       ptr.x86_64.fip,  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+    DEFINE_FPR_32(foseg,  ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fdp),
+    DEFINE_FPR_32(fooff,  ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fdp),
+    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),
 

diff  --git a/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
index 3bee9393719d..4d10600f4771 100644
--- a/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
+++ b/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
@@ -228,8 +228,10 @@ enum {
   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,

diff  --git a/lldb/test/Shell/Register/x86-64-fp-read.test b/lldb/test/Shell/Register/x86-64-fp-read.test
new file mode 100644
index 000000000000..2be85a6c3b35
--- /dev/null
+++ b/lldb/test/Shell/Register/x86-64-fp-read.test
@@ -0,0 +1,41 @@
+# XFAIL: system-windows
+# XFAIL: system-darwin
+# 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 &zero
+# CHECK: (uint32_t *) $1 = [[ZERO:0x[0-9a-f]*]]
+
+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}
+
+# legacy approach, superseded by fip/fdp registers
+print (void*)($fiseg*0x100000000 + $fioff)
+# CHECK: (void *) $2 = [[FDIV]]
+print (uint32_t*)($foseg * 0x100000000 + $fooff)
+# CHECK: (uint32_t *) $3 = [[ZERO]]
+
+process continue
+# CHECK: Process {{[0-9]+}} exited with status = 0

diff  --git a/lldb/test/Shell/Register/x86-64-fp-write.test b/lldb/test/Shell/Register/x86-64-fp-write.test
index 6f8047f94360..ad7cfe7a7ee4 100644
--- a/lldb/test/Shell/Register/x86-64-fp-write.test
+++ b/lldb/test/Shell/Register/x86-64-fp-write.test
@@ -14,10 +14,8 @@ register write fop 0x0033
 # the exact addresses do not matter, we want just to verify FXSAVE
 # note: fxrstor64 apparently truncates this to 48 bits, and sign extends
 #       the highest bits, so let's keep the value safely below
-register write fiseg 0x00000567
-register write fioff 0x89abcdef
-register write foseg 0x00000a98
-register write fooff 0x76543210
+register write fip 0x0000056789abcdef
+register write fdp 0x00000a9876543210
 
 register write st0 "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x00 0x40}"
 register write st1 "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x3f 0x00 0x00}"

diff  --git a/lldb/test/Shell/Register/x86-fp-read.test b/lldb/test/Shell/Register/x86-fp-read.test
index f0c35c726c7c..3c676c1d2118 100644
--- a/lldb/test/Shell/Register/x86-fp-read.test
+++ b/lldb/test/Shell/Register/x86-fp-read.test
@@ -1,10 +1,16 @@
 # 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
 # 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 &zero
+# CHECK: (uint32_t *) $1 = [[ZERO:0x[0-9a-f]*]]
+
 register read --all
 # CHECK-DAG: fctrl = 0x037b
 # CHECK-DAG: fstat = 0x8084
@@ -12,6 +18,8 @@ register read --all
 # FXSAVE/XSAVE is interpreted
 # CHECK-DAG: ftag = 0x007f
 # CHECK-DAG: fop = 0x0033
+# CHECK-DAG: fioff = [[FDIV]]
+# CHECK-DAG: fooff = [[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}
@@ -22,16 +30,5 @@ register read --all
 # 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}
 
-# fdiv (%rbx) gets encoded into 2 bytes, int3 into 1 byte
-print (void*)($pc-3)
-# CHECK: (void *) $0 = [[FDIV:0x[0-9a-f]*]]
-# TODO: we probably should not split it like this
-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]]
-
 process continue
 # CHECK: Process {{[0-9]+}} exited with status = 0

diff  --git a/lldb/test/Shell/Register/x86-fp-write.test b/lldb/test/Shell/Register/x86-fp-write.test
index a88bbfd8ce00..38ffe16bab02 100644
--- a/lldb/test/Shell/Register/x86-fp-write.test
+++ b/lldb/test/Shell/Register/x86-fp-write.test
@@ -1,5 +1,5 @@
 # XFAIL: system-windows
-# REQUIRES: native && target-x86
+# REQUIRES: native && (target-x86 || target-x86_64)
 # RUN: %clangxx_host %p/Inputs/x86-fp-write.cpp -o %t
 # RUN: %lldb -b -s %s %t | FileCheck %s
 process launch
@@ -31,8 +31,11 @@ process continue
 # CHECK-DAG: fstat = 0x8884
 # CHECK-DAG: ftag = 0xa961
 # CHECK-DAG: fop = 0x0033
-# CHECK-DAG: fip = 0x89abcdef
-# CHECK-DAG: fdp = 0x76543210
+
+# This test is run both on 32-bit and 64-bit systems, in order to test
+# that fioff/fooff setting works as well as fip/fdp.
+# CHECK-DAG: fip = 0x{{(00000000)?}}89abcdef
+# CHECK-DAG: fdp = 0x{{(00000000)?}}76543210
 
 # CHECK-DAG: st0 = { 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x00 0x40 }
 # CHECK-DAG: st1 = { 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x3f 0x00 0x00 }

diff  --git a/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp b/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
index 6aaf0e58984a..7d875c9bd8a1 100644
--- a/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
+++ b/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
@@ -82,11 +82,15 @@ TEST(RegisterContextFreeBSDTest, x86_64) {
   EXPECT_OFF(ftag_x86_64, 0x04, 2);
   EXPECT_OFF(fop_x86_64, 0x06, 2);
   // NB: Technically fiseg/foseg are 16-bit long and the higher 16 bits
-  // are reserved.  However, we use them to access/recombine 64-bit FIP/FDP.
+  // are reserved.  However, LLDB defines them to be 32-bit long for backwards
+  // compatibility, as they were used to reconstruct FIP/FDP before explicit
+  // register entries for them were added.  Also, this is still how GDB does it.
   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);


        


More information about the lldb-commits mailing list