fix mingw build and crashing bugs for Python Windows ARM64 (#496)
authorPaul Monson <paulmon@users.noreply.github.com>
Wed, 7 Aug 2019 18:57:45 +0000 (11:57 -0700)
committerAnthony Green <green@moxielogic.com>
Wed, 7 Aug 2019 18:57:45 +0000 (14:57 -0400)
* fix mingw build and crashing bugs for Python Windows ARM64

* Fix issues found in PR review

.appveyor.yml
Makefile.am
configure.host
msvc_build/aarch64/aarch64_include/ffi.h
msvcc.sh
src/aarch64/ffi.c
src/aarch64/ffitarget.h
src/aarch64/win64_armasm.S
src/prep_cif.c

index 1c7fe9bb8b509db8057150090f98d5769b479eb0..7a97c2aa5fc9f8cc7a19c63cfcb0a27d577ad84c 100644 (file)
@@ -13,6 +13,7 @@ platform:
   - x64
   - x86
   - arm
+  - arm64
 
 environment:
   global:
@@ -30,6 +31,12 @@ install:
           $env:HOST="i686-pc-cygwin"
           $env:MSVCC="/cygdrive/c/projects/libffi/msvcc.sh"
           $env:SRC_ARCHITECTURE="x86"
+        } ElseIf ($env:Platform -Match "arm64") {
+          $env:VCVARS_PLATFORM="x86_arm64"
+          $env:BUILD="i686-pc-cygwin"
+          $env:HOST="aarch64-w64-cygwin"
+          $env:MSVCC="/cygdrive/c/projects/libffi/msvcc.sh -marm64"
+          $env:SRC_ARCHITECTURE="aarch64"
         } ElseIf ($env:Platform -Match "arm") {
           $env:VCVARS_PLATFORM="x86_arm"
           $env:BUILD="i686-pc-cygwin"
index b74b73bbb1984be39ec32bb8153af460a3c8fd5f..07d928e31f340166c3ce06406b4c78893ac35f14 100644 (file)
@@ -79,6 +79,7 @@ noinst_HEADERS = \
 
 EXTRA_libffi_la_SOURCES = \
        src/aarch64/ffi.c src/aarch64/sysv.S                            \
+       src/aarch64/win64_armasm.S                                              \
        src/alpha/ffi.c src/alpha/osf.S                                 \
        src/arc/ffi.c src/arc/arcompact.S                               \
        src/arm/ffi.c src/arm/sysv.S                                    \
index 8181a61184598a2eba7bcd7901931ee56b8c38ff..6762eba0e0e4c39ed28b62541e70725950a3e7b5 100644 (file)
@@ -6,6 +6,11 @@
 # THIS TABLE IS SORTED.  KEEP IT THAT WAY.
 # Most of the time we can define all the variables all at once...
 case "${host}" in
+  aarch64*-*-cygwin* | aarch64*-*-mingw* | aarch64*-*-win* )
+       TARGET=ARM_WIN64; TARGETDIR=aarch64
+       MSVC=1
+       ;;
+
   aarch64*-*-*)
        TARGET=AARCH64; TARGETDIR=aarch64
        SOURCES="ffi.c sysv.S"
@@ -250,6 +255,9 @@ case "${TARGET}" in
   ARM_WIN32)
        SOURCES="ffi.c sysv_msvc_arm32.S"
        ;;
+  ARM_WIN64)
+       SOURCES="ffi.c win64_armasm.S"
+       ;;
   MIPS)
        SOURCES="ffi.c o32.S n32.S"
        ;;
index 3adb5cb9092683ce41f66d5a322e25476073bb1c..02f26a2f0f84c7fd85f32c761bba6ccaa6a25208 100644 (file)
@@ -197,7 +197,7 @@ FFI_EXTERN ffi_type ffi_type_float;
 FFI_EXTERN ffi_type ffi_type_double;
 FFI_EXTERN ffi_type ffi_type_pointer;
 
-#ifndef _M_ARM64 
+#ifndef _M_ARM64
 FFI_EXTERN ffi_type ffi_type_longdouble;
 #else
 #define ffi_type_longdouble ffi_type_double
@@ -227,7 +227,6 @@ typedef struct {
   ffi_type *rtype;
   unsigned bytes;
   unsigned flags;
-  unsigned isVariadic;
 #ifdef FFI_EXTRA_CIF_FIELDS
   FFI_EXTRA_CIF_FIELDS;
 #endif
index 9c52f527c1ea4adebd88db9f90bcd9917376b896..97facd6985d04488dac112b9f7fb89811d120c4c 100755 (executable)
--- a/msvcc.sh
+++ b/msvcc.sh
@@ -85,6 +85,11 @@ do
       safeseh=
       shift 1
     ;;
+    -marm64)
+      ml='armasm64'
+      safeseh=
+      shift 1
+    ;;
     -clang-cl)
       cl="clang-cl"
       shift 1
@@ -299,6 +304,10 @@ if [ -n "$assembly" ]; then
       defines="$defines -D_M_ARM"
     fi
 
+    if [ $ml = "armasm64" ]; then
+      defines="$defines -D_M_ARM64"
+    fi
+
     if test -n "$verbose"; then
       echo "$cl -nologo -EP $includes $defines $src > $ppsrc"
     fi
@@ -307,6 +316,8 @@ if [ -n "$assembly" ]; then
     output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')"
     if [ $ml = "armasm" ]; then
       args="-nologo -g -oldit $armasm_output $ppsrc -errorReport:prompt"
+    elif [ $ml = "armasm64" ]; then
+      args="-nologo -g $armasm_output $ppsrc -errorReport:prompt"
     else
       args="-nologo $safeseh $single $output $ppsrc"
     fi
index 4225f725eb1b5b1f38fc8d778934804eb812309b..1ebf43c192afe8eadc90fffd600602f30956cef7 100644 (file)
@@ -666,7 +666,7 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
              {
                int elems = 4 - (h & 3);
 #ifdef _M_ARM64 /* for handling armasm calling convention */
-                if (cif->isVariadic)
+                if (cif->is_variadic)
                   {
                     if (state.ngrn + elems <= N_X_ARG_REG)
                       {
@@ -808,7 +808,13 @@ 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
+  // Not using dlmalloc.c for Windows ARM64 builds
+  // so calling ffi_data_to_code_pointer() isn't necessary
+  unsigned char *tramp_code = tramp;
+  #else
   unsigned char *tramp_code = ffi_data_to_code_pointer (tramp);
+  #endif
   ffi_clear_cache (tramp_code, tramp_code + FFI_TRAMPOLINE_SIZE);
 #endif
 
@@ -909,7 +915,7 @@ ffi_closure_SYSV_inner (ffi_cif *cif,
            {
              n = 4 - (h & 3);
 #ifdef _M_ARM64  /* for handling armasm calling convention */
-              if (cif->isVariadic)
+              if (cif->is_variadic)
                 {
                   if (state.ngrn + n <= N_X_ARG_REG)
                     {
@@ -948,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 _M_ARM64  /* for handling armasm calling convention */
                 }
 #endif  /* for handling armasm calling convention */
             }
index 32c4f084c0e84e28b35cea5091182da1cb0d6933..ecb6d2deae0a9caca6f9e1a57aef61f37c9a8ea2 100644 (file)
@@ -69,6 +69,10 @@ typedef enum ffi_abi
 #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
 #endif
 
+#ifdef _M_ARM64
+#define FFI_EXTRA_CIF_FIELDS unsigned is_variadic
+#endif
+
 /* ---- Internal ---- */
 
 #if defined (__APPLE__)
index 906ceffb42439ac8d05528720496844a054cb8dd..8ebc44423e91316406fd8ecd802a71eeb5c7188f 100644 (file)
@@ -57,12 +57,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
    x5 closure\r
 */\r
 \r
-       NESTED_ENTRY ffi_call_SYSV\r
-       /* Use a stack frame allocated by our caller. */\r
-       PROLOG_NOP      stp     x29, x30, [x1, #32]\r
-    /* For unwind information, Windows has to store fp and lr  */\r
+       NESTED_ENTRY ffi_call_SYSV_fake\r
+\r
+       /* For unwind information, Windows has to store fp and lr  */\r
        PROLOG_SAVE_REG_PAIR    x29, x30, #-32!\r
-       \r
+\r
+       ALTERNATE_ENTRY ffi_call_SYSV\r
+       /* Use a stack frame allocated by our caller. */\r
+       stp     x29, x30, [x1]\r
        mov     x29, x1\r
        mov     sp, x0\r
 \r
@@ -97,8 +99,8 @@ ffi_call_SYSV_L1
 \r
        /* Partially deconstruct the stack frame. */\r
        mov     sp, x29 \r
-       ldp     x29, x30, [x29, #32]\r
-       \r
+       ldp     x29, x30, [x29]\r
+\r
        /* Save the return value as directed.  */\r
        adr     x5, ffi_call_SYSV_return\r
        and     w4, w4, #AARCH64_RET_MASK\r
@@ -177,7 +179,7 @@ ffi_call_SYSV_return
        nop\r
        \r
        \r
-       NESTED_END ffi_call_SYSV        \r
+       NESTED_END ffi_call_SYSV_fake\r
        \r
 \r
 /* ffi_closure_SYSV\r
index 406e4b61c0477d354258be3614e4954f2e320cff..06c65440361392007a24aee7d6d437cab2583197 100644 (file)
@@ -129,8 +129,8 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
   cif->rtype = rtype;
 
   cif->flags = 0;
- #ifdef _M_ARM64
-  cif->isVariadic = isvariadic;
+#ifdef _M_ARM64
+  cif->is_variadic = isvariadic;
 #endif
 #if HAVE_LONG_DOUBLE_VARIANT
   ffi_prep_types (abi);