1/*
2 * ptrace for 32-bit processes running on a 64-bit kernel.
3 *
4 *  PowerPC version
5 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 *
7 *  Derived from "arch/m68k/kernel/ptrace.c"
8 *  Copyright (C) 1994 by Hamish Macdonald
9 *  Taken from linux/kernel/ptrace.c and modified for M680x0.
10 *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
11 *
12 * Modified by Cort Dougan (cort@hq.fsmlabs.com)
13 * and Paul Mackerras (paulus@samba.org).
14 *
15 * This file is subject to the terms and conditions of the GNU General
16 * Public License.  See the file COPYING in the main directory of
17 * this archive for more details.
18 */
19
20#include <linux/kernel.h>
21#include <linux/sched.h>
22#include <linux/mm.h>
23#include <linux/smp.h>
24#include <linux/smp_lock.h>
25#include <linux/errno.h>
26#include <linux/ptrace.h>
27#include <linux/user.h>
28#include <linux/security.h>
29#include <linux/signal.h>
30
31#include <asm/uaccess.h>
32#include <asm/page.h>
33#include <asm/pgtable.h>
34#include <asm/system.h>
35
36#include "ptrace-common.h"
37
38/*
39 * does not yet catch signals sent when the child dies.
40 * in exit.c or in signal.c.
41 */
42
43long compat_sys_ptrace(int request, int pid, unsigned long addr,
44		       unsigned long data)
45{
46	struct task_struct *child;
47	int ret;
48
49	lock_kernel();
50	if (request == PTRACE_TRACEME) {
51		ret = ptrace_traceme();
52		goto out;
53	}
54
55	child = ptrace_get_task_struct(pid);
56	if (IS_ERR(child)) {
57		ret = PTR_ERR(child);
58		goto out;
59	}
60
61	if (request == PTRACE_ATTACH) {
62		ret = ptrace_attach(child);
63		goto out_tsk;
64	}
65
66	ret = ptrace_check_attach(child, request == PTRACE_KILL);
67	if (ret < 0)
68		goto out_tsk;
69
70	switch (request) {
71	/* when I and D space are separate, these will need to be fixed. */
72	case PTRACE_PEEKTEXT: /* read word at location addr. */
73	case PTRACE_PEEKDATA: {
74		unsigned int tmp;
75		int copied;
76
77		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
78		ret = -EIO;
79		if (copied != sizeof(tmp))
80			break;
81		ret = put_user(tmp, (u32 __user *)data);
82		break;
83	}
84
85	/*
86	 * Read 4 bytes of the other process' storage
87	 *  data is a pointer specifying where the user wants the
88	 *	4 bytes copied into
89	 *  addr is a pointer in the user's storage that contains an 8 byte
90	 *	address in the other process of the 4 bytes that is to be read
91	 * (this is run in a 32-bit process looking at a 64-bit process)
92	 * when I and D space are separate, these will need to be fixed.
93	 */
94	case PPC_PTRACE_PEEKTEXT_3264:
95	case PPC_PTRACE_PEEKDATA_3264: {
96		u32 tmp;
97		int copied;
98		u32 __user * addrOthers;
99
100		ret = -EIO;
101
102		/* Get the addr in the other process that we want to read */
103		if (get_user(addrOthers, (u32 __user * __user *)addr) != 0)
104			break;
105
106		copied = access_process_vm(child, (u64)addrOthers, &tmp,
107				sizeof(tmp), 0);
108		if (copied != sizeof(tmp))
109			break;
110		ret = put_user(tmp, (u32 __user *)data);
111		break;
112	}
113
114	/* Read a register (specified by ADDR) out of the "user area" */
115	case PTRACE_PEEKUSR: {
116		int index;
117		unsigned long tmp;
118
119		ret = -EIO;
120		/* convert to index and check */
121		index = (unsigned long) addr >> 2;
122		if ((addr & 3) || (index > PT_FPSCR32))
123			break;
124
125		if (index < PT_FPR0) {
126			tmp = get_reg(child, index);
127		} else {
128			flush_fp_to_thread(child);
129			/*
130			 * the user space code considers the floating point
131			 * to be an array of unsigned int (32 bits) - the
132			 * index passed in is based on this assumption.
133			 */
134			tmp = ((unsigned int *)child->thread.fpr)[index - PT_FPR0];
135		}
136		ret = put_user((unsigned int)tmp, (u32 __user *)data);
137		break;
138	}
139
140	/*
141	 * Read 4 bytes out of the other process' pt_regs area
142	 *  data is a pointer specifying where the user wants the
143	 *	4 bytes copied into
144	 *  addr is the offset into the other process' pt_regs structure
145	 *	that is to be read
146	 * (this is run in a 32-bit process looking at a 64-bit process)
147	 */
148	case PPC_PTRACE_PEEKUSR_3264: {
149		u32 index;
150		u32 reg32bits;
151		u64 tmp;
152		u32 numReg;
153		u32 part;
154
155		ret = -EIO;
156		/* Determine which register the user wants */
157		index = (u64)addr >> 2;
158		numReg = index / 2;
159		/* Determine which part of the register the user wants */
160		if (index % 2)
161			part = 1;  /* want the 2nd half of the register (right-most). */
162		else
163			part = 0;  /* want the 1st half of the register (left-most). */
164
165		/* Validate the input - check to see if address is on the wrong boundary or beyond the end of the user area */
166		if ((addr & 3) || numReg > PT_FPSCR)
167			break;
168
169		if (numReg >= PT_FPR0) {
170			flush_fp_to_thread(child);
171			tmp = ((unsigned long int *)child->thread.fpr)[numReg - PT_FPR0];
172		} else { /* register within PT_REGS struct */
173			tmp = get_reg(child, numReg);
174		}
175		reg32bits = ((u32*)&tmp)[part];
176		ret = put_user(reg32bits, (u32 __user *)data);
177		break;
178	}
179
180	/* If I and D space are separate, this will have to be fixed. */
181	case PTRACE_POKETEXT: /* write the word at location addr. */
182	case PTRACE_POKEDATA: {
183		unsigned int tmp;
184		tmp = data;
185		ret = 0;
186		if (access_process_vm(child, addr, &tmp, sizeof(tmp), 1)
187				== sizeof(tmp))
188			break;
189		ret = -EIO;
190		break;
191	}
192
193	/*
194	 * Write 4 bytes into the other process' storage
195	 *  data is the 4 bytes that the user wants written
196	 *  addr is a pointer in the user's storage that contains an
197	 *	8 byte address in the other process where the 4 bytes
198	 *	that is to be written
199	 * (this is run in a 32-bit process looking at a 64-bit process)
200	 * when I and D space are separate, these will need to be fixed.
201	 */
202	case PPC_PTRACE_POKETEXT_3264:
203	case PPC_PTRACE_POKEDATA_3264: {
204		u32 tmp = data;
205		u32 __user * addrOthers;
206
207		/* Get the addr in the other process that we want to write into */
208		ret = -EIO;
209		if (get_user(addrOthers, (u32 __user * __user *)addr) != 0)
210			break;
211		ret = 0;
212		if (access_process_vm(child, (u64)addrOthers, &tmp,
213					sizeof(tmp), 1) == sizeof(tmp))
214			break;
215		ret = -EIO;
216		break;
217	}
218
219	/* write the word at location addr in the USER area */
220	case PTRACE_POKEUSR: {
221		unsigned long index;
222
223		ret = -EIO;
224		/* convert to index and check */
225		index = (unsigned long) addr >> 2;
226		if ((addr & 3) || (index > PT_FPSCR32))
227			break;
228
229		if (index == PT_ORIG_R3)
230			break;
231		if (index < PT_FPR0) {
232			ret = put_reg(child, index, data);
233		} else {
234			flush_fp_to_thread(child);
235			/*
236			 * the user space code considers the floating point
237			 * to be an array of unsigned int (32 bits) - the
238			 * index passed in is based on this assumption.
239			 */
240			((unsigned int *)child->thread.fpr)[index - PT_FPR0] = data;
241			ret = 0;
242		}
243		break;
244	}
245
246	/*
247	 * Write 4 bytes into the other process' pt_regs area
248	 *  data is the 4 bytes that the user wants written
249	 *  addr is the offset into the other process' pt_regs structure
250	 *	that is to be written into
251	 * (this is run in a 32-bit process looking at a 64-bit process)
252	 */
253	case PPC_PTRACE_POKEUSR_3264: {
254		u32 index;
255		u32 numReg;
256
257		ret = -EIO;
258		/* Determine which register the user wants */
259		index = (u64)addr >> 2;
260		numReg = index / 2;
261		/*
262		 * Validate the input - check to see if address is on the
263		 * wrong boundary or beyond the end of the user area
264		 */
265		if ((addr & 3) || (numReg > PT_FPSCR))
266			break;
267		/* Insure it is a register we let them change */
268		if ((numReg == PT_ORIG_R3)
269				|| ((numReg > PT_CCR) && (numReg < PT_FPR0)))
270			break;
271		if (numReg >= PT_FPR0) {
272			flush_fp_to_thread(child);
273		}
274		if (numReg == PT_MSR)
275			data = (data & MSR_DEBUGCHANGE)
276				| (child->thread.regs->msr & ~MSR_DEBUGCHANGE);
277		((u32*)child->thread.regs)[index] = data;
278		ret = 0;
279		break;
280	}
281
282	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
283	case PTRACE_CONT: { /* restart after signal. */
284		ret = -EIO;
285		if (!valid_signal(data))
286			break;
287		if (request == PTRACE_SYSCALL)
288			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
289		else
290			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
291		child->exit_code = data;
292		/* make sure the single step bit is not set. */
293		clear_single_step(child);
294		wake_up_process(child);
295		ret = 0;
296		break;
297	}
298
299	/*
300	 * make the child exit.  Best I can do is send it a sigkill.
301	 * perhaps it should be put in the status that it wants to
302	 * exit.
303	 */
304	case PTRACE_KILL: {
305		ret = 0;
306		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
307			break;
308		child->exit_code = SIGKILL;
309		/* make sure the single step bit is not set. */
310		clear_single_step(child);
311		wake_up_process(child);
312		break;
313	}
314
315	case PTRACE_SINGLESTEP: {  /* set the trap flag. */
316		ret = -EIO;
317		if (!valid_signal(data))
318			break;
319		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
320		set_single_step(child);
321		child->exit_code = data;
322		/* give it a chance to run. */
323		wake_up_process(child);
324		ret = 0;
325		break;
326	}
327
328	case PTRACE_GET_DEBUGREG: {
329		ret = -EINVAL;
330		/* We only support one DABR and no IABRS at the moment */
331		if (addr > 0)
332			break;
333		ret = put_user(child->thread.dabr, (u32 __user *)data);
334		break;
335	}
336
337	case PTRACE_SET_DEBUGREG:
338		ret = ptrace_set_debugreg(child, addr, data);
339		break;
340
341	case PTRACE_DETACH:
342		ret = ptrace_detach(child, data);
343		break;
344
345	case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
346		int i;
347		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
348		unsigned int __user *tmp = (unsigned int __user *)addr;
349
350		for (i = 0; i < 32; i++) {
351			ret = put_user(*reg, tmp);
352			if (ret)
353				break;
354			reg++;
355			tmp++;
356		}
357		break;
358	}
359
360	case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
361		int i;
362		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
363		unsigned int __user *tmp = (unsigned int __user *)addr;
364
365		for (i = 0; i < 32; i++) {
366			ret = get_user(*reg, tmp);
367			if (ret)
368				break;
369			reg++;
370			tmp++;
371		}
372		break;
373	}
374
375	case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
376		int i;
377		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
378		unsigned int __user *tmp = (unsigned int __user *)addr;
379
380		flush_fp_to_thread(child);
381
382		for (i = 0; i < 32; i++) {
383			ret = put_user(*reg, tmp);
384			if (ret)
385				break;
386			reg++;
387			tmp++;
388		}
389		break;
390	}
391
392	case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
393		int i;
394		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
395		unsigned int __user *tmp = (unsigned int __user *)addr;
396
397		flush_fp_to_thread(child);
398
399		for (i = 0; i < 32; i++) {
400			ret = get_user(*reg, tmp);
401			if (ret)
402				break;
403			reg++;
404			tmp++;
405		}
406		break;
407	}
408
409	case PTRACE_GETEVENTMSG:
410		ret = put_user(child->ptrace_message, (unsigned int __user *) data);
411		break;
412
413#ifdef CONFIG_ALTIVEC
414	case PTRACE_GETVRREGS:
415		/* Get the child altivec register state. */
416		flush_altivec_to_thread(child);
417		ret = get_vrregs((unsigned long __user *)data, child);
418		break;
419
420	case PTRACE_SETVRREGS:
421		/* Set the child altivec register state. */
422		flush_altivec_to_thread(child);
423		ret = set_vrregs(child, (unsigned long __user *)data);
424		break;
425#endif
426
427	default:
428		ret = ptrace_request(child, request, addr, data);
429		break;
430	}
431out_tsk:
432	put_task_struct(child);
433out:
434	unlock_kernel();
435	return ret;
436}
437