diff options
| author | Michal Gorny <mgorny@gentoo.org> | 2019-07-01 15:11:04 +0000 |
|---|---|---|
| committer | Michal Gorny <mgorny@gentoo.org> | 2019-07-01 15:11:04 +0000 |
| commit | 2b2ad9342e65042baefc379e4a70774d8e538e84 (patch) | |
| tree | 246e0470ede1089c0952c970c375a5bba4252479 /lldb/source/Plugins/Process/NetBSD | |
| parent | 2ba16011c139ee12c1d4959e6c77702444a0b9cd (diff) | |
| download | bcm5719-llvm-2b2ad9342e65042baefc379e4a70774d8e538e84.tar.gz bcm5719-llvm-2b2ad9342e65042baefc379e4a70774d8e538e84.zip | |
[lldb] [Process/NetBSD] Support reading YMM registers via PT_*XSTATE
Provide a (conditional) support for the new PT_GETXSTATE
and PT_SETXSTATE ptrace() requests, and use them to implement getting
and setting YMM registers. The functions used for splitting
and recombining YMM register data are based on matching functions
in FreeBSD plugin, with some simplification and updates to match NetBSD
structures.
Differential Revision: https://reviews.llvm.org/D63545
llvm-svn: 364779
Diffstat (limited to 'lldb/source/Plugins/Process/NetBSD')
| -rw-r--r-- | lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp | 89 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h | 10 |
2 files changed, 97 insertions, 2 deletions
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp index c91e9bf2c50..d611e190489 100644 --- a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp +++ b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp @@ -22,7 +22,10 @@ #include <sys/types.h> #include <sys/ptrace.h> #include <sys/sysctl.h> +#include <sys/uio.h> #include <x86/cpu.h> +#include <x86/cpu_extended_state.h> +#include <x86/specialreg.h> #include <elf.h> #include <err.h> #include <stdint.h> @@ -148,7 +151,7 @@ int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum( else if (reg_num <= k_last_fpr_x86_64) return FPRegSet; else if (reg_num <= k_last_avx_x86_64) - return -1; // AVX + return XStateRegSet; // AVX else if (reg_num <= k_last_mpxr_x86_64) return -1; // MPXR else if (reg_num <= k_last_mpxc_x86_64) @@ -167,6 +170,15 @@ Status NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(uint32_t set) { return DoRegisterSet(PT_GETFPREGS, &m_fpr_x86_64); case DBRegSet: return DoRegisterSet(PT_GETDBREGS, &m_dbr_x86_64); + case XStateRegSet: +#ifdef HAVE_XSTATE + { + struct iovec iov = {&m_xstate_x86_64, sizeof(m_xstate_x86_64)}; + return DoRegisterSet(PT_GETXSTATE, &iov); + } +#else + return Status("XState is not supported by the kernel"); +#endif } llvm_unreachable("NativeRegisterContextNetBSD_x86_64::ReadRegisterSet"); } @@ -179,6 +191,15 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegisterSet(uint32_t set) { return DoRegisterSet(PT_SETFPREGS, &m_fpr_x86_64); case DBRegSet: return DoRegisterSet(PT_SETDBREGS, &m_dbr_x86_64); + case XStateRegSet: +#ifdef HAVE_XSTATE + { + struct iovec iov = {&m_xstate_x86_64, sizeof(m_xstate_x86_64)}; + return DoRegisterSet(PT_SETXSTATE, &iov); + } +#else + return Status("XState is not supported by the kernel"); +#endif } llvm_unreachable("NativeRegisterContextNetBSD_x86_64::WriteRegisterSet"); } @@ -360,6 +381,39 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info, reg_value.SetBytes(&m_fpr_x86_64.fxstate.fx_xmm[reg - lldb_xmm0_x86_64], reg_info->byte_size, endian::InlHostByteOrder()); break; + case lldb_ymm0_x86_64: + case lldb_ymm1_x86_64: + case lldb_ymm2_x86_64: + case lldb_ymm3_x86_64: + case lldb_ymm4_x86_64: + case lldb_ymm5_x86_64: + case lldb_ymm6_x86_64: + case lldb_ymm7_x86_64: + case lldb_ymm8_x86_64: + case lldb_ymm9_x86_64: + case lldb_ymm10_x86_64: + case lldb_ymm11_x86_64: + case lldb_ymm12_x86_64: + case lldb_ymm13_x86_64: + case lldb_ymm14_x86_64: + case lldb_ymm15_x86_64: +#ifdef HAVE_XSTATE + if (!(m_xstate_x86_64.xs_rfbm & XCR0_SSE) || + !(m_xstate_x86_64.xs_rfbm & XCR0_YMM_Hi128)) { + error.SetErrorStringWithFormat("register \"%s\" not supported by CPU/kernel", + reg_info->name); + } else { + uint32_t reg_index = reg - lldb_ymm0_x86_64; + YMMReg ymm = XStateToYMM( + m_xstate_x86_64.xs_fxsave.fx_xmm[reg_index].xmm_bytes, + m_xstate_x86_64.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes); + reg_value.SetBytes(ymm.bytes, reg_info->byte_size, + endian::InlHostByteOrder()); + } +#else + error.SetErrorString("XState queries not supported by the kernel"); +#endif + break; case lldb_dr0_x86_64: case lldb_dr1_x86_64: case lldb_dr2_x86_64: @@ -552,6 +606,39 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister( ::memcpy(&m_fpr_x86_64.fxstate.fx_xmm[reg - lldb_xmm0_x86_64], reg_value.GetBytes(), reg_value.GetByteSize()); break; + case lldb_ymm0_x86_64: + case lldb_ymm1_x86_64: + case lldb_ymm2_x86_64: + case lldb_ymm3_x86_64: + case lldb_ymm4_x86_64: + case lldb_ymm5_x86_64: + case lldb_ymm6_x86_64: + case lldb_ymm7_x86_64: + case lldb_ymm8_x86_64: + case lldb_ymm9_x86_64: + case lldb_ymm10_x86_64: + case lldb_ymm11_x86_64: + case lldb_ymm12_x86_64: + case lldb_ymm13_x86_64: + case lldb_ymm14_x86_64: + case lldb_ymm15_x86_64: +#ifdef HAVE_XSTATE + if (!(m_xstate_x86_64.xs_rfbm & XCR0_SSE) || + !(m_xstate_x86_64.xs_rfbm & XCR0_YMM_Hi128)) { + error.SetErrorStringWithFormat("register \"%s\" not supported by CPU/kernel", + reg_info->name); + } else { + uint32_t reg_index = reg - lldb_ymm0_x86_64; + YMMReg ymm; + ::memcpy(ymm.bytes, reg_value.GetBytes(), reg_value.GetByteSize()); + YMMToXState(ymm, + m_xstate_x86_64.xs_fxsave.fx_xmm[reg_index].xmm_bytes, + m_xstate_x86_64.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes); + } +#else + error.SetErrorString("XState not supported by the kernel"); +#endif + break; case lldb_dr0_x86_64: case lldb_dr1_x86_64: case lldb_dr2_x86_64: diff --git a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h index 7bf2833c2e4..0fed16542a9 100644 --- a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h +++ b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h @@ -14,6 +14,7 @@ // clang-format off #include <sys/param.h> #include <sys/types.h> +#include <sys/ptrace.h> #include <machine/reg.h> // clang-format on @@ -21,6 +22,10 @@ #include "Plugins/Process/Utility/RegisterContext_x86.h" #include "Plugins/Process/Utility/lldb-x86-register-enums.h" +#if defined(PT_GETXSTATE) && defined(PT_SETXSTATE) +#define HAVE_XSTATE +#endif + namespace lldb_private { namespace process_netbsd { @@ -68,12 +73,15 @@ public: private: // Private member types. - enum { GPRegSet, FPRegSet, DBRegSet }; + enum { GPRegSet, FPRegSet, DBRegSet, XStateRegSet }; // Private member variables. struct reg m_gpr_x86_64; struct fpreg m_fpr_x86_64; struct dbreg m_dbr_x86_64; +#ifdef HAVE_XSTATE + struct xstate m_xstate_x86_64; +#endif int GetSetForNativeRegNum(int reg_num) const; |

