From: Fan WenJie fanwj@mail.ustc.edu.cn
For example, on x86_64, value of sp on begin of callee must be 16n-8, because sp was 16n before instruction "call" on caller. But initilize value of sp on signal stack is 16n instead of 16n-8. It may cause error when store and load xmm register.
add "force_align_arg_pointer" to hanlder of signal can avoid potential risks --- dlls/ntdll/unix/signal_i386.c | 14 +++++++------- dlls/ntdll/unix/signal_x86_64.c | 14 +++++++------- include/winnt.h | 6 ++++++ 3 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 89af605443d..cd554fdf985 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -1853,7 +1853,7 @@ static BOOL handle_syscall_trap( ucontext_t *sigcontext ) * * Handler for SIGSEGV and related errors. */ -static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext ) +static DECLSPEC_FORCEALIGN void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { EXCEPTION_RECORD rec = { 0 }; struct xcontext xcontext; @@ -1943,7 +1943,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext ) * * Handler for SIGTRAP. */ -static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext ) +static DECLSPEC_FORCEALIGN void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { EXCEPTION_RECORD rec = { 0 }; struct xcontext xcontext; @@ -1989,7 +1989,7 @@ static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext ) * * Handler for SIGFPE. */ -static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) +static DECLSPEC_FORCEALIGN void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { EXCEPTION_RECORD rec = { 0 }; struct xcontext xcontext; @@ -2034,7 +2034,7 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) * * Handler for SIGINT. */ -static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext ) +static DECLSPEC_FORCEALIGN void int_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { HANDLE handle;
@@ -2051,7 +2051,7 @@ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext ) * * Handler for SIGABRT. */ -static void abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext ) +static DECLSPEC_FORCEALIGN void abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { EXCEPTION_RECORD rec = { EXCEPTION_WINE_ASSERTION, EH_NONCONTINUABLE };
@@ -2064,7 +2064,7 @@ static void abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext ) * * Handler for SIGQUIT. */ -static void quit_handler( int signal, siginfo_t *siginfo, void *sigcontext ) +static DECLSPEC_FORCEALIGN void quit_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { init_handler( sigcontext ); abort_thread(0); @@ -2076,7 +2076,7 @@ static void quit_handler( int signal, siginfo_t *siginfo, void *sigcontext ) * * Handler for SIGUSR1, used to signal a thread that it got suspended. */ -static void usr1_handler( int signal, siginfo_t *siginfo, void *sigcontext ) +static DECLSPEC_FORCEALIGN void usr1_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { struct xcontext xcontext;
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 97d3a009c03..eb6ddad3e8c 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1962,7 +1962,7 @@ static BOOL handle_syscall_trap( ucontext_t *sigcontext ) * * Handler for SIGSEGV and related errors. */ -static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext ) +static DECLSPEC_FORCEALIGN void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { EXCEPTION_RECORD rec = { 0 }; struct xcontext context; @@ -2049,7 +2049,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext ) * * Handler for SIGTRAP. */ -static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext ) +static DECLSPEC_FORCEALIGN void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { EXCEPTION_RECORD rec = { 0 }; struct xcontext context; @@ -2083,7 +2083,7 @@ static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext ) * * Handler for SIGFPE. */ -static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) +static DECLSPEC_FORCEALIGN void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { EXCEPTION_RECORD rec = { 0 }; ucontext_t *ucontext = init_handler( sigcontext ); @@ -2136,7 +2136,7 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) * * Handler for SIGINT. */ -static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext ) +static DECLSPEC_FORCEALIGN void int_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { ucontext_t *ucontext = init_handler( sigcontext ); HANDLE handle; @@ -2156,7 +2156,7 @@ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext ) * * Handler for SIGABRT. */ -static void abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext ) +static DECLSPEC_FORCEALIGN void abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { ucontext_t *ucontext = init_handler( sigcontext ); EXCEPTION_RECORD rec = { EXCEPTION_WINE_ASSERTION, EH_NONCONTINUABLE }; @@ -2170,7 +2170,7 @@ static void abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext ) * * Handler for SIGQUIT. */ -static void quit_handler( int signal, siginfo_t *siginfo, void *ucontext ) +static DECLSPEC_FORCEALIGN void quit_handler( int signal, siginfo_t *siginfo, void *ucontext ) { init_handler( ucontext ); abort_thread(0); @@ -2182,7 +2182,7 @@ static void quit_handler( int signal, siginfo_t *siginfo, void *ucontext ) * * Handler for SIGUSR1, used to signal a thread that it got suspended. */ -static void usr1_handler( int signal, siginfo_t *siginfo, void *sigcontext ) +static DECLSPEC_FORCEALIGN void usr1_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { ucontext_t *ucontext = init_handler( sigcontext ); struct xcontext context; diff --git a/include/winnt.h b/include/winnt.h index 64408126cba..50c5d24d70e 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -83,6 +83,12 @@ extern "C" { # endif #endif
+#if (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__) +#ifndef DECLSPEC_FORCEALIGN +#define DECLSPEC_FORCEALIGN __attribute__((force_align_arg_pointer)) +#endif +#endif + #ifndef DECLSPEC_NOTHROW # if defined(_MSC_VER) && (_MSC_VER >= 1200) && !defined(MIDL_PASS) # define DECLSPEC_NOTHROW __declspec(nothrow)