mgorny updated this revision to Diff 205763.
mgorny added a comment.

Rebased for changes in 
`NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum()`, and removed the 
conditions there.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63545/new/

https://reviews.llvm.org/D63545

Files:
  lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
  lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
  lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
  lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h

Index: lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
===================================================================
--- lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
+++ 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 {
 
@@ -70,20 +75,31 @@
   void *GetGPRBuffer() override { return &m_gpr_x86_64; }
   void *GetFPRBuffer() override { return &m_fpr_x86_64; }
   void *GetDBRBuffer() override { return &m_dbr_x86_64; }
+#ifdef HAVE_XSTATE
+  void *GetXStateBuffer() override { return &m_xstate_x86_64; }
+  size_t GetXStateSize() override { return sizeof(m_xstate_x86_64); }
+#endif
 
 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;
 
   Status ReadRegisterSet(uint32_t set);
   Status WriteRegisterSet(uint32_t set);
+
+  YMMReg CopyXSTATEtoYMM(uint32_t reg_index, lldb::ByteOrder byte_order);
+  void CopyYMMtoXSTATE(uint32_t reg_index, lldb::ByteOrder byte_order,
+                       YMMReg reg);
 };
 
 } // namespace process_netbsd
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
@@ -22,6 +22,8 @@
 #include <sys/types.h>
 #include <sys/sysctl.h>
 #include <x86/cpu.h>
+#include <x86/cpu_extended_state.h>
+#include <x86/specialreg.h>
 #include <elf.h>
 #include <err.h>
 #include <stdint.h>
@@ -147,7 +149,7 @@
   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)
@@ -166,6 +168,10 @@
     return ReadFPR();
   case DBRegSet:
     return ReadDBR();
+  case XStateRegSet:
+    return ReadXState();
+  default:
+    break;
   }
   llvm_unreachable("NativeRegisterContextNetBSD_x86_64::ReadRegisterSet");
 }
@@ -178,10 +184,74 @@
     return WriteFPR();
   case DBRegSet:
     return WriteDBR();
+  case XStateRegSet:
+    return WriteXState();
+  default:
+    break;
   }
   llvm_unreachable("NativeRegisterContextNetBSD_x86_64::WriteRegisterSet");
 }
 
+YMMReg NativeRegisterContextNetBSD_x86_64::CopyXSTATEtoYMM(
+    uint32_t reg_index, lldb::ByteOrder byte_order) {
+#ifdef HAVE_XSTATE
+  YMMReg ret;
+
+  if (byte_order == lldb::eByteOrderLittle) {
+    ::memcpy(ret.bytes,
+             m_xstate_x86_64.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
+             sizeof(XMMReg));
+    ::memcpy(ret.bytes + sizeof(XMMReg),
+             m_xstate_x86_64.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes,
+             sizeof(YMMHReg));
+    return ret;
+  }
+
+  if (byte_order == lldb::eByteOrderBig) {
+    ::memcpy(ret.bytes + sizeof(XMMReg),
+             m_xstate_x86_64.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
+             sizeof(XMMReg));
+    ::memcpy(ret.bytes,
+             m_xstate_x86_64.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes,
+             sizeof(YMMHReg));
+    return ret;
+  }
+
+  llvm_unreachable("invalid byte order");
+#else
+  llvm_unreachable("CopyXSTATEtoYMM() called without XState support");
+#endif
+}
+
+void NativeRegisterContextNetBSD_x86_64::CopyYMMtoXSTATE(
+    uint32_t reg_index, lldb::ByteOrder byte_order, YMMReg reg) {
+#ifdef HAVE_XSTATE
+  if (byte_order == lldb::eByteOrderLittle) {
+    ::memcpy(m_xstate_x86_64.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
+             reg.bytes,
+             sizeof(XMMReg));
+    ::memcpy(m_xstate_x86_64.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes,
+             reg.bytes + sizeof(XMMReg),
+             sizeof(YMMHReg));
+    return;
+  }
+
+  if (byte_order == lldb::eByteOrderBig) {
+    ::memcpy(m_xstate_x86_64.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
+             reg.bytes + sizeof(XMMReg),
+             sizeof(XMMReg));
+    ::memcpy(m_xstate_x86_64.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes,
+             reg.bytes,
+             sizeof(YMMHReg));
+    return;
+  }
+
+  llvm_unreachable("invalid byte order");
+#else
+  llvm_unreachable("CopyYMMtoXSTATE() called without XState support");
+#endif
+}
+
 Status
 NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
                                                  RegisterValue &reg_value) {
@@ -359,6 +429,37 @@
     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 {
+      YMMReg ymm = CopyXSTATEtoYMM(reg - lldb_ymm0_x86_64,
+                                   endian::InlHostByteOrder());
+      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:
@@ -551,6 +652,36 @@
     ::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 {
+      YMMReg ymm;
+      ::memcpy(ymm.bytes, reg_value.GetBytes(), reg_value.GetByteSize());
+      CopyYMMtoXSTATE(reg - lldb_ymm0_x86_64, endian::InlHostByteOrder(), ymm);
+    }
+#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:
Index: lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
===================================================================
--- lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
+++ lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
@@ -41,6 +41,9 @@
   virtual Status ReadDBR();
   virtual Status WriteDBR();
 
+  virtual Status ReadXState();
+  virtual Status WriteXState();
+
   virtual void *GetGPRBuffer() { return nullptr; }
   virtual size_t GetGPRSize() {
     return GetRegisterInfoInterface().GetGPRSize();
@@ -52,6 +55,9 @@
   virtual void *GetDBRBuffer() { return nullptr; }
   virtual size_t GetDBRSize() { return 0; }
 
+  virtual void *GetXStateBuffer() { return nullptr; }
+  virtual size_t GetXStateSize() { return 0; }
+
   virtual Status DoReadGPR(void *buf);
   virtual Status DoWriteGPR(void *buf);
 
@@ -61,6 +67,9 @@
   virtual Status DoReadDBR(void *buf);
   virtual Status DoWriteDBR(void *buf);
 
+  virtual Status DoReadXState(void *buf, size_t buflen);
+  virtual Status DoWriteXState(void *buf, size_t buflen);
+
   virtual NativeProcessNetBSD &GetProcess();
   virtual ::pid_t GetProcessPid();
 };
Index: lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
===================================================================
--- lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
+++ lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
@@ -16,6 +16,7 @@
 // clang-format off
 #include <sys/types.h>
 #include <sys/ptrace.h>
+#include <sys/uio.h>
 // clang-format on
 
 NativeRegisterContextNetBSD::NativeRegisterContextNetBSD(
@@ -72,6 +73,28 @@
   return DoWriteDBR(buf);
 }
 
+Status NativeRegisterContextNetBSD::ReadXState() {
+  void *buf = GetXStateBuffer();
+  size_t buflen = GetXStateSize();
+  if (!buf)
+    return Status("XState buffer is NULL");
+  if (buflen == 0)
+    return Status("XState length is zero");
+
+  return DoReadXState(buf, buflen);
+}
+
+Status NativeRegisterContextNetBSD::WriteXState() {
+  void *buf = GetXStateBuffer();
+  size_t buflen = GetXStateSize();
+  if (!buf)
+    return Status("XState buffer is NULL");
+  if (buflen == 0)
+    return Status("XState length is zero");
+
+  return DoWriteXState(buf, buflen);
+}
+
 Status NativeRegisterContextNetBSD::DoReadGPR(void *buf) {
   return NativeProcessNetBSD::PtraceWrapper(PT_GETREGS, GetProcessPid(), buf,
                                             m_thread.GetID());
@@ -102,6 +125,26 @@
                                             m_thread.GetID());
 }
 
+Status NativeRegisterContextNetBSD::DoReadXState(void *buf, size_t buflen) {
+#ifdef PT_GETXSTATE
+  struct iovec iov = {buf, buflen};
+  return NativeProcessNetBSD::PtraceWrapper(PT_GETXSTATE, GetProcessPid(), &iov,
+                                            m_thread.GetID());
+#else
+  return Status("PT_GETXSTATE not supported by the kernel");
+#endif
+}
+
+Status NativeRegisterContextNetBSD::DoWriteXState(void *buf, size_t buflen) {
+#ifdef PT_SETXSTATE
+  struct iovec iov = {buf, buflen};
+  return NativeProcessNetBSD::PtraceWrapper(PT_SETXSTATE, GetProcessPid(), &iov,
+                                            m_thread.GetID());
+#else
+  return Status("PT_SETXSTATE not supported by the kernel");
+#endif
+}
+
 NativeProcessNetBSD &NativeRegisterContextNetBSD::GetProcess() {
   return static_cast<NativeProcessNetBSD &>(m_thread.GetProcess());
 }
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to