FreeBSD/sys/mips/mips/freebsd32_machdep.c
/*
 * Send an interrupt to process.
 *
 * Stack is set up to allow sigcode stored
 * at top to call routine, followed by kcall
 * to sigreturn routine below.	After sigreturn
 * resets the signal mask, the stack, and the
 * frame pointer, it returns to the user
 * specified pc, psl.
 */
Send an interrupt to process.
Stack is set up to allow sigcode stored
at top to call routine, followed by kcall
to sigreturn routine below.  After sigreturn
resets the signal mask, the stack, and the
frame pointer, it returns to the user
specified pc, psl.
Send an interrupt to process . Stack is set up to allow sigcode stored at top to call routine followed by kcall to sigreturn routine below . After sigreturn resets the signal mask the stack and the frame pointer it returns to the user specified pc psl .
static void
freebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
	struct proc *p;
	struct thread *td;
	struct fpreg32 fpregs;
	struct reg32 regs;
	struct sigacts *psp;
	struct sigframe32 sf, *sfp;
	int sig;
	int oonstack;
	unsigned i;
	td = curthread;
	p = td->td_proc;
	PROC_LOCK_ASSERT(p, MA_OWNED);
	sig = ksi->ksi_signo;
	psp = p->p_sigacts;
	mtx_assert(&psp->ps_mtx, MA_OWNED);
	fill_regs32(td, &regs);
	oonstack = sigonstack(td->td_frame->sp);
	bzero(&sf, sizeof sf);
	sf.sf_uc.uc_sigmask = *mask;
	sf.sf_uc.uc_stack.ss_sp = (int32_t)(intptr_t)td->td_sigstk.ss_sp;
	sf.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size;
	sf.sf_uc.uc_stack.ss_flags = td->td_sigstk.ss_flags;
	sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
	sf.sf_uc.uc_mcontext.mc_pc = regs.r_regs[PC];
	sf.sf_uc.uc_mcontext.mullo = regs.r_regs[MULLO];
	sf.sf_uc.uc_mcontext.mulhi = regs.r_regs[MULHI];
	sf.sf_uc.uc_mcontext.mc_tls = (int32_t)(intptr_t)td->td_md.md_tls;
	sf.sf_uc.uc_mcontext.mc_regs[0] = UCONTEXT_MAGIC;  
	for (i = 1; i < 32; i++)
		sf.sf_uc.uc_mcontext.mc_regs[i] = regs.r_regs[i];
	sf.sf_uc.uc_mcontext.mc_fpused = td->td_md.md_flags & MDTD_FPUSED;
	if (sf.sf_uc.uc_mcontext.mc_fpused) {
		if (td == PCPU_GET(fpcurthread))
			MipsSaveCurFPState(td);
		fill_fpregs32(td, &fpregs);
		for (i = 0; i < 33; i++)
			sf.sf_uc.uc_mcontext.mc_fpregs[i] = fpregs.r_regs[i];
	}
	if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
		sfp = (struct sigframe32 *)(((uintptr_t)td->td_sigstk.ss_sp +
		    td->td_sigstk.ss_size - sizeof(struct sigframe32))
		    & ~(sizeof(__int64_t) - 1));
	} else
		sfp = (struct sigframe32 *)((vm_offset_t)(td->td_frame->sp - 
		    sizeof(struct sigframe32)) & ~(sizeof(__int64_t) - 1));
	td->td_frame->a0 = sig;
	td->td_frame->a2 = (register_t)(intptr_t)&sfp->sf_uc;
	if (SIGISMEMBER(psp->ps_siginfo, sig)) {
		td->td_frame->a1 = (register_t)(intptr_t)&sfp->sf_si;
		sf.sf_si.si_signo = sig;
		sf.sf_si.si_code = ksi->ksi_code;
		sf.sf_si.si_addr = td->td_frame->badvaddr;
	} else {
		td->td_frame->a1 = ksi->ksi_code;
		td->td_frame->a3 = td->td_frame->badvaddr;
	}
	mtx_unlock(&psp->ps_mtx);
	PROC_UNLOCK(p);
	if (copyout(&sf, sfp, sizeof(struct sigframe32)) != 0) {
		PROC_LOCK(p);
		sigexit(td, SIGILL);
	}
	td->td_frame->pc = (register_t)(intptr_t)catcher;
	td->td_frame->t9 = (register_t)(intptr_t)catcher;
	td->td_frame->sp = (register_t)(intptr_t)sfp;
	td->td_frame->ra = (register_t)(intptr_t)FREEBSD32_PS_STRINGS - *(p->p_sysent->sv_szsigcode);
	PROC_LOCK(p);
	mtx_lock(&psp->ps_mtx);
}
static void freebsd32_sendsig ( sig_t catcher , ksiginfo_t * ksi , sigset_t * mask ) { struct proc * p ; struct thread * td ; struct fpreg32 fpregs ; struct reg32 regs ; struct sigacts * psp ; struct sigframe32 sf , * sfp ; int sig ; int oonstack ; unsigned i ; td = curthread ; p = td -> td_proc ; PROC_LOCK_ASSERT ( p , MA_OWNED ) ; sig = ksi -> ksi_signo ; psp = p -> p_sigacts ; mtx_assert ( & psp -> ps_mtx , MA_OWNED ) ; fill_regs32 ( td , & regs ) ; oonstack = sigonstack ( td -> td_frame -> sp ) ; bzero ( & sf , sizeof sf ) ; sf . sf_uc . uc_sigmask = * mask ; sf . sf_uc . uc_stack . ss_sp = ( int32_t ) ( intptr_t ) td -> td_sigstk . ss_sp ; sf . sf_uc . uc_stack . ss_size = td -> td_sigstk . ss_size ; sf . sf_uc . uc_stack . ss_flags = td -> td_sigstk . ss_flags ; sf . sf_uc . uc_mcontext . mc_onstack = ( oonstack ) ? 1 : 0 ; sf . sf_uc . uc_mcontext . mc_pc = regs . r_regs [ PC ] ; sf . sf_uc . uc_mcontext . mullo = regs . r_regs [ MULLO ] ; sf . sf_uc . uc_mcontext . mulhi = regs . r_regs [ MULHI ] ; sf . sf_uc . uc_mcontext . mc_tls = ( int32_t ) ( intptr_t ) td -> td_md . md_tls ; sf . sf_uc . uc_mcontext . mc_regs [ 0 ] = UCONTEXT_MAGIC ; for ( i = 1 ; i < 32 ; i ++ ) sf . sf_uc . uc_mcontext . mc_regs [ i ] = regs . r_regs [ i ] ; sf . sf_uc . uc_mcontext . mc_fpused = td -> td_md . md_flags & MDTD_FPUSED ; if ( sf . sf_uc . uc_mcontext . mc_fpused ) { if ( td == PCPU_GET ( fpcurthread ) ) MipsSaveCurFPState ( td ) ; fill_fpregs32 ( td , & fpregs ) ; for ( i = 0 ; i < 33 ; i ++ ) sf . sf_uc . uc_mcontext . mc_fpregs [ i ] = fpregs . r_regs [ i ] ; } if ( ( td -> td_pflags & TDP_ALTSTACK ) != 0 && ! oonstack && SIGISMEMBER ( psp -> ps_sigonstack , sig ) ) { sfp = ( struct sigframe32 * ) ( ( ( uintptr_t ) td -> td_sigstk . ss_sp + td -> td_sigstk . ss_size - sizeof ( struct sigframe32 ) ) & ~ ( sizeof ( __int64_t ) - 1 ) ) ; } else sfp = ( struct sigframe32 * ) ( ( vm_offset_t ) ( td -> td_frame -> sp - sizeof ( struct sigframe32 ) ) & ~ ( sizeof ( __int64_t ) - 1 ) ) ; td -> td_frame -> a0 = sig ; td -> td_frame -> a2 = ( register_t ) ( intptr_t ) & sfp -> sf_uc ; if ( SIGISMEMBER ( psp -> ps_siginfo , sig ) ) { td -> td_frame -> a1 = ( register_t ) ( intptr_t ) & sfp -> sf_si ; sf . sf_si . si_signo = sig ; sf . sf_si . si_code = ksi -> ksi_code ; sf . sf_si . si_addr = td -> td_frame -> badvaddr ; } else { td -> td_frame -> a1 = ksi -> ksi_code ; td -> td_frame -> a3 = td -> td_frame -> badvaddr ; } mtx_unlock ( & psp -> ps_mtx ) ; PROC_UNLOCK ( p ) ; if ( copyout ( & sf , sfp , sizeof ( struct sigframe32 ) ) != 0 ) { PROC_LOCK ( p ) ; sigexit ( td , SIGILL ) ; } td -> td_frame -> pc = ( register_t ) ( intptr_t ) catcher ; td -> td_frame -> t9 = ( register_t ) ( intptr_t ) catcher ; td -> td_frame -> sp = ( register_t ) ( intptr_t ) sfp ; td -> td_frame -> ra = ( register_t ) ( intptr_t ) FREEBSD32_PS_STRINGS - * ( p -> p_sysent -> sv_szsigcode ) ; PROC_LOCK ( p ) ; mtx_lock ( & psp -> ps_mtx ) ; }
Send an interrupt to process.
Send an interrupt to process .
/* save user context */ /* magic number */ /* if FPU has current state, save it first */ /* Allocate and validate space for the signal handler context. */ /* Build the argument list for the signal handler. */ /* Signal handler installed with SA_SIGINFO. */ /* sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; */ /* fill siginfo structure */ /* Old FreeBSD-style arguments. */ /* sf.sf_ahu.sf_handler = catcher; */ /*
	 * Copy the sigframe out to the user's stack.
	 */ /*
		 * Something is wrong with the stack pointer.
		 * ...Kill the process.
		 */ /*
	 * Signal trampoline code is at base of user stack.
	 */