diff options
author | peter <peter@FreeBSD.org> | 2003-11-08 07:43:44 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2003-11-08 07:43:44 +0000 |
commit | b652116ae946f9f6b733455558cc0f8a35407ed2 (patch) | |
tree | 9dd7ec964780095843f3c394f45716ecd177b0cd /sys/amd64/ia32/ia32_signal.c | |
parent | 4de1c73f1033a90d81b1b1ba9e7b5a0dda9892af (diff) | |
download | FreeBSD-src-b652116ae946f9f6b733455558cc0f8a35407ed2.zip FreeBSD-src-b652116ae946f9f6b733455558cc0f8a35407ed2.tar.gz |
Move a MD 32 bit binary support routine into the MD areas. exec_setregs
is highly MD in an emulation environment since it operates on the host
environment. Although the setregs functions are really for exec support
rather than signals, they deal with the same sorts of context and include
files. So I put it there rather than create yet another file.
Diffstat (limited to 'sys/amd64/ia32/ia32_signal.c')
-rw-r--r-- | sys/amd64/ia32/ia32_signal.c | 41 |
1 files changed, 41 insertions, 0 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; +} |