Пример #1
0
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);
}
Пример #2
0
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);
}
Пример #3
0
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);
}
Пример #4
0
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));
}
Пример #5
0
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);
}
Пример #6
0
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);
}
Пример #7
0
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);
}
Пример #10
0
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;
}
Пример #11
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));
}
Пример #12
0
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);
}
Пример #13
0
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);
}
Пример #14
0
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);	
}
Пример #15
0
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));
}
Пример #16
0
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);
}
Пример #17
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);
}
Пример #18
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;
}
Пример #19
0
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;
		}
	}
}
Пример #20
0
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;
}
Пример #21
0
/*
 * 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
}
Пример #22
0
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;
}
Пример #23
0
/*
 * 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;
	}
}