blob: 4aa562a8bf3f3b57af1e37b0838bfc434f563afe [file] [log] [blame] [edit]
From 955a5b73059d27eba7db0783bb4769934d8c8a82 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st>
Date: Sun, 26 Apr 2020 04:58:33 +0300
Subject: [PATCH] Fix building for aarch64 windows with mingw toolchains (#555)
* aarch64: Check _WIN32 instead of _M_ARM64 for detecting windows
This fixes building for aarch64 with mingw toolchains. _M_ARM64 is
predefined by MSVC, while mingw compilers predefine __aarch64__.
In aarch64 specific code, change checks for _M_ARM64 into checks for
_WIN32.
In arch independent code, check for
(defined(_M_ARM64) || defined(__aarch64__)) && defined(_WIN32)
instead of just _M_ARM64.
In src/closures.c, coalesce checks like
defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64)
into plain defined(_WIN32). Technically, this enables code for
ARM32 windows where it wasn't, but as far as I can see it, those
codepaths should be fine for that architecture variant as well.
* aarch64: Only use armasm source when building with MSVC
When building for windows/arm64 with clang, the normal gas style .S
source works fine. sysv.S and win64_armasm.S seem to be functionally
equivalent, with only differences being due to assembler syntax.
---
configure.host | 10 ++++++++--
src/aarch64/ffi.c | 14 +++++++-------
src/aarch64/ffitarget.h | 8 ++++----
src/closures.c | 12 ++++++------
src/prep_cif.c | 2 +-
5 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/configure.host b/configure.host
index 9a72cda..947e73b 100644
--- a/configure.host
+++ b/configure.host
@@ -8,7 +8,9 @@
case "${host}" in
aarch64*-*-cygwin* | aarch64*-*-mingw* | aarch64*-*-win* )
TARGET=ARM_WIN64; TARGETDIR=aarch64
- MSVC=1
+ if test "${ax_cv_c_compiler_vendor}" = "microsoft"; then
+ MSVC=1
+ fi
;;
aarch64*-*-*)
@@ -256,7 +258,11 @@ case "${TARGET}" in
SOURCES="ffi.c sysv_msvc_arm32.S"
;;
ARM_WIN64)
- SOURCES="ffi.c win64_armasm.S"
+ if test "$MSVC" = 1; then
+ SOURCES="ffi.c win64_armasm.S"
+ else
+ SOURCES="ffi.c sysv.S"
+ fi
;;
MIPS)
SOURCES="ffi.c o32.S n32.S"
diff --git a/src/aarch64/ffi.c b/src/aarch64/ffi.c
index 1ebf43c..2906c20 100644
--- a/src/aarch64/ffi.c
+++ b/src/aarch64/ffi.c
@@ -27,7 +27,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include <ffi.h>
#include <ffi_common.h>
#include "internal.h"
-#ifdef _M_ARM64
+#ifdef _WIN32
#include <windows.h> /* FlushInstructionCache */
#endif
@@ -78,7 +78,7 @@ ffi_clear_cache (void *start, void *end)
sys_icache_invalidate (start, (char *)end - (char *)start);
#elif defined (__GNUC__)
__builtin___clear_cache (start, end);
-#elif defined (_M_ARM64)
+#elif defined (_WIN32)
FlushInstructionCache(GetCurrentProcess(), start, (char*)end - (char*)start);
#else
#error "Missing builtin to flush instruction cache"
@@ -665,7 +665,7 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
if (h)
{
int elems = 4 - (h & 3);
-#ifdef _M_ARM64 /* for handling armasm calling convention */
+#ifdef _WIN32 /* for handling armasm calling convention */
if (cif->is_variadic)
{
if (state.ngrn + elems <= N_X_ARG_REG)
@@ -690,7 +690,7 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
}
state.nsrn = N_V_ARG_REG;
dest = allocate_to_stack (&state, stack, ty->alignment, s);
-#ifdef _M_ARM64 /* for handling armasm calling convention */
+#ifdef _WIN32 /* for handling armasm calling convention */
}
#endif /* for handling armasm calling convention */
}
@@ -808,7 +808,7 @@ ffi_prep_closure_loc (ffi_closure *closure,
ffi_clear_cache(tramp, tramp + FFI_TRAMPOLINE_SIZE);
/* Also flush the cache for code mapping. */
-#ifdef _M_ARM64
+#ifdef _WIN32
// Not using dlmalloc.c for Windows ARM64 builds
// so calling ffi_data_to_code_pointer() isn't necessary
unsigned char *tramp_code = tramp;
@@ -914,7 +914,7 @@ ffi_closure_SYSV_inner (ffi_cif *cif,
if (h)
{
n = 4 - (h & 3);
-#ifdef _M_ARM64 /* for handling armasm calling convention */
+#ifdef _WIN32 /* for handling armasm calling convention */
if (cif->is_variadic)
{
if (state.ngrn + n <= N_X_ARG_REG)
@@ -954,7 +954,7 @@ ffi_closure_SYSV_inner (ffi_cif *cif,
avalue[i] = allocate_to_stack(&state, stack,
ty->alignment, s);
}
-#ifdef _M_ARM64 /* for handling armasm calling convention */
+#ifdef _WIN32 /* for handling armasm calling convention */
}
#endif /* for handling armasm calling convention */
}
diff --git a/src/aarch64/ffitarget.h b/src/aarch64/ffitarget.h
index ecb6d2d..7a8cabe 100644
--- a/src/aarch64/ffitarget.h
+++ b/src/aarch64/ffitarget.h
@@ -32,7 +32,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#define FFI_SIZEOF_JAVA_RAW 4
typedef unsigned long long ffi_arg;
typedef signed long long ffi_sarg;
-#elif defined(_M_ARM64)
+#elif defined(_WIN32)
#define FFI_SIZEOF_ARG 8
typedef unsigned long long ffi_arg;
typedef signed long long ffi_sarg;
@@ -69,7 +69,7 @@ typedef enum ffi_abi
#define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
#endif
-#ifdef _M_ARM64
+#ifdef _WIN32
#define FFI_EXTRA_CIF_FIELDS unsigned is_variadic
#endif
@@ -78,13 +78,13 @@ typedef enum ffi_abi
#if defined (__APPLE__)
#define FFI_TARGET_SPECIFIC_VARIADIC
#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
-#elif !defined(_M_ARM64)
+#elif !defined(_WIN32)
/* iOS and Windows reserve x18 for the system. Disable Go closures until
a new static chain is chosen. */
#define FFI_GO_CLOSURES 1
#endif
-#ifndef _M_ARM64
+#ifndef _WIN32
/* No complex type on Windows */
#define FFI_TARGET_HAS_COMPLEX_TYPE
#endif
diff --git a/src/closures.c b/src/closures.c
index 5120021..12f8268 100644
--- a/src/closures.c
+++ b/src/closures.c
@@ -123,7 +123,7 @@ ffi_closure_free (void *ptr)
# define FFI_MMAP_EXEC_WRIT 1
# define HAVE_MNTENT 1
# endif
-# if defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)
+# if defined(_WIN32) || defined(__OS2__)
/* Windows systems may have Data Execution Protection (DEP) enabled,
which requires the use of VirtualMalloc/VirtualFree to alloc/free
executable memory. */
@@ -386,7 +386,7 @@ ffi_closure_free (void *ptr)
#endif
#include <string.h>
#include <stdio.h>
-#if !defined(X86_WIN32) && !defined(X86_WIN64) && !defined(_M_ARM64)
+#if !defined(_WIN32)
#ifdef HAVE_MNTENT
#include <mntent.h>
#endif /* HAVE_MNTENT */
@@ -512,11 +512,11 @@ static int dlmalloc_trim(size_t) MAYBE_UNUSED;
static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
static void dlmalloc_stats(void) MAYBE_UNUSED;
-#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
+#if !(defined(_WIN32) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
/* Use these for mmap and munmap within dlmalloc.c. */
static void *dlmmap(void *, size_t, int, int, int, off_t);
static int dlmunmap(void *, size_t);
-#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
+#endif /* !(defined(_WIN32) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
#define mmap dlmmap
#define munmap dlmunmap
@@ -526,7 +526,7 @@ static int dlmunmap(void *, size_t);
#undef mmap
#undef munmap
-#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
+#if !(defined(_WIN32) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
/* A mutex used to synchronize access to *exec* variables in this file. */
static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -908,7 +908,7 @@ segment_holding_code (mstate m, char* addr)
}
#endif
-#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
+#endif /* !(defined(_WIN32) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
/* Allocate a chunk of memory with the given size. Returns a pointer
to the writable address, and sets *CODE to the executable
diff --git a/src/prep_cif.c b/src/prep_cif.c
index 06c6544..1db3804 100644
--- a/src/prep_cif.c
+++ b/src/prep_cif.c
@@ -129,7 +129,7 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
cif->rtype = rtype;
cif->flags = 0;
-#ifdef _M_ARM64
+#if (defined(_M_ARM64) || defined(__aarch64__)) && defined(_WIN32)
cif->is_variadic = isvariadic;
#endif
#if HAVE_LONG_DOUBLE_VARIANT
--
2.30.0.windows.2