Exemple #1
0
void
native_to_linux_old_sigaction(struct linux_old_sigaction *lsa, const struct sigaction *bsa)
{
	lsa->linux_sa_handler = bsa->sa_handler;
	native_to_linux_old_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
}
Exemple #2
0
int
linux_sys_sigpending(struct lwp *l, const struct linux_sys_sigpending_args *uap, register_t *retval)
{
	/* {
		syscallarg(linux_old_sigset_t *) mask;
	} */
	sigset_t bss;
	linux_old_sigset_t lss;

	sigpending1(l, &bss);
	native_to_linux_old_sigset(&lss, &bss);
	return copyout(&lss, SCARG(uap, set), sizeof(lss));
}
/* ARGSUSED */
int
linux_sys_siggetmask(struct lwp *l, const void *v, register_t *retval)
{
    struct proc *p = l->l_proc;
    sigset_t bss;
    linux_old_sigset_t lss;
    int error;

    mutex_enter(p->p_lock);
    error = sigprocmask1(l, SIG_SETMASK, 0, &bss);
    mutex_exit(p->p_lock);
    if (error)
        return (error);
    native_to_linux_old_sigset(&lss, &bss);
    return (0);
}
Exemple #4
0
static void
linux_save_sigcontext(struct lwp *l, struct trapframe *tf,
    const sigset_t *mask, struct linux_sigcontext *sc)
{
	struct pcb *pcb = lwp_getpcb(l);

	/* Save register context. */
#ifdef VM86
	if (tf->tf_eflags & PSL_VM) {
		sc->sc_gs = tf->tf_vm86_gs;
		sc->sc_fs = tf->tf_vm86_fs;
		sc->sc_es = tf->tf_vm86_es;
		sc->sc_ds = tf->tf_vm86_ds;
		sc->sc_eflags = get_vflags(l);
	} else
#endif
	{
		sc->sc_gs = tf->tf_gs;
		sc->sc_fs = tf->tf_fs;
		sc->sc_es = tf->tf_es;
		sc->sc_ds = tf->tf_ds;
		sc->sc_eflags = tf->tf_eflags;
	}
	sc->sc_edi = tf->tf_edi;
	sc->sc_esi = tf->tf_esi;
	sc->sc_esp = tf->tf_esp;
	sc->sc_ebp = tf->tf_ebp;
	sc->sc_ebx = tf->tf_ebx;
	sc->sc_edx = tf->tf_edx;
	sc->sc_ecx = tf->tf_ecx;
	sc->sc_eax = tf->tf_eax;
	sc->sc_eip = tf->tf_eip;
	sc->sc_cs = tf->tf_cs;
	sc->sc_esp_at_signal = tf->tf_esp;
	sc->sc_ss = tf->tf_ss;
	sc->sc_err = tf->tf_err;
	sc->sc_trapno = tf->tf_trapno;
	sc->sc_cr2 = pcb->pcb_cr2;
	sc->sc_387 = NULL;

	/* Save signal stack. */
	/* Linux doesn't save the onstack flag in sigframe */

	/* Save signal mask. */
	native_to_linux_old_sigset(&sc->sc_mask, mask);
}
Exemple #5
0
int
linux_sigprocmask1(struct lwp *l, int how, const linux_old_sigset_t *set, linux_old_sigset_t *oset)
{
	struct proc *p = l->l_proc;
	linux_old_sigset_t nlss, olss;
	sigset_t nbss, obss;
	int error;

	switch (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);
	}

	if (set) {
		error = copyin(set, &nlss, sizeof(nlss));
		if (error)
			return (error);
		linux_old_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)
		return (error);
	if (oset) {
		native_to_linux_old_sigset(&olss, &obss);
		error = copyout(&olss, oset, sizeof(olss));
		if (error)
			return (error);
	}
	return (error);
}
/*
 * The following three functions fiddle with a process' signal mask.
 * Convert the signal masks because of the different signal
 * values for Linux. The need for this is the reason why
 * they are here, and have not been mapped directly.
 */
int
linux_sys_sigsetmask(struct lwp *l, const struct linux_sys_sigsetmask_args *uap, register_t *retval)
{
    /* {
    	syscallarg(linux_old_sigset_t) mask;
    } */
    sigset_t nbss, obss;
    linux_old_sigset_t nlss, olss;
    struct proc *p = l->l_proc;
    int error;

    nlss = SCARG(uap, mask);
    linux_old_to_native_sigset(&nbss, &nlss);
    mutex_enter(p->p_lock);
    error = sigprocmask1(l, SIG_SETMASK, &nbss, &obss);
    mutex_exit(p->p_lock);
    if (error)
        return (error);
    native_to_linux_old_sigset(&olss, &obss);
    *retval = olss;
    return (0);
}
Exemple #7
0
void setup_linux_sigframe(struct trapframe *tf, const ksiginfo_t *ksi,
    const sigset_t *mask)
{
	struct lwp *l = curlwp;
	struct proc *p = l->l_proc;
	struct linux_sigframe *sfp, sigframe;
	int onstack, error;
	int fsize, rndfsize;
	int sig = ksi->ksi_signo;
	extern char linux_sigcode[], linux_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_sigframe);
	rndfsize = ((fsize + 15) / 16) * 16;

	if (onstack)
		sfp = (struct linux_sigframe *)
		    ((char *)l->l_sigstk.ss_sp + l->l_sigstk.ss_size);
	else
		sfp = (struct linux_sigframe *)(alpha_pal_rdusp());
	sfp = (struct linux_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.sf_sc, 0, sizeof(struct linux_sigcontext));
	sigframe.sf_sc.sc_onstack = onstack;
	native_to_linux_old_sigset(&sigframe.sf_sc.sc_mask, mask);
	sigframe.sf_sc.sc_pc = tf->tf_regs[FRAME_PC];
	sigframe.sf_sc.sc_ps = ALPHA_PSL_USERMODE;
	frametoreg(tf, (struct reg *)sigframe.sf_sc.sc_regs);
	sigframe.sf_sc.sc_regs[R_SP] = alpha_pal_rdusp();

	if (l == fpcurlwp) {
		struct pcb *pcb = lwp_getpcb(l);

		alpha_pal_wrfen(1);
		savefpstate(&pcb->pcb_fp);
		alpha_pal_wrfen(0);
		sigframe.sf_sc.sc_fpcr = pcb->pcb_fp.fpr_cr;
		fpcurlwp = NULL;
	}
	/* XXX ownedfp ? etc...? */

	sigframe.sf_sc.sc_traparg_a0 = tf->tf_regs[FRAME_A0];
	sigframe.sf_sc.sc_traparg_a1 = tf->tf_regs[FRAME_A1];
	sigframe.sf_sc.sc_traparg_a2 = tf->tf_regs[FRAME_A2];

	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 sigcontext in the regs */
	tf->tf_regs[FRAME_A1] = 0;
	tf->tf_regs[FRAME_A2] = (unsigned long)&sfp->sf_sc;

	/* Address of trampoline code.  End up at this PC after mi_switch */
	tf->tf_regs[FRAME_PC] =
	    (u_int64_t)(p->p_psstrp - (linux_esigcode - linux_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;
}