[ARM] ptrace: clean up single stepping support
authorRussell King <rmk@dyn-67.arm.linux.org.uk>
Sun, 4 Mar 2007 09:50:28 +0000 (09:50 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 21 Apr 2007 19:34:58 +0000 (20:34 +0100)
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/kernel/ptrace.c
arch/arm/kernel/ptrace.h
arch/arm/kernel/signal.c

index 9254ba2f46fc147b756407d6d21fdff16a117f84..e594b84cca839d39e69c259a48aef29826baf9c7 100644 (file)
@@ -457,13 +457,10 @@ void ptrace_cancel_bpt(struct task_struct *child)
 
 /*
  * Called by kernel/ptrace.c when detaching..
- *
- * Make sure the single step bit is not set.
  */
 void ptrace_disable(struct task_struct *child)
 {
-       child->ptrace &= ~PT_SINGLESTEP;
-       ptrace_cancel_bpt(child);
+       single_step_disable(child);
 }
 
 /*
@@ -712,9 +709,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        else
                                clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
                        child->exit_code = data;
-                       /* make sure single-step breakpoint is gone. */
-                       child->ptrace &= ~PT_SINGLESTEP;
-                       ptrace_cancel_bpt(child);
+                       single_step_disable(child);
                        wake_up_process(child);
                        ret = 0;
                        break;
@@ -725,9 +720,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                 * exit.
                 */
                case PTRACE_KILL:
-                       /* make sure single-step breakpoint is gone. */
-                       child->ptrace &= ~PT_SINGLESTEP;
-                       ptrace_cancel_bpt(child);
+                       single_step_disable(child);
                        if (child->exit_state != EXIT_ZOMBIE) {
                                child->exit_code = SIGKILL;
                                wake_up_process(child);
@@ -742,7 +735,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        ret = -EIO;
                        if (!valid_signal(data))
                                break;
-                       child->ptrace |= PT_SINGLESTEP;
+                       single_step_enable(child);
                        clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
                        child->exit_code = data;
                        /* give it a chance to run. */
index f7cad13a22e9830bbf0eba078ef2ae3dde22045e..def3b6184a7962756c11ec849d68d962b2f98567 100644 (file)
@@ -7,6 +7,45 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/ptrace.h>
+
 extern void ptrace_cancel_bpt(struct task_struct *);
 extern void ptrace_set_bpt(struct task_struct *);
 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);
+}
index 3843d3bab2ddc4d2e7eb536cc8380ee3d420d5f5..54cdf1aeefc3df83458d83f1b5ff7dc9c41b5c10 100644 (file)
@@ -9,7 +9,6 @@
  */
 #include <linux/errno.h>
 #include <linux/signal.h>
-#include <linux/ptrace.h>
 #include <linux/personality.h>
 #include <linux/freezer.h>
 
@@ -285,11 +284,7 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
        if (restore_sigframe(regs, frame))
                goto badframe;
 
-       /* Send SIGTRAP if we're single-stepping */
-       if (current->ptrace & PT_SINGLESTEP) {
-               ptrace_cancel_bpt(current);
-               send_sig(SIGTRAP, current, 1);
-       }
+       single_step_trap(current);
 
        return regs->ARM_r0;
 
@@ -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)
                goto badframe;
 
-       /* Send SIGTRAP if we're single-stepping */
-       if (current->ptrace & PT_SINGLESTEP) {
-               ptrace_cancel_bpt(current);
-               send_sig(SIGTRAP, current, 1);
-       }
+       single_step_trap(current);
 
        return regs->ARM_r0;
 
@@ -644,14 +635,12 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
        if (try_to_freeze())
                goto no_signal;
 
-       if (current->ptrace & PT_SINGLESTEP)
-               ptrace_cancel_bpt(current);
+       single_step_clear(current);
 
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
        if (signr > 0) {
                handle_signal(signr, &ka, &info, oldset, regs, syscall);
-               if (current->ptrace & PT_SINGLESTEP)
-                       ptrace_set_bpt(current);
+               single_step_set(current);
                return 1;
        }
 
@@ -705,8 +694,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
                        restart_syscall(regs);
                }
        }
-       if (current->ptrace & PT_SINGLESTEP)
-               ptrace_set_bpt(current);
+       single_step_set(current);
        return 0;
 }