static inline void netbsd32_from_partinfo(struct partinfo *p, struct netbsd32_partinfo *s32p, u_long cmd) { NETBSD32PTR32(s32p->disklab, p->disklab); NETBSD32PTR32(s32p->part, p->part); }
void native_to_linux32_sigaction(struct linux32_sigaction *lsa, const struct sigaction *bsa) { NETBSD32PTR32(lsa->linux_sa_handler, bsa->sa_handler); native_to_linux32_sigset(&lsa->linux_sa_mask, &bsa->sa_mask); lsa->linux_sa_flags = native_to_linux32_sigflags(bsa->sa_flags); NETBSD32PTR32(lsa->linux_sa_restorer, NULL); }
static inline void netbsd32_from_opiocdesc(struct opiocdesc *p, struct netbsd32_opiocdesc *s32p, u_long cmd) { s32p->op_nodeid = p->op_nodeid; s32p->op_namelen = p->op_namelen; NETBSD32PTR32(s32p->op_name, p->op_name); s32p->op_buflen = p->op_buflen; NETBSD32PTR32(s32p->op_buf, p->op_buf); }
static void netbsd32_copyoutpiod(const struct ptrace_io_desc *piod, void *addr) { struct netbsd32_ptrace_io_desc piod32; piod32.piod_op = piod->piod_op; NETBSD32PTR32(piod32.piod_offs, piod->piod_offs); NETBSD32PTR32(piod32.piod_addr, piod->piod_addr); piod32.piod_len = (netbsd32_size_t)piod->piod_len; (void) copyout(&piod32, addr, sizeof(piod32)); }
static void linux32_save_sigcontext(struct lwp *l, struct trapframe *tf, const sigset_t *mask, struct linux32_sigcontext *sc) { struct pcb *pcb = lwp_getpcb(l); /* Save register context. */ 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_rflags; sc->sc_edi = tf->tf_rdi; sc->sc_esi = tf->tf_rsi; sc->sc_esp = tf->tf_rsp; sc->sc_ebp = tf->tf_rbp; sc->sc_ebx = tf->tf_rbx; sc->sc_edx = tf->tf_rdx; sc->sc_ecx = tf->tf_rcx; sc->sc_eax = tf->tf_rax; sc->sc_eip = tf->tf_rip; sc->sc_cs = tf->tf_cs; sc->sc_esp_at_signal = tf->tf_rsp; sc->sc_ss = tf->tf_ss; sc->sc_err = tf->tf_err; sc->sc_trapno = tf->tf_trapno; sc->sc_cr2 = pcb->pcb_cr2; NETBSD32PTR32(sc->sc_387, NULL); /* Save signal stack. */ /* Linux doesn't save the onstack flag in sigframe */ /* Save signal mask. */ native_to_linux32_old_sigset(&sc->sc_mask, mask); }
void netbsd32_ktrpsig(int sig, sig_t action, const sigset_t *mask, const ksiginfo_t *ksi) { struct ktrace_entry *kte; lwp_t *l = curlwp; struct { struct netbsd32_ktr_psig kp; siginfo32_t si; } *kbuf; if (!KTRPOINT(l->l_proc, KTR_PSIG)) return; if (ktealloc(&kte, (void *)&kbuf, l, KTR_PSIG, sizeof(*kbuf))) return; kbuf->kp.signo = (char)sig; NETBSD32PTR32(kbuf->kp.action, action); kbuf->kp.mask = *mask; if (ksi) { kbuf->kp.code = KSI_TRAPCODE(ksi); (void)memset(&kbuf->si, 0, sizeof(kbuf->si)); netbsd32_ksi_to_ksi32(&kbuf->si._info, &ksi->ksi_info); ktesethdrlen(kte, sizeof(*kbuf)); } else { kbuf->kp.code = 0; ktesethdrlen(kte, sizeof(struct netbsd32_ktr_psig)); } ktraddentry(l, kte, KTA_WAITOK); }
static inline void netbsd32_from_ifconf(struct ifconf *p, struct netbsd32_ifconf *s32p, u_long cmd) { s32p->ifc_len = p->ifc_len; /* ifc_buf & ifc_req are the same size so this works */ NETBSD32PTR32(s32p->ifc_buf, p->ifc_buf); }
static void bsd_to_linux32_msqid_ds(struct msqid_ds *bmp, struct linux32_msqid_ds *lmp) { memset(lmp, 0, sizeof(*lmp)); bsd_to_linux32_ipc_perm(&bmp->msg_perm, &lmp->l_msg_perm); NETBSD32PTR32(lmp->l_msg_first, bmp->_msg_first); NETBSD32PTR32(lmp->l_msg_last, bmp->_msg_last); lmp->l_msg_cbytes = bmp->_msg_cbytes; lmp->l_msg_qnum = bmp->msg_qnum; lmp->l_msg_qbytes = bmp->msg_qbytes; lmp->l_msg_lspid = bmp->msg_lspid; lmp->l_msg_lrpid = bmp->msg_lrpid; lmp->l_msg_stime = bmp->msg_stime; lmp->l_msg_rtime = bmp->msg_rtime; lmp->l_msg_ctime = bmp->msg_ctime; }
static void bsd_to_linux32_semid_ds(struct semid_ds *bsp, struct linux32_semid_ds *lsp) { bsd_to_linux32_ipc_perm(&bsp->sem_perm, &lsp->l_sem_perm); lsp->l_sem_otime = bsp->sem_otime; lsp->l_sem_ctime = bsp->sem_ctime; lsp->l_sem_nsems = bsp->sem_nsems; NETBSD32PTR32(lsp->l_sem_base, bsp->_sem_base); }
void native_to_linux32_sigaltstack(struct linux32_sigaltstack *lss, const struct sigaltstack *bss) { NETBSD32PTR32(lss->ss_sp, bss->ss_sp); lss->ss_size = bss->ss_size; if (bss->ss_flags & SS_ONSTACK) lss->ss_flags = LINUX32_SS_ONSTACK; else if (bss->ss_flags & SS_DISABLE) lss->ss_flags = LINUX32_SS_DISABLE; else lss->ss_flags = 0; }
static void linux32_save_ucontext(struct lwp *l, struct trapframe *tf, const sigset_t *mask, struct sigaltstack *sas, struct linux32_ucontext *uc) { uc->uc_flags = 0; NETBSD32PTR32(uc->uc_link, NULL); native_to_linux32_sigaltstack(&uc->uc_stack, sas); linux32_save_sigcontext(l, tf, mask, &uc->uc_mcontext); native_to_linux32_sigset(&uc->uc_sigmask, mask); (void)memset(&uc->uc_fpregs_mem, 0, sizeof(uc->uc_fpregs_mem)); }
static void bsd_to_linux32_shmid_ds(struct shmid_ds *bsp, struct linux32_shmid_ds *lsp) { bsd_to_linux32_ipc_perm(&bsp->shm_perm, &lsp->l_shm_perm); lsp->l_shm_segsz = bsp->shm_segsz; lsp->l_shm_atime = bsp->shm_atime; lsp->l_shm_dtime = bsp->shm_dtime; lsp->l_shm_ctime = bsp->shm_ctime; lsp->l_shm_cpid = bsp->shm_cpid; lsp->l_shm_lpid = bsp->shm_lpid; lsp->l_shm_nattch = bsp->shm_nattch; NETBSD32PTR32(lsp->l_private2, bsp->_shm_internal); }
static inline void netbsd32_from_ifreq(struct ifreq *p, struct netbsd32_ifreq *s32p, u_long cmd) { /* * XXX * struct ifreq says the same, but sometimes the ifr_data * union member needs to be converted to 64 bits... this * is very driver specific and so we ignore it for now.. */ *s32p->ifr_name = *p->ifr_name; if (cmd == SIOCGIFDATA || cmd == SIOCZIFDATA) NETBSD32PTR32(s32p->ifr_data, p->ifr_data); }
int linux32_sys_waitpid(struct lwp *l, const struct linux32_sys_waitpid_args *uap, register_t *retval) { /* { syscallarg(int) pid; syscallarg(netbsd32_intp) status; syscallarg(int) options; } */ struct linux32_sys_wait4_args ua; SCARG(&ua, pid) = SCARG(uap, pid); SCARG(&ua, status) = SCARG(uap, status); SCARG(&ua, options) = SCARG(uap, options); NETBSD32PTR32(SCARG(&ua, rusage), NULL); return linux32_sys_wait4(l, &ua, retval); }
int netbsd32__lwp_ctl(struct lwp *l, const struct netbsd32__lwp_ctl_args *uap, register_t *retval) { /* { syscallarg(int) features; syscallarg(netbsd32_pointer_t) address; } */ netbsd32_pointer_t vaddr32; int error, features; vaddr_t vaddr; features = SCARG(uap, features); features &= ~(LWPCTL_FEATURE_CURCPU | LWPCTL_FEATURE_PCTR); if (features != 0) return ENODEV; if ((error = lwp_ctl_alloc(&vaddr)) != 0) return error; NETBSD32PTR32(vaddr32, (void *)vaddr); return copyout(&vaddr32, SCARG_P32(uap, address), sizeof(vaddr32)); }
int netbsd32_sigaction(struct lwp *l, const struct netbsd32_sigaction_args *uap, register_t *retval) { /* { syscallarg(int) signum; syscallarg(const netbsd32_sigactionp_t) nsa; syscallarg(netbsd32_sigactionp_t) osa; } */ struct sigaction nsa, osa; struct netbsd32_sigaction13 *sa32p, sa32; int error; if (SCARG_P32(uap, nsa)) { sa32p = SCARG_P32(uap, nsa); if (copyin(sa32p, &sa32, sizeof(sa32))) return EFAULT; nsa.sa_handler = (void *)NETBSD32PTR64(sa32.netbsd32_sa_handler); memset(&nsa.sa_mask, 0, sizeof(nsa.sa_mask)); nsa.sa_mask.__bits[0] = sa32.netbsd32_sa_mask; nsa.sa_flags = sa32.netbsd32_sa_flags; } error = sigaction1(l, SCARG(uap, signum), SCARG_P32(uap, nsa) ? &nsa : 0, SCARG_P32(uap, osa) ? &osa : 0, NULL, 0); if (error) return (error); if (SCARG_P32(uap, osa)) { NETBSD32PTR32(sa32.netbsd32_sa_handler, osa.sa_handler); sa32.netbsd32_sa_mask = osa.sa_mask.__bits[0]; sa32.netbsd32_sa_flags = osa.sa_flags; sa32p = SCARG_P32(uap, osa); if (copyout(&sa32, sa32p, sizeof(sa32))) return EFAULT; } return (0); }
/* ARGSUSED */ int netbsd32___sigaction_sigtramp(struct lwp *l, const struct netbsd32___sigaction_sigtramp_args *uap, register_t *retval) { /* { syscallarg(int) signum; syscallarg(const netbsd32_sigactionp_t) nsa; syscallarg(netbsd32_sigactionp_t) osa; syscallarg(netbsd32_voidp) tramp; syscallarg(int) vers; } */ struct netbsd32_sigaction sa32; struct sigaction nsa, osa; int error; if (SCARG_P32(uap, nsa)) { error = copyin(SCARG_P32(uap, nsa), &sa32, sizeof(sa32)); if (error) return (error); nsa.sa_handler = NETBSD32PTR64(sa32.netbsd32_sa_handler); nsa.sa_mask = sa32.netbsd32_sa_mask; nsa.sa_flags = sa32.netbsd32_sa_flags; } error = sigaction1(l, SCARG(uap, signum), SCARG_P32(uap, nsa) ? &nsa : 0, SCARG_P32(uap, osa) ? &osa : 0, SCARG_P32(uap, tramp), SCARG(uap, vers)); if (error) return (error); if (SCARG_P32(uap, osa)) { NETBSD32PTR32(sa32.netbsd32_sa_handler, osa.sa_handler); sa32.netbsd32_sa_mask = osa.sa_mask; sa32.netbsd32_sa_flags = osa.sa_flags; error = copyout(&sa32, SCARG_P32(uap, osa), sizeof(sa32)); if (error) return (error); } return (0); }
static int linux32_shmat(struct lwp *l, const struct linux32_sys_ipc_args *uap, register_t *retval) { struct sys_shmat_args ua; netbsd32_pointer_t addr32; int error; SCARG(&ua, shmid) = SCARG(uap, a1); SCARG(&ua, shmaddr) = SCARG_P32(uap, ptr); SCARG(&ua, shmflg) = SCARG(uap, a2); if ((error = sys_shmat(l, &ua, retval))) return error; NETBSD32PTR32(addr32, (const void *)(uintptr_t)retval[0]); error = copyout(&addr32, NETBSD32IPTR64(SCARG(uap, a3)), sizeof addr32); if (error == 0) retval[0] = 0; return error; }
void native_to_linux32_siginfo(linux32_siginfo_t *lsi, const struct _ksiginfo *ksi) { memset(lsi, 0, sizeof(*lsi)); lsi->lsi_signo = native_to_linux32_signo[ksi->_signo]; lsi->lsi_errno = native_to_linux32_errno[ksi->_errno]; lsi->lsi_code = native_to_linux32_si_code(ksi->_code); switch (ksi->_code) { case SI_NOINFO: break; case SI_USER: lsi->lsi_pid = ksi->_reason._rt._pid; lsi->lsi_uid = ksi->_reason._rt._uid; if (lsi->lsi_signo == LINUX_SIGALRM || lsi->lsi_signo >= LINUX_SIGRTMIN) NETBSD32PTR32(lsi->lsi_value.sival_ptr, ksi->_reason._rt._value.sival_ptr); break; case SI_TIMER: case SI_QUEUE: lsi->lsi_uid = ksi->_reason._rt._uid; lsi->lsi_uid = ksi->_reason._rt._uid; NETBSD32PTR32(lsi->lsi_value.sival_ptr, ksi->_reason._rt._value.sival_ptr); break; case SI_ASYNCIO: case SI_MESGQ: NETBSD32PTR32(lsi->lsi_value.sival_ptr, ksi->_reason._rt._value.sival_ptr); break; default: switch (ksi->_signo) { case SIGCHLD: lsi->lsi_uid = ksi->_reason._child._uid; lsi->lsi_pid = ksi->_reason._child._pid; lsi->lsi_status = native_to_linux32_si_status( ksi->_code, ksi->_reason._child._status); lsi->lsi_utime = ksi->_reason._child._utime; lsi->lsi_stime = ksi->_reason._child._stime; break; case SIGILL: case SIGFPE: case SIGSEGV: case SIGBUS: case SIGTRAP: NETBSD32PTR32(lsi->lsi_addr, ksi->_reason._fault._addr); break; case SIGIO: lsi->lsi_fd = ksi->_reason._poll._fd; lsi->lsi_band = ksi->_reason._poll._band; break; default: break; } } }
void linux32_old_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) { struct lwp *l = curlwp; struct proc *p = l->l_proc; struct trapframe *tf; struct linux32_sigframe *fp, frame; int onstack, error; int sig = ksi->ksi_signo; sig_t catcher = SIGACTION(p, sig).sa_handler; struct sigaltstack *sas = &l->l_sigstk; tf = l->l_md.md_regs; /* Do we need to jump onto the signal stack? */ onstack = (sas->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; /* Allocate space for the signal handler context. */ if (onstack) fp = (struct linux32_sigframe *)((char *)sas->ss_sp + sas->ss_size); else fp = (struct linux32_sigframe *)tf->tf_rsp; fp--; DPRINTF(("old: onstack = %d, fp = %p sig = %d rip = 0x%lx\n", onstack, fp, sig, tf->tf_rip)); /* Build stack frame for signal trampoline. */ NETBSD32PTR32(frame.sf_handler, catcher); frame.sf_sig = native_to_linux32_signo[sig]; linux32_save_sigcontext(l, tf, mask, &frame.sf_sc); sendsig_reset(l, sig); mutex_exit(p->p_lock); error = copyout(&frame, fp, sizeof(frame)); mutex_enter(p->p_lock); if (error != 0) { /* * Process has trashed its stack; give it an illegal * instruction to halt it in its tracks. */ sigexit(l, SIGILL); /* NOTREACHED */ } /* * Build context to run handler in. */ tf->tf_fs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; tf->tf_es = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; tf->tf_ds = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; tf->tf_rip = ((long)p->p_sigctx.ps_sigcode) & 0xffffffff; tf->tf_cs = GSEL(GUCODE32_SEL, SEL_UPL) & 0xffffffff; tf->tf_rflags &= ~PSL_CLEARSIG & 0xffffffff; tf->tf_rsp = (long)fp & 0xffffffff; tf->tf_ss = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; /* Remember that we're now on the signal stack. */ if (onstack) sas->ss_flags |= SS_ONSTACK; return; }
/* * Send an interrupt to process. * * Stack is set up to allow sigcode stored * in u. to call routine. After the handler is * done svr4 will call setcontext for us * with the user context we just set up, and we * will return to the user pc, psl. */ void svr4_32_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) { int sig = ksi->ksi_signo; register struct lwp *l = curlwp; struct proc *p = l->l_proc; register struct trapframe64 *tf; struct svr4_32_sigframe *fp, frame; int onstack, error; vaddr_t oldsp, newsp, addr; sig_t catcher = SIGACTION(p, sig).sa_handler; sigset_t tmask; tf = (struct trapframe64 *)l->l_md.md_tf; oldsp = tf->tf_out[6]; /* 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) fp = (struct svr4_32_sigframe *)((char *)l->l_sigstk.ss_sp + l->l_sigstk.ss_size); else fp = (struct svr4_32_sigframe *)oldsp; fp = (struct svr4_32_sigframe *) ((long) (fp - 1) & ~7); #ifdef DEBUG sigpid = p->p_pid; if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) { printf("svr4_32_sendsig: %s[%d] sig %d newusp %p scp %p oldsp %p\n", p->p_comm, p->p_pid, sig, fp, &fp->sf_uc, (void *)(u_long)oldsp); #ifdef DDB if (sigdebug & SDB_DDB) Debugger(); #endif } #endif /* * Build the argument list for the signal handler. */ svr4_32_getsiginfo(&frame.sf_si, sig, ksi->ksi_trap, (void *)(u_long)tf->tf_pc); /* Build stack frame for signal trampoline. */ frame.sf_signum = frame.sf_si.si_signo; NETBSD32PTR32(frame.sf_sip, &fp->sf_si); NETBSD32PTR32(frame.sf_ucp, &fp->sf_uc); frame.sf_handler = catcher; DPRINTF(("svr4_32_sendsig signum=%d si = %p uc = %p handler = %p\n", frame.sf_signum, frame.sf_sip, frame.sf_ucp, frame.sf_handler)); /* * Modify the signal context to be used by sigreturn. */ tmask = *mask; sendsig_reset(l, sig); frame.sf_uc.uc_mcontext.greg[SVR4_SPARC_SP] = oldsp; newsp = (u_long)fp - sizeof(struct rwindow32); mutex_exit(p->p_lock); svr4_32_getcontext(l, &frame.sf_uc, &tmask); write_user_windows(); #ifdef DEBUG if ((sigdebug & SDB_KSTACK)) printf("svr4_32_sendsig: saving sf to %p, setting stack pointer %p to %p\n", fp, &(((struct rwindow32 *)newsp)->rw_in[6]), (void *)(u_long)oldsp); #endif error = (rwindow_save(l) || copyout(&frame, fp, sizeof(frame)) != 0 || copyout(&oldsp, &((struct rwindow32 *)newsp)->rw_in[6], sizeof(oldsp))); mutex_enter(p->p_lock); if (error) { /* * Process has trashed its stack; give it an illegal * instruction to halt it in its tracks. */ #ifdef DEBUG mutex_exit(p->p_lock); if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("svr4_32_sendsig: window save or copyout error\n"); printf("svr4_32_sendsig: stack was trashed trying to send sig %d, sending SIGILL\n", sig); #ifdef DDB Debugger(); #endif mutex_enter(p->p_lock); #endif sigexit(l, SIGILL); /* NOTREACHED */ } #ifdef DEBUG if (sigdebug & SDB_FOLLOW) { printf("svr4_32_sendsig: %s[%d] sig %d scp %p\n", p->p_comm, p->p_pid, sig, &fp->sf_uc); } #endif /* * Build context to run handler in. */ addr = (vaddr_t)p->p_sigctx.ps_sigcode; tf->tf_pc = addr; tf->tf_npc = addr + 4; tf->tf_global[1] = (vaddr_t)catcher; tf->tf_out[6] = newsp; /* Remember that we're now on the signal stack. */ if (onstack) l->l_sigstk.ss_flags |= SS_ONSTACK; #ifdef DEBUG if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) { mutex_exit(p->p_lock); printf("svr4_32_sendsig: about to return to catcher %p thru %p\n", catcher, (void *)(u_long)addr); #ifdef DDB if (sigdebug & SDB_DDB) Debugger(); #endif mutex_enter(p->p_lock); } #endif }
void linux32_rt_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) { struct lwp *l = curlwp; struct proc *p = l->l_proc; struct trapframe *tf; struct linux32_rt_sigframe *fp, frame; int onstack, error; linux32_siginfo_t *lsi; int sig = ksi->ksi_signo; sig_t catcher = SIGACTION(p, sig).sa_handler; struct sigaltstack *sas = &l->l_sigstk; tf = l->l_md.md_regs; /* Do we need to jump onto the signal stack? */ onstack = (sas->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; /* Allocate space for the signal handler context. */ if (onstack) fp = (struct linux32_rt_sigframe *)((char *)sas->ss_sp + sas->ss_size); else fp = (struct linux32_rt_sigframe *)tf->tf_rsp; fp--; /* Build stack frame for signal trampoline. */ NETBSD32PTR32(frame.sf_handler, catcher); frame.sf_sig = native_to_linux32_signo[sig]; NETBSD32PTR32(frame.sf_sip, &fp->sf_si); NETBSD32PTR32(frame.sf_ucp, &fp->sf_uc); DPRINTF(("rt: onstack = %d, fp = %p sig = %d rip = 0x%lx\n", onstack, fp, sig, tf->tf_rip)); lsi = &frame.sf_si; (void)memset(lsi, 0, sizeof(frame.sf_si)); lsi->lsi_errno = native_to_linux32_errno[ksi->ksi_errno]; lsi->lsi_code = native_to_linux_si_code(ksi->ksi_code); lsi->lsi_signo = frame.sf_sig; switch (lsi->lsi_signo) { case LINUX32_SIGILL: case LINUX32_SIGFPE: case LINUX32_SIGSEGV: case LINUX32_SIGBUS: case LINUX32_SIGTRAP: NETBSD32PTR32(lsi->lsi_addr, ksi->ksi_addr); break; case LINUX32_SIGCHLD: lsi->lsi_uid = ksi->ksi_uid; lsi->lsi_pid = ksi->ksi_pid; lsi->lsi_utime = ksi->ksi_utime; lsi->lsi_stime = ksi->ksi_stime; lsi->lsi_status = native_to_linux_si_status(ksi->ksi_code, ksi->ksi_status); break; case LINUX32_SIGIO: lsi->lsi_band = ksi->ksi_band; lsi->lsi_fd = ksi->ksi_fd; break; default: lsi->lsi_uid = ksi->ksi_uid; lsi->lsi_pid = ksi->ksi_pid; if (lsi->lsi_signo == LINUX32_SIGALRM || lsi->lsi_signo >= LINUX32_SIGRTMIN) NETBSD32PTR32(lsi->lsi_value.sival_ptr, ksi->ksi_value.sival_ptr); break; } /* Save register context. */ linux32_save_ucontext(l, tf, mask, sas, &frame.sf_uc); sendsig_reset(l, sig); mutex_exit(p->p_lock); error = copyout(&frame, fp, sizeof(frame)); mutex_enter(p->p_lock); if (error != 0) { /* * Process has trashed its stack; give it an illegal * instruction to halt it in its tracks. */ sigexit(l, SIGILL); /* NOTREACHED */ } /* * Build context to run handler in. */ tf->tf_fs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; tf->tf_es = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; tf->tf_ds = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; tf->tf_rip = (((long)p->p_sigctx.ps_sigcode) + (linux32_rt_sigcode - linux32_sigcode)) & 0xffffffff; tf->tf_cs = GSEL(GUCODE32_SEL, SEL_UPL) & 0xffffffff; tf->tf_rflags &= ~PSL_CLEARSIG & 0xffffffff; tf->tf_rsp = (long)fp & 0xffffffff; tf->tf_ss = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; /* Remember that we're now on the signal stack. */ if (onstack) sas->ss_flags |= SS_ONSTACK; return; }
/* * map the trap code into the svr4 siginfo as best we can */ static void svr4_32_getsiginfo(union svr4_32_siginfo *si, int sig, u_long code, void *addr) { si->si_signo = native_to_svr4_signo[sig]; si->si_errno = 0; NETBSD32PTR32(si->si_addr, addr); /* * we can do this direct map as they are the same as all sparc * architectures. */ si->si_trap = code; switch (code) { case T_POR: case T_WDR: case T_XIR: case T_SIR: case T_RED_EXCEPTION: si->si_code = 0; break; case T_TEXTFAULT: si->si_code = SVR4_BUS_ADRALN; break; case T_ILLINST: si->si_code = SVR4_ILL_ILLOPC; break; case T_PRIVINST: si->si_code = SVR4_ILL_PRVOPC; break; case T_FPDISABLED: si->si_code = SVR4_FPE_FLTINV; break; case T_ALIGN: si->si_code = SVR4_BUS_ADRALN; break; case T_FP_IEEE_754: case T_FP_OTHER: si->si_code = SVR4_FPE_FLTINV; break; case T_DATAFAULT: si->si_code = SVR4_BUS_ADRALN; break; case T_TAGOF: si->si_code = SVR4_EMT_TAGOVF; break; case T_IDIV0: si->si_code = SVR4_FPE_INTDIV; break; case T_INTOF: si->si_code = SVR4_FPE_INTOVF; break; case T_BREAKPOINT: si->si_code = SVR4_TRAP_BRKPT; break; /* * XXX - hardware traps with unknown code */ case T_L1INT: case T_L2INT: case T_L3INT: case T_L4INT: case T_L5INT: case T_L6INT: case T_L7INT: case T_L8INT: case T_L9INT: case T_L10INT: case T_L11INT: case T_L12INT: case T_L13INT: case T_L14INT: case T_L15INT: si->si_code = 0; break; /* * XXX - software traps with unknown code */ case T_SUN_SYSCALL: case T_FLUSHWIN: case T_CLEANWIN: case T_RANGECHECK: case T_FIXALIGN: case T_SVR4_SYSCALL: case T_BSD_SYSCALL: case T_KGDB_EXEC: si->si_code = 0; break; default: si->si_code = 0; #ifdef notyet /* * XXX: in trap.c, code gets passed the address * of the fault! not the trap code on SEGV! */ #ifdef DIAGNOSTIC printf("sig %d code %ld\n", sig, code); panic("svr4_32_getsiginfo"); #endif #endif break; } }