Commit b2a0d36f authored by Russell King's avatar Russell King Committed by Russell King

[ARM] ptrace: clean up single stepping support

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 0f0a00be
...@@ -457,13 +457,10 @@ void ptrace_cancel_bpt(struct task_struct *child) ...@@ -457,13 +457,10 @@ void ptrace_cancel_bpt(struct task_struct *child)
/* /*
* Called by kernel/ptrace.c when detaching.. * Called by kernel/ptrace.c when detaching..
*
* Make sure the single step bit is not set.
*/ */
void ptrace_disable(struct task_struct *child) void ptrace_disable(struct task_struct *child)
{ {
child->ptrace &= ~PT_SINGLESTEP; single_step_disable(child);
ptrace_cancel_bpt(child);
} }
/* /*
...@@ -712,9 +709,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -712,9 +709,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
else else
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data; child->exit_code = data;
/* make sure single-step breakpoint is gone. */ single_step_disable(child);
child->ptrace &= ~PT_SINGLESTEP;
ptrace_cancel_bpt(child);
wake_up_process(child); wake_up_process(child);
ret = 0; ret = 0;
break; break;
...@@ -725,9 +720,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -725,9 +720,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
* exit. * exit.
*/ */
case PTRACE_KILL: case PTRACE_KILL:
/* make sure single-step breakpoint is gone. */ single_step_disable(child);
child->ptrace &= ~PT_SINGLESTEP;
ptrace_cancel_bpt(child);
if (child->exit_state != EXIT_ZOMBIE) { if (child->exit_state != EXIT_ZOMBIE) {
child->exit_code = SIGKILL; child->exit_code = SIGKILL;
wake_up_process(child); wake_up_process(child);
...@@ -742,7 +735,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -742,7 +735,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = -EIO; ret = -EIO;
if (!valid_signal(data)) if (!valid_signal(data))
break; break;
child->ptrace |= PT_SINGLESTEP; single_step_enable(child);
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data; child->exit_code = data;
/* give it a chance to run. */ /* give it a chance to run. */
......
...@@ -7,6 +7,45 @@ ...@@ -7,6 +7,45 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/ptrace.h>
extern void ptrace_cancel_bpt(struct task_struct *); extern void ptrace_cancel_bpt(struct task_struct *);
extern void ptrace_set_bpt(struct task_struct *); extern void ptrace_set_bpt(struct task_struct *);
extern void ptrace_break(struct task_struct *, struct pt_regs *); extern void ptrace_break(struct task_struct *, struct pt_regs *);
/*
* make sure single-step breakpoint is gone.
*/
static inline void single_step_disable(struct task_struct *task)
{
task->ptrace &= ~PT_SINGLESTEP;
ptrace_cancel_bpt(task);
}
static inline void single_step_enable(struct task_struct *task)
{
task->ptrace |= PT_SINGLESTEP;
}
/*
* Send SIGTRAP if we're single-stepping
*/
static inline void single_step_trap(struct task_struct *task)
{
if (task->ptrace & PT_SINGLESTEP) {
ptrace_cancel_bpt(task);
send_sig(SIGTRAP, task, 1);
}
}
static inline void single_step_clear(struct task_struct *task)
{
if (task->ptrace & PT_SINGLESTEP)
ptrace_cancel_bpt(task);
}
static inline void single_step_set(struct task_struct *task)
{
if (task->ptrace & PT_SINGLESTEP)
ptrace_set_bpt(task);
}
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
*/ */
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/ptrace.h>
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/freezer.h> #include <linux/freezer.h>
...@@ -285,11 +284,7 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs) ...@@ -285,11 +284,7 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
if (restore_sigframe(regs, frame)) if (restore_sigframe(regs, frame))
goto badframe; goto badframe;
/* Send SIGTRAP if we're single-stepping */ single_step_trap(current);
if (current->ptrace & PT_SINGLESTEP) {
ptrace_cancel_bpt(current);
send_sig(SIGTRAP, current, 1);
}
return regs->ARM_r0; return regs->ARM_r0;
...@@ -324,11 +319,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) ...@@ -324,11 +319,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT) if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT)
goto badframe; goto badframe;
/* Send SIGTRAP if we're single-stepping */ single_step_trap(current);
if (current->ptrace & PT_SINGLESTEP) {
ptrace_cancel_bpt(current);
send_sig(SIGTRAP, current, 1);
}
return regs->ARM_r0; return regs->ARM_r0;
...@@ -644,14 +635,12 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) ...@@ -644,14 +635,12 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
if (try_to_freeze()) if (try_to_freeze())
goto no_signal; goto no_signal;
if (current->ptrace & PT_SINGLESTEP) single_step_clear(current);
ptrace_cancel_bpt(current);
signr = get_signal_to_deliver(&info, &ka, regs, NULL); signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) { if (signr > 0) {
handle_signal(signr, &ka, &info, oldset, regs, syscall); handle_signal(signr, &ka, &info, oldset, regs, syscall);
if (current->ptrace & PT_SINGLESTEP) single_step_set(current);
ptrace_set_bpt(current);
return 1; return 1;
} }
...@@ -705,8 +694,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) ...@@ -705,8 +694,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
restart_syscall(regs); restart_syscall(regs);
} }
} }
if (current->ptrace & PT_SINGLESTEP) single_step_set(current);
ptrace_set_bpt(current);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment