Loading arch/sparc64/kernel/ptrace.c +108 −158 Original line number Diff line number Diff line Loading @@ -684,72 +684,39 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task) return &user_sparc64_view; } long arch_ptrace(struct task_struct *child, long request, long addr, long data) struct compat_fps { unsigned int regs[32]; unsigned int fsr; unsigned int flags; unsigned int extra; unsigned int fpqd; struct compat_fq { unsigned int insnaddr; unsigned int insn; } fpq[16]; }; long compat_arch_ptrace(struct task_struct *child, compat_long_t request, compat_ulong_t caddr, compat_ulong_t cdata) { long addr2 = task_pt_regs(current)->u_regs[UREG_I4]; const struct user_regset_view *view; const struct user_regset_view *view = task_user_regset_view(child); compat_ulong_t caddr2 = task_pt_regs(current)->u_regs[UREG_I4]; struct pt_regs32 __user *pregs; struct compat_fps __user *fps; unsigned long addr2 = caddr2; unsigned long addr = caddr; unsigned long data = cdata; int ret; if (test_thread_flag(TIF_32BIT)) addr2 &= 0xffffffffUL; view = task_user_regset_view(child); pregs = (struct pt_regs32 __user *) addr; fps = (struct compat_fps __user *) addr; switch (request) { case PTRACE_PEEKUSR: ret = (addr != 0) ? -EIO : 0; break; case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKDATA: { unsigned long tmp64; unsigned int tmp32; int copied; ret = -EIO; if (test_thread_flag(TIF_32BIT)) { copied = access_process_vm(child, addr, &tmp32, sizeof(tmp32), 0); if (copied == sizeof(tmp32)) ret = put_user(tmp32, (unsigned int __user *) data); } else { copied = access_process_vm(child, addr, &tmp64, sizeof(tmp64), 0); if (copied == sizeof(tmp64)) ret = put_user(tmp64, (unsigned long __user *) data); } break; } case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKEDATA: { unsigned long tmp64; unsigned int tmp32; 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)) ret = 0; } else { tmp64 = data; copied = access_process_vm(child, addr, &tmp64, sizeof(tmp64), 1); if (copied == sizeof(tmp64)) ret = 0; } break; } case PTRACE_GETREGS: { struct pt_regs32 __user *pregs = (struct pt_regs32 __user *) addr; case PTRACE_GETREGS: ret = copy_regset_to_user(child, view, REGSET_GENERAL, 32 * sizeof(u32), 4 * sizeof(u32), Loading @@ -760,29 +727,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) 15 * sizeof(u32), &pregs->u_regs[0]); break; } case PTRACE_GETREGS64: { struct pt_regs __user *pregs = (struct pt_regs __user *) addr; ret = copy_regset_to_user(child, view, REGSET_GENERAL, 1 * sizeof(u64), 15 * sizeof(u64), &pregs->u_regs[0]); if (!ret) { /* XXX doesn't handle 'y' register correctly XXX */ ret = copy_regset_to_user(child, view, REGSET_GENERAL, 32 * sizeof(u64), 4 * sizeof(u64), &pregs->tstate); } break; } case PTRACE_SETREGS: { struct pt_regs32 __user *pregs = (struct pt_regs32 __user *) addr; case PTRACE_SETREGS: ret = copy_regset_from_user(child, view, REGSET_GENERAL, 32 * sizeof(u32), 4 * sizeof(u32), Loading @@ -793,39 +739,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) 15 * sizeof(u32), &pregs->u_regs[0]); break; } case PTRACE_SETREGS64: { struct pt_regs __user *pregs = (struct pt_regs __user *) addr; ret = copy_regset_from_user(child, view, REGSET_GENERAL, 1 * sizeof(u64), 15 * sizeof(u64), &pregs->u_regs[0]); if (!ret) { /* XXX doesn't handle 'y' register correctly XXX */ ret = copy_regset_from_user(child, view, REGSET_GENERAL, 32 * sizeof(u64), 4 * sizeof(u64), &pregs->tstate); } break; } case PTRACE_GETFPREGS: { struct fps { unsigned int regs[32]; unsigned int fsr; unsigned int flags; unsigned int extra; unsigned int fpqd; struct fq { unsigned int insnaddr; unsigned int insn; } fpq[16]; }; struct fps __user *fps = (struct fps __user *) addr; case PTRACE_GETFPREGS: ret = copy_regset_to_user(child, view, REGSET_FP, 0 * sizeof(u32), 32 * sizeof(u32), Loading @@ -843,36 +758,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = -EFAULT; } break; } case PTRACE_GETFPREGS64: { struct fps { unsigned int regs[64]; unsigned long fsr; }; struct fps __user *fps = (struct fps __user *) addr; ret = copy_regset_to_user(child, view, REGSET_FP, 0 * sizeof(u64), 33 * sizeof(u64), fps); break; } case PTRACE_SETFPREGS: { struct fps { unsigned int regs[32]; unsigned int fsr; unsigned int flags; unsigned int extra; unsigned int fpqd; struct fq { unsigned int insnaddr; unsigned int insn; } fpq[16]; }; struct fps __user *fps = (struct fps __user *) addr; case PTRACE_SETFPREGS: ret = copy_regset_from_user(child, view, REGSET_FP, 0 * sizeof(u32), 32 * sizeof(u32), Loading @@ -883,21 +770,94 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) 1 * sizeof(u32), &fps->fsr); break; case PTRACE_READTEXT: 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: ret = ptrace_writedata(child, (char __user *) addr2, addr, data); if (ret == data) ret = 0; else if (ret >= 0) ret = -EIO; break; default: ret = compat_ptrace_request(child, request, addr, data); break; } return ret; } case PTRACE_SETFPREGS64: { struct fps { unsigned int regs[64]; unsigned long fsr; }; long arch_ptrace(struct task_struct *child, long request, long addr, long data) { const struct user_regset_view *view = task_user_regset_view(child); struct pt_regs __user *pregs = (struct pt_regs __user *) addr; unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4]; struct fps __user *fps = (struct fps __user *) addr; int ret; switch (request) { case PTRACE_PEEKUSR: ret = (addr != 0) ? -EIO : 0; break; case PTRACE_GETREGS64: ret = copy_regset_to_user(child, view, REGSET_GENERAL, 1 * sizeof(u64), 15 * sizeof(u64), &pregs->u_regs[0]); if (!ret) { /* XXX doesn't handle 'y' register correctly XXX */ ret = copy_regset_to_user(child, view, REGSET_GENERAL, 32 * sizeof(u64), 4 * sizeof(u64), &pregs->tstate); } break; case PTRACE_SETREGS64: ret = copy_regset_from_user(child, view, REGSET_GENERAL, 1 * sizeof(u64), 15 * sizeof(u64), &pregs->u_regs[0]); if (!ret) { /* XXX doesn't handle 'y' register correctly XXX */ ret = copy_regset_from_user(child, view, REGSET_GENERAL, 32 * sizeof(u64), 4 * sizeof(u64), &pregs->tstate); } break; case PTRACE_GETFPREGS64: ret = copy_regset_to_user(child, view, REGSET_FP, 0 * sizeof(u64), 33 * sizeof(u64), fps); break; case PTRACE_SETFPREGS64: ret = copy_regset_to_user(child, view, REGSET_FP, 0 * sizeof(u64), 33 * sizeof(u64), fps); break; } case PTRACE_READTEXT: case PTRACE_READDATA: Loading @@ -919,16 +879,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = -EIO; break; case PTRACE_GETEVENTMSG: { if (test_thread_flag(TIF_32BIT)) ret = put_user(child->ptrace_message, (unsigned int __user *) data); else ret = put_user(child->ptrace_message, (unsigned long __user *) data); break; } default: ret = ptrace_request(child, request, addr, data); break; Loading arch/sparc64/kernel/systbls.S +1 −1 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ sys_call_table32: /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys32_chown16, sys32_mknod /*15*/ .word sys_chmod, sys32_lchown16, sparc_brk, sys32_perfctr, sys32_lseek /*20*/ .word sys_getpid, sys_capget, sys_capset, sys32_setuid16, sys32_getuid16 /*25*/ .word sys32_vmsplice, sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice .word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile /*40*/ .word compat_sys_newlstat, sys_dup, sys_pipe, compat_sys_times, sys_getuid Loading include/asm-sparc64/ptrace.h +2 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,8 @@ struct sparc_trapf { #ifdef __KERNEL__ #define __ARCH_WANT_COMPAT_SYS_PTRACE #define force_successful_syscall_return() \ do { current_thread_info()->syscall_noerror = 1; \ } while (0) Loading Loading
arch/sparc64/kernel/ptrace.c +108 −158 Original line number Diff line number Diff line Loading @@ -684,72 +684,39 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task) return &user_sparc64_view; } long arch_ptrace(struct task_struct *child, long request, long addr, long data) struct compat_fps { unsigned int regs[32]; unsigned int fsr; unsigned int flags; unsigned int extra; unsigned int fpqd; struct compat_fq { unsigned int insnaddr; unsigned int insn; } fpq[16]; }; long compat_arch_ptrace(struct task_struct *child, compat_long_t request, compat_ulong_t caddr, compat_ulong_t cdata) { long addr2 = task_pt_regs(current)->u_regs[UREG_I4]; const struct user_regset_view *view; const struct user_regset_view *view = task_user_regset_view(child); compat_ulong_t caddr2 = task_pt_regs(current)->u_regs[UREG_I4]; struct pt_regs32 __user *pregs; struct compat_fps __user *fps; unsigned long addr2 = caddr2; unsigned long addr = caddr; unsigned long data = cdata; int ret; if (test_thread_flag(TIF_32BIT)) addr2 &= 0xffffffffUL; view = task_user_regset_view(child); pregs = (struct pt_regs32 __user *) addr; fps = (struct compat_fps __user *) addr; switch (request) { case PTRACE_PEEKUSR: ret = (addr != 0) ? -EIO : 0; break; case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKDATA: { unsigned long tmp64; unsigned int tmp32; int copied; ret = -EIO; if (test_thread_flag(TIF_32BIT)) { copied = access_process_vm(child, addr, &tmp32, sizeof(tmp32), 0); if (copied == sizeof(tmp32)) ret = put_user(tmp32, (unsigned int __user *) data); } else { copied = access_process_vm(child, addr, &tmp64, sizeof(tmp64), 0); if (copied == sizeof(tmp64)) ret = put_user(tmp64, (unsigned long __user *) data); } break; } case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKEDATA: { unsigned long tmp64; unsigned int tmp32; 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)) ret = 0; } else { tmp64 = data; copied = access_process_vm(child, addr, &tmp64, sizeof(tmp64), 1); if (copied == sizeof(tmp64)) ret = 0; } break; } case PTRACE_GETREGS: { struct pt_regs32 __user *pregs = (struct pt_regs32 __user *) addr; case PTRACE_GETREGS: ret = copy_regset_to_user(child, view, REGSET_GENERAL, 32 * sizeof(u32), 4 * sizeof(u32), Loading @@ -760,29 +727,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) 15 * sizeof(u32), &pregs->u_regs[0]); break; } case PTRACE_GETREGS64: { struct pt_regs __user *pregs = (struct pt_regs __user *) addr; ret = copy_regset_to_user(child, view, REGSET_GENERAL, 1 * sizeof(u64), 15 * sizeof(u64), &pregs->u_regs[0]); if (!ret) { /* XXX doesn't handle 'y' register correctly XXX */ ret = copy_regset_to_user(child, view, REGSET_GENERAL, 32 * sizeof(u64), 4 * sizeof(u64), &pregs->tstate); } break; } case PTRACE_SETREGS: { struct pt_regs32 __user *pregs = (struct pt_regs32 __user *) addr; case PTRACE_SETREGS: ret = copy_regset_from_user(child, view, REGSET_GENERAL, 32 * sizeof(u32), 4 * sizeof(u32), Loading @@ -793,39 +739,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) 15 * sizeof(u32), &pregs->u_regs[0]); break; } case PTRACE_SETREGS64: { struct pt_regs __user *pregs = (struct pt_regs __user *) addr; ret = copy_regset_from_user(child, view, REGSET_GENERAL, 1 * sizeof(u64), 15 * sizeof(u64), &pregs->u_regs[0]); if (!ret) { /* XXX doesn't handle 'y' register correctly XXX */ ret = copy_regset_from_user(child, view, REGSET_GENERAL, 32 * sizeof(u64), 4 * sizeof(u64), &pregs->tstate); } break; } case PTRACE_GETFPREGS: { struct fps { unsigned int regs[32]; unsigned int fsr; unsigned int flags; unsigned int extra; unsigned int fpqd; struct fq { unsigned int insnaddr; unsigned int insn; } fpq[16]; }; struct fps __user *fps = (struct fps __user *) addr; case PTRACE_GETFPREGS: ret = copy_regset_to_user(child, view, REGSET_FP, 0 * sizeof(u32), 32 * sizeof(u32), Loading @@ -843,36 +758,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = -EFAULT; } break; } case PTRACE_GETFPREGS64: { struct fps { unsigned int regs[64]; unsigned long fsr; }; struct fps __user *fps = (struct fps __user *) addr; ret = copy_regset_to_user(child, view, REGSET_FP, 0 * sizeof(u64), 33 * sizeof(u64), fps); break; } case PTRACE_SETFPREGS: { struct fps { unsigned int regs[32]; unsigned int fsr; unsigned int flags; unsigned int extra; unsigned int fpqd; struct fq { unsigned int insnaddr; unsigned int insn; } fpq[16]; }; struct fps __user *fps = (struct fps __user *) addr; case PTRACE_SETFPREGS: ret = copy_regset_from_user(child, view, REGSET_FP, 0 * sizeof(u32), 32 * sizeof(u32), Loading @@ -883,21 +770,94 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) 1 * sizeof(u32), &fps->fsr); break; case PTRACE_READTEXT: 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: ret = ptrace_writedata(child, (char __user *) addr2, addr, data); if (ret == data) ret = 0; else if (ret >= 0) ret = -EIO; break; default: ret = compat_ptrace_request(child, request, addr, data); break; } return ret; } case PTRACE_SETFPREGS64: { struct fps { unsigned int regs[64]; unsigned long fsr; }; long arch_ptrace(struct task_struct *child, long request, long addr, long data) { const struct user_regset_view *view = task_user_regset_view(child); struct pt_regs __user *pregs = (struct pt_regs __user *) addr; unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4]; struct fps __user *fps = (struct fps __user *) addr; int ret; switch (request) { case PTRACE_PEEKUSR: ret = (addr != 0) ? -EIO : 0; break; case PTRACE_GETREGS64: ret = copy_regset_to_user(child, view, REGSET_GENERAL, 1 * sizeof(u64), 15 * sizeof(u64), &pregs->u_regs[0]); if (!ret) { /* XXX doesn't handle 'y' register correctly XXX */ ret = copy_regset_to_user(child, view, REGSET_GENERAL, 32 * sizeof(u64), 4 * sizeof(u64), &pregs->tstate); } break; case PTRACE_SETREGS64: ret = copy_regset_from_user(child, view, REGSET_GENERAL, 1 * sizeof(u64), 15 * sizeof(u64), &pregs->u_regs[0]); if (!ret) { /* XXX doesn't handle 'y' register correctly XXX */ ret = copy_regset_from_user(child, view, REGSET_GENERAL, 32 * sizeof(u64), 4 * sizeof(u64), &pregs->tstate); } break; case PTRACE_GETFPREGS64: ret = copy_regset_to_user(child, view, REGSET_FP, 0 * sizeof(u64), 33 * sizeof(u64), fps); break; case PTRACE_SETFPREGS64: ret = copy_regset_to_user(child, view, REGSET_FP, 0 * sizeof(u64), 33 * sizeof(u64), fps); break; } case PTRACE_READTEXT: case PTRACE_READDATA: Loading @@ -919,16 +879,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = -EIO; break; case PTRACE_GETEVENTMSG: { if (test_thread_flag(TIF_32BIT)) ret = put_user(child->ptrace_message, (unsigned int __user *) data); else ret = put_user(child->ptrace_message, (unsigned long __user *) data); break; } default: ret = ptrace_request(child, request, addr, data); break; Loading
arch/sparc64/kernel/systbls.S +1 −1 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ sys_call_table32: /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys32_chown16, sys32_mknod /*15*/ .word sys_chmod, sys32_lchown16, sparc_brk, sys32_perfctr, sys32_lseek /*20*/ .word sys_getpid, sys_capget, sys_capset, sys32_setuid16, sys32_getuid16 /*25*/ .word sys32_vmsplice, sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice .word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile /*40*/ .word compat_sys_newlstat, sys_dup, sys_pipe, compat_sys_times, sys_getuid Loading
include/asm-sparc64/ptrace.h +2 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,8 @@ struct sparc_trapf { #ifdef __KERNEL__ #define __ARCH_WANT_COMPAT_SYS_PTRACE #define force_successful_syscall_return() \ do { current_thread_info()->syscall_noerror = 1; \ } while (0) Loading