ptrace: use ptrace_request() in the remaining architectures
[linux-3.10.git] / arch / m68knommu / kernel / ptrace.c
index 621d7b9..b100394 100644 (file)
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
-#include <linux/config.h>
 #include <linux/signal.h>
 
 #include <asm/uaccess.h>
@@ -63,7 +61,7 @@ static inline long get_reg(struct task_struct *task, int regno)
 
        if (regno == PT_USP)
                addr = &task->thread.usp;
-       else if (regno < sizeof(regoff)/sizeof(regoff[0]))
+       else if (regno < ARRAY_SIZE(regoff))
                addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
        else
                return 0;
@@ -80,7 +78,7 @@ static inline int put_reg(struct task_struct *task, int regno,
 
        if (regno == PT_USP)
                addr = &task->thread.usp;
-       else if (regno < sizeof(regoff)/sizeof(regoff[0]))
+       else if (regno < ARRAY_SIZE(regoff))
                addr = (unsigned long *) (task->thread.esp0 + regoff[regno]);
        else
                return -1;
@@ -88,6 +86,20 @@ static inline int put_reg(struct task_struct *task, int regno,
        return 0;
 }
 
+void user_enable_single_step(struct task_struct *task)
+{
+       unsigned long srflags;
+       srflags = get_reg(task, PT_SR) | (TRACE_BITS << 16);
+       put_reg(task, PT_SR, srflags);
+}
+
+void user_disable_single_step(struct task_struct *task)
+{
+       unsigned long srflags;
+       srflags = get_reg(task, PT_SR) & ~(TRACE_BITS << 16);
+       put_reg(task, PT_SR, srflags);
+}
+
 /*
  * Called by kernel/ptrace.c when detaching..
  *
@@ -95,64 +107,15 @@ static inline int put_reg(struct task_struct *task, int regno,
  */
 void ptrace_disable(struct task_struct *child)
 {
-       unsigned long tmp;
        /* make sure the single step bit is not set. */
-       tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
-       put_reg(child, PT_SR, tmp);
+       user_disable_single_step(child);
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        int ret;
 
-       lock_kernel();
-       ret = -EPERM;
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-
-       ret = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0)
-               goto out_tsk;
-
        switch (request) {
-               /* when I and D space are separate, these will need to be fixed. */
-               case PTRACE_PEEKTEXT: /* read word at location addr. */ 
-               case PTRACE_PEEKDATA: {
-                       unsigned long tmp;
-                       int copied;
-
-                       copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
-                       ret = -EIO;
-                       if (copied != sizeof(tmp))
-                               break;
-                       ret = put_user(tmp,(unsigned long *) data);
-                       break;
-               }
-
                /* read the word at location addr in the USER area. */
                case PTRACE_PEEKUSR: {
                        unsigned long tmp;
@@ -191,15 +154,6 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
                        break;
                }
 
-               /* when I and D space are separate, this will have to be fixed. */
-               case PTRACE_POKETEXT: /* write the word at location addr. */
-               case PTRACE_POKEDATA:
-                       ret = 0;
-                       if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
-                               break;
-                       ret = -EIO;
-                       break;
-
                case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
                        ret = -EIO;
                        if ((addr & 3) || addr < 0 ||
@@ -292,10 +246,6 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
                        break;
                }
 
-               case PTRACE_DETACH:     /* detach a process that was attached. */
-                       ret = ptrace_detach(child, data);
-                       break;
-
                case PTRACE_GETREGS: { /* Get all gp regs from the child. */
                        int i;
                        unsigned long tmp;
@@ -353,14 +303,15 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
                }
 #endif
 
+       case PTRACE_GET_THREAD_AREA:
+               ret = put_user(task_thread_info(child)->tp_value,
+                              (unsigned long __user *)data);
+               break;
+
                default:
-                       ret = -EIO;
+                       ret = ptrace_request(child, request, addr, data);
                        break;
        }
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
        return ret;
 }