1/*
2 * Kernel support for the ptrace() and syscall tracing interfaces.
3 *
4 * Copyright (C) 2000 Hewlett-Packard Co, Linuxcare Inc.
5 * Copyright (C) 2000 Matthew Wilcox <matthew@wil.cx>
6 * Copyright (C) 2000 David Huggins-Daines <dhd@debian.org>
7 */
8
9#include <linux/kernel.h>
10#include <linux/sched.h>
11#include <linux/mm.h>
12#include <linux/smp.h>
13#include <linux/errno.h>
14#include <linux/ptrace.h>
15#include <linux/user.h>
16#include <linux/personality.h>
17#include <linux/security.h>
18#include <linux/compat.h>
19#include <linux/signal.h>
20
21#include <asm/uaccess.h>
22#include <asm/pgtable.h>
23#include <asm/system.h>
24#include <asm/processor.h>
25#include <asm/asm-offsets.h>
26
27/* PSW bits we allow the debugger to modify */
28#define USER_PSW_BITS	(PSW_N | PSW_V | PSW_CB)
29
30#undef DEBUG_PTRACE
31
32#ifdef DEBUG_PTRACE
33#define DBG(x...)	printk(x)
34#else
35#define DBG(x...)
36#endif
37
38#ifdef CONFIG_64BIT
39
40/* This function is needed to translate 32 bit pt_regs offsets in to
41 * 64 bit pt_regs offsets.  For example, a 32 bit gdb under a 64 bit kernel
42 * will request offset 12 if it wants gr3, but the lower 32 bits of
43 * the 64 bit kernels view of gr3 will be at offset 28 (3*8 + 4).
44 * This code relies on a 32 bit pt_regs being comprised of 32 bit values
45 * except for the fp registers which (a) are 64 bits, and (b) follow
46 * the gr registers at the start of pt_regs.  The 32 bit pt_regs should
47 * be half the size of the 64 bit pt_regs, plus 32*4 to allow for fr[]
48 * being 64 bit in both cases.
49 */
50
51static long translate_usr_offset(long offset)
52{
53	if (offset < 0)
54		return -1;
55	else if (offset <= 32*4)	/* gr[0..31] */
56		return offset * 2 + 4;
57	else if (offset <= 32*4+32*8)	/* gr[0..31] + fr[0..31] */
58		return offset + 32*4;
59	else if (offset < sizeof(struct pt_regs)/2 + 32*4)
60		return offset * 2 + 4 - 32*8;
61	else
62		return -1;
63}
64#endif
65
66/*
67 * Called by kernel/ptrace.c when detaching..
68 *
69 * Make sure single step bits etc are not set.
70 */
71void ptrace_disable(struct task_struct *child)
72{
73	/* make sure the trap bits are not set */
74	pa_psw(child)->r = 0;
75	pa_psw(child)->t = 0;
76	pa_psw(child)->h = 0;
77	pa_psw(child)->l = 0;
78}
79
80long arch_ptrace(struct task_struct *child, long request, long addr, long data)
81{
82	long ret;
83#ifdef DEBUG_PTRACE
84	long oaddr=addr, odata=data;
85#endif
86
87	switch (request) {
88	case PTRACE_PEEKTEXT: /* read word at location addr. */
89	case PTRACE_PEEKDATA: {
90		int copied;
91
92#ifdef CONFIG_64BIT
93		if (__is_compat_task(child)) {
94			unsigned int tmp;
95
96			addr &= 0xffffffffL;
97			copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
98			ret = -EIO;
99			if (copied != sizeof(tmp))
100				goto out_tsk;
101			ret = put_user(tmp,(unsigned int *) data);
102			DBG("sys_ptrace(PEEK%s, %d, %lx, %lx) returning %ld, data %x\n",
103				request == PTRACE_PEEKTEXT ? "TEXT" : "DATA",
104				pid, oaddr, odata, ret, tmp);
105		}
106		else
107#endif
108		{
109			unsigned long tmp;
110
111			copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
112			ret = -EIO;
113			if (copied != sizeof(tmp))
114				goto out_tsk;
115			ret = put_user(tmp,(unsigned long *) data);
116		}
117		goto out_tsk;
118	}
119
120	/* when I and D space are separate, this will have to be fixed. */
121	case PTRACE_POKETEXT: /* write the word at location addr. */
122	case PTRACE_POKEDATA:
123		ret = 0;
124#ifdef CONFIG_64BIT
125		if (__is_compat_task(child)) {
126			unsigned int tmp = (unsigned int)data;
127			DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
128				request == PTRACE_POKETEXT ? "TEXT" : "DATA",
129				pid, oaddr, odata);
130			addr &= 0xffffffffL;
131			if (access_process_vm(child, addr, &tmp, sizeof(tmp), 1) == sizeof(tmp))
132				goto out_tsk;
133		}
134		else
135#endif
136		{
137			if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
138				goto out_tsk;
139		}
140		ret = -EIO;
141		goto out_tsk;
142
143	/* Read the word at location addr in the USER area.  For ptraced
144	   processes, the kernel saves all regs on a syscall. */
145	case PTRACE_PEEKUSR: {
146		ret = -EIO;
147#ifdef CONFIG_64BIT
148		if (__is_compat_task(child)) {
149			unsigned int tmp;
150
151			if (addr & (sizeof(int)-1))
152				goto out_tsk;
153			if ((addr = translate_usr_offset(addr)) < 0)
154				goto out_tsk;
155
156			tmp = *(unsigned int *) ((char *) task_regs(child) + addr);
157			ret = put_user(tmp, (unsigned int *) data);
158			DBG("sys_ptrace(PEEKUSR, %d, %lx, %lx) returning %ld, addr %lx, data %x\n",
159				pid, oaddr, odata, ret, addr, tmp);
160		}
161		else
162#endif
163		{
164			unsigned long tmp;
165
166			if ((addr & (sizeof(long)-1)) || (unsigned long) addr >= sizeof(struct pt_regs))
167				goto out_tsk;
168			tmp = *(unsigned long *) ((char *) task_regs(child) + addr);
169			ret = put_user(tmp, (unsigned long *) data);
170		}
171		goto out_tsk;
172	}
173
174	case PTRACE_POKEUSR:
175		ret = -EIO;
176		/* Some register values written here may be ignored in
177		 * entry.S:syscall_restore_rfi; e.g. iaoq is written with
178		 * r31/r31+4, and not with the values in pt_regs.
179		 */
180		 /* PT_PSW=0, so this is valid for 32 bit processes under 64
181		 * bit kernels.
182		 */
183		if (addr == PT_PSW) {
184			/* PT_PSW=0, so this is valid for 32 bit processes
185			 * under 64 bit kernels.
186			 *
187			 * Allow writing to Nullify, Divide-step-correction,
188			 * and carry/borrow bits.
189			 * BEWARE, if you set N, and then single step, it won't
190			 * stop on the nullified instruction.
191			 */
192			DBG("sys_ptrace(POKEUSR, %d, %lx, %lx)\n",
193				pid, oaddr, odata);
194			data &= USER_PSW_BITS;
195			task_regs(child)->gr[0] &= ~USER_PSW_BITS;
196			task_regs(child)->gr[0] |= data;
197			ret = 0;
198			goto out_tsk;
199		}
200#ifdef CONFIG_64BIT
201		if (__is_compat_task(child)) {
202			if (addr & (sizeof(int)-1))
203				goto out_tsk;
204			if ((addr = translate_usr_offset(addr)) < 0)
205				goto out_tsk;
206			DBG("sys_ptrace(POKEUSR, %d, %lx, %lx) addr %lx\n",
207				pid, oaddr, odata, addr);
208			if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
209				/* Special case, fp regs are 64 bits anyway */
210				*(unsigned int *) ((char *) task_regs(child) + addr) = data;
211				ret = 0;
212			}
213			else if ((addr >= PT_GR1+4 && addr <= PT_GR31+4) ||
214					addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4 ||
215					addr == PT_SAR+4) {
216				/* Zero the top 32 bits */
217				*(unsigned int *) ((char *) task_regs(child) + addr - 4) = 0;
218				*(unsigned int *) ((char *) task_regs(child) + addr) = data;
219				ret = 0;
220			}
221			goto out_tsk;
222		}
223		else
224#endif
225		{
226			if ((addr & (sizeof(long)-1)) || (unsigned long) addr >= sizeof(struct pt_regs))
227				goto out_tsk;
228			if ((addr >= PT_GR1 && addr <= PT_GR31) ||
229					addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
230					(addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
231					addr == PT_SAR) {
232				*(unsigned long *) ((char *) task_regs(child) + addr) = data;
233				ret = 0;
234			}
235			goto out_tsk;
236		}
237
238	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
239	case PTRACE_CONT:
240		ret = -EIO;
241		DBG("sys_ptrace(%s)\n",
242			request == PTRACE_SYSCALL ? "SYSCALL" : "CONT");
243		if (!valid_signal(data))
244			goto out_tsk;
245		child->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP);
246		if (request == PTRACE_SYSCALL) {
247			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
248		} else {
249			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
250		}
251		child->exit_code = data;
252		goto out_wake_notrap;
253
254	case PTRACE_KILL:
255		/*
256		 * make the child exit.  Best I can do is send it a
257		 * sigkill.  perhaps it should be put in the status
258		 * that it wants to exit.
259		 */
260		ret = 0;
261		DBG("sys_ptrace(KILL)\n");
262		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
263			goto out_tsk;
264		child->exit_code = SIGKILL;
265		goto out_wake_notrap;
266
267	case PTRACE_SINGLEBLOCK:
268		DBG("sys_ptrace(SINGLEBLOCK)\n");
269		ret = -EIO;
270		if (!valid_signal(data))
271			goto out_tsk;
272		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
273		child->ptrace &= ~PT_SINGLESTEP;
274		child->ptrace |= PT_BLOCKSTEP;
275		child->exit_code = data;
276
277		/* Enable taken branch trap. */
278		pa_psw(child)->r = 0;
279		pa_psw(child)->t = 1;
280		pa_psw(child)->h = 0;
281		pa_psw(child)->l = 0;
282		goto out_wake;
283
284	case PTRACE_SINGLESTEP:
285		DBG("sys_ptrace(SINGLESTEP)\n");
286		ret = -EIO;
287		if (!valid_signal(data))
288			goto out_tsk;
289
290		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
291		child->ptrace &= ~PT_BLOCKSTEP;
292		child->ptrace |= PT_SINGLESTEP;
293		child->exit_code = data;
294
295		if (pa_psw(child)->n) {
296			struct siginfo si;
297
298			/* Nullified, just crank over the queue. */
299			task_regs(child)->iaoq[0] = task_regs(child)->iaoq[1];
300			task_regs(child)->iasq[0] = task_regs(child)->iasq[1];
301			task_regs(child)->iaoq[1] = task_regs(child)->iaoq[0] + 4;
302			pa_psw(child)->n = 0;
303			pa_psw(child)->x = 0;
304			pa_psw(child)->y = 0;
305			pa_psw(child)->z = 0;
306			pa_psw(child)->b = 0;
307			ptrace_disable(child);
308			/* Don't wake up the child, but let the
309			   parent know something happened. */
310			si.si_code = TRAP_TRACE;
311			si.si_addr = (void __user *) (task_regs(child)->iaoq[0] & ~3);
312			si.si_signo = SIGTRAP;
313			si.si_errno = 0;
314			force_sig_info(SIGTRAP, &si, child);
315			//notify_parent(child, SIGCHLD);
316			//ret = 0;
317			goto out_wake;
318		}
319
320		/* Enable recovery counter traps.  The recovery counter
321		 * itself will be set to zero on a task switch.  If the
322		 * task is suspended on a syscall then the syscall return
323		 * path will overwrite the recovery counter with a suitable
324		 * value such that it traps once back in user space.  We
325		 * disable interrupts in the childs PSW here also, to avoid
326		 * interrupts while the recovery counter is decrementing.
327		 */
328		pa_psw(child)->r = 1;
329		pa_psw(child)->t = 0;
330		pa_psw(child)->h = 0;
331		pa_psw(child)->l = 0;
332		/* give it a chance to run. */
333		goto out_wake;
334
335	case PTRACE_DETACH:
336		ret = ptrace_detach(child, data);
337		goto out_tsk;
338
339	case PTRACE_GETEVENTMSG:
340                ret = put_user(child->ptrace_message, (unsigned int __user *) data);
341		goto out_tsk;
342
343	default:
344		ret = ptrace_request(child, request, addr, data);
345		goto out_tsk;
346	}
347
348out_wake_notrap:
349	ptrace_disable(child);
350out_wake:
351	wake_up_process(child);
352	ret = 0;
353out_tsk:
354	DBG("arch_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
355		request, pid, oaddr, odata, ret);
356	return ret;
357}
358
359void syscall_trace(void)
360{
361	if (!test_thread_flag(TIF_SYSCALL_TRACE))
362		return;
363	if (!(current->ptrace & PT_PTRACED))
364		return;
365	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
366				 ? 0x80 : 0));
367	/*
368	 * this isn't the same as continuing with a signal, but it will do
369	 * for normal use.  strace only continues with a signal if the
370	 * stopping signal is not SIGTRAP.  -brl
371	 */
372	if (current->exit_code) {
373		send_sig(current->exit_code, current, 1);
374		current->exit_code = 0;
375	}
376}
377