x86: Fix MSVC runtime checks interop (#612)
authorOle André Vadla Ravnås <oleavr@gmail.com>
Wed, 24 Mar 2021 11:04:51 +0000 (12:04 +0100)
committerGitHub <noreply@github.com>
Wed, 24 Mar 2021 11:04:51 +0000 (07:04 -0400)
MSVC can add runtime code that checks if a stack frame is mismanaged,
however our custom assembly deliberately accesses and modifies the parent
stack frame.  Fortunately we can disable that specific check for the
function call so do that.

Co-authored-by: Matthew Waters <matthew@centricular.com>
src/x86/ffi.c
src/x86/ffiw64.c

index b4d0d3908cb26d77d38e7540ef99a65b21b10c16..26dbc05912d8de35d44d63d00521628f85808886 100644 (file)
@@ -256,6 +256,13 @@ static const struct abi_params abi_params[FFI_LAST_ABI] = {
 
 extern void FFI_DECLARE_FASTCALL ffi_call_i386(struct call_frame *, char *) FFI_HIDDEN;
 
+/* We perform some black magic here to use some of the parent's stack frame in
+ * ffi_call_i386() that breaks with the MSVC compiler with the /RTCs or /GZ
+ * flags.  Disable the 'Stack frame run time error checking' for this function
+ * so we don't hit weird exceptions in debug builds. */
+#if defined(_MSC_VER)
+#pragma runtime_checks("s", off)
+#endif
 static void
 ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
              void **avalue, void *closure)
@@ -391,6 +398,9 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
 
   ffi_call_i386 (frame, stack);
 }
+#if defined(_MSC_VER)
+#pragma runtime_checks("s", restore)
+#endif
 
 void
 ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
index 6c28d59b10a1ec7932084bb856f6068fd46cfd20..6870d07c92b787c26544ff5e69c8bd4febe3e71c 100644 (file)
@@ -108,6 +108,13 @@ EFI64(ffi_prep_cif_machdep)(ffi_cif *cif)
   return FFI_OK;
 }
 
+/* We perform some black magic here to use some of the parent's stack frame in
+ * ffi_call_win64() that breaks with the MSVC compiler with the /RTCs or /GZ
+ * flags.  Disable the 'Stack frame run time error checking' for this function
+ * so we don't hit weird exceptions in debug builds. */
+#if defined(_MSC_VER)
+#pragma runtime_checks("s", off)
+#endif
 static void
 ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
              void **avalue, void *closure)
@@ -172,6 +179,9 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
 
   ffi_call_win64 (stack, frame, closure);
 }
+#if defined(_MSC_VER)
+#pragma runtime_checks("s", restore)
+#endif
 
 void
 EFI64(ffi_call)(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)