diff options
-rw-r--r-- | sys/amd64/ia32/ia32_signal.c | 41 | ||||
-rw-r--r-- | sys/compat/ia32/ia32_signal.h | 2 | ||||
-rw-r--r-- | sys/compat/ia32/ia32_sysvec.c | 45 |
3 files changed, 43 insertions, 45 deletions
diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c index 30074e8..ae5978e 100644 --- a/sys/amd64/ia32/ia32_signal.c +++ b/sys/amd64/ia32/ia32_signal.c @@ -558,3 +558,44 @@ freebsd32_sigreturn(td, uap) PROC_UNLOCK(p); return (EJUSTRETURN); } + +/* + * Clear registers on exec + */ +void +ia32_setregs(td, entry, stack, ps_strings) + struct thread *td; + u_long entry; + u_long stack; + u_long ps_strings; +{ + struct trapframe *regs = td->td_frame; + struct pcb *pcb = td->td_pcb; + + wrmsr(MSR_FSBASE, 0); + wrmsr(MSR_KGSBASE, 0); /* User value while we're in the kernel */ + pcb->pcb_fsbase = 0; + pcb->pcb_gsbase = 0; + load_ds(_udatasel); + load_es(_udatasel); + load_fs(_udatasel); + load_gs(_udatasel); + pcb->pcb_ds = _udatasel; + pcb->pcb_es = _udatasel; + pcb->pcb_fs = _udatasel; + pcb->pcb_gs = _udatasel; + + bzero((char *)regs, sizeof(struct trapframe)); + regs->tf_rip = entry; + regs->tf_rsp = stack; + regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T); + regs->tf_ss = _udatasel; + regs->tf_cs = _ucode32sel; + regs->tf_rbx = ps_strings; + load_cr0(rcr0() | CR0_MP | CR0_TS); + fpstate_drop(td); + + /* Return via doreti so that we can change to a different %cs */ + pcb->pcb_flags |= PCB_FULLCTX; + td->td_retval[1] = 0; +} diff --git a/sys/compat/ia32/ia32_signal.h b/sys/compat/ia32/ia32_signal.h index e9b3502..12bf946 100644 --- a/sys/compat/ia32/ia32_signal.h +++ b/sys/compat/ia32/ia32_signal.h @@ -160,3 +160,5 @@ extern char freebsd4_ia32_sigcode[]; extern int sz_ia32_sigcode; extern int sz_freebsd4_ia32_sigcode; extern void ia32_sendsig(sig_t, int, sigset_t *, u_long); +extern void ia32_setregs(struct thread *td, u_long entry, u_long stack, + u_long ps_strings); diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c index e1c6102..2a0d684 100644 --- a/sys/compat/ia32/ia32_sysvec.c +++ b/sys/compat/ia32/ia32_sysvec.c @@ -86,8 +86,6 @@ CTASSERT(sizeof(struct ia32_sigframe4) == 408); #endif static register_t *ia32_copyout_strings(struct image_params *imgp); -static void ia32_setregs(struct thread *td, u_long entry, u_long stack, - u_long ps_strings); static void ia32_fixlimits(struct image_params *imgp); extern struct sysent freebsd32_sysent[]; @@ -244,49 +242,6 @@ ia32_copyout_strings(struct image_params *imgp) return ((register_t *)stack_base); } -/* - * Clear registers on exec - * XXX backend MD - */ -extern int _ucode32sel, _udatasel; -void -ia32_setregs(td, entry, stack, ps_strings) - struct thread *td; - u_long entry; - u_long stack; - u_long ps_strings; -{ - struct trapframe *regs = td->td_frame; - struct pcb *pcb = td->td_pcb; - - wrmsr(MSR_FSBASE, 0); - wrmsr(MSR_KGSBASE, 0); /* User value while we're in the kernel */ - pcb->pcb_fsbase = 0; - pcb->pcb_gsbase = 0; - load_ds(_udatasel); - load_es(_udatasel); - load_fs(_udatasel); - load_gs(_udatasel); - pcb->pcb_ds = _udatasel; - pcb->pcb_es = _udatasel; - pcb->pcb_fs = _udatasel; - pcb->pcb_gs = _udatasel; - - bzero((char *)regs, sizeof(struct trapframe)); - regs->tf_rip = entry; - regs->tf_rsp = stack; - regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T); - regs->tf_ss = _udatasel; - regs->tf_cs = _ucode32sel; - regs->tf_rbx = ps_strings; - load_cr0(rcr0() | CR0_MP | CR0_TS); - fpstate_drop(td); - - /* Return via doreti so that we can change to a different %cs */ - pcb->pcb_flags |= PCB_FULLCTX; - td->td_retval[1] = 0; -} - static u_long ia32_maxdsiz = IA32_MAXDSIZ; SYSCTL_ULONG(_compat_ia32, OID_AUTO, maxdsiz, CTLFLAG_RW, &ia32_maxdsiz, 0, ""); static u_long ia32_maxssiz = IA32_MAXSSIZ; |