]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Fix PTRACE_CONT after single-step into signal delivery
authorRoland McGrath <roland@redhat.com>
Fri, 10 Sep 2004 16:20:19 +0000 (09:20 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Fri, 10 Sep 2004 16:20:19 +0000 (09:20 -0700)
The previous single-step patch ("make single-step into signal delivery
stop in handler") took things a little too far.

It left TF set in the sigcontext on the stack, so a PTRACE_CONT after
stopping at the handler entry will step instead of resume.  This
additional patch fixes it.

Signed-off-by: Roland McGrath <roland@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/i386/kernel/signal.c
arch/x86_64/ia32/ia32_signal.c
arch/x86_64/kernel/signal.c

index a0af3edb674d17887bce44969ecb8e62b416234c..a9b33b1e93b59064dd0fa02221b96f69845e178d 100644 (file)
@@ -270,6 +270,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate,
                 struct pt_regs *regs, unsigned long mask)
 {
        int tmp, err = 0;
+       unsigned long eflags;
 
        tmp = 0;
        __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
@@ -291,7 +292,11 @@ setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate,
        err |= __put_user(current->thread.error_code, &sc->err);
        err |= __put_user(regs->eip, &sc->eip);
        err |= __put_user(regs->xcs, (unsigned int __user *)&sc->cs);
-       err |= __put_user(regs->eflags, &sc->eflags);
+       eflags = regs->eflags;
+       if (current->ptrace & PT_PTRACED) {
+               eflags &= ~TF_MASK;
+       }
+       err |= __put_user(eflags, &sc->eflags);
        err |= __put_user(regs->esp, &sc->esp_at_signal);
        err |= __put_user(regs->xss, (unsigned int __user *)&sc->ss);
 
index fc93a2212c4a4f8da10122a5fdf41119e03dc77c..432c8fa8d0e50fd5d6f4e503a4e04aac8d2eaebb 100644 (file)
@@ -349,6 +349,7 @@ ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __
                 struct pt_regs *regs, unsigned int mask)
 {
        int tmp, err = 0;
+       u32 eflags;
 
        tmp = 0;
        __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
@@ -373,7 +374,11 @@ ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __
        err |= __put_user(current->thread.trap_no, &sc->trapno);
        err |= __put_user(current->thread.error_code, &sc->err);
        err |= __put_user((u32)regs->rip, &sc->eip);
-       err |= __put_user((u32)regs->eflags, &sc->eflags);
+       eflags = regs->eflags;
+       if (current->ptrace & PT_PTRACED) {
+               eflags &= ~TF_MASK;
+       }
+       err |= __put_user((u32)eflags, &sc->eflags);
        err |= __put_user((u32)regs->rsp, &sc->esp_at_signal);
 
        tmp = save_i387_ia32(current, fpstate, regs, 0);
index b84becb315787b3fc63629b3c20abaaf6674c62e..99bcd72751097d7e59219dddcf1e312f5077e977 100644 (file)
@@ -181,6 +181,7 @@ static inline int
 setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned long mask, struct task_struct *me)
 {
        int err = 0;
+       unsigned long eflags;
 
        err |= __put_user(0, &sc->gs);
        err |= __put_user(0, &sc->fs);
@@ -204,7 +205,11 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned lo
        err |= __put_user(me->thread.trap_no, &sc->trapno);
        err |= __put_user(me->thread.error_code, &sc->err);
        err |= __put_user(regs->rip, &sc->rip);
-       err |= __put_user(regs->eflags, &sc->eflags);
+       eflags = regs->eflags;
+       if (current->ptrace & PT_PTRACED) {
+               eflags &= ~TF_MASK;
+       }
+       err |= __put_user(eflags, &sc->eflags);
        err |= __put_user(mask, &sc->oldmask);
        err |= __put_user(me->thread.cr2, &sc->cr2);