Fix alignment issue when converting to/from native context.
authorAditya Mandaleeka <adityam@microsoft.com>
Mon, 20 Jul 2015 00:24:17 +0000 (17:24 -0700)
committerAditya Mandaleeka <adityam@microsoft.com>
Tue, 21 Jul 2015 00:01:53 +0000 (17:01 -0700)
When building in release mode, the code in CONTEXTFromNativeContext and
CONTEXTToNativeContext was using the movaps instruction to move the float
and XMM register values to/from the native context. This is because the
macros FPREG_St and FPREG_Xmm were casting unaligned pointers to an
aligned struct type (M128A). This change adds a type M128U which is the
same as M128A but without the alignment guarantee. Using this type in
those macros prevents the compiler from trying to use movaps on
potentially unaligned memory. This bug manifested when trying to call
these functions with native contexts that were passed into a real-time
signal handler.

src/pal/inc/pal.h
src/pal/src/arch/i386/context.cpp
src/pal/src/include/pal/context.h

index 2148b11..547fab1 100644 (file)
@@ -2710,10 +2710,13 @@ typedef struct _CONTEXT {
 #define CONTEXT_EXCEPTION_REQUEST 0x40000000
 #define CONTEXT_EXCEPTION_REPORTING 0x80000000
 
-typedef struct DECLSPEC_ALIGN(16) _M128A {
+typedef struct _M128U {
     ULONGLONG Low;
     LONGLONG High;
-} M128A, *PM128A;
+} M128U, *PM128U;
+
+// Same as _M128U but aligned to a 16-byte boundary
+typedef DECLSPEC_ALIGN(16) M128U M128A, *PM128A;
 
 typedef struct _XMM_SAVE_AREA32 {
     WORD   ControlWord;
index d749f87..14a96bb 100644 (file)
@@ -402,13 +402,13 @@ void CONTEXTToNativeContext(CONST CONTEXT *lpContext, native_context_t *native)
 
         for (int i = 0; i < 8; i++)
         {
-            FPREG_St(native, i) = lpContext->FltSave.FloatRegisters[i];
+            FPREG_St(native, i) = ((M128U*)lpContext->FltSave.FloatRegisters)[i];
         }
 
         for (int i = 0; i < 16; i++)
         {
-            FPREG_Xmm(native, i) = lpContext->FltSave.XmmRegisters[i];
-        }        
+            FPREG_Xmm(native, i) = ((M128U*)lpContext->FltSave.XmmRegisters)[i];
+        }
     }
 }
 
@@ -459,13 +459,13 @@ void CONTEXTFromNativeContext(const native_context_t *native, LPCONTEXT lpContex
 
         for (int i = 0; i < 8; i++)
         {
-            lpContext->FltSave.FloatRegisters[i] = FPREG_St(native, i);
+            ((M128U*)lpContext->FltSave.FloatRegisters)[i] = FPREG_St(native, i);
         }
 
         for (int i = 0; i < 16; i++)
         {
-            lpContext->FltSave.XmmRegisters[i] = FPREG_Xmm(native, i);
-        }        
+            ((M128U*)lpContext->FltSave.XmmRegisters)[i] = FPREG_Xmm(native, i);
+        }
     }
 }
 
index 9963ed5..0a801f3 100644 (file)
@@ -67,9 +67,9 @@ typedef ucontext_t native_context_t;
 #define MCREG_R14(mc)       ((mc).gregs[REG_R14])
 #define MCREG_R15(mc)       ((mc).gregs[REG_R15])
 
-#define FPREG_Xmm(uc, index) *(M128A*)&((uc)->__fpregs_mem._xmm[index])
+#define FPREG_Xmm(uc, index) *(M128U*)&((uc)->__fpregs_mem._xmm[index])
 
-#define FPREG_St(uc, index) *(M128A*)&((uc)->__fpregs_mem._st[index])
+#define FPREG_St(uc, index) *(M128U*)&((uc)->__fpregs_mem._st[index])
 
 #define FPREG_ControlWord(uc) ((uc)->__fpregs_mem.cwd)
 #define FPREG_StatusWord(uc) ((uc)->__fpregs_mem.swd)