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,

Reply via email to