Consolidate multiple switch statements in do_ptrace_resume().
No functional changes, except in PTRACE_EVENT_SYSCALL_EXIT
case ptrace(SINGLESTEP, signr)->ptrace_resume() first does
send_sigtrap() then send_sig_info(signr). Hopefully this is
OK, and we should move this sigtrap logic into the tracee's
context anyway.

To simplify the review:

        static void do_ptrace_resume(struct utrace_engine *engine,
                                        struct task_struct *tracee,
                                        enum utrace_resume_action action,
                                        long request, long data)
        {
                struct ptrace_context *context = ptrace_context(engine);

                switch (get_stop_event(context)) {
                case PTRACE_EVENT_VFORK:
                        if (context->options & PTRACE_O_TRACEVFORKDONE) {
                                set_stop_code(context, PTRACE_EVENT_VFORK_DONE);
                                utrace_control(tracee, engine, UTRACE_REPORT);
                                return;
                        }
                        break;

                case PTRACE_EVENT_EXEC:
                case PTRACE_EVENT_FORK:
                case PTRACE_EVENT_CLONE:
                case PTRACE_EVENT_VFORK_DONE:
                        if (request == PTRACE_SYSCALL) {
                                set_syscall_code(context, 
PTRACE_EVENT_SYSCALL_EXIT);
                                do_ptrace_notify_stop(context, tracee);
                                return;
                        }
                        /* fallthrough, but suppress send_sig_info() below */
                        data = 0;

                case PTRACE_EVENT_SYSCALL_EXIT:
                        if (action != UTRACE_RESUME) {
                                read_lock(&tasklist_lock);
                                if (tracee->sighand)
                                        send_sigtrap(tracee, 
task_pt_regs(tracee),
                                                        0, TRAP_BRKPT);
                                read_unlock(&tasklist_lock);
                                action = UTRACE_RESUME;
                        }
                        /* fallthrough */

                case PTRACE_EVENT_SYSCALL_ENTRY:
                        if (data)
                                send_sig_info(data, SEND_SIG_PRIV, tracee);
                        break;

                case PTRACE_EVENT_SIGNAL:
                        context->signr = data;
                        break;

                case 0:
                        // XXX: JCTL stop
                        break;
                }

                context->resume = action;
                ptrace_wake_up(tracee, engine, action, true);
        }

---

 kernel/ptrace.c |   53 +++++++++++++++++++++++------------------------------
 1 file changed, 23 insertions(+), 30 deletions(-)

--- PU/kernel/ptrace.c~100_RESUME_CONSOLIDATE_SWITCH    2009-10-17 
19:50:54.000000000 +0200
+++ PU/kernel/ptrace.c  2009-10-18 16:51:38.000000000 +0200
@@ -972,10 +972,6 @@ static void do_ptrace_resume(struct utra
        struct ptrace_context *context = ptrace_context(engine);
 
        switch (get_stop_event(context)) {
-       case 0:
-               // XXX: JCTL stop
-               break;
-
        case PTRACE_EVENT_VFORK:
                if (context->options & PTRACE_O_TRACEVFORKDONE) {
                        set_stop_code(context, PTRACE_EVENT_VFORK_DONE);
@@ -984,45 +980,41 @@ static void do_ptrace_resume(struct utra
                }
                break;
 
-       case PTRACE_EVENT_SYSCALL_ENTRY:
-       case PTRACE_EVENT_SYSCALL_EXIT:
-               if (data)
-                       send_sig_info(data, SEND_SIG_PRIV, tracee);
-               break;
-
-       case PTRACE_EVENT_SIGNAL:
-               context->signr = data;
-               break;
-       }
-
-       if (request == PTRACE_SYSCALL) {
-               switch (get_stop_event(context)) {
-               case PTRACE_EVENT_EXEC:
-               case PTRACE_EVENT_FORK:
-               case PTRACE_EVENT_CLONE:
-               case PTRACE_EVENT_VFORK_DONE:
+       case PTRACE_EVENT_EXEC:
+       case PTRACE_EVENT_FORK:
+       case PTRACE_EVENT_CLONE:
+       case PTRACE_EVENT_VFORK_DONE:
+               if (request == PTRACE_SYSCALL) {
                        set_syscall_code(context, PTRACE_EVENT_SYSCALL_EXIT);
                        do_ptrace_notify_stop(context, tracee);
                        return;
                }
-       }
+               /* fallthrough, but suppress send_sig_info() below */
+               data = 0;
 
-       if (action != UTRACE_RESUME) {
-               switch (get_stop_event(context)) {
-               case PTRACE_EVENT_EXEC:
-               case PTRACE_EVENT_FORK:
-               case PTRACE_EVENT_CLONE:
-               case PTRACE_EVENT_VFORK_DONE:
-               case PTRACE_EVENT_SYSCALL_EXIT:
+       case PTRACE_EVENT_SYSCALL_EXIT:
+               if (action != UTRACE_RESUME) {
                        read_lock(&tasklist_lock);
                        if (tracee->sighand)
                                send_sigtrap(tracee, task_pt_regs(tracee),
                                                0, TRAP_BRKPT);
                        read_unlock(&tasklist_lock);
-
                        action = UTRACE_RESUME;
-                       break;
                }
+               /* fallthrough */
+
+       case PTRACE_EVENT_SYSCALL_ENTRY:
+               if (data)
+                       send_sig_info(data, SEND_SIG_PRIV, tracee);
+               break;
+
+       case PTRACE_EVENT_SIGNAL:
+               context->signr = data;
+               break;
+
+       case 0:
+               // XXX: JCTL stop
+               break;
        }
 
        context->resume = action;

Reply via email to