Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Fixes bug 1296 - SDL_SetVideoMode crashes because of unaligned MOVAPS…

… instruction

t.grundner@goto3d.de 2011-09-01 03:59:17 PDT
I figured out what is going on. GCC 4.5.2 assumes the stack is 16 byte aligned
by default. Therefore there are no AND alignment corrections necessary if we
wish to align a stack variable to a 16 byte boundary. That is bad if your OS
ABI is not 16 byte aligned. Windows 32 bit stacks are 4 byte aligned. This
results in the above mentioned SIGSEGV. This is also no problem if I compile
both SDL.dll and my app with MingW because MinGW/GCC inserts a

        andl    $-16, %esp

instruction right in the beginning of the main function. So at least the stack
of the thread calling the main function is 16 byte aligned. But as soon as I
start to use the SDL.dll from an application not compiled by MinGW there is no
ANDL safing my app.

However there is a GCC option that can change the default stack alignment:

        -mpreferred-stack-boundary=num

Setting num=2 assumes a the stack is aligned to a 4 byte boundary. This results
in GCC inserting the necessary

        andl    $-16, %esp

into SDL_FillRect. Rebuilding SDL with

       ./configure "CFLAGS=-mpreferred-stack-boundary=2 -g -O3"

solved the problem.

IMHO this should also be a problem on Solaris.

The following links contain further information:

http://gcc.gnu.org/onlinedocs/gcc-4.5.2/gcc/i386-and-x86_002d64-Options.html#i386-and-x86_002d64-Options

http://www.agner.org/optimize/calling_conventions.pdf
  • Loading branch information
slouken committed Dec 29, 2011
1 parent 795b43e commit 3dcb512b99f3d02f048cfdbf0568751f4a9144cb
Showing with 363 additions and 18 deletions.
  1. +67 −0 configure
  2. +27 −0 configure.in
  3. +269 −18 include/SDL_config.h
fi
}

CheckStackBoundary()
{
{ echo "$as_me:$LINENO: checking for GCC -mpreferred-stack-boundary option" >&5
echo $ECHO_N "checking for GCC -mpreferred-stack-boundary option... $ECHO_C" >&6; }
have_gcc_preferred_stack_boundary=no

save_CFLAGS="$CFLAGS"
CFLAGS="$save_CFLAGS -mpreferred-stack-boundary=2"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */

int x = 0;

int
main ()
{


;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then

have_gcc_preferred_stack_boundary=yes

else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5


fi

rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ echo "$as_me:$LINENO: result: $have_gcc_preferred_stack_boundary" >&5
echo "${ECHO_T}$have_gcc_preferred_stack_boundary" >&6; }
CFLAGS="$save_CFLAGS"

if test x$have_gcc_preferred_stack_boundary = xyes; then
EXTRA_CFLAGS="$EXTRA_CFLAGS -mpreferred-stack-boundary=2"
fi
}


CheckWarnAll()
{
{ echo "$as_me:$LINENO: checking for GCC -Wall option" >&5
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ echo "$as_me:$LINENO: result: $have_wince" >&5
echo "${ECHO_T}$have_wince" >&6; }

# This fixes Windows stack alignment with newer GCC
CheckStackBoundary
}

CheckDIRECTX()
@@ -939,6 +939,30 @@ CheckVisibilityHidden()
fi
}

dnl See if GCC's -mpreferred-stack-boundary is supported.
dnl Reference: http://bugzilla.libsdl.org/show_bug.cgi?id=1296
CheckStackBoundary()
{
AC_MSG_CHECKING(for GCC -mpreferred-stack-boundary option)
have_gcc_preferred_stack_boundary=no

save_CFLAGS="$CFLAGS"
CFLAGS="$save_CFLAGS -mpreferred-stack-boundary=2"
AC_TRY_COMPILE([
int x = 0;
],[
],[
have_gcc_preferred_stack_boundary=yes
])
AC_MSG_RESULT($have_gcc_preferred_stack_boundary)
CFLAGS="$save_CFLAGS"

if test x$have_gcc_preferred_stack_boundary = xyes; then
EXTRA_CFLAGS="$EXTRA_CFLAGS -mpreferred-stack-boundary=2"
fi
}


dnl See if GCC's -Wall is supported.
CheckWarnAll()
{
@@ -1757,6 +1781,9 @@ CheckWINDOWS()
have_wince=yes
])
AC_MSG_RESULT($have_wince)

# This fixes Windows stack alignment with newer GCC
CheckStackBoundary
}

dnl Find the DirectX includes and libraries

0 comments on commit 3dcb512

Please sign in to comment.