Kill the now unneeded code. >From now ->ptrace is only used for PT_PTRACED and PT_PTRACE_CAP.
--- kernel/ptrace.c | 281 +------------------------------------------------------- 1 file changed, 6 insertions(+), 275 deletions(-) --- PU/kernel/ptrace.c~44_KILL_OLD_CODE 2009-09-16 20:14:57.000000000 +0200 +++ PU/kernel/ptrace.c 2009-09-17 17:54:06.000000000 +0200 @@ -130,65 +130,6 @@ void __ptrace_unlink(struct task_struct arch_ptrace_untrace(child); } -static void ptrace_set_action(struct task_struct *task, - enum utrace_resume_action action, - enum utrace_syscall_action syscall) -{ - task->ptrace &= ~((UTRACE_SYSCALL_MASK | UTRACE_RESUME_MASK) << 16); - task->ptrace |= ((UTRACE_RESUME - action) | syscall) << 16; -} - -static enum utrace_resume_action ptrace_resume_action(struct task_struct *task) -{ - return UTRACE_RESUME - ((task->ptrace >> 16) & UTRACE_RESUME_MASK); -} - -/* - * Remember which event stop this was. We have to keep a record that - * won't be wiped by ptrace_do_wait() when @task->exit_code is cleared. - * So we store the PTRACE_EVENT_* value in a nybble of @task->ptrace. - */ -static void ptrace_set_stop_event(struct task_struct *task, int event) -{ - task->ptrace &= 0xf0ffffffU; - task->ptrace |= event << 24; -} - -static int ptrace_stop_event(struct task_struct *task) -{ - return (task->ptrace >> 24) & 0xf; -} - -/* - * This doesn't really exist in the user API, but we pick an unused value - * encoded with ptrace_set_stop_event() to record when the last stop was - * for a syscall stop. - */ -#define PTRACE_EVENT_SYSCALL 0xf - -static u32 utrace_ptrace_report(u32 action, struct task_struct *task, - int event, int code) -{ - /* - * Special kludge magic in utrace.c (utrace_stop) sees this - * and calls do_notify_parent_cldstop() for us. This kludge - * is necessary to keep that wakeup after we enter TASK_TRACED. - */ - ptrace_set_action(task, UTRACE_STOP, 0); - - /* - * If we already have a pending stop event, then don't override it. - * We'll simulate this stop when the pending one is cleared, - * in ptrace_resume(), below. - */ - if (ptrace_stop_event(task) == 0) { - ptrace_set_stop_event(task, event); - task->exit_code = code; - } - - return action | UTRACE_STOP; -} - static u32 ptrace_report_exit(enum utrace_resume_action action, struct utrace_engine *engine, struct task_struct *task, @@ -372,62 +313,9 @@ static u32 ptrace_report_exec(enum utrac return UTRACE_STOP; } - -static u32 ptrace_resumed(struct task_struct *task, - struct utrace_engine *engine, - siginfo_t *info, struct k_sigaction *return_ka) -{ - enum utrace_resume_action resume = ptrace_resume_action(task); - - /* - * If we're stopping, or we haven't reported any signal, - * then we're all done for now. - */ - if (resume == UTRACE_STOP || !task->last_siginfo) - return UTRACE_SIGNAL_REPORT | resume; - - /* - * We're resuming. If there's no signal to deliver, just go. - * If we were given a signal, deliver it now. - */ - WARN_ON(task->last_siginfo != info); - task->last_siginfo = NULL; - if (!task->exit_code) - return UTRACE_SIGNAL_REPORT | resume; - - /* Update the siginfo structure if the signal has - changed. If the debugger wanted something - specific in the siginfo structure then it should - have updated *info via PTRACE_SETSIGINFO. */ - if (task->exit_code != info->si_signo) { - info->si_signo = task->exit_code; - info->si_errno = 0; - info->si_code = SI_USER; - info->si_pid = task_pid_vnr(task->parent); - info->si_uid = __task_cred(task->parent)->uid; - } - - task->exit_code = 0; - - /* - * If the (new) signal is now blocked, requeue it. - */ - if (sigismember(&task->blocked, info->si_signo)) { - send_sig_info(info->si_signo, info, task); - return UTRACE_SIGNAL_IGN | resume; - } - - spin_lock_irq(&task->sighand->siglock); - *return_ka = task->sighand->action[info->si_signo - 1]; - spin_unlock_irq(&task->sighand->siglock); - - return UTRACE_SIGNAL_DELIVER | resume; -} - /* * XXX: This all is wrong/racy/crashable */ - static void ptrace_resume_signal(struct utrace_engine *engine, struct task_struct *tracee, long data) { @@ -503,41 +391,6 @@ static u32 ptrace_report_signal(u32 acti return UTRACE_STOP | UTRACE_SIGNAL_IGN; } - - // everything below is dead - - switch (utrace_signal_action(action)) { - default: - WARN_ON(ptrace_stop_event(task) && info->si_signo != SIGKILL); - break; - case UTRACE_SIGNAL_HANDLER: - WARN_ON(ptrace_stop_event(task)); - /* - * A handler was set up. If we are stepping, pretend - * another SIGTRAP arrived. - */ - if (ptrace_resume_action(task) == UTRACE_SINGLESTEP || - ptrace_resume_action(task) == UTRACE_BLOCKSTEP) { - memset(info, 0, sizeof *info); - info->si_signo = SIGTRAP; - info->si_code = SIGTRAP; - info->si_pid = task_pid_vnr(task); - info->si_uid = __task_cred(task->parent)->uid; - break; - } - /* Fall through. */ - case UTRACE_SIGNAL_REPORT: - /* - * This is not a new signal, but just a notification we - * asked for. Either we're stopping after another report - * like exec or syscall, or we're resuming. - */ - return ptrace_resumed(task, engine, info, return_ka); - } - - WARN_ON(!valid_signal(info->si_signo)); - task->last_siginfo = info; - return utrace_ptrace_report(UTRACE_SIGNAL_IGN, task, 0, info->si_signo); } static u32 ptrace_report_quiesce(u32 action, @@ -552,11 +405,7 @@ static u32 ptrace_report_quiesce(u32 act return UTRACE_STOP; } - if (event == 0) { - task->last_siginfo = NULL; - } - - return ptrace_resume_action(task); + return UTRACE_RESUME; } static void ptrace_release(void *data) @@ -1048,16 +897,11 @@ void ptrace_notify_stop(struct task_stru } context = ptrace_context(engine); - if (!ev_empty(context)) { - do_ptrace_notify_stop(context, tracee); + + if (WARN_ON(ev_empty(context))) return; - } - if (ptrace_resume_action(tracee) == UTRACE_STOP) { - read_lock(&tasklist_lock); - do_notify_parent_cldstop(tracee, CLD_TRAPPED); - read_unlock(&tasklist_lock); - } + do_ptrace_notify_stop(context, tracee); } static void ptrace_wake_up(struct utrace_engine *engine, @@ -1155,121 +999,8 @@ static int ptrace_resume(struct task_str action = UTRACE_SINGLESTEP; } - if (!ret) { - int event; - - if (!ev_empty(context)) { - do_ptrace_resume(engine, child, request, data); - utrace_engine_put(engine); - return 0; - } - - /* - * If there was a non-signal event reported last time, - * we may need to simulate another event that follows - * it, or do some other special case. We'll set @event - * nonzero here if there is an event to simulate. - */ - event = ptrace_stop_event(child); - ptrace_set_stop_event(child, 0); - - switch (event) { - case 0: - break; - - default: - WARN_ON(1); - case PTRACE_EVENT_EXIT: - event = 0; - break; - - case PTRACE_EVENT_FORK: - case PTRACE_EVENT_CLONE: - case PTRACE_EVENT_EXEC: - case PTRACE_EVENT_VFORK_DONE: - /* - * At these events, @data is ignored. - * After these there might be a syscall-exit stop. - */ - if (request == PTRACE_SYSCALL) { - data = SIGTRAP; - if (context->options & PTRACE_O_TRACESYSGOOD) - data |= 0x80; - ptrace_set_stop_event(child, - PTRACE_EVENT_SYSCALL); - } else { - data = 0; - event = 0; - } - break; - - case PTRACE_EVENT_SYSCALL: - /* - * After a syscall stop, @data is treated specially. - * It just queues the signal. - */ - if (data) { - /* XXX: until do_send_sig_info() */ - read_lock(&tasklist_lock); - if (child->signal) - send_sig(data, child, 1); - read_unlock(&tasklist_lock); - } - data = 0; - event = 0; - break; - - case PTRACE_EVENT_VFORK: - WARN_ON(1); - break; - } - - child->exit_code = data; - - ptrace_set_action(child, action, syscall); - - /* - * Whatever action we want to resume with, we need to make - * sure the child gets into ptrace_report_quiesce() so that - * it clears last_siginfo before going back to user mode. - */ - if (child->last_siginfo) - action = UTRACE_REPORT; - - if (event) { - /* - * We have a stacked event. That is, @child is - * already at the last utrace stop point before - * returning to user mode. But the ptrace API - * wants multiple stops on the way out. Here the - * original ptrace would resume the child and have - * to stop again almost immediately. Instead we - * just leave it stopped and simulate the wake-up - * and new stop by notifying the parent, i.e. - * current's own thread group. - */ - read_lock(&tasklist_lock); - do_notify_parent_cldstop(child, CLD_TRAPPED); - read_unlock(&tasklist_lock); - } else { - unsigned long flags; - - if (lock_task_sighand(child, &flags)) { - child->signal->flags &= ~SIGNAL_STOP_STOPPED; - unlock_task_sighand(child, &flags); - } - - /* - * To resume with a signal we must arrange - * to enter ptrace_report_signal(). - */ - if (data) - action = UTRACE_INTERRUPT; - - if (utrace_control(child, engine, action)) - ret = -ESRCH; - } - } + if (!ret) + do_ptrace_resume(engine, child, request, data); utrace_engine_put(engine);