2 /* By Ross Biro 1/23/92 */
3 /* edited by Linus Torvalds */
4 /* edited for ARM by Russell King */
6 #include <linux/kernel.h>
7 #include <linux/sched.h>
10 #include <linux/smp_lock.h>
11 #include <linux/errno.h>
12 #include <linux/ptrace.h>
13 #include <linux/user.h>
15 #include <asm/uaccess.h>
16 #include <asm/pgtable.h>
17 #include <asm/system.h>
20 * does not yet catch signals sent when the child dies.
21 * in exit.c or in signal.c.
25 * Breakpoint SWI instruction: SWI &9F0001
27 #define BREAKINST 0xef9f0001
30 * this routine will get a word off of the processes privileged stack.
31 * the offset is how far from the base addr as stored in the THREAD.
32 * this routine assumes that all the privileged stacks are in our
35 static inline long get_stack_long(struct task_struct
*task
, int offset
)
39 regs
= (struct pt_regs
*)((unsigned long)task
+ 8192 - sizeof(struct pt_regs
));
41 return regs
->uregs
[offset
];
45 * this routine will put a word on the processes privileged stack.
46 * the offset is how far from the base addr as stored in the THREAD.
47 * this routine assumes that all the privileged stacks are in our
50 static inline long put_stack_long(struct task_struct
*task
, int offset
,
55 regs
= (struct pt_regs
*)((unsigned long)task
+ 8192 - sizeof(struct pt_regs
));
57 regs
->uregs
[offset
] = data
;
63 read_long(struct task_struct
*child
, unsigned long addr
, unsigned long *res
)
67 copied
= access_process_vm(child
, addr
, res
, sizeof(*res
), 0);
69 return copied
!= sizeof(*res
) ? -EIO
: 0;
73 write_long(struct task_struct
*child
, unsigned long addr
, unsigned long val
)
77 copied
= access_process_vm(child
, addr
, &val
, sizeof(val
), 1);
79 return copied
!= sizeof(val
) ? -EIO
: 0;
83 * Get value of register `rn' (in the instruction)
85 static unsigned long ptrace_getrn (struct task_struct
*child
, unsigned long insn
)
87 unsigned int reg
= (insn
>> 16) & 15;
91 val
= pc_pointer (get_stack_long (child
, reg
));
93 val
= get_stack_long (child
, reg
);
95 printk ("r%02d=%08lX ", reg
, val
);
100 * Get value of operand 2 (in an ALU instruction)
102 static unsigned long ptrace_getaluop2 (struct task_struct
*child
, unsigned long insn
)
109 if (insn
& 1 << 25) {
111 shift
= (insn
>> 8) & 15;
115 val
= get_stack_long (child
, insn
& 15);
118 shift
= (int)get_stack_long (child
, (insn
>> 8) & 15);
120 shift
= (insn
>> 7) & 31;
122 type
= (insn
>> 5) & 3;
123 printk ("(r%02ld)", insn
& 15);
125 printk ("sh%dx%d", type
, shift
);
127 case 0: val
<<= shift
; break;
128 case 1: val
>>= shift
; break;
130 val
= (((signed long)val
) >> shift
);
133 val
= (val
>> shift
) | (val
<< (32 - shift
));
136 printk ("=%08lX ", val
);
141 * Get value of operand 2 (in a LDR instruction)
143 static unsigned long ptrace_getldrop2 (struct task_struct
*child
, unsigned long insn
)
149 val
= get_stack_long (child
, insn
& 15);
150 shift
= (insn
>> 7) & 31;
151 type
= (insn
>> 5) & 3;
153 printk ("op2=r%02ldsh%dx%d", insn
& 15, shift
, type
);
155 case 0: val
<<= shift
; break;
156 case 1: val
>>= shift
; break;
158 val
= (((signed long)val
) >> shift
);
161 val
= (val
>> shift
) | (val
<< (32 - shift
));
164 printk ("=%08lX ", val
);
169 get_branch_address(struct task_struct
*child
, unsigned long pc
, unsigned long insn
)
171 unsigned long alt
= 0;
173 printk(KERN_DEBUG
"ptrace_set_bpt: insn=%08lX pc=%08lX ", insn
, pc
);
174 switch (insn
& 0x0e100000) {
178 case 0x02100000: /* data processing */
180 switch (insn
& 0x01e0f000) {
182 alt
= ptrace_getrn(child
, insn
) & ptrace_getaluop2(child
, insn
);
185 alt
= ptrace_getrn(child
, insn
) ^ ptrace_getaluop2(child
, insn
);
188 alt
= ptrace_getrn(child
, insn
) - ptrace_getaluop2(child
, insn
);
191 alt
= ptrace_getaluop2(child
, insn
) - ptrace_getrn(child
, insn
);
194 alt
= ptrace_getrn(child
, insn
) + ptrace_getaluop2(child
, insn
);
197 alt
= ptrace_getrn(child
, insn
) + ptrace_getaluop2(child
, insn
) +
198 (get_stack_long (child
, 16/*REG_PSR*/) & CC_C_BIT
? 1 : 0);
201 alt
= ptrace_getrn(child
, insn
) - ptrace_getaluop2(child
, insn
) +
202 (get_stack_long (child
, 16/*REG_PSR*/) & CC_C_BIT
? 1 : 0);
205 alt
= ptrace_getaluop2(child
, insn
) - ptrace_getrn(child
, insn
) +
206 (get_stack_long (child
, 16/*REG_PSR*/) & CC_C_BIT
? 1 : 0);
209 alt
= ptrace_getrn(child
, insn
) | ptrace_getaluop2(child
, insn
);
212 alt
= ptrace_getaluop2(child
, insn
);
215 alt
= ptrace_getrn(child
, insn
) & ~ptrace_getaluop2(child
, insn
);
218 alt
= ~ptrace_getaluop2(child
, insn
);
223 case 0x04100000: /* ldr */
224 if ((insn
& 0xf000) == 0xf000) {
226 alt
= ptrace_getrn(child
, insn
);
227 if (insn
& 1 << 24) {
229 alt
+= ptrace_getldrop2 (child
, insn
);
231 alt
-= ptrace_getldrop2 (child
, insn
);
233 if (read_long (child
, alt
, &alt
) < 0)
234 alt
= 0; /* not valid */
236 alt
= pc_pointer (alt
);
240 case 0x06100000: /* ldr imm */
241 if ((insn
& 0xf000) == 0xf000) {
243 alt
= ptrace_getrn(child
, insn
);
244 if (insn
& 1 << 24) {
250 if (read_long (child
, alt
, &alt
) < 0)
251 alt
= 0; /* not valid */
253 alt
= pc_pointer (alt
);
257 case 0x08100000: /* ldm */
258 if (insn
& (1 << 15)) {
263 if (insn
& (1 << 23)) {
264 nr_regs
= insn
& 65535;
266 nr_regs
= (nr_regs
& 0x5555) + ((nr_regs
& 0xaaaa) >> 1);
267 nr_regs
= (nr_regs
& 0x3333) + ((nr_regs
& 0xcccc) >> 2);
268 nr_regs
= (nr_regs
& 0x0707) + ((nr_regs
& 0x7070) >> 4);
269 nr_regs
= (nr_regs
& 0x000f) + ((nr_regs
& 0x0f00) >> 8);
272 if (!(insn
& (1 << 24)))
275 if (insn
& (1 << 24))
281 base
= ptrace_getrn (child
, insn
);
283 if (read_long (child
, base
+ nr_regs
, &alt
) < 0)
284 alt
= 0; /* not valid */
286 alt
= pc_pointer (alt
);
292 case 0x0a100000: { /* bl or b */
295 /* It's a branch/branch link: instead of trying to
296 * figure out whether the branch will be taken or not,
297 * we'll put a breakpoint at either location. This is
298 * simpler, more reliable, and probably not a whole lot
299 * slower than the alternative approach of emulating the
302 displ
= (insn
& 0x00ffffff) << 8;
303 displ
= (displ
>> 6) + 8;
304 if (displ
!= 0 && displ
!= 4)
309 printk ("=%08lX\n", alt
);
315 add_breakpoint(struct task_struct
*child
, struct debug_info
*dbg
, unsigned long addr
)
317 int nr
= dbg
->nsaved
;
321 res
= read_long(child
, addr
, &dbg
->bp
[nr
].insn
);
323 res
= write_long(child
, addr
, BREAKINST
);
326 dbg
->bp
[nr
].address
= addr
;
330 printk(KERN_DEBUG
"add_breakpoint: too many breakpoints\n");
335 int ptrace_set_bpt (struct task_struct
*child
)
337 struct debug_info
*dbg
= &child
->thread
.debug
;
338 unsigned long insn
, pc
, alt
;
341 pc
= pc_pointer (get_stack_long (child
, 15/*REG_PC*/));
343 res
= read_long(child
, pc
, &insn
);
349 res
= add_breakpoint(child
, dbg
, pc
+ 4);
352 alt
= get_branch_address(child
, pc
, insn
);
354 res
= add_breakpoint(child
, dbg
, alt
);
361 /* Ensure no single-step breakpoint is pending. Returns non-zero
362 * value if child was being single-stepped.
364 int ptrace_cancel_bpt (struct task_struct
*child
)
366 struct debug_info
*dbg
= &child
->thread
.debug
;
368 int i
, nsaved
= dbg
->nsaved
;
373 printk ("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved
);
377 for (i
= 0; i
< nsaved
; i
++) {
378 read_long(child
, dbg
->bp
[i
].address
, &tmp
);
379 if (tmp
!= BREAKINST
)
380 printk(KERN_ERR
"ptrace_cancel_bpt: weirdness\n");
381 write_long(child
, dbg
->bp
[i
].address
, dbg
->bp
[i
].insn
);
387 asmlinkage
int sys_ptrace(long request
, long pid
, long addr
, long data
)
389 struct task_struct
*child
;
394 if (request
== PTRACE_TRACEME
) {
395 /* are we already being traced? */
396 if (current
->flags
& PF_PTRACED
)
398 /* set the ptrace bit in the process flags. */
399 current
->flags
|= PF_PTRACED
;
403 if (pid
== 1) /* you may not mess with init */
406 if (!(child
= find_task_by_pid(pid
)))
409 if (request
== PTRACE_ATTACH
) {
410 if (child
== current
)
412 if ((!child
->dumpable
||
413 (current
->uid
!= child
->euid
) ||
414 (current
->uid
!= child
->suid
) ||
415 (current
->uid
!= child
->uid
) ||
416 (current
->gid
!= child
->egid
) ||
417 (current
->gid
!= child
->sgid
) ||
418 (!cap_issubset(child
->cap_permitted
, current
->cap_permitted
)) ||
419 (current
->gid
!= child
->gid
)) && !capable(CAP_SYS_PTRACE
))
421 /* the same process cannot be attached many times */
422 if (child
->flags
& PF_PTRACED
)
424 child
->flags
|= PF_PTRACED
;
425 if (child
->p_pptr
!= current
) {
427 child
->p_pptr
= current
;
430 send_sig(SIGSTOP
, child
, 1);
435 if (!(child
->flags
& PF_PTRACED
))
437 if (child
->state
!= TASK_STOPPED
) {
438 if (request
!= PTRACE_KILL
)
441 if (child
->p_pptr
!= current
)
445 case PTRACE_PEEKTEXT
: /* read word at location addr. */
446 case PTRACE_PEEKDATA
: {
449 ret
= read_long(child
, addr
, &tmp
);
451 put_user(tmp
, (unsigned long *) data
);
455 case PTRACE_PEEKUSR
: { /* read the word at location addr in the USER area. */
459 if ((addr
& 3) || addr
< 0 || addr
>= sizeof(struct user
))
462 tmp
= 0; /* Default return condition */
463 if (addr
< sizeof (struct pt_regs
))
464 tmp
= get_stack_long(child
, (int)addr
>> 2);
465 ret
= put_user(tmp
, (unsigned long *)data
);
469 case PTRACE_POKETEXT
: /* write the word at location addr. */
470 case PTRACE_POKEDATA
:
471 ret
= write_long(child
, addr
, data
);
474 case PTRACE_POKEUSR
: /* write the word at location addr in the USER area */
476 if ((addr
& 3) || addr
< 0 || addr
>= sizeof(struct user
))
479 if (addr
< sizeof (struct pt_regs
))
480 ret
= put_stack_long(child
, (int)addr
>> 2, data
);
483 case PTRACE_SYSCALL
: /* continue and stop at next (return from) syscall */
484 case PTRACE_CONT
: /* restart after signal. */
486 if ((unsigned long) data
> _NSIG
)
488 if (request
== PTRACE_SYSCALL
)
489 child
->flags
|= PF_TRACESYS
;
491 child
->flags
&= ~PF_TRACESYS
;
492 child
->exit_code
= data
;
493 wake_up_process (child
);
494 /* make sure single-step breakpoint is gone. */
495 ptrace_cancel_bpt (child
);
499 /* make the child exit. Best I can do is send it a sigkill.
500 * perhaps it should be put in the status that it wants to
504 if (child
->state
== TASK_ZOMBIE
) /* already dead */
506 wake_up_process (child
);
507 child
->exit_code
= SIGKILL
;
508 /* make sure single-step breakpoint is gone. */
509 ptrace_cancel_bpt (child
);
513 case PTRACE_SINGLESTEP
: /* execute single instruction. */
515 if ((unsigned long) data
> _NSIG
)
517 child
->thread
.debug
.nsaved
= -1;
518 child
->flags
&= ~PF_TRACESYS
;
519 wake_up_process(child
);
520 child
->exit_code
= data
;
521 /* give it a chance to run. */
525 case PTRACE_DETACH
: /* detach a process that was attached. */
527 if ((unsigned long) data
> _NSIG
)
529 child
->flags
&= ~(PF_PTRACED
|PF_TRACESYS
);
530 wake_up_process (child
);
531 child
->exit_code
= data
;
533 child
->p_pptr
= child
->p_opptr
;
535 /* make sure single-step breakpoint is gone. */
536 ptrace_cancel_bpt (child
);
549 asmlinkage
void syscall_trace(void)
551 if ((current
->flags
& (PF_PTRACED
|PF_TRACESYS
))
552 != (PF_PTRACED
|PF_TRACESYS
))
554 current
->exit_code
= SIGTRAP
;
555 current
->state
= TASK_STOPPED
;
556 notify_parent(current
, SIGCHLD
);
559 * this isn't the same as continuing with a signal, but it will do
560 * for normal use. strace only continues with a signal if the
561 * stopping signal is not SIGTRAP. -brl
563 if (current
->exit_code
) {
564 send_sig(current
->exit_code
, current
, 1);
565 current
->exit_code
= 0;