2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
6 #include "linux/audit.h"
7 #include "linux/ptrace.h"
8 #include "linux/sched.h"
9 #include "asm/uaccess.h"
13 #include "skas_ptrace.h"
15 static inline void set_singlestepping(struct task_struct
*child
, int on
)
18 child
->ptrace
|= PT_DTRACE
;
20 child
->ptrace
&= ~PT_DTRACE
;
21 child
->thread
.singlestep_syscall
= 0;
23 #ifdef SUBARCH_SET_SINGLESTEPPING
24 SUBARCH_SET_SINGLESTEPPING(child
, on
);
29 * Called by kernel/ptrace.c when detaching..
31 void ptrace_disable(struct task_struct
*child
)
33 set_singlestepping(child
,0);
36 extern int peek_user(struct task_struct
* child
, long addr
, long data
);
37 extern int poke_user(struct task_struct
* child
, long addr
, long data
);
39 long arch_ptrace(struct task_struct
*child
, long request
, long addr
, long data
)
42 unsigned long __user
*p
= (void __user
*)(unsigned long)data
;
45 /* read word at location addr. */
48 ret
= generic_ptrace_peekdata(child
, addr
, data
);
51 /* read the word at location addr in the USER area. */
53 ret
= peek_user(child
, addr
, data
);
56 /* write the word at location addr. */
59 ret
= generic_ptrace_pokedata(child
, addr
, data
);
62 /* write the word at location addr in the USER area */
64 ret
= poke_user(child
, addr
, data
);
68 case PTRACE_SYSEMU_SINGLESTEP
:
72 /* continue and stop at next (return from) syscall */
74 /* restart after signal. */
77 if (!valid_signal(data
))
80 set_singlestepping(child
, 0);
81 if (request
== PTRACE_SYSCALL
)
82 set_tsk_thread_flag(child
, TIF_SYSCALL_TRACE
);
83 else clear_tsk_thread_flag(child
, TIF_SYSCALL_TRACE
);
84 child
->exit_code
= data
;
85 wake_up_process(child
);
91 * make the child exit. Best I can do is send it a sigkill.
92 * perhaps it should be put in the status that it wants to
97 if (child
->exit_state
== EXIT_ZOMBIE
) /* already dead */
100 set_singlestepping(child
, 0);
101 child
->exit_code
= SIGKILL
;
102 wake_up_process(child
);
106 case PTRACE_SINGLESTEP
: { /* set the trap flag. */
108 if (!valid_signal(data
))
110 clear_tsk_thread_flag(child
, TIF_SYSCALL_TRACE
);
111 set_singlestepping(child
, 1);
112 child
->exit_code
= data
;
113 /* give it a chance to run. */
114 wake_up_process(child
);
119 #ifdef PTRACE_GETREGS
120 case PTRACE_GETREGS
: { /* Get all gp regs from the child. */
121 if (!access_ok(VERIFY_WRITE
, p
, MAX_REG_OFFSET
)) {
125 for ( i
= 0; i
< MAX_REG_OFFSET
; i
+= sizeof(long) ) {
126 __put_user(getreg(child
, i
), p
);
133 #ifdef PTRACE_SETREGS
134 case PTRACE_SETREGS
: { /* Set all gp regs in the child. */
135 unsigned long tmp
= 0;
136 if (!access_ok(VERIFY_READ
, p
, MAX_REG_OFFSET
)) {
140 for ( i
= 0; i
< MAX_REG_OFFSET
; i
+= sizeof(long) ) {
142 putreg(child
, i
, tmp
);
149 #ifdef PTRACE_GETFPREGS
150 case PTRACE_GETFPREGS
: /* Get the child FPU state. */
151 ret
= get_fpregs((struct user_i387_struct __user
*) data
,
155 #ifdef PTRACE_SETFPREGS
156 case PTRACE_SETFPREGS
: /* Set the child FPU state. */
157 ret
= set_fpregs((struct user_i387_struct __user
*) data
,
161 case PTRACE_GET_THREAD_AREA
:
162 ret
= ptrace_get_thread_area(child
, addr
,
163 (struct user_desc __user
*) data
);
166 case PTRACE_SET_THREAD_AREA
:
167 ret
= ptrace_set_thread_area(child
, addr
,
168 (struct user_desc __user
*) data
);
171 case PTRACE_FAULTINFO
: {
173 * Take the info from thread->arch->faultinfo,
174 * but transfer max. sizeof(struct ptrace_faultinfo).
175 * On i386, ptrace_faultinfo is smaller!
177 ret
= copy_to_user(p
, &child
->thread
.arch
.faultinfo
,
178 sizeof(struct ptrace_faultinfo
));
184 struct ptrace_ldt ldt
;
186 if (copy_from_user(&ldt
, p
, sizeof(ldt
))) {
192 * This one is confusing, so just punt and return -EIO for
199 #ifdef CONFIG_PROC_MM
200 case PTRACE_SWITCH_MM
: {
201 struct mm_struct
*old
= child
->mm
;
202 struct mm_struct
*new = proc_mm_get_mm(data
);
209 atomic_inc(&new->mm_users
);
211 child
->active_mm
= new;
217 #ifdef PTRACE_ARCH_PRCTL
218 case PTRACE_ARCH_PRCTL
:
219 /* XXX Calls ptrace on the host - needs some SMP thinking */
220 ret
= arch_prctl(child
, data
, (void *) addr
);
224 ret
= ptrace_request(child
, request
, addr
, data
);
226 ret
= subarch_ptrace(child
, request
, addr
, data
);
233 static void send_sigtrap(struct task_struct
*tsk
, struct uml_pt_regs
*regs
,
238 memset(&info
, 0, sizeof(info
));
239 info
.si_signo
= SIGTRAP
;
240 info
.si_code
= TRAP_BRKPT
;
243 info
.si_addr
= UPT_IS_USER(regs
) ? (void __user
*) UPT_IP(regs
) : NULL
;
245 /* Send us the fake SIGTRAP */
246 force_sig_info(SIGTRAP
, &info
, tsk
);
250 * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and
251 * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check
253 void syscall_trace(struct uml_pt_regs
*regs
, int entryexit
)
255 int is_singlestep
= (current
->ptrace
& PT_DTRACE
) && entryexit
;
258 if (unlikely(current
->audit_context
)) {
260 audit_syscall_entry(HOST_AUDIT_ARCH
,
261 UPT_SYSCALL_NR(regs
),
262 UPT_SYSCALL_ARG1(regs
),
263 UPT_SYSCALL_ARG2(regs
),
264 UPT_SYSCALL_ARG3(regs
),
265 UPT_SYSCALL_ARG4(regs
));
266 else audit_syscall_exit(AUDITSC_RESULT(UPT_SYSCALL_RET(regs
)),
267 UPT_SYSCALL_RET(regs
));
270 /* Fake a debug trap */
272 send_sigtrap(current
, regs
, 0);
274 if (!test_thread_flag(TIF_SYSCALL_TRACE
))
277 if (!(current
->ptrace
& PT_PTRACED
))
281 * the 0x80 provides a way for the tracing parent to distinguish
282 * between a syscall stop and SIGTRAP delivery
284 tracesysgood
= (current
->ptrace
& PT_TRACESYSGOOD
);
285 ptrace_notify(SIGTRAP
| (tracesysgood
? 0x80 : 0));
287 if (entryexit
) /* force do_signal() --> is_syscall() */
288 set_thread_flag(TIF_SIGPENDING
);
291 * this isn't the same as continuing with a signal, but it will do
292 * for normal use. strace only continues with a signal if the
293 * stopping signal is not SIGTRAP. -brl
295 if (current
->exit_code
) {
296 send_sig(current
->exit_code
, current
, 1);
297 current
->exit_code
= 0;