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;
|
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,
|
int ptrace_request(struct task_struct *child, long request,
|
||||||
long addr, long data)
|
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. */
|
case PTRACE_DETACH: /* detach a process that was attached. */
|
||||||
ret = ptrace_detach(child, data);
|
ret = ptrace_detach(child, data);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue