Convert ptrace_report_syscall_exit() to use ptrace_context. Incomplete:
- I don't underastand SYSEMU/SINGLESTEP magic yet - last_siginfo logic is not supported yet, but afaics the current is wrong too. --- kernel/ptrace.c | 49 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 11 deletions(-) --- PU/kernel/ptrace.c~27_SYSCALL_EXIT 2009-09-07 22:52:39.000000000 +0200 +++ PU/kernel/ptrace.c 2009-09-07 23:50:50.000000000 +0200 @@ -316,24 +316,51 @@ static u32 ptrace_report_vfork_done(stru task->ptrace_message); } +static void ptrace_wake_up(struct utrace_engine *engine, + struct task_struct *tracee, + enum utrace_resume_action action) +{ + /* preserve the compatibility bug */ + if (task_is_stopped(tracee)) { + spin_lock_irq(&tracee->sighand->siglock); + tracee->signal->flags &= ~SIGNAL_STOP_STOPPED; + spin_unlock_irq(&tracee->sighand->siglock); + } + + // XXX: FIXME!!! racy. + tracee->exit_code = 0; + + utrace_control(tracee, engine, action); +} + +static void ptrace_resume_syscall(struct utrace_engine *engine, + struct task_struct *tracee, long data) +{ + if (data) { + // XXX: until do_send_sig_info() + read_lock(&tasklist_lock); + if (tracee->signal) + send_sig(data, tracee, 1); + read_unlock(&tasklist_lock); + } + + ptrace_wake_up(engine, tracee, UTRACE_RESUME); +} + static u32 ptrace_report_syscall_exit(enum utrace_resume_action action, struct utrace_engine *engine, struct task_struct *task, struct pt_regs *regs) { - if (unlikely(ptrace_stop_event(task) == PTRACE_EVENT_VFORK)) - return ptrace_report_vfork_done(task); + struct ptrace_context *context = ptrace_context(engine); - if (unlikely(ptrace_syscall_action(task)) && - unlikely(ptrace_resume_action(task) == UTRACE_SINGLESTEP)) - /* - * This is PTRACE_SYSEMU_SINGLESTEP. - * Kludge: Prevent arch code from sending a SIGTRAP - * after tracehook_report_syscall_exit() returns. - */ - user_disable_single_step(task); + WARN_ON(context->resume_stopped); + WARN_ON(context->stopped_code); - return ptrace_report_syscall(0, engine, task); + context->resume_stopped = ptrace_resume_syscall; + context->stopped_code = (context->options & PTRACE_O_TRACESYSGOOD) ? + (SIGTRAP | 0x80) : SIGTRAP; + return action | UTRACE_STOP; } static u32 ptrace_resumed(struct task_struct *task,