printf("sigreturn(%d): ssp %x usp %x scp %x ft %d\n",
printf("sigreturn(%d): ssp %p usp %x scp %p ft %d\n",
sys_sigreturn(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	struct sys_sigreturn_args /* {		syscallarg(struct sigcontext *) sigcntxp;	} */ *uap = v;	extern short	exframesize[];	struct sigcontext *scp, context;	struct frame	*frame;	struct sigstate	tstate;	int     rf, flags;	scp = SCARG(uap, sigcntxp);#ifdef DEBUG	if (sigdebug & SDB_FOLLOW)		printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);#endif	if ((int) scp & 1)		return (EINVAL);	/*	 * Test and fetch the context structure.	 * We grab it all at once for speed.	 */	if (useracc((caddr_t) scp, sizeof(*scp), B_WRITE) == 0 ||	    copyin(scp, &context, sizeof(context)))		return (EINVAL);	scp = &context;	if ((scp->sc_ps & (PSL_MBZ | PSL_IPL | PSL_S)) != 0)		return (EINVAL);	/*	 * Restore the user supplied information	 */	if (scp->sc_onstack & 1)		p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;	else		p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;	p->p_sigmask = scp->sc_mask & ~sigcantmask;	frame = (struct frame *) p->p_md.md_regs;	frame->f_regs[SP] = scp->sc_sp;	frame->f_regs[A6] = scp->sc_fp;	frame->f_pc = scp->sc_pc;	frame->f_sr = scp->sc_ps;	/*	 * Grab pointer to hardware state information.	 * If zero, the user is probably doing a longjmp.	 */	if ((rf = scp->sc_ap) == 0)		return (EJUSTRETURN);	/*	 * See if there is anything to do before we go to the	 * expense of copying in close to 1/2K of data	 */	flags = fuword((caddr_t) rf);#ifdef DEBUG	if (sigdebug & SDB_FOLLOW)		printf("sigreturn(%d): sc_ap %x flags %x\n",		    p->p_pid, rf, flags);#endif	/*	 * fuword failed (bogus sc_ap value).	 */	if (flags == -1)		return (EINVAL);	if (flags == 0 || copyin((caddr_t) rf, (caddr_t) & tstate, sizeof tstate))		return (EJUSTRETURN);#ifdef DEBUG	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)		printf("sigreturn(%d): ssp %x usp %x scp %x ft %d\n",		    p->p_pid, &flags, scp->sc_sp, SCARG(uap, sigcntxp),		    (flags & SS_RTEFRAME) ? tstate.ss_frame.f_format : -1);#endif	/*	 * Restore most of the users registers except for A6 and SP	 * which were handled above.	 */	if (flags & SS_USERREGS)		bcopy((caddr_t) tstate.ss_frame.f_regs,		    (caddr_t) frame->f_regs, sizeof(frame->f_regs) - 2 * NBPW);	/*	 * Restore long stack frames.  Note that we do not copy	 * back the saved SR or PC, they were picked up above from	 * the sigcontext structure.	 */	if (flags & SS_RTEFRAME) {		register int sz;		/* grab frame type and validate */		sz = tstate.ss_frame.f_format;		if (sz > 15 || (sz = exframesize[sz]) < 0)			return (EINVAL);		frame->f_stackadj -= sz;		frame->f_format = tstate.ss_frame.f_format;		frame->f_vector = tstate.ss_frame.f_vector;		bcopy((caddr_t) & tstate.ss_frame.F_u, (caddr_t) & frame->F_u, sz);#ifdef DEBUG		if (sigdebug & SDB_FOLLOW)			printf("sigreturn(%d): copy in %d of frame type %d\n",			    p->p_pid, sz, tstate.ss_frame.f_format);#endif	}	/*	 * Finally we restore the original FP context	 */	if (flags & SS_FPSTATE)		m68881_restore(&tstate.ss_fpstate);#ifdef DEBUG	if ((sigdebug & SDB_FPSTATE) && *(char *) &tstate.ss_fpstate)		printf("sigreturn(%d): copied in FP state (%x) at %x\n",		    p->p_pid, *(u_int *) & tstate.ss_fpstate,		    &tstate.ss_fpstate);	if ((sigdebug & SDB_FOLLOW) ||	    ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid))		printf("sigreturn(%d): returns\n", p->p_pid);#endif	return (EJUSTRETURN);}