FreeBSD/sys/amd64/linux/linux_sysvec.c
/*
 * copied from amd64/amd64/machdep.c
 *
 * Send an interrupt to process.
 */
copied from amd64/amd64/machdep.c
Send an interrupt to process.
copied from amd64 / amd64 / machdep . c Send an interrupt to process .
static void
linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
	struct l_rt_sigframe sf, *sfp;
	struct proc *p;
	struct thread *td;
	struct sigacts *psp;
	caddr_t sp;
	struct trapframe *regs;
	int sig, code;
	int oonstack;
	td = curthread;
	p = td->td_proc;
	PROC_LOCK_ASSERT(p, MA_OWNED);
	sig = ksi->ksi_signo;
	psp = p->p_sigacts;
	code = ksi->ksi_code;
	mtx_assert(&psp->ps_mtx, MA_OWNED);
	regs = td->td_frame;
	oonstack = sigonstack(regs->tf_rsp);
	LINUX_CTR4(rt_sendsig, "%p, %d, %p, %u",
	    catcher, sig, mask, code);
	if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
		sp = (caddr_t)td->td_sigstk.ss_sp + td->td_sigstk.ss_size -
		    sizeof(struct l_rt_sigframe);
	} else
		sp = (caddr_t)regs->tf_rsp - sizeof(struct l_rt_sigframe) - 128;
	sfp = (struct l_rt_sigframe *)((unsigned long)sp & ~0xFul);
	mtx_unlock(&psp->ps_mtx);
	sig = bsd_to_linux_signal(sig);
	bzero(&sf, sizeof(sf));
	bsd_to_linux_sigset(mask, &sf.sf_sc.uc_sigmask);
	bsd_to_linux_sigset(mask, &sf.sf_sc.uc_mcontext.sc_mask);
	sf.sf_sc.uc_stack.ss_sp = PTROUT(td->td_sigstk.ss_sp);
	sf.sf_sc.uc_stack.ss_size = td->td_sigstk.ss_size;
	sf.sf_sc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
	    ? ((oonstack) ? LINUX_SS_ONSTACK : 0) : LINUX_SS_DISABLE;
	PROC_UNLOCK(p);
	sf.sf_sc.uc_mcontext.sc_rdi    = regs->tf_rdi;
	sf.sf_sc.uc_mcontext.sc_rsi    = regs->tf_rsi;
	sf.sf_sc.uc_mcontext.sc_rdx    = regs->tf_rdx;
	sf.sf_sc.uc_mcontext.sc_rbp    = regs->tf_rbp;
	sf.sf_sc.uc_mcontext.sc_rbx    = regs->tf_rbx;
	sf.sf_sc.uc_mcontext.sc_rcx    = regs->tf_rcx;
	sf.sf_sc.uc_mcontext.sc_rax    = regs->tf_rax;
	sf.sf_sc.uc_mcontext.sc_rip    = regs->tf_rip;
	sf.sf_sc.uc_mcontext.sc_rsp    = regs->tf_rsp;
	sf.sf_sc.uc_mcontext.sc_r8     = regs->tf_r8;
	sf.sf_sc.uc_mcontext.sc_r9     = regs->tf_r9;
	sf.sf_sc.uc_mcontext.sc_r10    = regs->tf_r10;
	sf.sf_sc.uc_mcontext.sc_r11    = regs->tf_r11;
	sf.sf_sc.uc_mcontext.sc_r12    = regs->tf_r12;
	sf.sf_sc.uc_mcontext.sc_r13    = regs->tf_r13;
	sf.sf_sc.uc_mcontext.sc_r14    = regs->tf_r14;
	sf.sf_sc.uc_mcontext.sc_r15    = regs->tf_r15;
	sf.sf_sc.uc_mcontext.sc_cs     = regs->tf_cs;
	sf.sf_sc.uc_mcontext.sc_rflags = regs->tf_rflags;
	sf.sf_sc.uc_mcontext.sc_err    = regs->tf_err;
	sf.sf_sc.uc_mcontext.sc_trapno = bsd_to_linux_trapcode(code);
	sf.sf_sc.uc_mcontext.sc_cr2    = (register_t)ksi->ksi_addr;
	regs->tf_rdi = sig;			
	regs->tf_rax = 0;
	regs->tf_rsi = (register_t)&sfp->sf_si;	
	regs->tf_rdx = (register_t)&sfp->sf_sc;	
	sf.sf_handler = catcher;
	ksiginfo_to_lsiginfo(ksi, &sf.sf_si, sig);
	if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
#ifdef DEBUG
		printf("process %ld has trashed its stack\n", (long)p->p_pid);
#endif
		PROC_LOCK(p);
		sigexit(td, SIGILL);
	}
	regs->tf_rsp = (long)sfp;
	regs->tf_rip = linux_rt_sigcode;
	regs->tf_rflags &= ~(PSL_T | PSL_D);
	regs->tf_cs = _ucodesel;
	set_pcb_flags(td->td_pcb, PCB_FULL_IRET);
	PROC_LOCK(p);
	mtx_lock(&psp->ps_mtx);
}
static void linux_rt_sendsig ( sig_t catcher , ksiginfo_t * ksi , sigset_t * mask ) { struct l_rt_sigframe sf , * sfp ; struct proc * p ; struct thread * td ; struct sigacts * psp ; caddr_t sp ; struct trapframe * regs ; int sig , code ; int oonstack ; td = curthread ; p = td -> td_proc ; PROC_LOCK_ASSERT ( p , MA_OWNED ) ; sig = ksi -> ksi_signo ; psp = p -> p_sigacts ; code = ksi -> ksi_code ; mtx_assert ( & psp -> ps_mtx , MA_OWNED ) ; regs = td -> td_frame ; oonstack = sigonstack ( regs -> tf_rsp ) ; LINUX_CTR4 ( rt_sendsig , " " , catcher , sig , mask , code ) ; if ( ( td -> td_pflags & TDP_ALTSTACK ) != 0 && ! oonstack && SIGISMEMBER ( psp -> ps_sigonstack , sig ) ) { sp = ( caddr_t ) td -> td_sigstk . ss_sp + td -> td_sigstk . ss_size - sizeof ( struct l_rt_sigframe ) ; } else sp = ( caddr_t ) regs -> tf_rsp - sizeof ( struct l_rt_sigframe ) - 128 ; sfp = ( struct l_rt_sigframe * ) ( ( unsigned long ) sp & ~ 0xFul ) ; mtx_unlock ( & psp -> ps_mtx ) ; sig = bsd_to_linux_signal ( sig ) ; bzero ( & sf , sizeof ( sf ) ) ; bsd_to_linux_sigset ( mask , & sf . sf_sc . uc_sigmask ) ; bsd_to_linux_sigset ( mask , & sf . sf_sc . uc_mcontext . sc_mask ) ; sf . sf_sc . uc_stack . ss_sp = PTROUT ( td -> td_sigstk . ss_sp ) ; sf . sf_sc . uc_stack . ss_size = td -> td_sigstk . ss_size ; sf . sf_sc . uc_stack . ss_flags = ( td -> td_pflags & TDP_ALTSTACK ) ? ( ( oonstack ) ? LINUX_SS_ONSTACK : 0 ) : LINUX_SS_DISABLE ; PROC_UNLOCK ( p ) ; sf . sf_sc . uc_mcontext . sc_rdi = regs -> tf_rdi ; sf . sf_sc . uc_mcontext . sc_rsi = regs -> tf_rsi ; sf . sf_sc . uc_mcontext . sc_rdx = regs -> tf_rdx ; sf . sf_sc . uc_mcontext . sc_rbp = regs -> tf_rbp ; sf . sf_sc . uc_mcontext . sc_rbx = regs -> tf_rbx ; sf . sf_sc . uc_mcontext . sc_rcx = regs -> tf_rcx ; sf . sf_sc . uc_mcontext . sc_rax = regs -> tf_rax ; sf . sf_sc . uc_mcontext . sc_rip = regs -> tf_rip ; sf . sf_sc . uc_mcontext . sc_rsp = regs -> tf_rsp ; sf . sf_sc . uc_mcontext . sc_r8 = regs -> tf_r8 ; sf . sf_sc . uc_mcontext . sc_r9 = regs -> tf_r9 ; sf . sf_sc . uc_mcontext . sc_r10 = regs -> tf_r10 ; sf . sf_sc . uc_mcontext . sc_r11 = regs -> tf_r11 ; sf . sf_sc . uc_mcontext . sc_r12 = regs -> tf_r12 ; sf . sf_sc . uc_mcontext . sc_r13 = regs -> tf_r13 ; sf . sf_sc . uc_mcontext . sc_r14 = regs -> tf_r14 ; sf . sf_sc . uc_mcontext . sc_r15 = regs -> tf_r15 ; sf . sf_sc . uc_mcontext . sc_cs = regs -> tf_cs ; sf . sf_sc . uc_mcontext . sc_rflags = regs -> tf_rflags ; sf . sf_sc . uc_mcontext . sc_err = regs -> tf_err ; sf . sf_sc . uc_mcontext . sc_trapno = bsd_to_linux_trapcode ( code ) ; sf . sf_sc . uc_mcontext . sc_cr2 = ( register_t ) ksi -> ksi_addr ; regs -> tf_rdi = sig ; regs -> tf_rax = 0 ; regs -> tf_rsi = ( register_t ) & sfp -> sf_si ; regs -> tf_rdx = ( register_t ) & sfp -> sf_sc ; sf . sf_handler = catcher ; ksiginfo_to_lsiginfo ( ksi , & sf . sf_si , sig ) ; if ( copyout ( & sf , sfp , sizeof ( * sfp ) ) != 0 ) { #ifdef DEBUG printf ( " \n " , ( long ) p -> p_pid ) ; #endif PROC_LOCK ( p ) ; sigexit ( td , SIGILL ) ; } regs -> tf_rsp = ( long ) sfp ; regs -> tf_rip = linux_rt_sigcode ; regs -> tf_rflags &= ~ ( PSL_T | PSL_D ) ; regs -> tf_cs = _ucodesel ; set_pcb_flags ( td -> td_pcb , PCB_FULL_IRET ) ; PROC_LOCK ( p ) ; mtx_lock ( & psp -> ps_mtx ) ; }
copied from amd64/amd64/machdep.c
 Send an interrupt to process.
copied from amd64 / amd64 / machdep . c Send an interrupt to process .
/* Allocate space for the signal handler context. */ /* Align to 16 bytes. */ /* Translate the signal. */ /* Save user context. */ /* Build the argument list for the signal handler. */ /* arg 1 in %rdi */ /* arg 2 in %rsi */ /* arg 3 in %rdx */ /* Fill in POSIX parts */ /*
	 * Copy the sigframe out to the user's stack.
	 */