Add support for Floating Point registers in ucontext_t on NetBSD
authorKamil Rytarowski <n54@gmx.com>
Tue, 9 Feb 2016 04:33:02 +0000 (05:33 +0100)
committerKamil Rytarowski <n54@gmx.com>
Tue, 9 Feb 2016 04:37:46 +0000 (05:37 +0100)
This code assumes x86_64 platform and modern fxsave style of FP regs.

i386 Floating Point registers ship with different flavors, what will be
handled once the 64-bit code will be finished.

src/pal/src/include/pal/context.h
src/pal/src/thread/context.cpp

index 7a20f8b..7591703 100644 (file)
@@ -68,6 +68,20 @@ typedef ucontext_t native_context_t;
 #define MCREG_R15(mc)       ((mc).__gregs[_REG_R15])
 #define MCREG_EFlags(mc)    ((mc).__gregs[_REG_RFLAGS])
 
+#define FPREG_Xmm(uc, index) *(M128A*)&(((struct fxsave*)(&(uc)->uc_mcontext.__fpregs))->fx_xmm[index])
+
+#define FPREG_St(uc, index) *(M128A*)&(((struct fxsave*)(&(uc)->uc_mcontext.__fpregs))->fx_87_ac[index])
+
+#define FPREG_ControlWord(uc) (((struct fxsave*)(&(uc)->uc_mcontext.__fpregs))->fx_cw)
+#define FPREG_StatusWord(uc) (((struct fxsave*)(&(uc)->uc_mcontext.__fpregs))->fx_sw)
+#define FPREG_TagWord(uc) (((struct fxsave*)(&(uc)->uc_mcontext.__fpregs))->fx_tw)
+#define FPREG_ErrorOffset(uc) (*(DWORD*) &(((struct fxsave*)(&(uc)->uc_mcontext.__fpregs))->fx_ip))
+#define FPREG_ErrorSelector(uc) *((WORD*) &(((struct fxsave*)(&(uc)->uc_mcontext.__fpregs))->fx_ip) + 2)
+#define FPREG_DataOffset(uc) (*(DWORD*) &(((struct fxsave*)(&(uc)->uc_mcontext.__fpregs))->fx_dp))
+#define FPREG_DataSelector(uc) *((WORD*) &(((struct fxsave*)(&(uc)->uc_mcontext.__fpregs))->fx_dp) + 2)
+#define FPREG_MxCsr(uc) (((struct fxsave*)(&(uc)->uc_mcontext.__fpregs))->fx_mxcsr)
+#define FPREG_MxCsr_Mask(uc) (((struct fxsave*)(&(uc)->uc_mcontext.__fpregs))->fx_mxcsr_mask)
+
 #else // BIT64
 
 #define MCREG_Ebx(mc)       ((mc).__gregs[_REG_EBX])
index 166c242..ed2790a 100644 (file)
@@ -423,8 +423,12 @@ void CONTEXTToNativeContext(CONST CONTEXT *lpContext, native_context_t *native)
     }
 #undef ASSIGN_REG
 
+#if HAVE_GREGSET_T || HAVE_GREGSET_T
 #if HAVE_GREGSET_T
     if (native->uc_mcontext.fpregs == nullptr)
+#elif HAVE___GREGSET_T
+    if (native->uc_mcontext.__fpregs == nullptr)
+#endif
     {
         // If the pointer to the floating point state in the native context
         // is not valid, we can't copy floating point registers regardless of
@@ -492,8 +496,12 @@ void CONTEXTFromNativeContext(const native_context_t *native, LPCONTEXT lpContex
     }
 #undef ASSIGN_REG
 
+#if HAVE_GREGSET_T || HAVE___GREGSET_T
 #if HAVE_GREGSET_T
     if (native->uc_mcontext.fpregs == nullptr)
+#elif HAVE___GREGSET_T
+    if (native->uc_mcontext.__fpregs == nullptr)
+#endif
     {
         // Reset the CONTEXT_FLOATING_POINT bit(s) so it's clear that the floating point
         // data in the CONTEXT is not valid. Since CONTEXT_FLOATING_POINT is defined as