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); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits