sigset_t *set, struct pt_regs * regs);
asmlinkage long
-sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs regs)
+sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs)
{
sigset_t saveset, newset;
spin_unlock_irq(¤t->sighand->siglock);
#ifdef DEBUG_SIG
printk("rt_sigsuspend savset(%lx) newset(%lx) regs(%p) rip(%lx)\n",
- saveset, newset, ®s, regs.rip);
+ saveset, newset, regs, regs->rip);
#endif
- regs.rax = -EINTR;
+ regs->rax = -EINTR;
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
- if (do_signal(®s, &saveset))
+ if (do_signal(regs, &saveset))
return -EINTR;
}
}
asmlinkage long
-sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, struct pt_regs regs)
+sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
+ struct pt_regs *regs)
{
- return do_sigaltstack(uss, uoss, regs.rsp);
+ return do_sigaltstack(uss, uoss, regs->rsp);
}
return 1;
}
-asmlinkage long sys_rt_sigreturn(struct pt_regs regs)
+asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
sigset_t set;
long eax;
- frame = (struct rt_sigframe __user *)(regs.rsp - 8);
+ frame = (struct rt_sigframe __user *)(regs->rsp - 8);
if (verify_area(VERIFY_READ, frame, sizeof(*frame))) {
goto badframe;
}
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
- if (restore_sigcontext(®s, &frame->uc.uc_mcontext, &eax)) {
+ if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax)) {
goto badframe;
}
printk("%d sigreturn rip:%lx rsp:%lx frame:%p rax:%lx\n",current->pid,regs.rip,regs.rsp,frame,eax);
#endif
- if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs.rsp) == -EFAULT)
+ if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->rsp) == -EFAULT)
goto badframe;
return eax;
badframe:
- signal_fault(®s,frame,"sigreturn");
+ signal_fault(regs,frame,"sigreturn");
return 0;
}
setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned long mask, struct task_struct *me)
{
int err = 0;
+ unsigned long eflags;
err |= __put_user(0, &sc->gs);
err |= __put_user(0, &sc->fs);
err |= __put_user(me->thread.trap_no, &sc->trapno);
err |= __put_user(me->thread.error_code, &sc->err);
err |= __put_user(regs->rip, &sc->rip);
- err |= __put_user(regs->eflags, &sc->eflags);
+ eflags = regs->eflags;
+ if (current->ptrace & PT_PTRACED) {
+ eflags &= ~TF_MASK;
+ }
+ err |= __put_user(eflags, &sc->eflags);
err |= __put_user(mask, &sc->oldmask);
err |= __put_user(me->thread.cr2, &sc->cr2);
if (ka->sa.sa_flags & SA_RESTORER) {
err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
} else {
- printk("%s forgot to set SA_RESTORER for signal %d.\n", me->comm, sig);
+ /* could use a vstub here */
goto give_sigsegv;
}
regs->rsp = (unsigned long)frame;
set_fs(USER_DS);
- regs->eflags &= ~TF_MASK;
+ if (regs->eflags & TF_MASK) {
+ if (current->ptrace & PT_PTRACED) {
+ ptrace_notify(SIGTRAP);
+ } else {
+ regs->eflags &= ~TF_MASK;
+ }
+ }
#ifdef DEBUG_SIG
printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
return;
give_sigsegv:
- if (sig == SIGSEGV)
- ka->sa.sa_handler = SIG_DFL;
- signal_fault(regs,frame,"signal deliver");
+ force_sigsegv(sig, current);
}
/*
*/
static void
-handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
- struct pt_regs * regs)
+handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
+ sigset_t *oldset, struct pt_regs *regs)
{
- struct k_sigaction *ka = ¤t->sighand->action[sig-1];
-
#ifdef DEBUG_SIG
printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n", current->pid, sig,
regs->rip, regs->rsp, regs);
#endif
setup_rt_frame(sig, ka, info, oldset, regs);
- if (ka->sa.sa_flags & SA_ONESHOT)
- ka->sa.sa_handler = SIG_DFL;
-
if (!(ka->sa.sa_flags & SA_NODEFER)) {
spin_lock_irq(¤t->sighand->siglock);
sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
*/
int do_signal(struct pt_regs *regs, sigset_t *oldset)
{
+ struct k_sigaction ka;
siginfo_t info;
int signr;
if (!oldset)
oldset = ¤t->blocked;
- signr = get_signal_to_deliver(&info, regs, NULL);
+ signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
/* Reenable any watchpoints before delivering the
* signal to user space. The processor register will
asm volatile("movq %0,%%db7" : : "r" (current->thread.debugreg7));
/* Whee! Actually deliver the signal. */
- handle_signal(signr, &info, oldset, regs);
+ handle_signal(signr, &info, &ka, oldset, regs);
return 1;
}