int netbsd32_process_read_regs(struct lwp *l, struct reg32 *regs) { struct trapframe *tf = l->l_md.md_regs; regs->r_gs = LSEL(LUCODE32_SEL, SEL_UPL); regs->r_fs = LSEL(LUCODE32_SEL, SEL_UPL); regs->r_es = LSEL(LUCODE32_SEL, SEL_UPL); regs->r_ds = LSEL(LUCODE32_SEL, SEL_UPL); regs->r_eflags = tf->tf_rflags; /* XXX avoid sign extension problems with unknown upper bits? */ regs->r_edi = tf->tf_rdi & 0xffffffff; regs->r_esi = tf->tf_rsi & 0xffffffff; regs->r_ebp = tf->tf_rbp & 0xffffffff; regs->r_ebx = tf->tf_rbx & 0xffffffff; regs->r_edx = tf->tf_rdx & 0xffffffff; regs->r_ecx = tf->tf_rcx & 0xffffffff; regs->r_eax = tf->tf_rax & 0xffffffff; regs->r_eip = tf->tf_rip & 0xffffffff; regs->r_cs = tf->tf_cs; regs->r_esp = tf->tf_rsp & 0xffffffff; regs->r_ss = tf->tf_ss; return (0); }
void netbsd32_setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack) { struct pcb *pcb; struct trapframe *tf; struct proc *p = l->l_proc; pcb = lwp_getpcb(l); /* If we were using the FPU, forget about it. */ if (pcb->pcb_fpcpu != NULL) { fpusave_lwp(l, false); } #if defined(USER_LDT) && 0 pmap_ldt_cleanup(p); #endif netbsd32_adjust_limits(p); l->l_md.md_flags &= ~MDL_USEDFPU; l->l_md.md_flags |= MDL_COMPAT32; /* Force iret not sysret */ pcb->pcb_flags = PCB_COMPAT32; if (pack->ep_osversion >= 699002600) pcb->pcb_savefpu.fp_fxsave.fx_fcw = __NetBSD_NPXCW__; else pcb->pcb_savefpu.fp_fxsave.fx_fcw = __NetBSD_COMPAT_NPXCW__; pcb->pcb_savefpu.fp_fxsave.fx_mxcsr = __INITIAL_MXCSR__; pcb->pcb_savefpu.fp_fxsave.fx_mxcsr_mask = __INITIAL_MXCSR_MASK__; p->p_flag |= PK_32; tf = l->l_md.md_regs; tf->tf_ds = LSEL(LUDATA32_SEL, SEL_UPL); tf->tf_es = LSEL(LUDATA32_SEL, SEL_UPL); cpu_fsgs_zero(l); cpu_fsgs_reload(l, tf->tf_ds, tf->tf_es); tf->tf_rdi = 0; tf->tf_rsi = 0; tf->tf_rbp = 0; tf->tf_rbx = (uint32_t)p->p_psstrp; tf->tf_rdx = 0; tf->tf_rcx = 0; tf->tf_rax = 0; tf->tf_rip = pack->ep_entry; tf->tf_cs = LSEL(LUCODE32_SEL, SEL_UPL); tf->tf_rflags = PSL_USERSET; tf->tf_rsp = stack; tf->tf_ss = LSEL(LUDATA32_SEL, SEL_UPL); }
/* * Clear registers on exec */ void setregs(struct proc *p, struct exec_package *pack, u_long stack, register_t *retval) { struct pcb *pcb = &p->p_addr->u_pcb; struct trapframe *tf; /* If we were using the FPU, forget about it. */ if (p->p_addr->u_pcb.pcb_fpcpu != NULL) fpusave_proc(p, 0); #ifdef USER_LDT pmap_ldt_cleanup(p); #endif p->p_md.md_flags &= ~MDP_USEDFPU; pcb->pcb_flags = 0; pcb->pcb_savefpu.fp_fxsave.fx_fcw = __INITIAL_NPXCW__; pcb->pcb_savefpu.fp_fxsave.fx_mxcsr = __INITIAL_MXCSR__; pcb->pcb_savefpu.fp_fxsave.fx_mxcsr_mask = __INITIAL_MXCSR_MASK__; tf = p->p_md.md_regs; tf->tf_ds = LSEL(LUDATA_SEL, SEL_UPL); tf->tf_es = LSEL(LUDATA_SEL, SEL_UPL); tf->tf_fs = LSEL(LUDATA_SEL, SEL_UPL); tf->tf_gs = LSEL(LUDATA_SEL, SEL_UPL); tf->tf_rdi = 0; tf->tf_rsi = 0; tf->tf_rbp = 0; tf->tf_rbx = 0; tf->tf_rdx = 0; tf->tf_rcx = 0; tf->tf_rax = 0; tf->tf_rip = pack->ep_entry; tf->tf_cs = LSEL(LUCODE_SEL, SEL_UPL); tf->tf_rflags = PSL_USERSET; tf->tf_rsp = stack; tf->tf_ss = LSEL(LUDATA_SEL, SEL_UPL); retval[1] = 0; }
/* * 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(sig_t catcher, int sig, int mask, u_long code, int type, union sigval val) { struct proc *p = curproc; struct trapframe *tf = p->p_md.md_regs; struct sigacts * psp = p->p_sigacts; struct sigcontext ksc; siginfo_t ksi; register_t sp, scp, sip; u_long sss; #ifdef DEBUG if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) printf("sendsig: %s[%d] sig %d catcher %p\n", p->p_comm, p->p_pid, sig, catcher); #endif bcopy(tf, &ksc, sizeof(*tf)); ksc.sc_onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; ksc.sc_mask = mask; ksc.sc_fpstate = NULL; /* Allocate space for the signal handler context. */ if ((psp->ps_flags & SAS_ALTSTACK) && !ksc.sc_onstack && (psp->ps_sigonstack & sigmask(sig))) { sp = (register_t)psp->ps_sigstk.ss_sp + psp->ps_sigstk.ss_size; psp->ps_sigstk.ss_flags |= SS_ONSTACK; } else sp = tf->tf_rsp - 128; sp &= ~15ULL; /* just in case */ sss = (sizeof(ksc) + 15) & ~15; if (p->p_md.md_flags & MDP_USEDFPU) { fpusave_proc(p, 1); sp -= sizeof(struct fxsave64); ksc.sc_fpstate = (struct fxsave64 *)sp; if (copyout(&p->p_addr->u_pcb.pcb_savefpu.fp_fxsave, (void *)sp, sizeof(struct fxsave64))) sigexit(p, SIGILL); } sip = 0; if (psp->ps_siginfo & sigmask(sig)) { sip = sp - ((sizeof(ksi) + 15) & ~15); sss += (sizeof(ksi) + 15) & ~15; initsiginfo(&ksi, sig, code, type, val); if (copyout(&ksi, (void *)sip, sizeof(ksi))) sigexit(p, SIGILL); } scp = sp - sss; if (copyout(&ksc, (void *)scp, sizeof(ksc))) sigexit(p, SIGILL); /* * Build context to run handler in. */ tf->tf_ds = LSEL(LUDATA_SEL, SEL_UPL); tf->tf_es = LSEL(LUDATA_SEL, SEL_UPL); tf->tf_fs = LSEL(LUDATA_SEL, SEL_UPL); tf->tf_gs = LSEL(LUDATA_SEL, SEL_UPL); tf->tf_rax = (u_int64_t)catcher; tf->tf_rdi = sig; tf->tf_rsi = sip; tf->tf_rdx = scp; tf->tf_rip = (u_int64_t)p->p_sigcode; tf->tf_cs = LSEL(LUCODE_SEL, SEL_UPL); tf->tf_rflags &= ~(PSL_T|PSL_VM|PSL_AC); tf->tf_rsp = scp; tf->tf_ss = LSEL(LUDATA_SEL, SEL_UPL); #ifdef DEBUG if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) printf("sendsig(%d): pc 0x%x, catcher 0x%x\n", p->p_pid, tf->tf_rip, tf->tf_rax); #endif }