File: /usr/src/linux/arch/arm/kernel/ptrace.c

1     /*
2      *  linux/arch/arm/kernel/ptrace.c
3      *
4      *  By Ross Biro 1/23/92
5      * edited by Linus Torvalds
6      * ARM modifications Copyright (C) 2000 Russell King
7      *
8      * This program is free software; you can redistribute it and/or modify
9      * it under the terms of the GNU General Public License version 2 as
10      * published by the Free Software Foundation.
11      */
12     #include <linux/kernel.h>
13     #include <linux/sched.h>
14     #include <linux/mm.h>
15     #include <linux/smp.h>
16     #include <linux/smp_lock.h>
17     #include <linux/ptrace.h>
18     #include <linux/user.h>
19     
20     #include <asm/uaccess.h>
21     #include <asm/pgtable.h>
22     #include <asm/system.h>
23     
24     #include "ptrace.h"
25     
26     #define REG_PC	15
27     #define REG_PSR	16
28     /*
29      * does not yet catch signals sent when the child dies.
30      * in exit.c or in signal.c.
31      */
32     
33     /*
34      * Breakpoint SWI instruction: SWI &9F0001
35      */
36     #define BREAKINST	0xef9f0001
37     
38     /*
39      * Get the address of the live pt_regs for the specified task.
40      * These are saved onto the top kernel stack when the process
41      * is not running.
42      */
43     static inline struct pt_regs *
44     get_user_regs(struct task_struct *task)
45     {
46     	return (struct pt_regs *)
47     		((unsigned long)task + 8192 - sizeof(struct pt_regs));
48     }
49     
50     /*
51      * this routine will get a word off of the processes privileged stack.
52      * the offset is how far from the base addr as stored in the THREAD.
53      * this routine assumes that all the privileged stacks are in our
54      * data space.
55      */
56     static inline long get_stack_long(struct task_struct *task, int offset)
57     {
58     	return get_user_regs(task)->uregs[offset];
59     }
60     
61     /*
62      * this routine will put a word on the processes privileged stack.
63      * the offset is how far from the base addr as stored in the THREAD.
64      * this routine assumes that all the privileged stacks are in our
65      * data space.
66      */
67     static inline int
68     put_stack_long(struct task_struct *task, int offset, long data)
69     {
70     	struct pt_regs newregs, *regs = get_user_regs(task);
71     	int ret = -EINVAL;
72     
73     	newregs = *regs;
74     	newregs.uregs[offset] = data;
75     	
76     	if (valid_user_regs(&newregs)) {
77     		regs->uregs[offset] = data;
78     		ret = 0;
79     	}
80     
81     	return ret;
82     }
83     
84     static inline int
85     read_tsk_long(struct task_struct *child, unsigned long addr, unsigned long *res)
86     {
87     	int copied;
88     
89     	copied = access_process_vm(child, addr, res, sizeof(*res), 0);
90     
91     	return copied != sizeof(*res) ? -EIO : 0;
92     }
93     
94     static inline int
95     write_tsk_long(struct task_struct *child, unsigned long addr, unsigned long val)
96     {
97     	int copied;
98     
99     	copied = access_process_vm(child, addr, &val, sizeof(val), 1);
100     
101     	return copied != sizeof(val) ? -EIO : 0;
102     }
103     
104     /*
105      * Get value of register `rn' (in the instruction)
106      */
107     static unsigned long
108     ptrace_getrn(struct task_struct *child, unsigned long insn)
109     {
110     	unsigned int reg = (insn >> 16) & 15;
111     	unsigned long val;
112     
113     	val = get_stack_long(child, reg);
114     	if (reg == 15)
115     		val = pc_pointer(val + 8);
116     
117     	return val;
118     }
119     
120     /*
121      * Get value of operand 2 (in an ALU instruction)
122      */
123     static unsigned long
124     ptrace_getaluop2(struct task_struct *child, unsigned long insn)
125     {
126     	unsigned long val;
127     	int shift;
128     	int type;
129     
130     	if (insn & 1 << 25) {
131     		val = insn & 255;
132     		shift = (insn >> 8) & 15;
133     		type = 3;
134     	} else {
135     		val = get_stack_long (child, insn & 15);
136     
137     		if (insn & (1 << 4))
138     			shift = (int)get_stack_long (child, (insn >> 8) & 15);
139     		else
140     			shift = (insn >> 7) & 31;
141     
142     		type = (insn >> 5) & 3;
143     	}
144     
145     	switch (type) {
146     	case 0:	val <<= shift;	break;
147     	case 1:	val >>= shift;	break;
148     	case 2:
149     		val = (((signed long)val) >> shift);
150     		break;
151     	case 3:
152      		val = (val >> shift) | (val << (32 - shift));
153     		break;
154     	}
155     	return val;
156     }
157     
158     /*
159      * Get value of operand 2 (in a LDR instruction)
160      */
161     static unsigned long
162     ptrace_getldrop2(struct task_struct *child, unsigned long insn)
163     {
164     	unsigned long val;
165     	int shift;
166     	int type;
167     
168     	val = get_stack_long(child, insn & 15);
169     	shift = (insn >> 7) & 31;
170     	type = (insn >> 5) & 3;
171     
172     	switch (type) {
173     	case 0:	val <<= shift;	break;
174     	case 1:	val >>= shift;	break;
175     	case 2:
176     		val = (((signed long)val) >> shift);
177     		break;
178     	case 3:
179      		val = (val >> shift) | (val << (32 - shift));
180     		break;
181     	}
182     	return val;
183     }
184     
185     static unsigned long
186     get_branch_address(struct task_struct *child, unsigned long pc, unsigned long insn)
187     {
188     	unsigned long alt = 0;
189     
190     	switch (insn & 0x0e000000) {
191     	case 0x00000000:
192     	case 0x02000000: {
193     		/*
194     		 * data processing
195     		 */
196     		long aluop1, aluop2, ccbit;
197     
198     		if ((insn & 0xf000) != 0xf000)
199     			break;
200     
201     		aluop1 = ptrace_getrn(child, insn);
202     		aluop2 = ptrace_getaluop2(child, insn);
203     		ccbit  = get_stack_long(child, REG_PSR) & CC_C_BIT ? 1 : 0;
204     
205     		switch (insn & 0x01e00000) {
206     		case 0x00000000: alt = aluop1 & aluop2;		break;
207     		case 0x00200000: alt = aluop1 ^ aluop2;		break;
208     		case 0x00400000: alt = aluop1 - aluop2;		break;
209     		case 0x00600000: alt = aluop2 - aluop1;		break;
210     		case 0x00800000: alt = aluop1 + aluop2;		break;
211     		case 0x00a00000: alt = aluop1 + aluop2 + ccbit;	break;
212     		case 0x00c00000: alt = aluop1 - aluop2 + ccbit;	break;
213     		case 0x00e00000: alt = aluop2 - aluop1 + ccbit;	break;
214     		case 0x01800000: alt = aluop1 | aluop2;		break;
215     		case 0x01a00000: alt = aluop2;			break;
216     		case 0x01c00000: alt = aluop1 & ~aluop2;	break;
217     		case 0x01e00000: alt = ~aluop2;			break;
218     		}
219     		break;
220     	}
221     
222     	case 0x04000000:
223     	case 0x06000000:
224     		/*
225     		 * ldr
226     		 */
227     		if ((insn & 0x0010f000) == 0x0010f000) {
228     			unsigned long base;
229     
230     			base = ptrace_getrn(child, insn);
231     			if (insn & 1 << 24) {
232     				long aluop2;
233     
234     				if (insn & 0x02000000)
235     					aluop2 = ptrace_getldrop2(child, insn);
236     				else
237     					aluop2 = insn & 0xfff;
238     
239     				if (insn & 1 << 23)
240     					base += aluop2;
241     				else
242     					base -= aluop2;
243     			}
244     			if (read_tsk_long(child, base, &alt) == 0)
245     				alt = pc_pointer(alt);
246     		}
247     		break;
248     
249     	case 0x08000000:
250     		/*
251     		 * ldm
252     		 */
253     		if ((insn & 0x00108000) == 0x00108000) {
254     			unsigned long base;
255     			unsigned int nr_regs;
256     
257     			if (insn & (1 << 23)) {
258     				nr_regs = insn & 65535;
259     
260     				nr_regs = (nr_regs & 0x5555) + ((nr_regs & 0xaaaa) >> 1);
261     				nr_regs = (nr_regs & 0x3333) + ((nr_regs & 0xcccc) >> 2);
262     				nr_regs = (nr_regs & 0x0707) + ((nr_regs & 0x7070) >> 4);
263     				nr_regs = (nr_regs & 0x000f) + ((nr_regs & 0x0f00) >> 8);
264     				nr_regs <<= 2;
265     
266     				if (!(insn & (1 << 24)))
267     					nr_regs -= 4;
268     			} else {
269     				if (insn & (1 << 24))
270     					nr_regs = -4;
271     				else
272     					nr_regs = 0;
273     			}
274     
275     			base = ptrace_getrn(child, insn);
276     
277     			if (read_tsk_long(child, base + nr_regs, &alt) == 0)
278     				alt = pc_pointer (alt);
279     			break;
280     		}
281     		break;
282     
283     	case 0x0a000000: {
284     		/*
285     		 * bl or b
286     		 */
287     		signed long displ;
288     		/* It's a branch/branch link: instead of trying to
289     		 * figure out whether the branch will be taken or not,
290     		 * we'll put a breakpoint at both locations.  This is
291     		 * simpler, more reliable, and probably not a whole lot
292     		 * slower than the alternative approach of emulating the
293     		 * branch.
294     		 */
295     		displ = (insn & 0x00ffffff) << 8;
296     		displ = (displ >> 6) + 8;
297     		if (displ != 0 && displ != 4)
298     			alt = pc + displ;
299     	    }
300     	    break;
301     	}
302     
303     	return alt;
304     }
305     
306     static int
307     add_breakpoint(struct task_struct *child, struct debug_info *dbg, unsigned long addr)
308     {
309     	int nr = dbg->nsaved;
310     	int res = -EINVAL;
311     
312     	if (nr < 2) {
313     		res = read_tsk_long(child, addr, &dbg->bp[nr].insn);
314     		if (res == 0)
315     			res = write_tsk_long(child, addr, BREAKINST);
316     
317     		if (res == 0) {
318     			dbg->bp[nr].address = addr;
319     			dbg->nsaved += 1;
320     		}
321     	} else
322     		printk(KERN_ERR "ptrace: too many breakpoints\n");
323     
324     	return res;
325     }
326     
327     int ptrace_set_bpt(struct task_struct *child)
328     {
329     	struct pt_regs *regs;
330     	unsigned long pc, insn;
331     	int res;
332     
333     	regs = get_user_regs(child);
334     	pc = instruction_pointer(regs);
335     
336     	res = read_tsk_long(child, pc, &insn);
337     	if (!res) {
338     		struct debug_info *dbg = &child->thread.debug;
339     		unsigned long alt;
340     
341     		dbg->nsaved = 0;
342     
343     		alt = get_branch_address(child, pc, insn);
344     		if (alt)
345     			res = add_breakpoint(child, dbg, alt);
346     
347     		/*
348     		 * Note that we ignore the result of setting the above
349     		 * breakpoint since it may fail.  When it does, this is
350     		 * not so much an error, but a forewarning that we may
351     		 * be receiving a prefetch abort shortly.
352     		 *
353     		 * If we don't set this breakpoint here, then we can
354     		 * loose control of the thread during single stepping.
355     		 */
356     		if (!alt || predicate(insn) != PREDICATE_ALWAYS)
357     			res = add_breakpoint(child, dbg, pc + 4);
358     	}
359     
360     	return res;
361     }
362     
363     /*
364      * Ensure no single-step breakpoint is pending.  Returns non-zero
365      * value if child was being single-stepped.
366      */
367     void __ptrace_cancel_bpt(struct task_struct *child)
368     {
369     	struct debug_info *dbg = &child->thread.debug;
370     	int i, nsaved = dbg->nsaved;
371     
372     	dbg->nsaved = 0;
373     
374     	if (nsaved > 2) {
375     		printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
376     		nsaved = 2;
377     	}
378     
379     	for (i = 0; i < nsaved; i++) {
380     		unsigned long tmp;
381     
382     		read_tsk_long(child, dbg->bp[i].address, &tmp);
383     		write_tsk_long(child, dbg->bp[i].address, dbg->bp[i].insn);
384     		if (tmp != BREAKINST)
385     			printk(KERN_ERR "ptrace_cancel_bpt: weirdness\n");
386     	}
387     }
388     
389     /*
390      * Called by kernel/ptrace.c when detaching..
391      *
392      * Make sure the single step bit is not set.
393      */
394     void ptrace_disable(struct task_struct *child)
395     {
396     	__ptrace_cancel_bpt(child);
397     }
398     
399     static int do_ptrace(int request, struct task_struct *child, long addr, long data)
400     {
401     	unsigned long tmp;
402     	int ret;
403     
404     	switch (request) {
405     		/*
406     		 * read word at location "addr" in the child process.
407     		 */
408     		case PTRACE_PEEKTEXT:
409     		case PTRACE_PEEKDATA:
410     			ret = read_tsk_long(child, addr, &tmp);
411     			if (!ret)
412     				ret = put_user(tmp, (unsigned long *) data);
413     			break;
414     
415     		/*
416     		 * read the word at location "addr" in the user registers.
417     		 */
418     		case PTRACE_PEEKUSR:
419     			ret = -EIO;
420     			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
421     				break;
422     
423     			tmp = 0;  /* Default return condition */
424     			if (addr < sizeof(struct pt_regs))
425     				tmp = get_stack_long(child, (int)addr >> 2);
426     			ret = put_user(tmp, (unsigned long *)data);
427     			break;
428     
429     		/*
430     		 * write the word at location addr.
431     		 */
432     		case PTRACE_POKETEXT:
433     		case PTRACE_POKEDATA:
434     			ret = write_tsk_long(child, addr, data);
435     			break;
436     
437     		/*
438     		 * write the word at location addr in the user registers.
439     		 */
440     		case PTRACE_POKEUSR:
441     			ret = -EIO;
442     			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
443     				break;
444     
445     			if (addr < sizeof(struct pt_regs))
446     				ret = put_stack_long(child, (int)addr >> 2, data);
447     			break;
448     
449     		/*
450     		 * continue/restart and stop at next (return from) syscall
451     		 */
452     		case PTRACE_SYSCALL:
453     		case PTRACE_CONT:
454     			ret = -EIO;
455     			if ((unsigned long) data > _NSIG)
456     				break;
457     			if (request == PTRACE_SYSCALL)
458     				child->ptrace |= PT_TRACESYS;
459     			else
460     				child->ptrace &= ~PT_TRACESYS;
461     			child->exit_code = data;
462     			/* make sure single-step breakpoint is gone. */
463     			__ptrace_cancel_bpt(child);
464     			wake_up_process(child);
465     			ret = 0;
466     			break;
467     
468     		/*
469     		 * make the child exit.  Best I can do is send it a sigkill.
470     		 * perhaps it should be put in the status that it wants to
471     		 * exit.
472     		 */
473     		case PTRACE_KILL:
474     			/* already dead */
475     			ret = 0;
476     			if (child->state == TASK_ZOMBIE)
477     				break;
478     			child->exit_code = SIGKILL;
479     			/* make sure single-step breakpoint is gone. */
480     			__ptrace_cancel_bpt(child);
481     			wake_up_process(child);
482     			ret = 0;
483     			break;
484     
485     		/*
486     		 * execute single instruction.
487     		 */
488     		case PTRACE_SINGLESTEP:
489     			ret = -EIO;
490     			if ((unsigned long) data > _NSIG)
491     				break;
492     			child->thread.debug.nsaved = -1;
493     			child->ptrace &= ~PT_TRACESYS;
494     			child->exit_code = data;
495     			/* give it a chance to run. */
496     			wake_up_process(child);
497     			ret = 0;
498     			break;
499     
500     		/*
501     		 * detach a process that was attached.
502     		 */
503     		case PTRACE_DETACH:
504     			ret = ptrace_detach(child, data);
505     			break;
506     
507     		/*
508     		 * Get all gp regs from the child.
509     		 */
510     		case PTRACE_GETREGS: {
511     			struct pt_regs *regs = get_user_regs(child);
512     
513     			ret = 0;
514     			if (copy_to_user((void *)data, regs,
515     					 sizeof(struct pt_regs)))
516     				ret = -EFAULT;
517     
518     			break;
519     		}
520     
521     		/*
522     		 * Set all gp regs in the child.
523     		 */
524     		case PTRACE_SETREGS: {
525     			struct pt_regs newregs;
526     
527     			ret = -EFAULT;
528     			if (copy_from_user(&newregs, (void *)data,
529     					   sizeof(struct pt_regs)) == 0) {
530     				struct pt_regs *regs = get_user_regs(child);
531     
532     				ret = -EINVAL;
533     				if (valid_user_regs(&newregs)) {
534     					*regs = newregs;
535     					ret = 0;
536     				}
537     			}
538     			break;
539     		}
540     
541     		/*
542     		 * Get the child FPU state.
543     		 */
544     		case PTRACE_GETFPREGS:
545     			ret = -EIO;
546     			if (!access_ok(VERIFY_WRITE, (void *)data, sizeof(struct user_fp)))
547     				break;
548     
549     			/* we should check child->used_math here */
550     			ret = __copy_to_user((void *)data, &child->thread.fpstate,
551     					     sizeof(struct user_fp)) ? -EFAULT : 0;
552     			break;
553     		
554     		/*
555     		 * Set the child FPU state.
556     		 */
557     		case PTRACE_SETFPREGS:
558     			ret = -EIO;
559     			if (!access_ok(VERIFY_READ, (void *)data, sizeof(struct user_fp)))
560     				break;
561     
562     			child->used_math = 1;
563     			ret = __copy_from_user(&child->thread.fpstate, (void *)data,
564     					   sizeof(struct user_fp)) ? -EFAULT : 0;
565     			break;
566     
567     		default:
568     			ret = -EIO;
569     			break;
570     	}
571     
572     	return ret;
573     }
574     
575     asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
576     {
577     	struct task_struct *child;
578     	int ret;
579     
580     	lock_kernel();
581     	ret = -EPERM;
582     	if (request == PTRACE_TRACEME) {
583     		/* are we already being traced? */
584     		if (current->ptrace & PT_PTRACED)
585     			goto out;
586     		/* set the ptrace bit in the process flags. */
587     		current->ptrace |= PT_PTRACED;
588     		ret = 0;
589     		goto out;
590     	}
591     	ret = -ESRCH;
592     	read_lock(&tasklist_lock);
593     	child = find_task_by_pid(pid);
594     	if (child)
595     		get_task_struct(child);
596     	read_unlock(&tasklist_lock);
597     	if (!child)
598     		goto out;
599     
600     	ret = -EPERM;
601     	if (pid == 1)		/* you may not mess with init */
602     		goto out_tsk;
603     
604     	if (request == PTRACE_ATTACH) {
605     		ret = ptrace_attach(child);
606     		goto out_tsk;
607     	}
608     	ret = -ESRCH;
609     	if (!(child->ptrace & PT_PTRACED))
610     		goto out_tsk;
611     	if (child->state != TASK_STOPPED && request != PTRACE_KILL)
612     		goto out_tsk;
613     	if (child->p_pptr != current)
614     		goto out_tsk;
615     
616     	ret = do_ptrace(request, child, addr, data);
617     
618     out_tsk:
619     	free_task_struct(child);
620     out:
621     	unlock_kernel();
622     	return ret;
623     }
624     
625     asmlinkage void syscall_trace(int why, struct pt_regs *regs)
626     {
627     	unsigned long ip;
628     
629     	if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
630     			!= (PT_PTRACED|PT_TRACESYS))
631     		return;
632     
633     	/*
634     	 * Save IP.  IP is used to denote syscall entry/exit:
635     	 *  IP = 0 -> entry, = 1 -> exit
636     	 */
637     	ip = regs->ARM_ip;
638     	regs->ARM_ip = why;
639     
640     	/* the 0x80 provides a way for the tracing parent to distinguish
641     	   between a syscall stop and SIGTRAP delivery */
642     	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
643     					? 0x80 : 0);
644     	current->state = TASK_STOPPED;
645     	notify_parent(current, SIGCHLD);
646     	schedule();
647     	/*
648     	 * this isn't the same as continuing with a signal, but it will do
649     	 * for normal use.  strace only continues with a signal if the
650     	 * stopping signal is not SIGTRAP.  -brl
651     	 */
652     	if (current->exit_code) {
653     		send_sig(current->exit_code, current, 1);
654     		current->exit_code = 0;
655     	}
656     	regs->ARM_ip = ip;
657     }
658