aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2007-12-20 06:59:04 -0500
committerPaul Mackerras <paulus@samba.org>2008-02-07 04:40:21 -0500
commit0deef2c7ab9dcf82f6ad26fc2fca358cd56c9cb9 (patch)
tree00e0b016d28ec2f4d717196fb43b0f70fcce5a69 /arch
parent81e695c026eeda9a97e412fa4f458e5cab2f6c85 (diff)
[POWERPC] Use regset code for compat PTRACE_*REGS* calls
This cleans up the 32-bit ptrace syscall support to use user_regset calls to get at the register data for PTRACE_*REGS* calls. Signed-off-by: Roland McGrath <roland@redhat.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/ptrace32.c96
1 files changed, 25 insertions, 71 deletions
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index 0f6eea086a23..4c1de6af4c09 100644
--- a/arch/powerpc/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -24,6 +24,7 @@
24#include <linux/smp_lock.h> 24#include <linux/smp_lock.h>
25#include <linux/errno.h> 25#include <linux/errno.h>
26#include <linux/ptrace.h> 26#include <linux/ptrace.h>
27#include <linux/regset.h>
27#include <linux/user.h> 28#include <linux/user.h>
28#include <linux/security.h> 29#include <linux/security.h>
29#include <linux/signal.h> 30#include <linux/signal.h>
@@ -46,43 +47,21 @@
46static long compat_ptrace_old(struct task_struct *child, long request, 47static long compat_ptrace_old(struct task_struct *child, long request,
47 long addr, long data) 48 long addr, long data)
48{ 49{
49 int ret = -EPERM; 50 switch (request) {
50 51 case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
51 switch(request) { 52 return copy_regset_to_user(child,
52 case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */ 53 task_user_regset_view(current), 0,
53 int i; 54 0, 32 * sizeof(compat_long_t),
54 unsigned long *reg = &((unsigned long *)child->thread.regs)[0]; 55 compat_ptr(data));
55 unsigned int __user *tmp = (unsigned int __user *)addr; 56
56 57 case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
57 CHECK_FULL_REGS(child->thread.regs); 58 return copy_regset_from_user(child,
58 for (i = 0; i < 32; i++) { 59 task_user_regset_view(current), 0,
59 ret = put_user(*reg, tmp); 60 0, 32 * sizeof(compat_long_t),
60 if (ret) 61 compat_ptr(data));
61 break;
62 reg++;
63 tmp++;
64 }
65 break;
66 }
67
68 case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
69 int i;
70 unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
71 unsigned int __user *tmp = (unsigned int __user *)addr;
72
73 CHECK_FULL_REGS(child->thread.regs);
74 for (i = 0; i < 32; i++) {
75 ret = get_user(*reg, tmp);
76 if (ret)
77 break;
78 reg++;
79 tmp++;
80 }
81 break;
82 } 62 }
83 63
84 } 64 return -EPERM;
85 return ret;
86} 65}
87 66
88long compat_arch_ptrace(struct task_struct *child, compat_long_t request, 67long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
@@ -291,42 +270,17 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
291 break; 270 break;
292 } 271 }
293 272
294 case PTRACE_GETREGS: { /* Get all pt_regs from the child. */ 273 case PTRACE_GETREGS: /* Get all pt_regs from the child. */
295 int ui; 274 return copy_regset_to_user(
296 if (!access_ok(VERIFY_WRITE, (void __user *)data, 275 child, task_user_regset_view(current), 0,
297 PT_REGS_COUNT * sizeof(int))) { 276 0, PT_REGS_COUNT * sizeof(compat_long_t),
298 ret = -EIO; 277 compat_ptr(data));
299 break; 278
300 } 279 case PTRACE_SETREGS: /* Set all gp regs in the child. */
301 CHECK_FULL_REGS(child->thread.regs); 280 return copy_regset_from_user(
302 ret = 0; 281 child, task_user_regset_view(current), 0,
303 for (ui = 0; ui < PT_REGS_COUNT; ui ++) { 282 0, PT_REGS_COUNT * sizeof(compat_long_t),
304 ret |= __put_user(ptrace_get_reg(child, ui), 283 compat_ptr(data));
305 (unsigned int __user *) data);
306 data += sizeof(int);
307 }
308 break;
309 }
310
311 case PTRACE_SETREGS: { /* Set all gp regs in the child. */
312 unsigned long tmp;
313 int ui;
314 if (!access_ok(VERIFY_READ, (void __user *)data,
315 PT_REGS_COUNT * sizeof(int))) {
316 ret = -EIO;
317 break;
318 }
319 CHECK_FULL_REGS(child->thread.regs);
320 ret = 0;
321 for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
322 ret = __get_user(tmp, (unsigned int __user *) data);
323 if (ret)
324 break;
325 ptrace_put_reg(child, ui, tmp);
326 data += sizeof(int);
327 }
328 break;
329 }
330 284
331 case PTRACE_GETFPREGS: 285 case PTRACE_GETFPREGS:
332 case PTRACE_SETFPREGS: 286 case PTRACE_SETFPREGS: