aboutsummaryrefslogtreecommitdiffstats
path: root/arch/alpha/kernel/ptrace.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2010-03-10 18:22:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-12 18:52:38 -0500
commitfd341abba65e3d93fc24c132e4c0278d18b6d2fc (patch)
tree4fc6ca0190c803d669ac1e3ad9df4386134496be /arch/alpha/kernel/ptrace.c
parentdacbe41f776db0a5a9aee1e41594f405c95778a5 (diff)
alpha: use generic ptrace_resume code
Use the generic ptrace_resume code for PTRACE_SYSCALL, PTRACE_CONT, PTRACE_KILL and PTRACE_SINGLESTEP. This implies defining arch_has_single_step in <asm/ptrace.h> and implementing the user_enable_single_step and user_disable_single_step functions, which also causes the breakpoint information to be cleared on fork, which could be considered a bug fix. Also the TIF_SYSCALL_TRACE thread flag is now cleared on PTRACE_KILL which it previously wasn't, which is consistent with all architectures using the modern ptrace code. Signed-off-by: Christoph Hellwig <hch@lst.de> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Roland McGrath <roland@redhat.com> Acked-by: Matt Turner <mattst88@gmail.com> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Richard Henderson <rth@twiddle.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/alpha/kernel/ptrace.c')
-rw-r--r--arch/alpha/kernel/ptrace.c59
1 files changed, 12 insertions, 47 deletions
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index e072041d19f8..9acadc6b16a0 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -249,6 +249,17 @@ ptrace_cancel_bpt(struct task_struct * child)
249 return (nsaved != 0); 249 return (nsaved != 0);
250} 250}
251 251
252void user_enable_single_step(struct task_struct *child)
253{
254 /* Mark single stepping. */
255 task_thread_info(child)->bpt_nsaved = -1;
256}
257
258void user_disable_single_step(struct task_struct *child)
259{
260 ptrace_cancel_bpt(child);
261}
262
252/* 263/*
253 * Called by kernel/ptrace.c when detaching.. 264 * Called by kernel/ptrace.c when detaching..
254 * 265 *
@@ -256,7 +267,7 @@ ptrace_cancel_bpt(struct task_struct * child)
256 */ 267 */
257void ptrace_disable(struct task_struct *child) 268void ptrace_disable(struct task_struct *child)
258{ 269{
259 ptrace_cancel_bpt(child); 270 user_disable_single_step(child);
260} 271}
261 272
262long arch_ptrace(struct task_struct *child, long request, long addr, long data) 273long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -295,52 +306,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
295 DBG(DBG_MEM, ("poke $%ld<-%#lx\n", addr, data)); 306 DBG(DBG_MEM, ("poke $%ld<-%#lx\n", addr, data));
296 ret = put_reg(child, addr, data); 307 ret = put_reg(child, addr, data);
297 break; 308 break;
298
299 case PTRACE_SYSCALL:
300 /* continue and stop at next (return from) syscall */
301 case PTRACE_CONT: /* restart after signal. */
302 ret = -EIO;
303 if (!valid_signal(data))
304 break;
305 if (request == PTRACE_SYSCALL)
306 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
307 else
308 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
309 child->exit_code = data;
310 /* make sure single-step breakpoint is gone. */
311 ptrace_cancel_bpt(child);
312 wake_up_process(child);
313 ret = 0;
314 break;
315
316 /*
317 * Make the child exit. Best I can do is send it a sigkill.
318 * perhaps it should be put in the status that it wants to
319 * exit.
320 */
321 case PTRACE_KILL:
322 ret = 0;
323 if (child->exit_state == EXIT_ZOMBIE)
324 break;
325 child->exit_code = SIGKILL;
326 /* make sure single-step breakpoint is gone. */
327 ptrace_cancel_bpt(child);
328 wake_up_process(child);
329 break;
330
331 case PTRACE_SINGLESTEP: /* execute single instruction. */
332 ret = -EIO;
333 if (!valid_signal(data))
334 break;
335 /* Mark single stepping. */
336 task_thread_info(child)->bpt_nsaved = -1;
337 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
338 child->exit_code = data;
339 wake_up_process(child);
340 /* give it a chance to run. */
341 ret = 0;
342 break;
343
344 default: 309 default:
345 ret = ptrace_request(child, request, addr, data); 310 ret = ptrace_request(child, request, addr, data);
346 break; 311 break;