예제 #1
0
void
native_to_linux_sigaction(struct linux_sigaction *lsa, const struct sigaction *bsa)
{
	lsa->linux_sa_handler = bsa->sa_handler;
	native_to_linux_sigset(&lsa->linux_sa_mask, &bsa->sa_mask);
	lsa->linux_sa_flags = native_to_linux_sigflags(bsa->sa_flags);
#ifndef __alpha__
	lsa->linux_sa_restorer = NULL;
#endif
}
예제 #2
0
static void
linux_save_ucontext(struct lwp *l, struct trapframe *tf, const sigset_t *mask, struct sigaltstack *sas, struct linux_ucontext *uc)
{
	uc->uc_flags = 0;
	uc->uc_link = NULL;
	native_to_linux_sigaltstack(&uc->uc_stack, sas);
	linux_save_sigcontext(l, tf, mask, &uc->uc_mcontext);
	native_to_linux_sigset(&uc->uc_sigmask, mask);
	(void)memset(&uc->uc_fpregs_mem, 0, sizeof(uc->uc_fpregs_mem));
}
예제 #3
0
void
native_to_linux_old_extra_sigset(linux_old_sigset_t *lss, unsigned long *extra, const sigset_t *bss)
{
	linux_sigset_t lsnew;

	native_to_linux_sigset(&lsnew, bss);

	/* convert new sigset to old sigset */
	*lss = lsnew.sig[0];
	if (extra)
		memcpy(extra, &lsnew.sig[1],
		    sizeof(linux_sigset_t) - sizeof(linux_old_sigset_t));
}
예제 #4
0
int
linux_sys_rt_sigprocmask(struct lwp *l, const struct linux_sys_rt_sigprocmask_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) how;
		syscallarg(const linux_sigset_t *) set;
		syscallarg(linux_sigset_t *) oset;
		syscallarg(size_t) sigsetsize;
	} */
	linux_sigset_t nlss, olss, *oset;
	const linux_sigset_t *set;
	struct proc *p = l->l_proc;
	sigset_t nbss, obss;
	int error, how;

	if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
		return (EINVAL);

	switch (SCARG(uap, how)) {
	case LINUX_SIG_BLOCK:
		how = SIG_BLOCK;
		break;
	case LINUX_SIG_UNBLOCK:
		how = SIG_UNBLOCK;
		break;
	case LINUX_SIG_SETMASK:
		how = SIG_SETMASK;
		break;
	default:
		return (EINVAL);
	}

	set = SCARG(uap, set);
	oset = SCARG(uap, oset);

	if (set) {
		error = copyin(set, &nlss, sizeof(nlss));
		if (error)
			return (error);
		linux_to_native_sigset(&nbss, &nlss);
	}
	mutex_enter(p->p_lock);
	error = sigprocmask1(l, how,
	    set ? &nbss : NULL, oset ? &obss : NULL);
	mutex_exit(p->p_lock);
	if (!error && oset) {
		native_to_linux_sigset(&olss, &obss);
		error = copyout(&olss, oset, sizeof(olss));
	}
	return (error);
}
예제 #5
0
int
linux_sys_rt_sigpending(struct lwp *l, const struct linux_sys_rt_sigpending_args *uap, register_t *retval)
{
	/* {
		syscallarg(linux_sigset_t *) set;
		syscallarg(size_t) sigsetsize;
	} */
	sigset_t bss;
	linux_sigset_t lss;

	if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
		return (EINVAL);

	sigpending1(l, &bss);
	native_to_linux_sigset(&lss, &bss);
	return copyout(&lss, SCARG(uap, set), sizeof(lss));
}
예제 #6
0
void
linux_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
{
    const int sig = ksi->ksi_signo;
    struct lwp *l = curlwp;
    struct proc *p = l->l_proc;
    struct sigacts *ps = p->p_sigacts;
    struct linux_rt_sigframe *fp;
    struct frame *f;
    int i, onstack, error;
    struct linux_rt_sigframe sf;

#ifdef DEBUG_LINUX
    printf("linux_sendsig()\n");
#endif /* DEBUG_LINUX */
    f = (struct frame *)l->l_md.md_regs;

    /*
     * Do we need to jump onto the signal stack?
     */
    onstack =
        (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
        (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;

    /*
     * Allocate space for the signal handler context.
     */
    if (onstack)
        panic("linux_sendsig: onstack notyet");
    else
        fp = (struct linux_rt_sigframe *)(u_int32_t)f->f_regs[_R_SP];

    /*
     * Build stack frame for signal trampoline.
     */
    memset(&sf, 0, sizeof sf);

#if LINUX_SYS_rt_sigreturn > 127
#error LINUX_SYS_rt_sigreturn does not fit in a 16-bit opcode.
#endif

    /*
     * This is the signal trampoline used by Linux, we don't use it,
     * but we set it up in case an application expects it to be there.
     *
     * 	mov	r8, LINUX_SYS_rt_sigreturn
     * 	scall
     */
    sf.lrs_code = (0x3008d733 | LINUX_SYS_rt_sigreturn << 20);

    /*
     * The user context.
     */
    native_to_linux_sigset(&sf.lrs_uc.luc_sigmask, mask);
    sf.lrs_uc.luc_flags = 0;
    sf.lrs_uc.luc_link = NULL;

    /* This is used regardless of SA_ONSTACK in Linux AVR32. */
    sf.lrs_uc.luc_stack.ss_sp = l->l_sigstk.ss_sp;
    sf.lrs_uc.luc_stack.ss_size = l->l_sigstk.ss_size;
    sf.lrs_uc.luc_stack.ss_flags = 0;
    if (l->l_sigstk.ss_flags & SS_ONSTACK)
        sf.lrs_uc.luc_stack.ss_flags |= LINUX_SS_ONSTACK;
    if (l->l_sigstk.ss_flags & SS_DISABLE)
        sf.lrs_uc.luc_stack.ss_flags |= LINUX_SS_DISABLE;
    memcpy(sf.lrs_uc.luc_mcontext.lsc_regs, f->f_regs,
           sizeof(sf.lrs_uc.luc_mcontext.lsc_regs));
    sendsig_reset(l, sig);

    /*
     * Install the sigframe onto the stack.
     */
    fp -= sizeof(struct linux_rt_sigframe);
    mutex_exit(p->p_lock);
    error = copyout(&sf, fp, sizeof(sf));
    mutex_enter(p->p_lock);

    if (error != 0) {
        /*
         * Process has trashed its stack; give it an illegal
         * instruction to halt it in its tracks.
         */
#ifdef DEBUG_LINUX
        printf("linux_sendsig: stack trashed\n");
#endif /* DEBUG_LINUX */
        sigexit(l, SIGILL);
        /* NOTREACHED */
    }

#ifdef DEBUG_LINUX
    printf("sigcontext is at %p\n", &fp->lrs_sc);
#endif /* DEBUG_LINUX */

    /* Set up the registers to return to sigcode. */
    f->f_regs[_R_SP] = (register_t)fp;
    f->f_regs[_R_R12] = native_to_linux_signo[sig];
    f->f_regs[_R_R11] = 0;
    f->f_regs[_R_R10] = (register_t)&fp->lrs_uc;
    f->f_regs[_R_PC] = (register_t)SIGACTION(p, sig).sa_handler;

#define RESTORER(p, sig) \
	(p->p_sigacts->sa_sigdesc[(sig)].sd_tramp)

    if (ps->sa_sigdesc[sig].sd_vers != 0)
        f->f_regs[_R_LR] = (register_t)RESTORER(p, sig);
    else
        panic("linux_sendsig: SA_RESTORER");

    /* Remember that we're now on the signal stack. */
    if (onstack)
        l->l_sigstk.ss_flags |= SS_ONSTACK;

    return;
}
예제 #7
0
void
setup_linux_rt_sigframe(struct trapframe *tf, const ksiginfo_t *ksi,
    const sigset_t *mask)
{
	struct lwp *l = curlwp;
	struct proc *p = l->l_proc;
	struct linux_rt_sigframe *sfp, sigframe;
	int onstack, error;
	int fsize, rndfsize;
	int sig = ksi->ksi_signo;
	extern char linux_rt_sigcode[], linux_rt_esigcode[];

	/* Do we need to jump onto the signal stack? */
	onstack = (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
		  (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;

	/* Allocate space for the signal handler context.  */
	fsize = sizeof(struct linux_rt_sigframe);
	rndfsize = ((fsize + 15) / 16) * 16;

	if (onstack)
		sfp = (struct linux_rt_sigframe *)
		    ((char *)l->l_sigstk.ss_sp + l->l_sigstk.ss_size);
	else
		sfp = (struct linux_rt_sigframe *)(alpha_pal_rdusp());
	sfp = (struct linux_rt_sigframe *)((char *)sfp - rndfsize);

#ifdef DEBUG
	if ((sigdebug & SDB_KSTACK) && (p->p_pid == sigpid))
		printf("linux_sendsig(%d): sig %d ssp %p usp %p\n", p->p_pid,
		    sig, &onstack, sfp);
#endif /* DEBUG */

	/*
	 * Build the signal context to be used by sigreturn.
	 */
	memset(&sigframe.uc, 0, sizeof(struct linux_ucontext));
	sigframe.uc.uc_mcontext.sc_onstack = onstack;

	/* Setup potentially partial signal mask in sc_mask. */
	/* But get all of it in uc_sigmask */
	native_to_linux_old_sigset(&sigframe.uc.uc_mcontext.sc_mask, mask);
	native_to_linux_sigset(&sigframe.uc.uc_sigmask, mask);

	sigframe.uc.uc_mcontext.sc_pc = tf->tf_regs[FRAME_PC];
	sigframe.uc.uc_mcontext.sc_ps = ALPHA_PSL_USERMODE;
	frametoreg(tf, (struct reg *)sigframe.uc.uc_mcontext.sc_regs);
	sigframe.uc.uc_mcontext.sc_regs[R_SP] = alpha_pal_rdusp();

	fpu_load();
	alpha_pal_wrfen(1);
	sigframe.uc.uc_mcontext.sc_fpcr = alpha_read_fpcr();
	sigframe.uc.uc_mcontext.sc_fp_control = alpha_read_fp_c(l);
	alpha_pal_wrfen(0);

	sigframe.uc.uc_mcontext.sc_traparg_a0 = tf->tf_regs[FRAME_A0];
	sigframe.uc.uc_mcontext.sc_traparg_a1 = tf->tf_regs[FRAME_A1];
	sigframe.uc.uc_mcontext.sc_traparg_a2 = tf->tf_regs[FRAME_A2];
	native_to_linux_siginfo(&sigframe.info, &ksi->ksi_info);
	sendsig_reset(l, sig);
	mutex_exit(p->p_lock);
	error = copyout((void *)&sigframe, (void *)sfp, fsize);
	mutex_enter(p->p_lock);

	if (error != 0) {
#ifdef DEBUG
		if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
			printf("sendsig(%d): copyout failed on sig %d\n",
			    p->p_pid, sig);
#endif
		/*
		 * Process has trashed its stack; give it an illegal
		 * instruction to halt it in its tracks.
		 */
		sigexit(l, SIGILL);
		/* NOTREACHED */
	}

	/* Pass pointers to siginfo and ucontext in the regs */
	tf->tf_regs[FRAME_A1] = (unsigned long)&sfp->info;
	tf->tf_regs[FRAME_A2] = (unsigned long)&sfp->uc;

	/* Address of trampoline code.  End up at this PC after mi_switch */
	tf->tf_regs[FRAME_PC] =
	    (u_int64_t)(p->p_psstrp - (linux_rt_esigcode - linux_rt_sigcode));

	/* Adjust the stack */
	alpha_pal_wrusp((unsigned long)sfp);

	/* Remember that we're now on the signal stack. */
	if (onstack)
		l->l_sigstk.ss_flags |= SS_ONSTACK;
}
예제 #8
0
void
linux_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
{
	const int sig = ksi->ksi_signo;
	struct lwp *l = curlwp;
	struct proc *p = l->l_proc;
	struct linux_sigframe *fp;
	struct frame *f;
	int i, onstack, error;
	sig_t catcher = SIGACTION(p, sig).sa_handler;
	struct linux_sigframe sf;

#ifdef DEBUG_LINUX
	printf("linux_sendsig()\n");
#endif /* DEBUG_LINUX */
	f = (struct frame *)l->l_md.md_regs;

	/*
	 * Do we need to jump onto the signal stack?
	 */
	onstack =
	    (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
	    (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;

	/*
	 * Signal stack is broken (see at the end of linux_sigreturn), so we do
	 * not use it yet. XXX fix this.
	 */
	onstack=0;

	/*
	 * Allocate space for the signal handler context.
	 */
	if (onstack)
		fp = (struct linux_sigframe *)
		    ((uint8_t *)l->l_sigstk.ss_sp
		    + l->l_sigstk.ss_size);
	else
		/* cast for _MIPS_BSD_API == _MIPS_BSD_API_LP32_64CLEAN case */
		fp = (struct linux_sigframe *)(u_int32_t)f->f_regs[_R_SP];

	/*
	 * Build stack frame for signal trampoline.
	 */
	memset(&sf, 0, sizeof sf);

	/*
	 * This is the signal trampoline used by Linux, we don't use it,
	 * but we set it up in case an application expects it to be there
	 */
	sf.lsf_code[0] = 0x24020000;	/* li	v0, __NR_sigreturn	*/
	sf.lsf_code[1] = 0x0000000c;	/* syscall			*/

	native_to_linux_sigset(&sf.lsf_mask, mask);
	for (i=0; i<32; i++) {
		sf.lsf_sc.lsc_regs[i] = f->f_regs[i];
	}
	sf.lsf_sc.lsc_mdhi = f->f_regs[_R_MULHI];
	sf.lsf_sc.lsc_mdlo = f->f_regs[_R_MULLO];
	sf.lsf_sc.lsc_pc = f->f_regs[_R_PC];
	sf.lsf_sc.lsc_status = f->f_regs[_R_SR];
	sf.lsf_sc.lsc_cause = f->f_regs[_R_CAUSE];
	sf.lsf_sc.lsc_badvaddr = f->f_regs[_R_BADVADDR];
	sendsig_reset(l, sig);

	/*
	 * Save signal stack.  XXX broken
	 */
	/* kregs.sc_onstack = l->l_sigstk.ss_flags & SS_ONSTACK; */

	/*
	 * Install the sigframe onto the stack
	 */
	fp -= sizeof(struct linux_sigframe);
	mutex_exit(p->p_lock);
	error = copyout(&sf, fp, sizeof(sf));
	mutex_enter(p->p_lock);

	if (error != 0) {
		/*
		 * Process has trashed its stack; give it an illegal
		 * instruction to halt it in its tracks.
		 */
#ifdef DEBUG_LINUX
		printf("linux_sendsig: stack trashed\n");
#endif /* DEBUG_LINUX */
		sigexit(l, SIGILL);
		/* NOTREACHED */
	}

	/* Set up the registers to return to sigcode. */
	f->f_regs[_R_A0] = native_to_linux_signo[sig];
	f->f_regs[_R_A1] = 0;
	f->f_regs[_R_A2] = (unsigned long)&fp->lsf_sc;

#ifdef DEBUG_LINUX
	printf("sigcontext is at %p\n", &fp->lsf_sc);
#endif /* DEBUG_LINUX */

	f->f_regs[_R_SP] = (unsigned long)fp;
	/* Signal trampoline code is at base of user stack. */
	f->f_regs[_R_RA] = (unsigned long)p->p_sigctx.ps_sigcode;
	f->f_regs[_R_T9] = (unsigned long)catcher;
	f->f_regs[_R_PC] = (unsigned long)catcher;

	/* Remember that we're now on the signal stack. */
	if (onstack)
		l->l_sigstk.ss_flags |= SS_ONSTACK;

	return;
}
예제 #9
0
void
linux_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
{
	struct lwp *l = curlwp;
	struct proc *p = l->l_proc;
	struct sigacts *ps = p->p_sigacts;
	int onstack, error;
	int sig = ksi->ksi_signo;
	struct linux_rt_sigframe *sfp, sigframe;
	struct linux__fpstate *fpsp, fpstate;
	struct fpreg fpregs;
	struct trapframe *tf = l->l_md.md_regs;
	sig_t catcher = SIGACTION(p, sig).sa_handler;
	linux_sigset_t lmask;
	char *sp;

	/* Do we need to jump onto the signal stack? */
	onstack =
	    (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
	    (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
	
	/* Allocate space for the signal handler context. */
	if (onstack)
		sp = ((char *)l->l_sigstk.ss_sp +
		    l->l_sigstk.ss_size);
	else
		sp = (char *)tf->tf_rsp - 128;

	/* 
	 * Save FPU state, if any 
	 */
	if (l->l_md.md_flags & MDP_USEDFPU) {
		sp = (char *)
		    (((long)sp - sizeof(struct linux__fpstate)) & ~0xfUL);
		fpsp = (struct linux__fpstate *)sp;
	} else
		fpsp = NULL;

	/* 
	 * Populate the rt_sigframe 
	 */
	sp = (char *)
	    ((((long)sp - sizeof(struct linux_rt_sigframe)) & ~0xfUL) - 8);
	sfp = (struct linux_rt_sigframe *)sp;

	bzero(&sigframe, sizeof(sigframe));
	if (ps->sa_sigdesc[sig].sd_vers != 0)
		sigframe.pretcode = 
		    (char *)(u_long)ps->sa_sigdesc[sig].sd_tramp;
	else
		sigframe.pretcode = NULL;

	/* 
	 * The user context 
	 */
	sigframe.uc.luc_flags = 0;
	sigframe.uc.luc_link = NULL;

	/* This is used regardless of SA_ONSTACK in Linux */
	sigframe.uc.luc_stack.ss_sp = l->l_sigstk.ss_sp;
	sigframe.uc.luc_stack.ss_size = l->l_sigstk.ss_size;
	sigframe.uc.luc_stack.ss_flags = 0;
	if (l->l_sigstk.ss_flags & SS_ONSTACK)
		sigframe.uc.luc_stack.ss_flags |= LINUX_SS_ONSTACK;
	if (l->l_sigstk.ss_flags & SS_DISABLE)
		sigframe.uc.luc_stack.ss_flags |= LINUX_SS_DISABLE;

	sigframe.uc.luc_mcontext.r8 = tf->tf_r8;
	sigframe.uc.luc_mcontext.r9 = tf->tf_r9;
	sigframe.uc.luc_mcontext.r10 = tf->tf_r10;
	sigframe.uc.luc_mcontext.r11 = tf->tf_r11;
	sigframe.uc.luc_mcontext.r12 = tf->tf_r12;
	sigframe.uc.luc_mcontext.r13 = tf->tf_r13;
	sigframe.uc.luc_mcontext.r14 = tf->tf_r14;
	sigframe.uc.luc_mcontext.r15 = tf->tf_r15;
	sigframe.uc.luc_mcontext.rdi = tf->tf_rdi;
	sigframe.uc.luc_mcontext.rsi = tf->tf_rsi;
	sigframe.uc.luc_mcontext.rbp = tf->tf_rbp;
	sigframe.uc.luc_mcontext.rbx = tf->tf_rbx;
	sigframe.uc.luc_mcontext.rdx = tf->tf_rdx;
	sigframe.uc.luc_mcontext.rax = tf->tf_rax;
	sigframe.uc.luc_mcontext.rcx = tf->tf_rcx;
	sigframe.uc.luc_mcontext.rsp = tf->tf_rsp;
	sigframe.uc.luc_mcontext.rip = tf->tf_rip;
	sigframe.uc.luc_mcontext.eflags = tf->tf_rflags;
	sigframe.uc.luc_mcontext.cs = tf->tf_cs;
	sigframe.uc.luc_mcontext.gs = tf->tf_gs;
	sigframe.uc.luc_mcontext.fs = tf->tf_fs;
	sigframe.uc.luc_mcontext.err = tf->tf_err;
	sigframe.uc.luc_mcontext.trapno = tf->tf_trapno;
	native_to_linux_sigset(&lmask, mask);
	sigframe.uc.luc_mcontext.oldmask = lmask.sig[0];
	sigframe.uc.luc_mcontext.cr2 = (long)l->l_addr->u_pcb.pcb_onfault;
	sigframe.uc.luc_mcontext.fpstate = fpsp;
	native_to_linux_sigset(&sigframe.uc.luc_sigmask, mask);

	/* 
	 * the siginfo structure
	 */
	sigframe.info.lsi_signo = native_to_linux_signo[sig];
	sigframe.info.lsi_errno = native_to_linux_errno[ksi->ksi_errno];
	sigframe.info.lsi_code = native_to_linux_si_code(ksi->ksi_code);

	/* XXX This is a rought conversion, taken from i386 code */
	switch (sigframe.info.lsi_signo) {
	case LINUX_SIGILL:
	case LINUX_SIGFPE:
	case LINUX_SIGSEGV:
	case LINUX_SIGBUS:
	case LINUX_SIGTRAP:
		sigframe.info._sifields._sigfault._addr = ksi->ksi_addr;
		break;
	case LINUX_SIGCHLD:
		sigframe.info._sifields._sigchld._pid = ksi->ksi_pid;
		sigframe.info._sifields._sigchld._uid = ksi->ksi_uid;
		sigframe.info._sifields._sigchld._utime = ksi->ksi_utime;
		sigframe.info._sifields._sigchld._stime = ksi->ksi_stime;

		if (WCOREDUMP(ksi->ksi_status)) {
			sigframe.info.lsi_code = LINUX_CLD_DUMPED;
			sigframe.info._sifields._sigchld._status =
			    _WSTATUS(ksi->ksi_status);
		} else if (_WSTATUS(ksi->ksi_status)) {
			sigframe.info.lsi_code = LINUX_CLD_KILLED;
			sigframe.info._sifields._sigchld._status =
			    _WSTATUS(ksi->ksi_status);
		} else {
			sigframe.info.lsi_code = LINUX_CLD_EXITED;
			sigframe.info._sifields._sigchld._status =
			    ((ksi->ksi_status & 0xff00U) >> 8);
		}
		break;
	case LINUX_SIGIO:
		sigframe.info._sifields._sigpoll._band = ksi->ksi_band;
		sigframe.info._sifields._sigpoll._fd = ksi->ksi_fd;
		break;
	default:
		sigframe.info._sifields._sigchld._pid = ksi->ksi_pid;
		sigframe.info._sifields._sigchld._uid = ksi->ksi_uid;
		if ((sigframe.info.lsi_signo == LINUX_SIGALRM) ||
		    (sigframe.info.lsi_signo >= LINUX_SIGRTMIN))
			sigframe.info._sifields._timer._sigval.sival_ptr =
			     ksi->ksi_value.sival_ptr;
		break;
	}

	sendsig_reset(l, sig);
	mutex_exit(p->p_lock);
	error = 0;

	/* 
	 * Save FPU state, if any 
	 */
	if (fpsp != NULL) {
		(void)process_read_fpregs(l, &fpregs);
		bzero(&fpstate, sizeof(fpstate));
		fpstate.cwd = fpregs.fp_fcw;
		fpstate.swd = fpregs.fp_fsw;
		fpstate.twd = fpregs.fp_ftw;
		fpstate.fop = fpregs.fp_fop;
		fpstate.rip = fpregs.fp_rip;
		fpstate.rdp = fpregs.fp_rdp;
		fpstate.mxcsr = fpregs.fp_mxcsr;
		fpstate.mxcsr_mask = fpregs.fp_mxcsr_mask;
		memcpy(&fpstate.st_space, &fpregs.fp_st, 
		    sizeof(fpstate.st_space));
		memcpy(&fpstate.xmm_space, &fpregs.fp_xmm, 
		    sizeof(fpstate.xmm_space));
		error = copyout(&fpstate, fpsp, sizeof(fpstate));
	}

	if (error == 0)
		error = copyout(&sigframe, sp, sizeof(sigframe));

	mutex_enter(p->p_lock);

	if (error != 0) {
		sigexit(l, SIGILL);
		return;
	}	

	linux_buildcontext(l, catcher, sp);
	tf->tf_rdi = sigframe.info.lsi_signo;
	tf->tf_rax = 0;
	tf->tf_rsi = (long)&sfp->info;
	tf->tf_rdx = (long)&sfp->uc;

	/*
	 * Remember we use signal stack
	 */
	if (onstack)
		l->l_sigstk.ss_flags |= SS_ONSTACK;
	return;
}