[PATCH] arm64: Use __builtin_ms_va_list and __attribute__((ms_abi)) on arm64

Martin Storsjo martin at martin.st
Mon Aug 14 05:35:25 CDT 2017


Windows uses a different ABI for va_list on arm64 just like on x86_64.

On x86_64, the calling convention for windows functions is completely
different from the one on other platforms. On arm64, they're mostly the
same, with the only exception being variadic functions (where all float
arguments are passed in integer registers, since the va_list is a single
pointer).

Any functions using __builtin_ms_va_start need to be decorated with
__attribute__((ms_abi)).

Add a check in configure for the support of __builtin_ms_va_list
(both features appared in clang at the same time, in the 5.0 release).

This fixes running binaries that use e.g. printf style functions
(e.g. midl.exe from the windows 10 sdk), fixing
https://bugs.winehq.org/show_bug.cgi?id=38886.

Signed-off-by: Martin Storsjo <martin at martin.st>
---
clang 5.0, which this requires, isn't yet released, but is in RC2 and
will probably be released pretty soon.
---
 configure.ac             | 7 +++++++
 include/msvcrt/crtdefs.h | 6 +++++-
 include/windef.h         | 6 +++++-
 include/wine/test.h      | 4 ++--
 4 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/configure.ac b/configure.ac
index 7d52b24..c33221f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -179,6 +179,13 @@ case $host in
     CFLAGS="$CFLAGS -marm"
     AC_SUBST(TARGETFLAGS,"-marm")
     ;;
+  aarch64*)
+    AC_MSG_CHECKING([whether $CC supports __builtin_ms_va_list])
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdarg.h>]], [[void func(__builtin_ms_va_list *args);]])],
+                      [AC_MSG_RESULT([yes])],
+                      [AC_MSG_RESULT([no])
+                       AC_MSG_ERROR([You need clang >= 5.0 to build Wine for arm64.])])
+    ;;
   i[[3456789]]86*)
     enable_win16=${enable_win16:-yes}
     ;;
diff --git a/include/msvcrt/crtdefs.h b/include/msvcrt/crtdefs.h
index 8aed64c..6ae8c8c 100644
--- a/include/msvcrt/crtdefs.h
+++ b/include/msvcrt/crtdefs.h
@@ -60,6 +60,8 @@
 #  else
 #   define __stdcall __attribute__((ms_abi))
 #  endif
+# elif defined(__aarch64__) && defined (__GNUC__)
+#  define __stdcall __attribute__((ms_abi))
 # else  /* __i386__ */
 #  define __stdcall
 # endif  /* __i386__ */
@@ -78,13 +80,15 @@
 #  else
 #   define __cdecl __attribute__((ms_abi))
 #  endif
+# elif defined(__aarch64__) && defined (__GNUC__)
+#  define __cdecl __attribute__((ms_abi))
 # elif !defined(_MSC_VER)
 #  define __cdecl
 # endif
 #endif /* __cdecl */
 
 #ifndef __ms_va_list
-# if defined(__x86_64__) && defined (__GNUC__)
+# if (defined(__x86_64__) || defined(__aarch64__)) && defined (__GNUC__)
 #  define __ms_va_list __builtin_ms_va_list
 #  define __ms_va_start(list,arg) __builtin_ms_va_start(list,arg)
 #  define __ms_va_end(list) __builtin_ms_va_end(list)
diff --git a/include/windef.h b/include/windef.h
index e77b1ca..49572d5 100644
--- a/include/windef.h
+++ b/include/windef.h
@@ -69,6 +69,8 @@ extern "C" {
 #  else
 #   define __stdcall __attribute__((ms_abi))
 #  endif
+# elif defined(__aarch64__) && defined (__GNUC__)
+#  define __stdcall __attribute__((ms_abi))
 # else  /* __i386__ */
 #  define __stdcall
 # endif  /* __i386__ */
@@ -87,13 +89,15 @@ extern "C" {
 #  else
 #   define __cdecl __attribute__((ms_abi))
 #  endif
+# elif defined(__aarch64__) && defined (__GNUC__)
+#  define __cdecl __attribute__((ms_abi))
 # elif !defined(_MSC_VER)
 #  define __cdecl
 # endif
 #endif /* __cdecl */
 
 #ifndef __ms_va_list
-# if defined(__x86_64__) && defined (__GNUC__)
+# if (defined(__x86_64__) || defined(__aarch64__)) && defined (__GNUC__)
 #  define __ms_va_list __builtin_ms_va_list
 #  define __ms_va_start(list,arg) __builtin_ms_va_start(list,arg)
 #  define __ms_va_end(list) __builtin_ms_va_end(list)
diff --git a/include/wine/test.h b/include/wine/test.h
index 4ec66d5..3caff6c 100644
--- a/include/wine/test.h
+++ b/include/wine/test.h
@@ -87,7 +87,7 @@ static inline int winetest_strcmpW( const WCHAR *str1, const WCHAR *str2 )
 #define START_TEST(name) void func_##name(void)
 #endif
 
-#if defined(__x86_64__) && defined(__GNUC__) && defined(__WINE_USE_MSVCRT)
+#if (defined(__x86_64__) || defined(__aarch64__)) && defined(__GNUC__) && defined(__WINE_USE_MSVCRT)
 #define __winetest_cdecl __cdecl
 #define __winetest_va_list __builtin_ms_va_list
 #else
@@ -178,7 +178,7 @@ extern void __winetest_cdecl winetest_trace( const char *msg, ... ) WINETEST_PRI
 #include <stdio.h>
 #include <excpt.h>
 
-#if defined(__x86_64__) && defined(__GNUC__) && defined(__WINE_USE_MSVCRT)
+#if (defined(__x86_64__) || defined(__aarch64__)) && defined(__GNUC__) && defined(__WINE_USE_MSVCRT)
 # define __winetest_va_start(list,arg) __builtin_ms_va_start(list,arg)
 # define __winetest_va_end(list) __builtin_ms_va_end(list)
 #else
-- 
2.7.4




More information about the wine-patches mailing list