Commit fccd7b34 authored by David S. Miller's avatar David S. Miller

Sparc{,64}: On PTRACEd processes, do the syscall restart before

we notify the parent.
parent ab4d28ea
......@@ -1173,9 +1173,23 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
signr = dequeue_signal(&current->blocked, &info);
spin_unlock_irq(&current->sigmask_lock);
if (!signr) break;
if (!signr)
break;
if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
/* Do the syscall restart before we let the debugger
* look at the child registers.
*/
if (restart_syscall &&
(regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
regs->u_regs[UREG_I0] == ERESTARTSYS ||
regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
/* replay the system call when we are done */
regs->u_regs[UREG_I0] = orig_i0;
regs->pc -= 4;
regs->npc -= 4;
restart_syscall = 0;
}
current->exit_code = signr;
current->state = TASK_STOPPED;
......@@ -1208,8 +1222,8 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
ka = &current->sig->action[signr-1];
if(ka->sa.sa_handler == SIG_IGN) {
if(signr != SIGCHLD)
if (ka->sa.sa_handler == SIG_IGN) {
if (signr != SIGCHLD)
continue;
/* sys_wait4() grabs the master kernel lock, so
......@@ -1221,12 +1235,12 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
;
continue;
}
if(ka->sa.sa_handler == SIG_DFL) {
if (ka->sa.sa_handler == SIG_DFL) {
unsigned long exit_code = signr;
if(current->pid == 1)
if (current->pid == 1)
continue;
switch(signr) {
switch (signr) {
case SIGCONT: case SIGCHLD: case SIGWINCH:
continue;
......@@ -1265,8 +1279,8 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
struct reg_window *rw = (struct reg_window *)regs->u_regs[UREG_FP];
unsigned int ins[8];
while(rw &&
!(((unsigned long) rw) & 0x3)) {
while (rw &&
!(((unsigned long) rw) & 0x3)) {
copy_from_user(ins, &rw->ins[0], sizeof(ins));
printk("Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
rw = (struct reg_window *)(unsigned long)ins[6];
......@@ -1287,15 +1301,15 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
/* NOT REACHED */
}
}
if(restart_syscall)
if (restart_syscall)
syscall_restart(orig_i0, regs, &ka->sa);
handle_signal(signr, ka, &info, oldset, regs, svr4_signal);
return 1;
}
if(restart_syscall &&
(regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
regs->u_regs[UREG_I0] == ERESTARTSYS ||
regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
if (restart_syscall &&
(regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
regs->u_regs[UREG_I0] == ERESTARTSYS ||
regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
/* replay the system call when we are done */
regs->u_regs[UREG_I0] = orig_i0;
regs->pc -= 4;
......
......@@ -709,9 +709,24 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
signr = dequeue_signal(&current->blocked, &info);
spin_unlock_irq(&current->sigmask_lock);
if (!signr) break;
if (!signr)
break;
if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
/* Do the syscall restart before we let the debugger
* look at the child registers.
*/
if (restart_syscall &&
(regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
regs->u_regs[UREG_I0] == ERESTARTSYS ||
regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
/* replay the system call when we are done */
regs->u_regs[UREG_I0] = orig_i0;
regs->tpc -= 4;
regs->tnpc -= 4;
restart_syscall = 0;
}
current->exit_code = signr;
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
......
......@@ -1383,9 +1383,24 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
signr = dequeue_signal(&current->blocked, &info);
spin_unlock_irq(&current->sigmask_lock);
if (!signr) break;
if (!signr)
break;
if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
/* Do the syscall restart before we let the debugger
* look at the child registers.
*/
if (restart_syscall &&
(regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
regs->u_regs[UREG_I0] == ERESTARTSYS ||
regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
/* replay the system call when we are done */
regs->u_regs[UREG_I0] = orig_i0;
regs->tpc -= 4;
regs->tnpc -= 4;
restart_syscall = 0;
}
current->exit_code = signr;
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment