Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / arch / sh / kernel / ptrace.c
index 732afae..f7eebbd 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: ptrace.c,v 1.14 2003/11/28 23:05:43 kkojima Exp $
- *
+/*
  * linux/arch/sh/kernel/ptrace.c
  *
  * Original x86 implementation:
@@ -10,7 +9,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
@@ -21,6 +19,7 @@
 #include <linux/user.h>
 #include <linux/slab.h>
 #include <linux/security.h>
+#include <linux/signal.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -41,12 +40,7 @@ static inline int get_stack_long(struct task_struct *task, int offset)
 {
        unsigned char *stack;
 
-       stack = (unsigned char *)
-               task->thread_info + THREAD_SIZE - sizeof(struct pt_regs)
-#ifdef CONFIG_SH_DSP
-               - sizeof(struct pt_dspregs)
-#endif
-               - sizeof(unsigned long);
+       stack = (unsigned char *)task_pt_regs(task);
        stack += offset;
        return (*((int *)stack));
 }
@@ -59,12 +53,7 @@ static inline int put_stack_long(struct task_struct *task, int offset,
 {
        unsigned char *stack;
 
-       stack = (unsigned char *)
-               task->thread_info + THREAD_SIZE - sizeof(struct pt_regs)
-#ifdef CONFIG_SH_DSP
-               - sizeof(struct pt_dspregs)
-#endif
-               - sizeof(unsigned long);
+       stack = (unsigned char *)task_pt_regs(task);
        stack += offset;
        *(unsigned long *) stack = data;
        return 0;
@@ -80,50 +69,11 @@ void ptrace_disable(struct task_struct *child)
        /* nothing to do.. */
 }
 
-asmlinkage int 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;
        struct user * dummy = NULL;
        int ret;
 
-       lock_kernel();
-       ret = -EPERM;
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-               ret = security_ptrace(current->parent, current);
-               if (ret)
-                       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;
-       if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT))
-               goto out_tsk;
-
-       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. */ 
@@ -152,7 +102,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
                        tmp = get_stack_long(child, addr);
                else if (addr >= (long) &dummy->fpu &&
                         addr < (long) &dummy->u_fpvalid) {
-                       if (!child->used_math) {
+                       if (!tsk_used_math(child)) {
                                if (addr == (long)&dummy->fpu.fpscr)
                                        tmp = FPSCR_INIT;
                                else
@@ -161,7 +111,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
                                tmp = ((long *)&child->thread.fpu)
                                        [(addr - (long)&dummy->fpu) >> 2];
                } else if (addr == (long) &dummy->u_fpvalid)
-                       tmp = child->used_math;
+                       tmp = !!tsk_used_math(child);
                else
                        tmp = 0;
                ret = put_user(tmp, (unsigned long *)data);
@@ -187,12 +137,12 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
                        ret = put_stack_long(child, addr, data);
                else if (addr >= (long) &dummy->fpu &&
                         addr < (long) &dummy->u_fpvalid) {
-                       child->used_math = 1;
+                       set_stopped_child_used_math(child);
                        ((long *)&child->thread.fpu)
                                [(addr - (long)&dummy->fpu) >> 2] = data;
                        ret = 0;
                } else if (addr == (long) &dummy->u_fpvalid) {
-                       child->used_math = data?1:0;
+                       conditional_stopped_child_used_math(data, child);
                        ret = 0;
                }
                break;
@@ -200,7 +150,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
        case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
        case PTRACE_CONT: { /* restart after signal. */
                ret = -EIO;
-               if ((unsigned long) data > _NSIG)
+               if (!valid_signal(data))
                        break;
                if (request == PTRACE_SYSCALL)
                        set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -219,7 +169,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
  */
        case PTRACE_KILL: {
                ret = 0;
-               if (child->state == TASK_ZOMBIE)        /* already dead */
+               if (child->exit_state == EXIT_ZOMBIE)   /* already dead */
                        break;
                child->exit_code = SIGKILL;
                wake_up_process(child);
@@ -231,7 +181,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
                struct pt_regs *dummy = NULL;
 
                ret = -EIO;
-               if ((unsigned long) data > _NSIG)
+               if (!valid_signal(data))
                        break;
                clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
                if ((child->ptrace & PT_DTRACE) == 0) {
@@ -257,13 +207,6 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
                ret = ptrace_detach(child, data);
                break;
 
-       case PTRACE_SETOPTIONS:
-               if (data & PTRACE_O_TRACESYSGOOD)
-                       child->ptrace |= PT_TRACESYSGOOD;
-               else
-                       child->ptrace &= ~PT_TRACESYSGOOD;
-               ret = 0;
-               break;
 #ifdef CONFIG_SH_DSP
        case PTRACE_GETDSPREGS: {
                unsigned long dp;
@@ -298,10 +241,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
                ret = ptrace_request(child, request, addr, data);
                break;
        }
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
+
        return ret;
 }