]> git.hungrycats.org Git - linux/commitdiff
x86: Clear DF before calling signal handler
authorAurelien Jarno <aurelien@aurel32.net>
Sat, 8 Mar 2008 10:43:52 +0000 (11:43 +0100)
committerChris Wright <chrisw@sous-sol.org>
Mon, 24 Mar 2008 18:47:10 +0000 (11:47 -0700)
x86: Clear DF before calling signal handler

The Linux kernel currently does not clear the direction flag before
calling a signal handler, whereas the x86/x86-64 ABI requires that.
This become a real problem with gcc version 4.3, which assumes that
the direction flag is correctly cleared at the entry of a function.

This patches changes the setup_frame() functions to clear the
direction before entering the signal handler.

This is a backport of patch e40cd10ccff3d9fbffd57b93780bee4b7b9bff51
("x86: clear DF before calling signal handler") that has been applied
in 2.6.25-rc.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
arch/x86/ia32/ia32_signal.c
arch/x86/kernel/signal_32.c
arch/x86/kernel/signal_64.c

index 6ea19c25f90d46ce209c646382443c5a8ae0e46e..4eaaf78a520210705341c40813d7ecad7f7c8cac 100644 (file)
@@ -494,7 +494,7 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
        regs->ss = __USER32_DS; 
 
        set_fs(USER_DS);
-       regs->eflags &= ~TF_MASK;
+       regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
        if (test_thread_flag(TIF_SINGLESTEP))
                ptrace_notify(SIGTRAP);
 
@@ -600,7 +600,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->ss = __USER32_DS; 
 
        set_fs(USER_DS);
-       regs->eflags &= ~TF_MASK;
+       regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
        if (test_thread_flag(TIF_SINGLESTEP))
                ptrace_notify(SIGTRAP);
 
index 9bdd83022f5f1659588409a2704d6a157f13e23e..20056db6e80f93622ef6481ba32d36dd13c21d24 100644 (file)
@@ -396,7 +396,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
         * The tracer may want to single-step inside the
         * handler too.
         */
-       regs->eflags &= ~TF_MASK;
+       regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
        if (test_thread_flag(TIF_SINGLESTEP))
                ptrace_notify(SIGTRAP);
 
@@ -489,7 +489,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
         * The tracer may want to single-step inside the
         * handler too.
         */
-       regs->eflags &= ~TF_MASK;
+       regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
        if (test_thread_flag(TIF_SINGLESTEP))
                ptrace_notify(SIGTRAP);
 
index ab086b0357fc7cc977378a97f3525ad47f105095..62964c5a8e70c22cff4475883ecdd8838e48d63f 100644 (file)
@@ -295,7 +295,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
           see include/asm-x86_64/uaccess.h for details. */
        set_fs(USER_DS);
 
-       regs->eflags &= ~TF_MASK;
+       regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
        if (test_thread_flag(TIF_SINGLESTEP))
                ptrace_notify(SIGTRAP);
 #ifdef DEBUG_SIG