FreeBSD/sys/amd64/linux32/linux32_sysvec.c
/*
 * Send an interrupt to process.
 *
 * Stack is set up to allow sigcode stored
 * in u. 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
in u. 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 in u . 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
linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
	struct thread *td = curthread;
	struct proc *p = td->td_proc;
	struct sigacts *psp;
	struct trapframe *regs;
	struct l_sigframe *fp, frame;
	l_sigset_t lmask;
	int oonstack;
	int sig, code;
	sig = ksi->ksi_signo;
	code = ksi->ksi_code;
	PROC_LOCK_ASSERT(p, MA_OWNED);
	psp = p->p_sigacts;
	mtx_assert(&psp->ps_mtx, MA_OWNED);
	if (SIGISMEMBER(psp->ps_siginfo, sig)) {
		linux_rt_sendsig(catcher, ksi, mask);
		return;
	}
	regs = td->td_frame;
	oonstack = sigonstack(regs->tf_rsp);
#ifdef DEBUG
	if (ldebug(sendsig))
		printf(ARGS(sendsig, "%p, %d, %p, %u"),
		    catcher, sig, (void*)mask, code);
#endif
	if ((td->td_pflags & TDP_ALTSTACK) && !oonstack &&
	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
		fp = (struct l_sigframe *)((uintptr_t)td->td_sigstk.ss_sp +
		    td->td_sigstk.ss_size - sizeof(struct l_sigframe));
	} else
		fp = (struct l_sigframe *)regs->tf_rsp - 1;
	mtx_unlock(&psp->ps_mtx);
	PROC_UNLOCK(p);
	sig = bsd_to_linux_signal(sig);
	bzero(&frame, sizeof(frame));
	frame.sf_handler = PTROUT(catcher);
	frame.sf_sig = sig;
	bsd_to_linux_sigset(mask, &lmask);
	frame.sf_sc.sc_mask   = lmask.__mask;
	frame.sf_sc.sc_gs     = regs->tf_gs;
	frame.sf_sc.sc_fs     = regs->tf_fs;
	frame.sf_sc.sc_es     = regs->tf_es;
	frame.sf_sc.sc_ds     = regs->tf_ds;
	frame.sf_sc.sc_edi    = regs->tf_rdi;
	frame.sf_sc.sc_esi    = regs->tf_rsi;
	frame.sf_sc.sc_ebp    = regs->tf_rbp;
	frame.sf_sc.sc_ebx    = regs->tf_rbx;
	frame.sf_sc.sc_esp    = regs->tf_rsp;
	frame.sf_sc.sc_edx    = regs->tf_rdx;
	frame.sf_sc.sc_ecx    = regs->tf_rcx;
	frame.sf_sc.sc_eax    = regs->tf_rax;
	frame.sf_sc.sc_eip    = regs->tf_rip;
	frame.sf_sc.sc_cs     = regs->tf_cs;
	frame.sf_sc.sc_eflags = regs->tf_rflags;
	frame.sf_sc.sc_esp_at_signal = regs->tf_rsp;
	frame.sf_sc.sc_ss     = regs->tf_ss;
	frame.sf_sc.sc_err    = regs->tf_err;
	frame.sf_sc.sc_cr2    = (u_int32_t)(uintptr_t)ksi->ksi_addr;
	frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(code);
	frame.sf_extramask[0] = lmask.__mask;
	if (copyout(&frame, fp, sizeof(frame)) != 0) {
		PROC_LOCK(p);
		sigexit(td, SIGILL);
	}
	regs->tf_rsp = PTROUT(fp);
	regs->tf_rip = linux32_sigcode;
	regs->tf_rflags &= ~(PSL_T | PSL_D);
	regs->tf_cs = _ucode32sel;
	regs->tf_ss = _udatasel;
	regs->tf_ds = _udatasel;
	regs->tf_es = _udatasel;
	regs->tf_fs = _ufssel;
	regs->tf_gs = _ugssel;
	regs->tf_flags = TF_HASSEGS;
	set_pcb_flags(td->td_pcb, PCB_FULL_IRET);
	PROC_LOCK(p);
	mtx_lock(&psp->ps_mtx);
}
static void linux_sendsig ( sig_t catcher , ksiginfo_t * ksi , sigset_t * mask ) { struct thread * td = curthread ; struct proc * p = td -> td_proc ; struct sigacts * psp ; struct trapframe * regs ; struct l_sigframe * fp , frame ; l_sigset_t lmask ; int oonstack ; int sig , code ; sig = ksi -> ksi_signo ; code = ksi -> ksi_code ; PROC_LOCK_ASSERT ( p , MA_OWNED ) ; psp = p -> p_sigacts ; mtx_assert ( & psp -> ps_mtx , MA_OWNED ) ; if ( SIGISMEMBER ( psp -> ps_siginfo , sig ) ) { linux_rt_sendsig ( catcher , ksi , mask ) ; return ; } regs = td -> td_frame ; oonstack = sigonstack ( regs -> tf_rsp ) ; #ifdef DEBUG if ( ldebug ( sendsig ) ) printf ( ARGS ( sendsig , " " ) , catcher , sig , ( void * ) mask , code ) ; #endif if ( ( td -> td_pflags & TDP_ALTSTACK ) && ! oonstack && SIGISMEMBER ( psp -> ps_sigonstack , sig ) ) { fp = ( struct l_sigframe * ) ( ( uintptr_t ) td -> td_sigstk . ss_sp + td -> td_sigstk . ss_size - sizeof ( struct l_sigframe ) ) ; } else fp = ( struct l_sigframe * ) regs -> tf_rsp - 1 ; mtx_unlock ( & psp -> ps_mtx ) ; PROC_UNLOCK ( p ) ; sig = bsd_to_linux_signal ( sig ) ; bzero ( & frame , sizeof ( frame ) ) ; frame . sf_handler = PTROUT ( catcher ) ; frame . sf_sig = sig ; bsd_to_linux_sigset ( mask , & lmask ) ; frame . sf_sc . sc_mask = lmask . __mask ; frame . sf_sc . sc_gs = regs -> tf_gs ; frame . sf_sc . sc_fs = regs -> tf_fs ; frame . sf_sc . sc_es = regs -> tf_es ; frame . sf_sc . sc_ds = regs -> tf_ds ; frame . sf_sc . sc_edi = regs -> tf_rdi ; frame . sf_sc . sc_esi = regs -> tf_rsi ; frame . sf_sc . sc_ebp = regs -> tf_rbp ; frame . sf_sc . sc_ebx = regs -> tf_rbx ; frame . sf_sc . sc_esp = regs -> tf_rsp ; frame . sf_sc . sc_edx = regs -> tf_rdx ; frame . sf_sc . sc_ecx = regs -> tf_rcx ; frame . sf_sc . sc_eax = regs -> tf_rax ; frame . sf_sc . sc_eip = regs -> tf_rip ; frame . sf_sc . sc_cs = regs -> tf_cs ; frame . sf_sc . sc_eflags = regs -> tf_rflags ; frame . sf_sc . sc_esp_at_signal = regs -> tf_rsp ; frame . sf_sc . sc_ss = regs -> tf_ss ; frame . sf_sc . sc_err = regs -> tf_err ; frame . sf_sc . sc_cr2 = ( u_int32_t ) ( uintptr_t ) ksi -> ksi_addr ; frame . sf_sc . sc_trapno = bsd_to_linux_trapcode ( code ) ; frame . sf_extramask [ 0 ] = lmask . __mask ; if ( copyout ( & frame , fp , sizeof ( frame ) ) != 0 ) { PROC_LOCK ( p ) ; sigexit ( td , SIGILL ) ; } regs -> tf_rsp = PTROUT ( fp ) ; regs -> tf_rip = linux32_sigcode ; regs -> tf_rflags &= ~ ( PSL_T | PSL_D ) ; regs -> tf_cs = _ucode32sel ; regs -> tf_ss = _udatasel ; regs -> tf_ds = _udatasel ; regs -> tf_es = _udatasel ; regs -> tf_fs = _ufssel ; regs -> tf_gs = _ugssel ; regs -> tf_flags = TF_HASSEGS ; set_pcb_flags ( td -> td_pcb , PCB_FULL_IRET ) ; PROC_LOCK ( p ) ; mtx_lock ( & psp -> ps_mtx ) ; }
Send an interrupt to process.
Send an interrupt to process .
/* Signal handler installed with SA_SIGINFO. */ /*
	 * Allocate space for the signal handler context.
	 */ /*
	 * Build the argument list for the signal handler.
	 */ /*
	 * Build the signal context to be used by sigreturn.
	 */ /*
		 * Process has trashed its stack; give it an illegal
		 * instruction to halt it in its tracks.
		 */ /*
	 * Build context to run handler in.
	 */