/* * Send an interrupt to process. */ void sendsig_sigcontext(const ksiginfo_t *ksi, const sigset_t *mask) { struct lwp *l = curlwp; struct proc *p = l->l_proc; struct sigacts *ps = p->p_sigacts; struct frame *frame = (struct frame *)l->l_md.md_regs; int onstack; int sig = ksi->ksi_signo; u_long code = KSI_TRAPCODE(ksi); struct sigframe_sigcontext *fp = getframe(l, sig, &onstack), kf; sig_t catcher = SIGACTION(p, sig).sa_handler; short ft = frame->f_format; fp--; #ifdef DEBUG if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("sendsig(%d): sig %d ssp %p usp %p scp %p ft %d\n", p->p_pid, sig, &onstack, fp, &fp->sf_sc, ft); #endif /* Build stack frame for signal trampoline. */ switch (ps->sa_sigdesc[sig].sd_vers) { case 0: /* legacy on-stack sigtramp */ kf.sf_ra = (int)p->p_sigctx.ps_sigcode; break; case 1: kf.sf_ra = (int)ps->sa_sigdesc[sig].sd_tramp; break; default: /* Don't know what trampoline version; kill it. */ sigexit(l, SIGILL); } kf.sf_signum = sig; kf.sf_code = code; kf.sf_scp = &fp->sf_sc; /* * Save necessary hardware state. Currently this includes: * - general registers * - original exception frame (if not a "normal" frame) * - FP coprocessor state */ kf.sf_state.ss_flags = SS_USERREGS; memcpy(kf.sf_state.ss_frame.f_regs, frame->f_regs, sizeof(frame->f_regs)); if (ft >= FMT4) { #ifdef DEBUG if (ft > 15 || exframesize[ft] < 0) panic("sendsig: bogus frame type"); #endif kf.sf_state.ss_flags |= SS_RTEFRAME; kf.sf_state.ss_frame.f_format = frame->f_format; kf.sf_state.ss_frame.f_vector = frame->f_vector; memcpy(&kf.sf_state.ss_frame.F_u, &frame->F_u, (size_t) exframesize[ft]); /* * Leave an indicator that we need to clean up the kernel * stack. We do this by setting the "pad word" above the * hardware stack frame to the amount the stack must be * adjusted by. * * N.B. we increment rather than just set f_stackadj in * case we are called from syscall when processing a * sigreturn. In that case, f_stackadj may be non-zero. */ frame->f_stackadj += exframesize[ft]; frame->f_format = frame->f_vector = 0; #ifdef DEBUG if (sigdebug & SDB_FOLLOW) printf("sendsig(%d): copy out %d of frame %d\n", p->p_pid, exframesize[ft], ft); #endif } if (fputype) { kf.sf_state.ss_flags |= SS_FPSTATE; m68881_save(&kf.sf_state.ss_fpstate); } #ifdef DEBUG if ((sigdebug & SDB_FPSTATE) && *(char *)&kf.sf_state.ss_fpstate) printf("sendsig(%d): copy out FP state (%x) to %p\n", p->p_pid, *(u_int *)&kf.sf_state.ss_fpstate, &kf.sf_state.ss_fpstate); #endif /* Build the signal context to be used by sigreturn. */ kf.sf_sc.sc_sp = frame->f_regs[SP]; kf.sf_sc.sc_fp = frame->f_regs[A6]; kf.sf_sc.sc_ap = (int)&fp->sf_state; kf.sf_sc.sc_pc = frame->f_pc; kf.sf_sc.sc_ps = frame->f_sr; /* Save signal stack. */ kf.sf_sc.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK; /* Save signal mask. */ kf.sf_sc.sc_mask = *mask; #ifdef COMPAT_13 /* * XXX We always have to save an old style signal mask because * XXX we might be delivering a signal to a process which will * XXX escape from the signal in a non-standard way and invoke * XXX sigreturn() directly. */ native_sigset_to_sigset13(mask, &kf.sf_sc.__sc_mask13); #endif if (copyout(&kf, fp, sizeof(kf)) != 0) { #ifdef DEBUG if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("sendsig(%d): copyout failed on sig %d\n", p->p_pid, sig); #endif /* * Process has trashed its stack; give it an illegal * instruction to halt it in its tracks. */ sigexit(l, SIGILL); /* NOTREACHED */ } #ifdef DEBUG if (sigdebug & SDB_FOLLOW) printf("sendsig(%d): sig %d scp %p fp %p sc_sp %x sc_ap %x\n", p->p_pid, sig, kf.sf_scp, fp, kf.sf_sc.sc_sp, kf.sf_sc.sc_ap); #endif buildcontext(l, catcher, fp); /* Remember that we're now on the signal stack. */ if (onstack) p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; #ifdef DEBUG if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("sendsig(%d): sig %d returns\n", p->p_pid, sig); #endif }
void sendsig_sigcontext(const ksiginfo_t *ksi, const sigset_t *mask) { struct lwp *l = curlwp; struct proc *p = l->l_proc; struct sigacts *ps = p->p_sigacts; int onstack, sig = ksi->ksi_signo; struct sigframe_sigcontext *fp, frame; struct trapframe *tf; sig_t catcher = SIGACTION(p, sig).sa_handler; tf = l->l_md.md_tf; fp = getframe(l, sig, &onstack), frame; fp--; #ifdef DEBUG if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("sendsig_sigcontext(%d): sig %d ssp %p usp %p\n", p->p_pid, sig, &onstack, fp); #endif /* Build stack frame for signal trampoline. */ frame.sf_sc.sc_pc = tf->tf_regs[FRAME_PC]; frame.sf_sc.sc_ps = tf->tf_regs[FRAME_PS]; /* Save register context. */ frametoreg(tf, (struct reg *)frame.sf_sc.sc_regs); frame.sf_sc.sc_regs[R_ZERO] = 0xACEDBADE; /* magic number */ frame.sf_sc.sc_regs[R_SP] = alpha_pal_rdusp(); /* save the floating-point state, if necessary, then copy it. */ if (l->l_addr->u_pcb.pcb_fpcpu != NULL) fpusave_proc(l, 1); frame.sf_sc.sc_ownedfp = l->l_md.md_flags & MDP_FPUSED; memcpy((struct fpreg *)frame.sf_sc.sc_fpregs, &l->l_addr->u_pcb.pcb_fp, sizeof(struct fpreg)); frame.sf_sc.sc_fp_control = alpha_read_fp_c(l); memset(frame.sf_sc.sc_reserved, 0, sizeof frame.sf_sc.sc_reserved); memset(frame.sf_sc.sc_xxx, 0, sizeof frame.sf_sc.sc_xxx); /* XXX */ /* Save signal stack. */ frame.sf_sc.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK; /* Save signal mask. */ frame.sf_sc.sc_mask = *mask; #ifdef COMPAT_13 /* * XXX We always have to save an old style signal mask because * XXX we might be delivering a signal to a process which will * XXX escape from the signal in a non-standard way and invoke * XXX sigreturn() directly. */ { /* Note: it's a long in the stack frame. */ sigset13_t mask13; native_sigset_to_sigset13(mask, &mask13); frame.sf_sc.__sc_mask13 = mask13; } #endif #ifdef COMPAT_OSF1 /* * XXX Create an OSF/1-style sigcontext and associated goo. */ #endif if (copyout(&frame, (caddr_t)fp, sizeof(frame)) != 0) { /* * Process has trashed its stack; give it an illegal * instruction to halt it in its tracks. */ #ifdef DEBUG if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("sendsig_sigcontext(%d): copyout failed on sig %d\n", p->p_pid, sig); #endif sigexit(l, SIGILL); /* NOTREACHED */ } #ifdef DEBUG if (sigdebug & SDB_FOLLOW) printf("sendsig_sigcontext(%d): sig %d usp %p code %x\n", p->p_pid, sig, fp, ksi->ksi_code); #endif /* * Set up the registers to directly invoke the signal handler. The * signal trampoline is then used to return from the signal. Note * the trampoline version numbers are coordinated with machine- * dependent code in libc. */ switch (ps->sa_sigdesc[sig].sd_vers) { case 0: /* legacy on-stack sigtramp */ buildcontext(l,(void *)catcher, (void *)p->p_sigctx.ps_sigcode, (void *)fp); break; case 1: buildcontext(l,(void *)catcher, (void *)ps->sa_sigdesc[sig].sd_tramp, (void *)fp); break; default: /* Don't know what trampoline version; kill it. */ sigexit(l, SIGILL); } /* sigcontext specific trap frame */ tf->tf_regs[FRAME_A0] = sig; /* tf->tf_regs[FRAME_A1] = ksi->ksi_code; */ tf->tf_regs[FRAME_A1] = KSI_TRAPCODE(ksi); tf->tf_regs[FRAME_A2] = (u_int64_t)&fp->sf_sc; /* Remember that we're now on the signal stack. */ if (onstack) p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; #ifdef DEBUG if (sigdebug & SDB_FOLLOW) printf("sendsig(%d): pc %lx, catcher %lx\n", p->p_pid, tf->tf_regs[FRAME_PC], tf->tf_regs[FRAME_A3]); if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("sendsig(%d): sig %d returns\n", p->p_pid, sig); #endif }
/* * 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. */ void freebsd_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) { int sig = ksi->ksi_signo; u_long code = KSI_TRAPCODE(ksi); struct lwp *l = curlwp; struct proc *p = l->l_proc; int onstack, error; struct freebsd_sigframe *fp = getframe(l, sig, &onstack), frame; sig_t catcher = SIGACTION(p, sig).sa_handler; struct trapframe *tf = l->l_md.md_regs; fp--; /* Build stack frame for signal trampoline. */ frame.sf_signum = sig; frame.sf_code = code; frame.sf_scp = &fp->sf_sc; frame.sf_addr = (char *)rcr2(); frame.sf_handler = catcher; /* Save context. */ #ifdef VM86 if (tf->tf_eflags & PSL_VM) { frame.sf_sc.sc_gs = tf->tf_vm86_gs; frame.sf_sc.sc_fs = tf->tf_vm86_fs; frame.sf_sc.sc_es = tf->tf_vm86_es; frame.sf_sc.sc_ds = tf->tf_vm86_ds; frame.sf_sc.sc_efl = get_vflags(l); (*p->p_emul->e_syscall_intern)(p); } else #endif { frame.sf_sc.sc_gs = tf->tf_gs; frame.sf_sc.sc_fs = tf->tf_fs; frame.sf_sc.sc_es = tf->tf_es; frame.sf_sc.sc_ds = tf->tf_ds; frame.sf_sc.sc_efl = tf->tf_eflags; } frame.sf_sc.sc_edi = tf->tf_edi; frame.sf_sc.sc_esi = tf->tf_esi; frame.sf_sc.sc_ebp = tf->tf_ebp; frame.sf_sc.sc_isp = 0; /* don't have to pass kernel sp to user. */ frame.sf_sc.sc_ebx = tf->tf_ebx; frame.sf_sc.sc_edx = tf->tf_edx; frame.sf_sc.sc_ecx = tf->tf_ecx; frame.sf_sc.sc_eax = tf->tf_eax; frame.sf_sc.sc_eip = tf->tf_eip; frame.sf_sc.sc_cs = tf->tf_cs; frame.sf_sc.sc_esp = tf->tf_esp; frame.sf_sc.sc_ss = tf->tf_ss; /* Save signal stack. */ frame.sf_sc.sc_onstack = l->l_sigstk.ss_flags & SS_ONSTACK; /* Save signal mask. */ /* XXX freebsd_osigcontext compat? */ frame.sf_sc.sc_mask = *mask; 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 */ } buildcontext(l, GUCODEBIG_SEL, p->p_sigctx.ps_sigcode, fp); /* Remember that we're now on the signal stack. */ if (onstack) l->l_sigstk.ss_flags |= SS_ONSTACK; }
int GrSetMode(GrGraphicsMode which,...) { int w,h,pl,vw,vh; int t,noclear,res; GrColor c; va_list ap; GRX_ENTER(); pl = 0; vw = 0; vh = 0; t = FALSE; noclear = FALSE; c = 0; res = FALSE; DBGPRINTF(DBG_SETMD,("Mode: %d\n",(int)which)); if(DRVINFO->vdriver == NULL) { GrSetDriver(NULL); if(DRVINFO->vdriver == NULL) { res = errhdlr("could not find suitable video driver"); goto done; } } va_start(ap,which); switch(which) { case GR_NC_default_text: noclear = TRUE; case GR_default_text: w = DRVINFO->deftw; h = DRVINFO->defth; c = DRVINFO->deftc; t = TRUE; break; case GR_NC_320_200_graphics: noclear = TRUE; case GR_320_200_graphics: w = 320; h = 200; c = DRVINFO->defgc; break; case GR_NC_default_graphics: noclear = TRUE; case GR_default_graphics: w = DRVINFO->defgw; h = DRVINFO->defgh; c = DRVINFO->defgc; break; case GR_NC_width_height_graphics: noclear = TRUE; case GR_width_height_graphics: w = va_arg(ap,int); h = va_arg(ap,int); c = DRVINFO->defgc; break; case GR_NC_biggest_graphics: noclear = TRUE; case GR_biggest_graphics: w = DRVINFO->biggw; h = DRVINFO->biggh; pl = 32; break; case GR_NC_width_height_color_graphics: noclear = TRUE; case GR_width_height_color_graphics: w = va_arg(ap,int); h = va_arg(ap,int); c = va_arg(ap,GrColor); break; case GR_NC_width_height_bpp_graphics: noclear = TRUE; case GR_width_height_bpp_graphics: w = va_arg(ap,int); h = va_arg(ap,int); pl = va_arg(ap,int); break; case GR_NC_custom_graphics: noclear = TRUE; case GR_custom_graphics: w = va_arg(ap,int); h = va_arg(ap,int); c = va_arg(ap,GrColor); vw = va_arg(ap,int); vh = va_arg(ap,int); break; case GR_NC_custom_bpp_graphics: noclear = TRUE; case GR_custom_bpp_graphics: w = va_arg(ap,int); h = va_arg(ap,int); pl = va_arg(ap,int); vw = va_arg(ap,int); vh = va_arg(ap,int); break; default: va_end(ap); res = errhdlr("unknown video mode"); goto done; } va_end(ap); if (c) for(pl = 1; (pl < 32) && ((1UL << pl) < (GrColor)c); pl++) ; for( ; ; ) { GrContext cxt; GrFrameDriver fdr; GrVideoMode *mdp,vmd; mdp = (DRVINFO->vdriver->selectmode)(DRVINFO->vdriver,w,h,pl,t,NULL); if(!mdp) { res = errhdlr("could not find suitable video mode"); goto done; } sttcopy(&vmd,mdp); if((t || buildframedriver(&vmd,&fdr)) && (*vmd.extinfo->setup)(&vmd,noclear) && (t || buildcontext(&vmd,&fdr,&cxt))) { if((!t) && ((vw > vmd.width) || (vh > vmd.height)) && (vmd.extinfo->setvsize != NULL) && (vmd.extinfo->scroll != NULL)) { int ww = vmd.width = imax(vw,vmd.width); int hh = vmd.height = imax(vh,vmd.height); if(!(*vmd.extinfo->setvsize)(&vmd,ww,hh,&vmd) || !buildcontext(&vmd,&fdr,&cxt)) { sttcopy(&vmd,mdp); buildcontext(&vmd,&fdr,&cxt); (*vmd.extinfo->setup)(&vmd,noclear); } } // DBGPRINTF(DBG_SETMD,("GrMouseUnInit ...\n")); // GrMouseUnInit(); // DBGPRINTF(DBG_SETMD,("GrMouseUnInit done\n")); DRVINFO->setbank = (void (*)(int ))_GrDummyFunction; DRVINFO->setrwbanks = (void (*)(int,int))_GrDummyFunction; DRVINFO->curbank = (-1); DRVINFO->splitbanks = FALSE; if(!t) { if(vmd.extinfo->setbank) { DRVINFO->setbank = vmd.extinfo->setbank; } if(vmd.extinfo->setrwbanks) { DRVINFO->setrwbanks = vmd.extinfo->setrwbanks; DRVINFO->splitbanks = TRUE; } if(umul32(vmd.lineoffset,vmd.height) <= 0x10000L) { DRVINFO->splitbanks = TRUE; } } else { sttzero(&cxt); sttcopy(&fdr,&DRVINFO->tdriver); cxt.gc_driver = &DRVINFO->tdriver; } sttcopy(&CXTINFO->current,&cxt); sttcopy(&CXTINFO->screen, &cxt); sttcopy(&DRVINFO->fdriver,&fdr); sttcopy(&DRVINFO->sdriver,&fdr); sttcopy(&DRVINFO->actmode,&vmd); DRVINFO->curmode = mdp; DRVINFO->mcode = which; DRVINFO->vposx = 0; DRVINFO->vposy = 0; DBGPRINTF(DBG_SETMD,("GrResetColors ...\n")); if ( !_GrResetColors() ) { res = errhdlr("could not set color mode"); goto done; } DBGPRINTF(DBG_SETMD,("GrResetColors done\n")); if(fdr.init) { DBGPRINTF(DBG_SETMD,("fdr.init ...\n")); (*fdr.init)(&DRVINFO->actmode); DBGPRINTF(DBG_SETMD,("fdr.init done\n")); } if(DRVINFO->mdsethook) { DBGPRINTF(DBG_SETMD,("mdsethook ...\n")); (*DRVINFO->mdsethook)(); DBGPRINTF(DBG_SETMD,("mdsethook done\n")); } DBGPRINTF(DBG_SETMD,("GrSetMode complete\n")); res = TRUE; goto done; } mdp->present = FALSE; } done: GRX_RETURN(res); }
/* * 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. */ void sendsig_sigcontext(const ksiginfo_t *ksi, const sigset_t *mask) { struct lwp *l = curlwp; struct proc *p = l->l_proc; struct pmap *pmap = vm_map_pmap(&p->p_vmspace->vm_map); int sel = pmap->pm_hiexec > I386_MAX_EXE_ADDR ? GUCODEBIG_SEL : GUCODE_SEL; struct sigacts *ps = p->p_sigacts; struct trapframe *tf = l->l_md.md_regs; int onstack, error; int sig = ksi->ksi_signo; u_long code = KSI_TRAPCODE(ksi); struct sigframe_sigcontext *fp = getframe(l, sig, &onstack), frame; sig_t catcher = SIGACTION(p, sig).sa_handler; fp--; /* Build stack frame for signal trampoline. */ switch (ps->sa_sigdesc[sig].sd_vers) { case 0: /* legacy on-stack sigtramp */ frame.sf_ra = (int)p->p_sigctx.ps_sigcode; break; case 1: frame.sf_ra = (int)ps->sa_sigdesc[sig].sd_tramp; break; default: /* Don't know what trampoline version; kill it. */ sigexit(l, SIGILL); } frame.sf_signum = sig; frame.sf_code = code; frame.sf_scp = &fp->sf_sc; /* Save register context. */ #ifdef VM86 if (tf->tf_eflags & PSL_VM) { frame.sf_sc.sc_gs = tf->tf_vm86_gs; frame.sf_sc.sc_fs = tf->tf_vm86_fs; frame.sf_sc.sc_es = tf->tf_vm86_es; frame.sf_sc.sc_ds = tf->tf_vm86_ds; frame.sf_sc.sc_eflags = get_vflags(l); (*p->p_emul->e_syscall_intern)(p); } else #endif { frame.sf_sc.sc_gs = tf->tf_gs; frame.sf_sc.sc_fs = tf->tf_fs; frame.sf_sc.sc_es = tf->tf_es; frame.sf_sc.sc_ds = tf->tf_ds; frame.sf_sc.sc_eflags = tf->tf_eflags; } frame.sf_sc.sc_edi = tf->tf_edi; frame.sf_sc.sc_esi = tf->tf_esi; frame.sf_sc.sc_ebp = tf->tf_ebp; frame.sf_sc.sc_ebx = tf->tf_ebx; frame.sf_sc.sc_edx = tf->tf_edx; frame.sf_sc.sc_ecx = tf->tf_ecx; frame.sf_sc.sc_eax = tf->tf_eax; frame.sf_sc.sc_eip = tf->tf_eip; frame.sf_sc.sc_cs = tf->tf_cs; frame.sf_sc.sc_esp = tf->tf_esp; frame.sf_sc.sc_ss = tf->tf_ss; frame.sf_sc.sc_trapno = tf->tf_trapno; frame.sf_sc.sc_err = tf->tf_err; /* Save signal stack. */ frame.sf_sc.sc_onstack = l->l_sigstk.ss_flags & SS_ONSTACK; /* Save signal mask. */ frame.sf_sc.sc_mask = *mask; #ifdef COMPAT_13 /* * XXX We always have to save an old style signal mask because * XXX we might be delivering a signal to a process which will * XXX escape from the signal in a non-standard way and invoke * XXX sigreturn() directly. */ native_sigset_to_sigset13(mask, &frame.sf_sc.__sc_mask13); #endif 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 */ } int svufpu = l->l_md.md_flags & MDL_USEDFPU; buildcontext(l, sel, catcher, fp); l->l_md.md_flags |= svufpu; /* Remember that we're now on the signal stack. */ if (onstack) l->l_sigstk.ss_flags |= SS_ONSTACK; }