aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/ptrace.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-06-04 01:15:46 -0400
committerPaul Mackerras <paulus@samba.org>2007-06-14 08:29:57 -0400
commit912000e73ee8fcb97831b123c9c3a7274b71cab7 (patch)
treea81fcda0f11cbb4c428ffae9f9f55f12677051fe /arch/powerpc/kernel/ptrace.c
parent1b6610d6fcb8dc23631cf48f09aa02e6649e379d (diff)
[POWERPC] Allow ptrace write to pt_regs trap and orig_r3
This patch allows a ptracer to write to the "trap" and "orig_r3" words of the pt_regs. This, along with a subsequent patch to the signal restart code, should enable gdb to properly handle syscall restarting after executing a separate function (at least when there's no restart block). This patch also removes ptrace32.c code toying directly with the registers and makes it use the ptrace_get/put_reg() accessors for everything so that the logic for checking what is permitted is in only one place. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/ptrace.c')
-rw-r--r--arch/powerpc/kernel/ptrace.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index c9c330d35c17..dd4837c4a68a 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -75,10 +75,15 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data)
75 if (task->thread.regs == NULL) 75 if (task->thread.regs == NULL)
76 return -EIO; 76 return -EIO;
77 77
78 if (regno <= PT_MAX_PUT_REG) { 78 if (regno <= PT_MAX_PUT_REG || regno == PT_TRAP) {
79 if (regno == PT_MSR) 79 if (regno == PT_MSR)
80 data = (data & MSR_DEBUGCHANGE) 80 data = (data & MSR_DEBUGCHANGE)
81 | (task->thread.regs->msr & ~MSR_DEBUGCHANGE); 81 | (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
82 /* We prevent mucking around with the reserved area of trap
83 * which are used internally by the kernel
84 */
85 if (regno == PT_TRAP)
86 data &= 0xfff0;
82 ((unsigned long *)task->thread.regs)[regno] = data; 87 ((unsigned long *)task->thread.regs)[regno] = data;
83 return 0; 88 return 0;
84 } 89 }
@@ -409,8 +414,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
409 break; 414 break;
410 415
411 CHECK_FULL_REGS(child->thread.regs); 416 CHECK_FULL_REGS(child->thread.regs);
412 if (index == PT_ORIG_R3)
413 break;
414 if (index < PT_FPR0) { 417 if (index < PT_FPR0) {
415 ret = ptrace_put_reg(child, index, data); 418 ret = ptrace_put_reg(child, index, data);
416 } else { 419 } else {