-- v2: configure: Use -mpreferred-stack-boundary=2 on i386.
From: Zebediah Figura zfigura@codeweavers.com
gcc currently assumes the stack alignment for i686-w64-mingw32 is 16, which is essentially wrong. It works around this in most cases by applying -mstackrealign when SSE is in use. However, this doesn't address the case of manually aligned types (i.e. DECLSPEC_ALIGN), and it also for some reason doesn't seem to apply when -mavx512f is in use, which seems to be an independent gcc bug.
The correct solution on the gcc end is not to assume that the stack is 4-byte aligned. -mpreferred-stack-boundary=2 achieves exactly this, and there is motion upstream to address this by effectively making this setting the default. Since this will take time to propagate downstream, though, it seems prudent to address this bug locally by essentially applying the same fix downstream.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55007 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55899 --- configure | 34 ++++++++++++++++++++++++++++++++++ configure.ac | 1 + 2 files changed, 35 insertions(+)
diff --git a/configure b/configure index 2ffbfd8520c..294ab23ba1f 100755 --- a/configure +++ b/configure @@ -11448,6 +11448,40 @@ printf "%s\n" "$ac_res" >&6; } if eval test "x$"$as_ac_var"" = x"yes" then : as_fn_append ${wine_arch}_EXTRACFLAGS " -fno-omit-frame-pointer" +fi } + { as_ac_var=`printf "%s\n" "ac_cv_${wine_arch}_cflags_-mpreferred-stack-boundary=2" | $as_tr_sh` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -mpreferred-stack-boundary=2" >&5 +printf %s "checking whether $CC supports -mpreferred-stack-boundary=2... " >&6; } +if eval test ${$as_ac_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_wine_try_cflags_saved=$CFLAGS +ac_wine_try_cflags_saved_exeext=$ac_exeext +CFLAGS="$CFLAGS -nostdlib -nodefaultlibs -mpreferred-stack-boundary=2" +ac_exeext=".exe" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +void *__os_arm64x_dispatch_ret = 0; +int __cdecl mainCRTStartup(void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + eval "$as_ac_var=yes" +else $as_nop + eval "$as_ac_var=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +CFLAGS=$ac_wine_try_cflags_saved +ac_exeext=$ac_wine_try_cflags_saved_exeext +fi +eval ac_res=$$as_ac_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test "x$"$as_ac_var"" = x"yes" +then : + as_fn_append ${wine_arch}_EXTRACFLAGS " -mpreferred-stack-boundary=2" fi } { as_ac_var=`printf "%s\n" "ac_cv_${wine_arch}_cflags_-Wl,--disable-stdcall-fixup" | $as_tr_sh` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wl,--disable-stdcall-fixup" >&5 diff --git a/configure.ac b/configure.ac index aba623ee6e7..6551f22042c 100644 --- a/configure.ac +++ b/configure.ac @@ -969,6 +969,7 @@ This is an error since --enable-archs=$wine_arch was requested.])])
case $wine_arch in i386) WINE_TRY_PE_CFLAGS([-fno-omit-frame-pointer]) + WINE_TRY_PE_CFLAGS([-mpreferred-stack-boundary=2]) WINE_TRY_PE_CFLAGS([-Wl,--disable-stdcall-fixup], [AS_VAR_APPEND([${wine_arch}_LDFLAGS],[" -Wl,--disable-stdcall-fixup"])]) ;; x86_64) WINE_TRY_PE_CFLAGS([-Wformat-overflow])
I see now that my original patch comment was also rather misleading, implying that we were working around bugs that should be fixed a proper way, which isn't really the case. I've reworded the commit message to explain better now.