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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
diff --git a/configure.host b/configure.host
index 055e955..7c951a0 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*-*-*)
@@ -259,7 +261,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 4cc5925..508a624 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
@@ -81,7 +81,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"
@@ -668,7 +668,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)
@@ -693,7 +693,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 */
}
@@ -814,7 +814,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;
@@ -920,7 +920,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)
@@ -960,7 +960,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 b5eb2bb..4fe6158 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. */
@@ -392,7 +392,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 */
@@ -518,11 +518,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
@@ -532,7 +532,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;
@@ -914,7 +914,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