[POWERPC] ptrace cleanups
[linux-2.6/kmemtrace.git] / arch / powerpc / kernel / ptrace.c
blobda53b0d4114b57149eef3dbba9c37e5abcf5e54a
1 /*
2 * PowerPC version
3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
5 * Derived from "arch/m68k/kernel/ptrace.c"
6 * Copyright (C) 1994 by Hamish Macdonald
7 * Taken from linux/kernel/ptrace.c and modified for M680x0.
8 * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
10 * Modified by Cort Dougan (cort@hq.fsmlabs.com)
11 * and Paul Mackerras (paulus@samba.org).
13 * This file is subject to the terms and conditions of the GNU General
14 * Public License. See the file README.legal in the main directory of
15 * this archive for more details.
18 #include <linux/kernel.h>
19 #include <linux/sched.h>
20 #include <linux/mm.h>
21 #include <linux/smp.h>
22 #include <linux/errno.h>
23 #include <linux/ptrace.h>
24 #include <linux/user.h>
25 #include <linux/security.h>
26 #include <linux/signal.h>
27 #include <linux/seccomp.h>
28 #include <linux/audit.h>
29 #ifdef CONFIG_PPC32
30 #include <linux/module.h>
31 #endif
33 #include <asm/uaccess.h>
34 #include <asm/page.h>
35 #include <asm/pgtable.h>
36 #include <asm/system.h>
38 #ifdef CONFIG_PPC64
39 #include "ptrace-ppc64.h"
40 #else
41 #include "ptrace-ppc32.h"
42 #endif
44 #include "ptrace-common.h"
47 * does not yet catch signals sent when the child dies.
48 * in exit.c or in signal.c.
52 * Called by kernel/ptrace.c when detaching..
54 * Make sure single step bits etc are not set.
56 void ptrace_disable(struct task_struct *child)
58 /* make sure the single step bit is not set. */
59 clear_single_step(child);
62 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
64 int ret = -EPERM;
66 switch (request) {
67 /* when I and D space are separate, these will need to be fixed. */
68 case PTRACE_PEEKTEXT: /* read word at location addr. */
69 case PTRACE_PEEKDATA: {
70 unsigned long tmp;
71 int copied;
73 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
74 ret = -EIO;
75 if (copied != sizeof(tmp))
76 break;
77 ret = put_user(tmp,(unsigned long __user *) data);
78 break;
81 /* read the word at location addr in the USER area. */
82 case PTRACE_PEEKUSR: {
83 unsigned long index, tmp;
85 ret = -EIO;
86 /* convert to index and check */
87 #ifdef CONFIG_PPC32
88 index = (unsigned long) addr >> 2;
89 if ((addr & 3) || (index > PT_FPSCR)
90 || (child->thread.regs == NULL))
91 #else
92 index = (unsigned long) addr >> 3;
93 if ((addr & 7) || (index > PT_FPSCR))
94 #endif
95 break;
97 #ifdef CONFIG_PPC32
98 CHECK_FULL_REGS(child->thread.regs);
99 #endif
100 if (index < PT_FPR0) {
101 tmp = get_reg(child, (int) index);
102 } else {
103 flush_fp_to_thread(child);
104 tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
106 ret = put_user(tmp,(unsigned long __user *) data);
107 break;
110 /* If I and D space are separate, this will have to be fixed. */
111 case PTRACE_POKETEXT: /* write the word at location addr. */
112 case PTRACE_POKEDATA:
113 ret = 0;
114 if (access_process_vm(child, addr, &data, sizeof(data), 1)
115 == sizeof(data))
116 break;
117 ret = -EIO;
118 break;
120 /* write the word at location addr in the USER area */
121 case PTRACE_POKEUSR: {
122 unsigned long index;
124 ret = -EIO;
125 /* convert to index and check */
126 #ifdef CONFIG_PPC32
127 index = (unsigned long) addr >> 2;
128 if ((addr & 3) || (index > PT_FPSCR)
129 || (child->thread.regs == NULL))
130 #else
131 index = (unsigned long) addr >> 3;
132 if ((addr & 7) || (index > PT_FPSCR))
133 #endif
134 break;
136 #ifdef CONFIG_PPC32
137 CHECK_FULL_REGS(child->thread.regs);
138 #endif
139 if (index == PT_ORIG_R3)
140 break;
141 if (index < PT_FPR0) {
142 ret = put_reg(child, index, data);
143 } else {
144 flush_fp_to_thread(child);
145 ((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
146 ret = 0;
148 break;
151 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
152 case PTRACE_CONT: { /* restart after signal. */
153 ret = -EIO;
154 if (!valid_signal(data))
155 break;
156 if (request == PTRACE_SYSCALL)
157 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
158 else
159 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
160 child->exit_code = data;
161 /* make sure the single step bit is not set. */
162 clear_single_step(child);
163 wake_up_process(child);
164 ret = 0;
165 break;
169 * make the child exit. Best I can do is send it a sigkill.
170 * perhaps it should be put in the status that it wants to
171 * exit.
173 case PTRACE_KILL: {
174 ret = 0;
175 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
176 break;
177 child->exit_code = SIGKILL;
178 /* make sure the single step bit is not set. */
179 clear_single_step(child);
180 wake_up_process(child);
181 break;
184 case PTRACE_SINGLESTEP: { /* set the trap flag. */
185 ret = -EIO;
186 if (!valid_signal(data))
187 break;
188 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
189 set_single_step(child);
190 child->exit_code = data;
191 /* give it a chance to run. */
192 wake_up_process(child);
193 ret = 0;
194 break;
197 #ifdef CONFIG_PPC64
198 case PTRACE_GET_DEBUGREG: {
199 ret = -EINVAL;
200 /* We only support one DABR and no IABRS at the moment */
201 if (addr > 0)
202 break;
203 ret = put_user(child->thread.dabr,
204 (unsigned long __user *)data);
205 break;
208 case PTRACE_SET_DEBUGREG:
209 ret = ptrace_set_debugreg(child, addr, data);
210 break;
211 #endif
213 case PTRACE_DETACH:
214 ret = ptrace_detach(child, data);
215 break;
217 case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
218 int i;
219 unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
220 unsigned long __user *tmp = (unsigned long __user *)addr;
222 for (i = 0; i < 32; i++) {
223 ret = put_user(*reg, tmp);
224 if (ret)
225 break;
226 reg++;
227 tmp++;
229 break;
232 case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
233 int i;
234 unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
235 unsigned long __user *tmp = (unsigned long __user *)addr;
237 for (i = 0; i < 32; i++) {
238 ret = get_user(*reg, tmp);
239 if (ret)
240 break;
241 reg++;
242 tmp++;
244 break;
247 #ifdef CONFIG_PPC64
248 case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
249 int i;
250 unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
251 unsigned long __user *tmp = (unsigned long __user *)addr;
253 flush_fp_to_thread(child);
255 for (i = 0; i < 32; i++) {
256 ret = put_user(*reg, tmp);
257 if (ret)
258 break;
259 reg++;
260 tmp++;
262 break;
265 case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
266 int i;
267 unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
268 unsigned long __user *tmp = (unsigned long __user *)addr;
270 flush_fp_to_thread(child);
272 for (i = 0; i < 32; i++) {
273 ret = get_user(*reg, tmp);
274 if (ret)
275 break;
276 reg++;
277 tmp++;
279 break;
281 #endif /* CONFIG_PPC64 */
283 #ifdef CONFIG_ALTIVEC
284 case PTRACE_GETVRREGS:
285 /* Get the child altivec register state. */
286 flush_altivec_to_thread(child);
287 ret = get_vrregs((unsigned long __user *)data, child);
288 break;
290 case PTRACE_SETVRREGS:
291 /* Set the child altivec register state. */
292 flush_altivec_to_thread(child);
293 ret = set_vrregs(child, (unsigned long __user *)data);
294 break;
295 #endif
296 #ifdef CONFIG_SPE
297 case PTRACE_GETEVRREGS:
298 /* Get the child spe register state. */
299 if (child->thread.regs->msr & MSR_SPE)
300 giveup_spe(child);
301 ret = get_evrregs((unsigned long __user *)data, child);
302 break;
304 case PTRACE_SETEVRREGS:
305 /* Set the child spe register state. */
306 /* this is to clear the MSR_SPE bit to force a reload
307 * of register state from memory */
308 if (child->thread.regs->msr & MSR_SPE)
309 giveup_spe(child);
310 ret = set_evrregs(child, (unsigned long __user *)data);
311 break;
312 #endif
314 default:
315 ret = ptrace_request(child, request, addr, data);
316 break;
319 return ret;
322 static void do_syscall_trace(void)
324 /* the 0x80 provides a way for the tracing parent to distinguish
325 between a syscall stop and SIGTRAP delivery */
326 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
327 ? 0x80 : 0));
330 * this isn't the same as continuing with a signal, but it will do
331 * for normal use. strace only continues with a signal if the
332 * stopping signal is not SIGTRAP. -brl
334 if (current->exit_code) {
335 send_sig(current->exit_code, current, 1);
336 current->exit_code = 0;
340 void do_syscall_trace_enter(struct pt_regs *regs)
342 secure_computing(regs->gpr[0]);
344 if (test_thread_flag(TIF_SYSCALL_TRACE)
345 && (current->ptrace & PT_PTRACED))
346 do_syscall_trace();
348 if (unlikely(current->audit_context)) {
349 #ifdef CONFIG_PPC64
350 if (!test_thread_flag(TIF_32BIT))
351 audit_syscall_entry(AUDIT_ARCH_PPC64,
352 regs->gpr[0],
353 regs->gpr[3], regs->gpr[4],
354 regs->gpr[5], regs->gpr[6]);
355 else
356 #endif
357 audit_syscall_entry(AUDIT_ARCH_PPC,
358 regs->gpr[0],
359 regs->gpr[3] & 0xffffffff,
360 regs->gpr[4] & 0xffffffff,
361 regs->gpr[5] & 0xffffffff,
362 regs->gpr[6] & 0xffffffff);
366 void do_syscall_trace_leave(struct pt_regs *regs)
368 if (unlikely(current->audit_context))
369 audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
370 regs->result);
372 if ((test_thread_flag(TIF_SYSCALL_TRACE)
373 || test_thread_flag(TIF_SINGLESTEP))
374 && (current->ptrace & PT_PTRACED))
375 do_syscall_trace();