[SPARC]: Move over to arch_ptrace().
authorDavid S. Miller <davem@davemloft.net>
Thu, 7 Feb 2008 11:00:17 +0000 (03:00 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 7 Feb 2008 11:00:17 +0000 (03:00 -0800)
Signed-off-by: David S. Miller <davem@davemloft.net>
arch/sparc/kernel/entry.S
arch/sparc/kernel/ptrace.c
arch/sparc64/kernel/entry.S
arch/sparc64/kernel/ptrace.c
include/asm-sparc/ptrace.h
include/asm-sparc64/ptrace.h

index 88d2cef..c2eed8f 100644 (file)
@@ -1224,23 +1224,6 @@ sys_nis_syscall:
        call    c_sys_nis_syscall
         mov    %l5, %o7
 
-       .align 4
-       .globl  sys_ptrace
-sys_ptrace:
-       call    do_ptrace
-        add    %sp, STACKFRAME_SZ, %o0
-
-       ld      [%curptr + TI_FLAGS], %l5
-       andcc   %l5, _TIF_SYSCALL_TRACE, %g0
-       be      1f
-        nop
-
-       call    syscall_trace
-        nop
-
-1:
-       RESTORE_ALL
-
        .align  4
        .globl  sys_execve
 sys_execve:
index 29fa6e5..1c0d536 100644 (file)
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-#define MAGIC_CONSTANT 0x80000000
-
-
-/* Returning from ptrace is a bit tricky because the syscall return
- * low level code assumes any value returned which is negative and
- * is a valid errno will mean setting the condition codes to indicate
- * an error return.  This doesn't work, so we have this hook.
- */
-static inline void pt_error_return(struct pt_regs *regs, unsigned long error)
-{
-       regs->u_regs[UREG_I0] = error;
-       regs->psr |= PSR_C;
-       regs->pc = regs->npc;
-       regs->npc += 4;
-}
-
-static inline void pt_succ_return(struct pt_regs *regs, unsigned long value)
-{
-       regs->u_regs[UREG_I0] = value;
-       regs->psr &= ~PSR_C;
-       regs->pc = regs->npc;
-       regs->npc += 4;
-}
-
-static void
-pt_succ_return_linux(struct pt_regs *regs, unsigned long value, long __user *addr)
-{
-       if (put_user(value, addr)) {
-               pt_error_return(regs, EFAULT);
-               return;
-       }
-       regs->u_regs[UREG_I0] = 0;
-       regs->psr &= ~PSR_C;
-       regs->pc = regs->npc;
-       regs->npc += 4;
-}
-
-static void
-pt_os_succ_return (struct pt_regs *regs, unsigned long val, long __user *addr)
-{
-       if (current->personality == PER_SUNOS)
-               pt_succ_return (regs, val);
-       else
-               pt_succ_return_linux (regs, val, addr);
-}
-
-/* Fuck me gently with a chainsaw... */
-static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset,
-                                  struct task_struct *tsk, long __user *addr)
-{
-       struct pt_regs *cregs = tsk->thread.kregs;
-       struct thread_info *t = task_thread_info(tsk);
-       int v;
-       
-       if(offset >= 1024)
-               offset -= 1024; /* whee... */
-       if(offset & ((sizeof(unsigned long) - 1))) {
-               pt_error_return(regs, EIO);
-               return;
-       }
-       if(offset >= 16 && offset < 784) {
-               offset -= 16; offset >>= 2;
-               pt_os_succ_return(regs, *(((unsigned long *)(&t->reg_window[0]))+offset), addr);
-               return;
-       }
-       if(offset >= 784 && offset < 832) {
-               offset -= 784; offset >>= 2;
-               pt_os_succ_return(regs, *(((unsigned long *)(&t->rwbuf_stkptrs[0]))+offset), addr);
-               return;
-       }
-       switch(offset) {
-       case 0:
-               v = t->ksp;
-               break;
-       case 4:
-               v = t->kpc;
-               break;
-       case 8:
-               v = t->kpsr;
-               break;
-       case 12:
-               v = t->uwinmask;
-               break;
-       case 832:
-               v = t->w_saved;
-               break;
-       case 896:
-               v = cregs->u_regs[UREG_I0];
-               break;
-       case 900:
-               v = cregs->u_regs[UREG_I1];
-               break;
-       case 904:
-               v = cregs->u_regs[UREG_I2];
-               break;
-       case 908:
-               v = cregs->u_regs[UREG_I3];
-               break;
-       case 912:
-               v = cregs->u_regs[UREG_I4];
-               break;
-       case 916:
-               v = cregs->u_regs[UREG_I5];
-               break;
-       case 920:
-               v = cregs->u_regs[UREG_I6];
-               break;
-       case 924:
-               if(tsk->thread.flags & MAGIC_CONSTANT)
-                       v = cregs->u_regs[UREG_G1];
-               else
-                       v = 0;
-               break;
-       case 940:
-               v = cregs->u_regs[UREG_I0];
-               break;
-       case 944:
-               v = cregs->u_regs[UREG_I1];
-               break;
-
-       case 948:
-               /* Isn't binary compatibility _fun_??? */
-               if(cregs->psr & PSR_C)
-                       v = cregs->u_regs[UREG_I0] << 24;
-               else
-                       v = 0;
-               break;
-
-               /* Rest of them are completely unsupported. */
-       default:
-               printk("%s [%d]: Wants to read user offset %ld\n",
-                      current->comm, task_pid_nr(current), offset);
-               pt_error_return(regs, EIO);
-               return;
-       }
-       if (current->personality == PER_SUNOS)
-               pt_succ_return (regs, v);
-       else
-               pt_succ_return_linux (regs, v, addr);
-       return;
-}
-
-static inline void write_sunos_user(struct pt_regs *regs, unsigned long offset,
-                                   struct task_struct *tsk)
-{
-       struct pt_regs *cregs = tsk->thread.kregs;
-       struct thread_info *t = task_thread_info(tsk);
-       unsigned long value = regs->u_regs[UREG_I3];
-
-       if(offset >= 1024)
-               offset -= 1024; /* whee... */
-       if(offset & ((sizeof(unsigned long) - 1)))
-               goto failure;
-       if(offset >= 16 && offset < 784) {
-               offset -= 16; offset >>= 2;
-               *(((unsigned long *)(&t->reg_window[0]))+offset) = value;
-               goto success;
-       }
-       if(offset >= 784 && offset < 832) {
-               offset -= 784; offset >>= 2;
-               *(((unsigned long *)(&t->rwbuf_stkptrs[0]))+offset) = value;
-               goto success;
-       }
-       switch(offset) {
-       case 896:
-               cregs->u_regs[UREG_I0] = value;
-               break;
-       case 900:
-               cregs->u_regs[UREG_I1] = value;
-               break;
-       case 904:
-               cregs->u_regs[UREG_I2] = value;
-               break;
-       case 908:
-               cregs->u_regs[UREG_I3] = value;
-               break;
-       case 912:
-               cregs->u_regs[UREG_I4] = value;
-               break;
-       case 916:
-               cregs->u_regs[UREG_I5] = value;
-               break;
-       case 920:
-               cregs->u_regs[UREG_I6] = value;
-               break;
-       case 924:
-               cregs->u_regs[UREG_I7] = value;
-               break;
-       case 940:
-               cregs->u_regs[UREG_I0] = value;
-               break;
-       case 944:
-               cregs->u_regs[UREG_I1] = value;
-               break;
-
-               /* Rest of them are completely unsupported or "no-touch". */
-       default:
-               printk("%s [%d]: Wants to write user offset %ld\n",
-                      current->comm, task_pid_nr(current), offset);
-               goto failure;
-       }
-success:
-       pt_succ_return(regs, 0);
-       return;
-failure:
-       pt_error_return(regs, EIO);
-       return;
-}
-
 /* #define ALLOW_INIT_TRACING */
 
 /*
@@ -528,113 +319,42 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
        return &user_sparc32_view;
 }
 
-asmlinkage void do_ptrace(struct pt_regs *regs)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       unsigned long request = regs->u_regs[UREG_I0];
-       unsigned long pid = regs->u_regs[UREG_I1];
-       unsigned long addr = regs->u_regs[UREG_I2];
-       unsigned long data = regs->u_regs[UREG_I3];
-       unsigned long addr2 = regs->u_regs[UREG_I4];
-       struct task_struct *child;
-       int ret;
-
-       lock_kernel();
-
-       if (request == PTRACE_TRACEME) {
-               ret = ptrace_traceme();
-               if (ret < 0)
-                       pt_error_return(regs, -ret);
-               else
-                       pt_succ_return(regs, 0);
-               goto out;
-       }
-
-       child = ptrace_get_task_struct(pid);
-       if (IS_ERR(child)) {
-               ret = PTR_ERR(child);
-               pt_error_return(regs, -ret);
-               goto out;
-       }
-
-       if (request == PTRACE_ATTACH) {
-               if (ptrace_attach(child)) {
-                       pt_error_return(regs, EPERM);
-                       goto out_tsk;
-               }
-               pt_succ_return(regs, 0);
-               goto out_tsk;
-       }
-
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0) {
-               pt_error_return(regs, -ret);
-               goto out_tsk;
-       }
+       unsigned long addr2 = current->thread.kregs->u_regs[UREG_I4];
+       int i, ret;
 
        switch(request) {
-       case PTRACE_PEEKTEXT: /* read word at location addr. */ 
-       case PTRACE_PEEKDATA: {
-               unsigned long tmp;
-
-               if (access_process_vm(child, addr,
-                                     &tmp, sizeof(tmp), 0) == sizeof(tmp))
-                       pt_os_succ_return(regs, tmp, (long __user *)data);
-               else
-                       pt_error_return(regs, EIO);
-               goto out_tsk;
-       }
-
-       case PTRACE_PEEKUSR:
-               read_sunos_user(regs, addr, child, (long __user *) data);
-               goto out_tsk;
-
-       case PTRACE_POKEUSR:
-               write_sunos_user(regs, addr, child);
-               goto out_tsk;
-
-       case PTRACE_POKETEXT: /* write the word at location addr. */
-       case PTRACE_POKEDATA: {
-               if (access_process_vm(child, addr,
-                                     &data, sizeof(data), 1) == sizeof(data))
-                       pt_succ_return(regs, 0);
-               else
-                       pt_error_return(regs, EIO);
-               goto out_tsk;
-       }
-
        case PTRACE_GETREGS: {
                struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
                struct pt_regs *cregs = child->thread.kregs;
-               int rval;
 
-               if (!access_ok(VERIFY_WRITE, pregs, sizeof(struct pt_regs))) {
-                       rval = -EFAULT;
-                       pt_error_return(regs, -rval);
-                       goto out_tsk;
-               }
+               ret = -EFAULT;
+               if (!access_ok(VERIFY_WRITE, pregs, sizeof(struct pt_regs)))
+                       break;
+
                __put_user(cregs->psr, (&pregs->psr));
                __put_user(cregs->pc, (&pregs->pc));
                __put_user(cregs->npc, (&pregs->npc));
                __put_user(cregs->y, (&pregs->y));
-               for(rval = 1; rval < 16; rval++)
-                       __put_user(cregs->u_regs[rval], (&pregs->u_regs[rval - 1]));
-               pt_succ_return(regs, 0);
-               goto out_tsk;
+               for (i = 1; i < 16; i++)
+                       __put_user(cregs->u_regs[i], &pregs->u_regs[i - 1]);
+               ret = 0;
+               break;
        }
 
        case PTRACE_SETREGS: {
                struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
                struct pt_regs *cregs = child->thread.kregs;
                unsigned long psr, pc, npc, y;
-               int i;
 
                /* Must be careful, tracing process can only set certain
                 * bits in the psr.
                 */
-               if (!access_ok(VERIFY_READ, pregs, sizeof(struct pt_regs))) {
-                       pt_error_return(regs, EFAULT);
-                       goto out_tsk;
-               }
+               ret = -EFAULT;
+               if (!access_ok(VERIFY_READ, pregs, sizeof(struct pt_regs)))
+                       break;
+
                __get_user(psr, (&pregs->psr));
                __get_user(pc, (&pregs->pc));
                __get_user(npc, (&pregs->npc));
@@ -647,10 +367,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
                        cregs->npc =npc;
                }
                cregs->y = y;
-               for(i = 1; i < 16; i++)
-                       __get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]));
-               pt_succ_return(regs, 0);
-               goto out_tsk;
+               for (i = 1; i < 16; i++)
+                       __get_user(cregs->u_regs[i], &pregs->u_regs[i-1]);
+               ret = 0;
+               break;
        }
 
        case PTRACE_GETFPREGS: {
@@ -666,26 +386,25 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
                        } fpq[16];
                };
                struct fps __user *fps = (struct fps __user *) addr;
-               int i;
 
-               if (!access_ok(VERIFY_WRITE, fps, sizeof(struct fps))) {
-                       i = -EFAULT;
-                       pt_error_return(regs, -i);
-                       goto out_tsk;
-               }
-               for(i = 0; i < 32; i++)
-                       __put_user(child->thread.float_regs[i], (&fps->regs[i]));
+               ret = -EFAULT;
+               if (!access_ok(VERIFY_WRITE, fps, sizeof(struct fps)))
+                       break;
+
+               for (i = 0; i < 32; i++)
+                       __put_user(child->thread.float_regs[i], &fps->regs[i]);
                __put_user(child->thread.fsr, (&fps->fsr));
                __put_user(child->thread.fpqdepth, (&fps->fpqd));
                __put_user(0, (&fps->flags));
                __put_user(0, (&fps->extra));
-               for(i = 0; i < 16; i++) {
+               for (i = 0; i < 16; i++) {
                        __put_user(child->thread.fpqueue[i].insn_addr,
                                   (&fps->fpq[i].insnaddr));
-                       __put_user(child->thread.fpqueue[i].insn, (&fps->fpq[i].insn));
+                       __put_user(child->thread.fpqueue[i].insn,
+                                  &fps->fpq[i].insn);
                }
-               pt_succ_return(regs, 0);
-               goto out_tsk;
+               ret = 0;
+               break;
        }
 
        case PTRACE_SETFPREGS: {
@@ -701,107 +420,53 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
                        } fpq[16];
                };
                struct fps __user *fps = (struct fps __user *) addr;
-               int i;
 
-               if (!access_ok(VERIFY_READ, fps, sizeof(struct fps))) {
-                       i = -EFAULT;
-                       pt_error_return(regs, -i);
-                       goto out_tsk;
-               }
-               copy_from_user(&child->thread.float_regs[0], &fps->regs[0], (32 * sizeof(unsigned long)));
+               ret = -EFAULT;
+               if (!access_ok(VERIFY_READ, fps, sizeof(struct fps)))
+                       break;
+
+               copy_from_user(&child->thread.float_regs[0], &fps->regs[0],
+                              (32 * sizeof(unsigned long)));
                __get_user(child->thread.fsr, (&fps->fsr));
                __get_user(child->thread.fpqdepth, (&fps->fpqd));
-               for(i = 0; i < 16; i++) {
+               for (i = 0; i < 16; i++) {
                        __get_user(child->thread.fpqueue[i].insn_addr,
                                   (&fps->fpq[i].insnaddr));
-                       __get_user(child->thread.fpqueue[i].insn, (&fps->fpq[i].insn));
+                       __get_user(child->thread.fpqueue[i].insn,
+                                  &fps->fpq[i].insn);
                }
-               pt_succ_return(regs, 0);
-               goto out_tsk;
+               ret = 0;
+               break;
        }
 
        case PTRACE_READTEXT:
-       case PTRACE_READDATA: {
-               int res = ptrace_readdata(child, addr,
-                                         (void __user *) addr2, data);
-
-               if (res == data) {
-                       pt_succ_return(regs, 0);
-                       goto out_tsk;
-               }
-               /* Partial read is an IO failure */
-               if (res >= 0)
-                       res = -EIO;
-               pt_error_return(regs, -res);
-               goto out_tsk;
-       }
+       case PTRACE_READDATA:
+               ret = ptrace_readdata(child, addr,
+                                     (void __user *) addr2, data);
+
+               if (ret == data)
+                       ret = 0;
+               else if (ret >= 0)
+                       ret = -EIO;
+               break;
 
        case PTRACE_WRITETEXT:
-       case PTRACE_WRITEDATA: {
-               int res = ptrace_writedata(child, (void __user *) addr2,
-                                          addr, data);
-
-               if (res == data) {
-                       pt_succ_return(regs, 0);
-                       goto out_tsk;
-               }
-               /* Partial write is an IO failure */
-               if (res >= 0)
-                       res = -EIO;
-               pt_error_return(regs, -res);
-               goto out_tsk;
-       }
-
-       case PTRACE_SYSCALL: /* continue and stop at (return from) syscall */
-               addr = 1;
-
-       case PTRACE_CONT: { /* restart after signal. */
-               if (!valid_signal(data)) {
-                       pt_error_return(regs, EIO);
-                       goto out_tsk;
-               }
-
-               if (request == PTRACE_SYSCALL)
-                       set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-               else
-                       clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-
-               child->exit_code = data;
-               wake_up_process(child);
-               pt_succ_return(regs, 0);
-               goto out_tsk;
-       }
+       case PTRACE_WRITEDATA:
+               ret = ptrace_writedata(child, (void __user *) addr2,
+                                      addr, data);
+
+               if (ret == data)
+                       ret = 0;
+               else if (ret >= 0)
+                       ret = -EIO;
+               break;
 
-/*
- * make the child exit.  Best I can do is send it a sigkill. 
- * perhaps it should be put in the status that it wants to 
- * exit.
- */
-       case PTRACE_KILL: {
-               if (child->exit_state == EXIT_ZOMBIE) { /* already dead */
-                       pt_succ_return(regs, 0);
-                       goto out_tsk;
-               }
-               wake_up_process(child);
-               child->exit_code = SIGKILL;
-               pt_succ_return(regs, 0);
-               goto out_tsk;
+       default:
+               ret = ptrace_request(child, request, addr, data);
+               break;
        }
 
-       default: {
-               int err = ptrace_request(child, request, addr, data);
-               if (err)
-                       pt_error_return(regs, -err);
-               else
-                       pt_succ_return(regs, 0);
-               goto out_tsk;
-       }
-       }
-out_tsk:
-       if (child)
-               put_task_struct(child);
-out:
-       unlock_kernel();
+       return ret;
 }
 
 asmlinkage void syscall_trace(void)
@@ -810,7 +475,6 @@ asmlinkage void syscall_trace(void)
                return;
        if (!(current->ptrace & PT_PTRACED))
                return;
-       current->thread.flags ^= MAGIC_CONSTANT;
        ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
                                 ? 0x80 : 0));
        /*
index ea257e8..6be4d2d 100644 (file)
@@ -1477,10 +1477,6 @@ sys32_rt_sigreturn:
                 add            %o7, 1f-.-4, %o7
                nop
 #endif
-sys_ptrace:    add             %sp, PTREGS_OFF, %o0
-               call            do_ptrace
-                add            %o7, 1f-.-4, %o7
-               nop
                .align          32
 1:             ldx             [%curptr + TI_FLAGS], %l5
                andcc           %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
index e881dbb..c831d42 100644 (file)
 #include <asm/page.h>
 #include <asm/cpudata.h>
 
-/* Returning from ptrace is a bit tricky because the syscall return
- * low level code assumes any value returned which is negative and
- * is a valid errno will mean setting the condition codes to indicate
- * an error return.  This doesn't work, so we have this hook.
- */
-static inline void pt_error_return(struct pt_regs *regs, unsigned long error)
-{
-       regs->u_regs[UREG_I0] = error;
-       regs->tstate |= (TSTATE_ICARRY | TSTATE_XCARRY);
-       regs->tpc = regs->tnpc;
-       regs->tnpc += 4;
-}
-
-static inline void pt_succ_return(struct pt_regs *regs, unsigned long value)
-{
-       regs->u_regs[UREG_I0] = value;
-       regs->tstate &= ~(TSTATE_ICARRY | TSTATE_XCARRY);
-       regs->tpc = regs->tnpc;
-       regs->tnpc += 4;
-}
-
-static inline void
-pt_succ_return_linux(struct pt_regs *regs, unsigned long value, void __user *addr)
-{
-       if (test_thread_flag(TIF_32BIT)) {
-               if (put_user(value, (unsigned int __user *) addr)) {
-                       pt_error_return(regs, EFAULT);
-                       return;
-               }
-       } else {
-               if (put_user(value, (long __user *) addr)) {
-                       pt_error_return(regs, EFAULT);
-                       return;
-               }
-       }
-       regs->u_regs[UREG_I0] = 0;
-       regs->tstate &= ~(TSTATE_ICARRY | TSTATE_XCARRY);
-       regs->tpc = regs->tnpc;
-       regs->tnpc += 4;
-}
-
-static void
-pt_os_succ_return (struct pt_regs *regs, unsigned long val, void __user *addr)
-{
-       if (current->personality == PER_SUNOS)
-               pt_succ_return (regs, val);
-       else
-               pt_succ_return_linux (regs, val, addr);
-}
-
 /* #define ALLOW_INIT_TRACING */
 
 /*
@@ -734,171 +684,113 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
        return &user_sparc64_view;
 }
 
-asmlinkage void do_ptrace(struct pt_regs *regs)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       int request = regs->u_regs[UREG_I0];
-       pid_t pid = regs->u_regs[UREG_I1];
-       unsigned long addr = regs->u_regs[UREG_I2];
-       unsigned long data = regs->u_regs[UREG_I3];
-       unsigned long addr2 = regs->u_regs[UREG_I4];
-       struct task_struct *child;
-       int ret;
+       long addr2 = task_pt_regs(current)->u_regs[UREG_I4];
+       int i, ret;
 
-       if (test_thread_flag(TIF_32BIT)) {
-               addr &= 0xffffffffUL;
-               data &= 0xffffffffUL;
+#if 1
+       printk(KERN_INFO
+              "arch_ptrace: request[%ld] addr[%lx] data[%lx] addr2[%lx]\n",
+              request, addr, data, addr2);
+#endif
+       if (test_thread_flag(TIF_32BIT))
                addr2 &= 0xffffffffUL;
-       }
-       lock_kernel();
-       if (request == PTRACE_TRACEME) {
-               ret = ptrace_traceme();
-               if (ret < 0)
-                       pt_error_return(regs, -ret);
-               else
-                       pt_succ_return(regs, 0);
-               goto out;
-       }
-
-       child = ptrace_get_task_struct(pid);
-       if (IS_ERR(child)) {
-               ret = PTR_ERR(child);
-               pt_error_return(regs, -ret);
-               goto out;
-       }
-
-       if (request == PTRACE_ATTACH) {
-               if (ptrace_attach(child)) {
-                       pt_error_return(regs, EPERM);
-                       goto out_tsk;
-               }
-               pt_succ_return(regs, 0);
-               goto out_tsk;
-       }
-
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0) {
-               pt_error_return(regs, -ret);
-               goto out_tsk;
-       }
-
-       if (!(test_thread_flag(TIF_32BIT))      &&
-           ((request == PTRACE_READDATA64)             ||
-            (request == PTRACE_WRITEDATA64)            ||
-            (request == PTRACE_READTEXT64)             ||
-            (request == PTRACE_WRITETEXT64)            ||
-            (request == PTRACE_PEEKTEXT64)             ||
-            (request == PTRACE_POKETEXT64)             ||
-            (request == PTRACE_PEEKDATA64)             ||
-            (request == PTRACE_POKEDATA64))) {
-               addr = regs->u_regs[UREG_G2];
-               addr2 = regs->u_regs[UREG_G3];
-               request -= 30; /* wheee... */
-       }
 
        switch(request) {
        case PTRACE_PEEKUSR:
-               if (addr != 0)
-                       pt_error_return(regs, EIO);
-               else
-                       pt_succ_return(regs, 0);
-               goto out_tsk;
+               ret = (addr != 0) ? -EIO : 0;
+               break;
 
        case PTRACE_PEEKTEXT: /* read word at location addr. */ 
        case PTRACE_PEEKDATA: {
                unsigned long tmp64;
                unsigned int tmp32;
-               int res, copied;
+               int copied;
 
-               res = -EIO;
+               ret = -EIO;
                if (test_thread_flag(TIF_32BIT)) {
                        copied = access_process_vm(child, addr,
                                                   &tmp32, sizeof(tmp32), 0);
-                       tmp64 = (unsigned long) tmp32;
                        if (copied == sizeof(tmp32))
-                               res = 0;
+                               ret = put_user(tmp32,
+                                              (unsigned int __user *) data);
                } else {
                        copied = access_process_vm(child, addr,
                                                   &tmp64, sizeof(tmp64), 0);
                        if (copied == sizeof(tmp64))
-                               res = 0;
+                               ret = put_user(tmp64,
+                                              (unsigned long __user *) data);
                }
-               if (res < 0)
-                       pt_error_return(regs, -res);
-               else
-                       pt_os_succ_return(regs, tmp64, (void __user *) data);
-               goto out_tsk;
+               break;
        }
 
        case PTRACE_POKETEXT: /* write the word at location addr. */
        case PTRACE_POKEDATA: {
                unsigned long tmp64;
                unsigned int tmp32;
-               int copied, res = -EIO;
+               int copied;
 
+               ret = -EIO;
                if (test_thread_flag(TIF_32BIT)) {
                        tmp32 = data;
                        copied = access_process_vm(child, addr,
                                                   &tmp32, sizeof(tmp32), 1);
                        if (copied == sizeof(tmp32))
-                               res = 0;
+                               ret = 0;
                } else {
                        tmp64 = data;
                        copied = access_process_vm(child, addr,
                                                   &tmp64, sizeof(tmp64), 1);
                        if (copied == sizeof(tmp64))
-                               res = 0;
+                               ret = 0;
                }
-               if (res < 0)
-                       pt_error_return(regs, -res);
-               else
-                       pt_succ_return(regs, res);
-               goto out_tsk;
+               break;
        }
 
        case PTRACE_GETREGS: {
                struct pt_regs32 __user *pregs =
                        (struct pt_regs32 __user *) addr;
                struct pt_regs *cregs = task_pt_regs(child);
-               int rval;
 
+               ret = -EFAULT;
                if (__put_user(tstate_to_psr(cregs->tstate), (&pregs->psr)) ||
                    __put_user(cregs->tpc, (&pregs->pc)) ||
                    __put_user(cregs->tnpc, (&pregs->npc)) ||
-                   __put_user(cregs->y, (&pregs->y))) {
-                       pt_error_return(regs, EFAULT);
-                       goto out_tsk;
+                   __put_user(cregs->y, (&pregs->y)))
+                       break;
+               for (i = 1; i < 16; i++) {
+                       if (__put_user(cregs->u_regs[i],
+                                      (&pregs->u_regs[i - 1])))
+                               break;
                }
-               for (rval = 1; rval < 16; rval++)
-                       if (__put_user(cregs->u_regs[rval], (&pregs->u_regs[rval - 1]))) {
-                               pt_error_return(regs, EFAULT);
-                               goto out_tsk;
-                       }
-               pt_succ_return(regs, 0);
-               goto out_tsk;
+               if (i == 16)
+                       ret = 0;
+               break;
        }
 
        case PTRACE_GETREGS64: {
                struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
                struct pt_regs *cregs = task_pt_regs(child);
                unsigned long tpc = cregs->tpc;
-               int rval;
 
                if ((task_thread_info(child)->flags & _TIF_32BIT) != 0)
                        tpc &= 0xffffffff;
+
+               ret = -EFAULT;
                if (__put_user(cregs->tstate, (&pregs->tstate)) ||
                    __put_user(tpc, (&pregs->tpc)) ||
                    __put_user(cregs->tnpc, (&pregs->tnpc)) ||
-                   __put_user(cregs->y, (&pregs->y))) {
-                       pt_error_return(regs, EFAULT);
-                       goto out_tsk;
+                   __put_user(cregs->y, (&pregs->y)))
+                       break;
+               for (i = 1; i < 16; i++) {
+                       if (__put_user(cregs->u_regs[i],
+                                      (&pregs->u_regs[i - 1])))
+                               break;
                }
-               for (rval = 1; rval < 16; rval++)
-                       if (__put_user(cregs->u_regs[rval], (&pregs->u_regs[rval - 1]))) {
-                               pt_error_return(regs, EFAULT);
-                               goto out_tsk;
-                       }
-               pt_succ_return(regs, 0);
-               goto out_tsk;
+               if (i == 16)
+                       ret = 0;
+               break;
        }
 
        case PTRACE_SETREGS: {
@@ -906,18 +798,16 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
                        (struct pt_regs32 __user *) addr;
                struct pt_regs *cregs = task_pt_regs(child);
                unsigned int psr, pc, npc, y;
-               int i;
 
                /* Must be careful, tracing process can only set certain
                 * bits in the psr.
                 */
+               ret = -EFAULT;
                if (__get_user(psr, (&pregs->psr)) ||
                    __get_user(pc, (&pregs->pc)) ||
                    __get_user(npc, (&pregs->npc)) ||
-                   __get_user(y, (&pregs->y))) {
-                       pt_error_return(regs, EFAULT);
-                       goto out_tsk;
-               }
+                   __get_user(y, (&pregs->y)))
+                       break;
                cregs->tstate &= ~(TSTATE_ICC);
                cregs->tstate |= psr_to_tstate_icc(psr);
                        if (!((pc | npc) & 3)) {
@@ -926,31 +816,28 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
                }
                cregs->y = y;
                for (i = 1; i < 16; i++) {
-                       if (__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]))) {
-                               pt_error_return(regs, EFAULT);
-                               goto out_tsk;
-                       }
+                       if (__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1])))
+                               break;
                }
-               pt_succ_return(regs, 0);
-               goto out_tsk;
+               if (i == 16)
+                       ret = 0;
+               break;
        }
 
        case PTRACE_SETREGS64: {
                struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
                struct pt_regs *cregs = task_pt_regs(child);
                unsigned long tstate, tpc, tnpc, y;
-               int i;
 
                /* Must be careful, tracing process can only set certain
                 * bits in the psr.
                 */
+               ret = -EFAULT;
                if (__get_user(tstate, (&pregs->tstate)) ||
                    __get_user(tpc, (&pregs->tpc)) ||
                    __get_user(tnpc, (&pregs->tnpc)) ||
-                   __get_user(y, (&pregs->y))) {
-                       pt_error_return(regs, EFAULT);
-                       goto out_tsk;
-               }
+                   __get_user(y, (&pregs->y)))
+                       break;
                if ((task_thread_info(child)->flags & _TIF_32BIT) != 0) {
                        tpc &= 0xffffffff;
                        tnpc &= 0xffffffff;
@@ -964,13 +851,12 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
                }
                cregs->y = y;
                for (i = 1; i < 16; i++) {
-                       if (__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]))) {
-                               pt_error_return(regs, EFAULT);
-                               goto out_tsk;
-                       }
+                       if (__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1])))
+                               break;
                }
-               pt_succ_return(regs, 0);
-               goto out_tsk;
+               if (i == 16)
+                       ret = 0;
+               break;
        }
 
        case PTRACE_GETFPREGS: {
@@ -988,18 +874,18 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
                struct fps __user *fps = (struct fps __user *) addr;
                unsigned long *fpregs = task_thread_info(child)->fpregs;
 
+               ret = -EFAULT;
                if (copy_to_user(&fps->regs[0], fpregs,
                                 (32 * sizeof(unsigned int))) ||
                    __put_user(task_thread_info(child)->xfsr[0], (&fps->fsr)) ||
                    __put_user(0, (&fps->fpqd)) ||
                    __put_user(0, (&fps->flags)) ||
                    __put_user(0, (&fps->extra)) ||
-                   clear_user(&fps->fpq[0], 32 * sizeof(unsigned int))) {
-                       pt_error_return(regs, EFAULT);
-                       goto out_tsk;
-               }
-               pt_succ_return(regs, 0);
-               goto out_tsk;
+                   clear_user(&fps->fpq[0], 32 * sizeof(unsigned int)))
+                       break;
+
+               ret = 0;
+               break;
        }
 
        case PTRACE_GETFPREGS64: {
@@ -1010,14 +896,14 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
                struct fps __user *fps = (struct fps __user *) addr;
                unsigned long *fpregs = task_thread_info(child)->fpregs;
 
+               ret = -EFAULT;
                if (copy_to_user(&fps->regs[0], fpregs,
                                 (64 * sizeof(unsigned int))) ||
-                   __put_user(task_thread_info(child)->xfsr[0], (&fps->fsr))) {
-                       pt_error_return(regs, EFAULT);
-                       goto out_tsk;
-               }
-               pt_succ_return(regs, 0);
-               goto out_tsk;
+                   __put_user(task_thread_info(child)->xfsr[0], (&fps->fsr)))
+                       break;
+
+               ret = 0;
+               break;
        }
 
        case PTRACE_SETFPREGS: {
@@ -1036,19 +922,19 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
                unsigned long *fpregs = task_thread_info(child)->fpregs;
                unsigned fsr;
 
+               ret = -EFAULT;
                if (copy_from_user(fpregs, &fps->regs[0],
                                   (32 * sizeof(unsigned int))) ||
-                   __get_user(fsr, (&fps->fsr))) {
-                       pt_error_return(regs, EFAULT);
-                       goto out_tsk;
-               }
+                   __get_user(fsr, (&fps->fsr)))
+                       break;
+
                task_thread_info(child)->xfsr[0] &= 0xffffffff00000000UL;
                task_thread_info(child)->xfsr[0] |= fsr;
                if (!(task_thread_info(child)->fpsaved[0] & FPRS_FEF))
                        task_thread_info(child)->gsr[0] = 0;
                task_thread_info(child)->fpsaved[0] |= (FPRS_FEF | FPRS_DL);
-               pt_succ_return(regs, 0);
-               goto out_tsk;
+               ret = 0;
+               break;
        }
 
        case PTRACE_SETFPREGS64: {
@@ -1059,113 +945,56 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
                struct fps __user *fps = (struct fps __user *) addr;
                unsigned long *fpregs = task_thread_info(child)->fpregs;
 
+               ret = -EFAULT;
                if (copy_from_user(fpregs, &fps->regs[0],
                                   (64 * sizeof(unsigned int))) ||
-                   __get_user(task_thread_info(child)->xfsr[0], (&fps->fsr))) {
-                       pt_error_return(regs, EFAULT);
-                       goto out_tsk;
-               }
+                   __get_user(task_thread_info(child)->xfsr[0], (&fps->fsr)))
+                       break;
+
                if (!(task_thread_info(child)->fpsaved[0] & FPRS_FEF))
                        task_thread_info(child)->gsr[0] = 0;
-               task_thread_info(child)->fpsaved[0] |= (FPRS_FEF | FPRS_DL | FPRS_DU);
-               pt_succ_return(regs, 0);
-               goto out_tsk;
+               task_thread_info(child)->fpsaved[0] |=
+                       (FPRS_FEF | FPRS_DL | FPRS_DU);
+               ret = 0;
+               break;
        }
 
        case PTRACE_READTEXT:
-       case PTRACE_READDATA: {
-               int res = ptrace_readdata(child, addr,
-                                         (char __user *)addr2, data);
-               if (res == data) {
-                       pt_succ_return(regs, 0);
-                       goto out_tsk;
-               }
-               if (res >= 0)
-                       res = -EIO;
-               pt_error_return(regs, -res);
-               goto out_tsk;
-       }
+       case PTRACE_READDATA:
+               ret = ptrace_readdata(child, addr,
+                                     (char __user *)addr2, data);
+               if (ret == data)
+                       ret = 0;
+               else if (ret >= 0)
+                       ret = -EIO;
+               break;
 
        case PTRACE_WRITETEXT:
-       case PTRACE_WRITEDATA: {
-               int res = ptrace_writedata(child, (char __user *) addr2,
-                                          addr, data);
-               if (res == data) {
-                       pt_succ_return(regs, 0);
-                       goto out_tsk;
-               }
-               if (res >= 0)
-                       res = -EIO;
-               pt_error_return(regs, -res);
-               goto out_tsk;
-       }
-       case PTRACE_SYSCALL: /* continue and stop at (return from) syscall */
-               addr = 1;
-
-       case PTRACE_CONT: { /* restart after signal. */
-               if (!valid_signal(data)) {
-                       pt_error_return(regs, EIO);
-                       goto out_tsk;
-               }
-
-               if (request == PTRACE_SYSCALL) {
-                       set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-               } else {
-                       clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-               }
-
-               child->exit_code = data;
-               wake_up_process(child);
-               pt_succ_return(regs, 0);
-               goto out_tsk;
-       }
-
-/*
- * make the child exit.  Best I can do is send it a sigkill. 
- * perhaps it should be put in the status that it wants to 
- * exit.
- */
-       case PTRACE_KILL: {
-               if (child->exit_state == EXIT_ZOMBIE) { /* already dead */
-                       pt_succ_return(regs, 0);
-                       goto out_tsk;
-               }
-               child->exit_code = SIGKILL;
-               wake_up_process(child);
-               pt_succ_return(regs, 0);
-               goto out_tsk;
-       }
+       case PTRACE_WRITEDATA:
+               ret = ptrace_writedata(child, (char __user *) addr2,
+                                      addr, data);
+               if (ret == data)
+                       ret = 0;
+               else if (ret >= 0)
+                       ret = -EIO;
+               break;
 
        case PTRACE_GETEVENTMSG: {
-               int err;
-
                if (test_thread_flag(TIF_32BIT))
-                       err = put_user(child->ptrace_message,
+                       ret = put_user(child->ptrace_message,
                                       (unsigned int __user *) data);
                else
-                       err = put_user(child->ptrace_message,
+                       ret = put_user(child->ptrace_message,
                                       (unsigned long __user *) data);
-               if (err)
-                       pt_error_return(regs, -err);
-               else
-                       pt_succ_return(regs, 0);
                break;
        }
 
-       default: {
-               int err = ptrace_request(child, request, addr, data);
-               if (err)
-                       pt_error_return(regs, -err);
-               else
-                       pt_succ_return(regs, 0);
-               goto out_tsk;
-       }
+       default:
+               ret = ptrace_request(child, request, addr, data);
+               break;
        }
-out_tsk:
-       if (child)
-               put_task_struct(child);
-out:
-       unlock_kernel();
+
+       return ret;
 }
 
 asmlinkage void syscall_trace(struct pt_regs *regs, int syscall_exit_p)
index a84345b..8201a7b 100644 (file)
@@ -61,8 +61,6 @@ struct sparc_stackf {
 
 #ifdef __KERNEL__
 
-#define __ARCH_SYS_PTRACE      1
-
 #define user_mode(regs) (!((regs)->psr & PSR_PS))
 #define instruction_pointer(regs) ((regs)->pc)
 unsigned long profile_pc(struct pt_regs *);
@@ -162,7 +160,4 @@ extern void show_regs(struct pt_regs *);
 #define PTRACE_GETFPAREGS         20
 #define PTRACE_SETFPAREGS         21
 
-#define PTRACE_GETUCODE           29  /* stupid bsd-ism */
-
-
 #endif /* !(_SPARC_PTRACE_H) */
index 2ba989b..734a767 100644 (file)
@@ -95,8 +95,6 @@ struct sparc_trapf {
 
 #ifdef __KERNEL__
 
-#define __ARCH_SYS_PTRACE      1
-
 #define force_successful_syscall_return()          \
 do {   current_thread_info()->syscall_noerror = 1; \
 } while (0)
@@ -282,18 +280,4 @@ extern void show_regs(struct pt_regs *);
 #define PTRACE_GETFPREGS64       25
 #define PTRACE_SETFPREGS64       26
 
-#define PTRACE_GETUCODE           29  /* stupid bsd-ism */
-
-/* These are for 32-bit processes debugging 64-bit ones.
- * Here addr and addr2 are passed in %g2 and %g3 respectively.
- */
-#define PTRACE_PEEKTEXT64         (30 + PTRACE_PEEKTEXT)
-#define PTRACE_POKETEXT64         (30 + PTRACE_POKETEXT)
-#define PTRACE_PEEKDATA64         (30 + PTRACE_PEEKDATA)
-#define PTRACE_POKEDATA64         (30 + PTRACE_POKEDATA)
-#define PTRACE_READDATA64         (30 + PTRACE_READDATA)
-#define PTRACE_WRITEDATA64        (30 + PTRACE_WRITEDATA)
-#define PTRACE_READTEXT64         (30 + PTRACE_READTEXT)
-#define PTRACE_WRITETEXT64        (30 + PTRACE_WRITETEXT)
-
 #endif /* !(_SPARC64_PTRACE_H) */