Preparation, no functional changes.

- change ptrace_report_signal()->resume_signal() to clear ctx->signr,
  not only ctx->siginfo. This allows us to overload ctx->signr.

  IOW, with this patch ctx->signr != 0 is only possible when a tracee
  is stopped with the valid ctx->siginfo after reporting the signal.

- move the "default" case out of "switch()". This allows to re-use
  this code path to inject SIGTRAP's.

---

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

--- PU/kernel/ptrace.c~126_REPORT_SIGNAL_MOVE_DEFAULT   2009-11-01 
22:48:24.000000000 +0100
+++ PU/kernel/ptrace.c  2009-11-02 00:31:30.000000000 +0100
@@ -440,9 +440,15 @@ static u32 ptrace_report_exec(enum utrac
 }
 
 static enum utrace_signal_action resume_signal(struct task_struct *task,
-                                               int signr, siginfo_t *info,
+                                               struct ptrace_context *ctx,
                                                struct k_sigaction *return_ka)
 {
+       siginfo_t *info = ctx->siginfo;
+       int signr = ctx->signr;
+
+       ctx->siginfo = NULL;
+       ctx->signr = 0;
+
        /* Did the debugger cancel the sig? */
        if (!signr)
                return UTRACE_SIGNAL_IGN;
@@ -505,25 +511,26 @@ static u32 ptrace_report_signal(u32 acti
 
                if (WARN_ON(ctx->siginfo != info))
                        return resume | UTRACE_SIGNAL_IGN;
-               ctx->siginfo = NULL;
 
-               return resume | resume_signal(task, ctx->signr,
-                                               info, return_ka);
+               return resume | resume_signal(task, ctx, return_ka);
+
        default:
-               WARN_ON(ctx->siginfo);
-               ctx->siginfo = info;
-               /*
-                * ctx->siginfo points to the caller's stack.
-                * Make sure the subsequent UTRACE_SIGNAL_REPORT clears
-                * ->siginfo before return from get_signal_to_deliver().
-                */
-               utrace_control(task, engine, UTRACE_INTERRUPT);
+               break;
+       }
 
-               ctx->stop_code = (PTRACE_EVENT_SIGNAL << 8) | info->si_signo;
-               ctx->signr   = info->si_signo;
+       WARN_ON(ctx->siginfo);
+       ctx->siginfo = info;
+       /*
+        * ctx->siginfo points to the caller's stack.
+        * Make sure the subsequent UTRACE_SIGNAL_REPORT clears
+        * ->siginfo before return from get_signal_to_deliver().
+        */
+       utrace_control(task, engine, UTRACE_INTERRUPT);
 
-               return UTRACE_STOP | UTRACE_SIGNAL_IGN;
-       }
+       ctx->signr = info->si_signo;
+       ctx->stop_code = (PTRACE_EVENT_SIGNAL << 8) | ctx->signr;
+
+       return UTRACE_STOP | UTRACE_SIGNAL_IGN;
 }
 
 static u32 ptrace_report_quiesce(u32 action,

Reply via email to