mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
ptrace: generic resume
This makes ptrace_request handle all the ptrace requests that wake up the traced task. These do low-level ptrace implementation magic that is not arch-specific and should be kept out of arch code. The implementations on each arch usually do the same thing. The new generic code makes use of the arch_has_single_step macro and generic entry points to handle PTRACE_SINGLESTEP. Signed-off-by: Roland McGrath <roland@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
e1f287735c
commit
36df29d799
1 changed files with 61 additions and 0 deletions
|
@ -366,6 +366,50 @@ static int ptrace_setsiginfo(struct task_struct *child, siginfo_t __user * data)
|
|||
return error;
|
||||
}
|
||||
|
||||
|
||||
#ifdef PTRACE_SINGLESTEP
|
||||
#define is_singlestep(request) ((request) == PTRACE_SINGLESTEP)
|
||||
#else
|
||||
#define is_singlestep(request) 0
|
||||
#endif
|
||||
|
||||
#ifdef PTRACE_SYSEMU
|
||||
#define is_sysemu_singlestep(request) ((request) == PTRACE_SYSEMU_SINGLESTEP)
|
||||
#else
|
||||
#define is_sysemu_singlestep(request) 0
|
||||
#endif
|
||||
|
||||
static int ptrace_resume(struct task_struct *child, long request, long data)
|
||||
{
|
||||
if (!valid_signal(data))
|
||||
return -EIO;
|
||||
|
||||
if (request == PTRACE_SYSCALL)
|
||||
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
|
||||
else
|
||||
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
|
||||
|
||||
#ifdef TIF_SYSCALL_EMU
|
||||
if (request == PTRACE_SYSEMU || request == PTRACE_SYSEMU_SINGLESTEP)
|
||||
set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
|
||||
else
|
||||
clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
|
||||
#endif
|
||||
|
||||
if (is_singlestep(request) || is_sysemu_singlestep(request)) {
|
||||
if (unlikely(!arch_has_single_step()))
|
||||
return -EIO;
|
||||
user_enable_single_step(child);
|
||||
}
|
||||
else
|
||||
user_disable_single_step(child);
|
||||
|
||||
child->exit_code = data;
|
||||
wake_up_process(child);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ptrace_request(struct task_struct *child, long request,
|
||||
long addr, long data)
|
||||
{
|
||||
|
@ -390,6 +434,23 @@ int ptrace_request(struct task_struct *child, long request,
|
|||
case PTRACE_DETACH: /* detach a process that was attached. */
|
||||
ret = ptrace_detach(child, data);
|
||||
break;
|
||||
|
||||
#ifdef PTRACE_SINGLESTEP
|
||||
case PTRACE_SINGLESTEP:
|
||||
#endif
|
||||
#ifdef PTRACE_SYSEMU
|
||||
case PTRACE_SYSEMU:
|
||||
case PTRACE_SYSEMU_SINGLESTEP:
|
||||
#endif
|
||||
case PTRACE_SYSCALL:
|
||||
case PTRACE_CONT:
|
||||
return ptrace_resume(child, request, data);
|
||||
|
||||
case PTRACE_KILL:
|
||||
if (child->exit_state) /* already dead */
|
||||
return 0;
|
||||
return ptrace_resume(child, request, SIGKILL);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue