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