diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-02-15 14:17:45 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-02-15 14:17:45 +0900 |
commit | 4b505db9c4c72dbd2a8e66b8d681640101325af6 (patch) | |
tree | edf6aed9194684935e8f88b9501ae3f4ed33f54d | |
parent | 724e6d3fe8003c3f60bf404bf22e4e331327c596 (diff) |
sh64: fix tracing of signals.
This follows the parisc change to ensure that tracehook_signal_handler()
is aware of when we are single-stepping in order to ptrace_notify()
appropriately. While this was implemented for 32-bit SH, sh64 neglected
to make use of TIF_SINGLESTEP when it was folded in with the 32-bit code,
resulting in ptrace_notify() never being called.
As sh64 uses all of the other abstractions already, this simply plugs in
the thread flag in the appropriate enable/disable paths and fixes up the
tracehook notification accordingly. With this in place, sh64 is brought
in line with what 32-bit is already doing.
Reported-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r-- | arch/sh/kernel/ptrace_64.c | 11 | ||||
-rw-r--r-- | arch/sh/kernel/signal_64.c | 4 |
2 files changed, 12 insertions, 3 deletions
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c index 873ebdc4f98..b063eb8b18e 100644 --- a/arch/sh/kernel/ptrace_64.c +++ b/arch/sh/kernel/ptrace_64.c @@ -133,6 +133,8 @@ void user_enable_single_step(struct task_struct *child) struct pt_regs *regs = child->thread.uregs; regs->sr |= SR_SSTEP; /* auto-resetting upon exception */ + + set_tsk_thread_flag(child, TIF_SINGLESTEP); } void user_disable_single_step(struct task_struct *child) @@ -140,6 +142,8 @@ void user_disable_single_step(struct task_struct *child) struct pt_regs *regs = child->thread.uregs; regs->sr &= ~SR_SSTEP; + + clear_tsk_thread_flag(child, TIF_SINGLESTEP); } static int genregs_get(struct task_struct *target, @@ -454,6 +458,8 @@ asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs) asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) { + int step; + if (unlikely(current->audit_context)) audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]), regs->regs[9]); @@ -461,8 +467,9 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) trace_sys_exit(regs, regs->regs[9]); - if (test_thread_flag(TIF_SYSCALL_TRACE)) - tracehook_report_syscall_exit(regs, 0); + step = test_thread_flag(TIF_SINGLESTEP); + if (step || test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(regs, step); } /* Called with interrupts disabled */ diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c index ce76dbdef29..580e97d46ca 100644 --- a/arch/sh/kernel/signal_64.c +++ b/arch/sh/kernel/signal_64.c @@ -118,7 +118,9 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset) * clear the TS_RESTORE_SIGMASK flag. */ current_thread_info()->status &= ~TS_RESTORE_SIGMASK; - tracehook_signal_handler(signr, &info, &ka, regs, 0); + + tracehook_signal_handler(signr, &info, &ka, regs, + test_thread_flag(TIF_SINGLESTEP)); return 1; } } |