summaryrefslogtreecommitdiff
path: root/sys/compat/ia32
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>2003-05-14 04:10:49 +0000
committerPeter Wemm <peter@FreeBSD.org>2003-05-14 04:10:49 +0000
commitd85631c4ac29e17917c0444837225df309fba37e (patch)
tree65e4ac1aca11723390006ee027d286f8177b0ec6 /sys/compat/ia32
parent5d5ca6d75e2f83055e723d2269dc0ca9934dfa88 (diff)
Notes
Diffstat (limited to 'sys/compat/ia32')
-rw-r--r--sys/compat/ia32/ia32_genassym.c24
-rw-r--r--sys/compat/ia32/ia32_signal.h164
-rw-r--r--sys/compat/ia32/ia32_sigtramp.S87
-rw-r--r--sys/compat/ia32/ia32_sysvec.c225
-rw-r--r--sys/compat/ia32/ia32_util.h2
5 files changed, 349 insertions, 153 deletions
diff --git a/sys/compat/ia32/ia32_genassym.c b/sys/compat/ia32/ia32_genassym.c
new file mode 100644
index 0000000000000..2134a4477c45c
--- /dev/null
+++ b/sys/compat/ia32/ia32_genassym.c
@@ -0,0 +1,24 @@
+/* $FreeBSD$ */
+
+#include "opt_compat.h"
+
+#include <sys/param.h>
+#include <sys/assym.h>
+#include <sys/systm.h>
+#include <sys/signal.h>
+
+#include <amd64/ia32/ia32_signal.h>
+
+ASSYM(IA32_SIGF_HANDLER, offsetof(struct ia32_sigframe, sf_ah));
+ASSYM(IA32_SIGF_UC, offsetof(struct ia32_sigframe, sf_uc));
+ASSYM(IA32_UC_GS, offsetof(struct ia32_ucontext, uc_mcontext.mc_gs));
+ASSYM(IA32_UC_FS, offsetof(struct ia32_ucontext, uc_mcontext.mc_fs));
+ASSYM(IA32_UC_ES, offsetof(struct ia32_ucontext, uc_mcontext.mc_es));
+ASSYM(IA32_UC_DS, offsetof(struct ia32_ucontext, uc_mcontext.mc_ds));
+#ifdef COMPAT_FREEBSD4
+ASSYM(IA32_SIGF_UC4, offsetof(struct ia32_sigframe, sf_uc));
+ASSYM(IA32_UC4_GS, offsetof(struct ia32_ucontext4, uc_mcontext.mc_gs));
+ASSYM(IA32_UC4_FS, offsetof(struct ia32_ucontext4, uc_mcontext.mc_fs));
+ASSYM(IA32_UC4_ES, offsetof(struct ia32_ucontext4, uc_mcontext.mc_es));
+ASSYM(IA32_UC4_DS, offsetof(struct ia32_ucontext4, uc_mcontext.mc_ds));
+#endif
diff --git a/sys/compat/ia32/ia32_signal.h b/sys/compat/ia32/ia32_signal.h
new file mode 100644
index 0000000000000..f251e72fb33c5
--- /dev/null
+++ b/sys/compat/ia32/ia32_signal.h
@@ -0,0 +1,164 @@
+/*-
+ * Copyright (c) 1999 Marcel Moolenaar
+ * Copyright (c) 2003 Peter Wemm
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+struct ia32_sigaltstack {
+ u_int32_t ss_sp; /* signal stack base */
+ u_int32_t ss_size; /* signal stack length */
+ int ss_flags; /* SS_DISABLE and/or SS_ONSTACK */
+};
+
+/* XXX should be 640 bytes long; check and see if __packed is needed */
+struct ia32_mcontext {
+ int mc_onstack; /* XXX - sigcontext compat. */
+ int mc_gs; /* machine state (struct trapframe) */
+ int mc_fs;
+ int mc_es;
+ int mc_ds;
+ int mc_edi;
+ int mc_esi;
+ int mc_ebp;
+ int mc_isp;
+ int mc_ebx;
+ int mc_edx;
+ int mc_ecx;
+ int mc_eax;
+ int mc_trapno;
+ int mc_err;
+ int mc_eip;
+ int mc_cs;
+ int mc_eflags;
+ int mc_esp;
+ int mc_ss;
+ int mc_len; /* sizeof(struct ia32_mcontext) */
+ /* We use the same values for fpformat and ownedfp */
+ int mc_fpformat;
+ int mc_ownedfp;
+ int mc_spare1[1]; /* align next field to 16 bytes */
+ /*
+ * See <machine/npx.h> for the internals of mc_fpstate[].
+ */
+ int mc_fpstate[128] __aligned(16);
+ int mc_spare2[8];
+};
+
+/* XXX should be 704 bytes long; check and see if __packed is needed */
+struct ia32_ucontext {
+ sigset_t uc_sigmask;
+ struct ia32_mcontext uc_mcontext;
+ u_int32_t uc_link;
+ struct ia32_sigaltstack uc_stack;
+ int uc_flags;
+ int __spare__[4];
+};
+
+
+#if defined(COMPAT_FREEBSD4)
+struct ia32_mcontext4 {
+ int mc_onstack; /* XXX - sigcontext compat. */
+ int mc_gs; /* machine state (struct trapframe) */
+ int mc_fs;
+ int mc_es;
+ int mc_ds;
+ int mc_edi;
+ int mc_esi;
+ int mc_ebp;
+ int mc_isp;
+ int mc_ebx;
+ int mc_edx;
+ int mc_ecx;
+ int mc_eax;
+ int mc_trapno;
+ int mc_err;
+ int mc_eip;
+ int mc_cs;
+ int mc_eflags;
+ int mc_esp;
+ int mc_ss;
+ int mc_fpregs[28];
+ int __spare__[17];
+};
+
+struct ia32_ucontext4 {
+ sigset_t uc_sigmask;
+ struct ia32_mcontext4 uc_mcontext;
+ u_int32_t uc_link;
+ struct ia32_sigaltstack uc_stack;
+ int __spare__[8];
+};
+#endif
+
+/*
+ * Signal frames, arguments passed to application signal handlers.
+ */
+union ia32_sigval {
+ int sigval_int;
+ u_int32_t sigval_ptr;
+};
+struct ia32_siginfo {
+ int si_signo; /* signal number */
+ int si_errno; /* errno association */
+ int si_code; /* signal code */
+ int32_t si_pid; /* sending process */
+ u_int32_t si_uid; /* sender's ruid */
+ int si_status; /* exit value */
+ u_int32_t si_addr; /* faulting instruction */
+ union ia32_sigval si_value; /* signal value */
+ int32_t si_band; /* band event for SIGPOLL */
+ int __spare__[7]; /* gimme some slack */
+};
+
+#ifdef COMPAT_FREEBSD4
+struct ia32_sigframe4 {
+ u_int32_t sf_signum;
+ u_int32_t sf_siginfo; /* code or pointer to sf_si */
+ u_int32_t sf_ucontext; /* points to sf_uc */
+ u_int32_t sf_addr; /* undocumented 4th arg */
+ u_int32_t sf_ah; /* action/handler pointer */
+ struct ia32_ucontext4 sf_uc; /* = *sf_ucontext */
+ struct ia32_siginfo sf_si; /* = *sf_siginfo (SA_SIGINFO case) */
+};
+#endif
+
+struct ia32_sigframe {
+ u_int32_t sf_signum;
+ u_int32_t sf_siginfo; /* code or pointer to sf_si */
+ u_int32_t sf_ucontext; /* points to sf_uc */
+ u_int32_t sf_addr; /* undocumented 4th arg */
+ u_int32_t sf_ah; /* action/handler pointer */
+ struct ia32_ucontext sf_uc; /* = *sf_ucontext */
+ struct ia32_siginfo sf_si; /* = *sf_siginfo (SA_SIGINFO case) */
+};
+
+extern char ia32_sigcode[];
+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);
diff --git a/sys/compat/ia32/ia32_sigtramp.S b/sys/compat/ia32/ia32_sigtramp.S
new file mode 100644
index 0000000000000..2e9f73d41bcee
--- /dev/null
+++ b/sys/compat/ia32/ia32_sigtramp.S
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2003 Peter Wemm
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "opt_compat.h"
+
+#include <machine/asmacros.h>
+#include <sys/syscall.h>
+
+#include "ia32_assym.h"
+
+ .text
+ .code32
+/*
+ * Signal trampoline, copied to top of user stack
+ */
+ ALIGN_TEXT
+ .globl ia32_sigcode
+ia32_sigcode:
+ calll *IA32_SIGF_HANDLER(%esp)
+ leal IA32_SIGF_UC(%esp),%eax /* get ucontext */
+ pushl %eax
+ movl IA32_UC_GS(%eax),%gs /* restore %gs */
+ movl IA32_UC_FS(%eax),%fs /* restore %fs */
+ movl IA32_UC_ES(%eax),%es /* restore %es */
+ movl IA32_UC_DS(%eax),%ds /* restore %ds */
+ movl $SYS_sigreturn,%eax
+ pushl %eax /* junk to fake return addr. */
+ int $0x80 /* enter kernel with args */
+ /* on stack */
+1:
+ jmp 1b
+
+#ifdef COMPAT_FREEBSD4
+ ALIGN_TEXT
+freebsd4_ia32_sigcode:
+ calll *IA32_SIGF_HANDLER(%esp)
+ leal IA32_SIGF_UC4(%esp),%eax/* get ucontext */
+ pushl %eax
+ movl IA32_UC4_GS(%eax),%gs /* restore %gs */
+ movl IA32_UC4_FS(%eax),%fs /* restore %fs */
+ movl IA32_UC4_ES(%eax),%es /* restore %es */
+ movl IA32_UC4_DS(%eax),%ds /* restore %ds */
+ movl $344,%eax /* 4.x SYS_sigreturn */
+ pushl %eax /* junk to fake return addr. */
+ int $0x80 /* enter kernel with args */
+ /* on stack */
+1:
+ jmp 1b
+#endif
+
+ ALIGN_TEXT
+esigcode:
+
+ .data
+ .globl sz_ia32_sigcode
+sz_ia32_sigcode:
+ .long esigcode-ia32_sigcode
+#ifdef COMPAT_FREEBSD4
+ .globl sz_freebsd4_ia32_sigcode
+sz_freebsd4_ia32_sigcode:
+ .long esigcode-freebsd4_ia32_sigcode
+#endif
diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c
index 18f4ee2fc78c6..684677a7cf88f 100644
--- a/sys/compat/ia32/ia32_sysvec.c
+++ b/sys/compat/ia32/ia32_sysvec.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2002 Doug Rabson
+ * Copyright (c) 2003 Peter Wemm
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,6 +27,8 @@
* $FreeBSD$
*/
+#include "opt_compat.h"
+
#define __ELF_WORD_SIZE 32
#include <sys/param.h>
@@ -60,12 +63,16 @@
#include <vm/vm_object.h>
#include <vm/vm_extern.h>
-#include <ia64/ia32/ia32_util.h>
-#include <i386/include/psl.h>
-#include <i386/include/segments.h>
-#include <i386/include/specialreg.h>
+#include <amd64/ia32/ia32_util.h>
+#include <amd64/ia32/ia32_proto.h>
+#include <amd64/ia32/ia32_signal.h>
+#include <machine/psl.h>
+#include <machine/segments.h>
+#include <machine/specialreg.h>
#include <machine/frame.h>
#include <machine/md_var.h>
+#include <machine/pcb.h>
+#include <machine/cpufunc.h>
static register_t *ia32_copyout_strings(struct image_params *imgp);
static void ia32_setregs(struct thread *td, u_long entry, u_long stack,
@@ -73,21 +80,6 @@ static void ia32_setregs(struct thread *td, u_long entry, u_long stack,
extern struct sysent ia32_sysent[];
-static char ia32_sigcode[] = {
- 0xff, 0x54, 0x24, 0x10, /* call *SIGF_HANDLER(%esp) */
- 0x8d, 0x44, 0x24, 0x14, /* lea SIGF_UC(%esp),%eax */
- 0x50, /* pushl %eax */
- 0xf7, 0x40, 0x54, 0x00, 0x00, 0x02, 0x02, /* testl $PSL_VM,UC_EFLAGS(%eax) */
- 0x75, 0x03, /* jne 9f */
- 0x8e, 0x68, 0x14, /* movl UC_GS(%eax),%gs */
- 0xb8, 0x57, 0x01, 0x00, 0x00, /* 9: movl $SYS_sigreturn,%eax */
- 0x50, /* pushl %eax */
- 0xcd, 0x80, /* int $0x80 */
- 0xeb, 0xfe, /* 0: jmp 0b */
- 0, 0, 0, 0
-};
-static int ia32_szsigcode = sizeof(ia32_sigcode) & ~3;
-
struct sysentvec ia32_freebsd_sysvec = {
SYS_MAXSYSCALL,
ia32_sysent,
@@ -98,24 +90,26 @@ struct sysentvec ia32_freebsd_sysvec = {
NULL,
NULL,
elf32_freebsd_fixup,
- sendsig,
+ ia32_sendsig,
ia32_sigcode,
- &ia32_szsigcode,
+ &sz_ia32_sigcode,
NULL,
- "FreeBSD ELF",
+ "FreeBSD ELF32",
elf32_coredump,
NULL,
MINSIGSTKSZ,
- 4096,
+ PAGE_SIZE,
0,
- IA32_USRSTACK,
- IA32_USRSTACK,
- IA32_PS_STRINGS,
+ USRSTACK,
+ USRSTACK,
+ PS_STRINGS,
VM_PROT_ALL,
ia32_copyout_strings,
ia32_setregs
};
+
+
static Elf32_Brandinfo ia32_brand_info = {
ELFOSABI_FREEBSD,
EM_386,
@@ -129,6 +123,8 @@ SYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf32_insert_brand_entry,
&ia32_brand_info);
+extern int _ucode32sel, _udatasel;
+
static register_t *
ia32_copyout_strings(struct image_params *imgp)
{
@@ -143,7 +139,7 @@ ia32_copyout_strings(struct image_params *imgp)
* Calculate string base and vector table pointers.
* Also deal with signal trampoline code for this exec type.
*/
- arginfo = (struct ia32_ps_strings *)IA32_PS_STRINGS;
+ arginfo = (struct ia32_ps_strings *)PS_STRINGS;
szsigcode = *(imgp->proc->p_sysent->sv_szsigcode);
destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
roundup((ARG_MAX - imgp->stringspace), sizeof(char *));
@@ -190,7 +186,6 @@ ia32_copyout_strings(struct image_params *imgp)
stringp = imgp->stringbase;
argc = imgp->argc;
envc = imgp->envc;
-
/*
* Copy out strings - arguments and environment.
*/
@@ -234,135 +229,61 @@ ia32_copyout_strings(struct image_params *imgp)
return ((register_t *)stack_base);
}
-static void
-ia32_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
+/*
+ * 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 *frame = td->td_frame;
- vm_offset_t gdt, ldt;
- u_int64_t codesel, datasel, ldtsel;
- u_int64_t codeseg, dataseg, gdtseg, ldtseg;
- struct segment_descriptor desc;
- struct vmspace *vmspace = td->td_proc->p_vmspace;
+ struct trapframe *regs = td->td_frame;
+ struct pcb *pcb = td->td_pcb;
+ u_int64_t pc;
+ register_t s;
+
+ wrmsr(MSR_FSBASE, 0);
+ wrmsr(MSR_KGSBASE, 0); /* User value while we're in the kernel */
+ pcb->pcb_fsbase = 0;
+ pcb->pcb_gsbase = 0;
+ pcb->pcb_kgsbase = rdmsr(MSR_GSBASE);
+ load_ds(_udatasel);
+ load_es(_udatasel);
+ load_fs(_udatasel);
+ s = intr_disable();
+ pc = rdmsr(MSR_GSBASE);
+ load_gs(_udatasel); /* Clobbers kernel %GS.base */
+ wrmsr(MSR_GSBASE, pc);
+ intr_restore(s);
+ 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;
/*
- * Make sure that we restore the entire trapframe after an
- * execve.
+ * Arrange to trap the next npx or `fwait' instruction (see npx.c
+ * for why fwait must be trapped at least if there is an npx or an
+ * emulator). This is mainly to handle the case where npx0 is not
+ * configured, since the npx routines normally set up the trap
+ * otherwise. It should be done only at boot time, but doing it
+ * here allows modifying `npx_exists' for testing the emulator on
+ * systems with an npx.
*/
- frame->tf_flags &= ~FRAME_SYSCALL;
-
- bzero(frame->tf_r, sizeof(frame->tf_r));
- bzero(frame->tf_f, sizeof(frame->tf_f));
-
- frame->tf_cr_iip = entry;
- frame->tf_cr_ipsr = (IA64_PSR_IC
- | IA64_PSR_I
- | IA64_PSR_IT
- | IA64_PSR_DT
- | IA64_PSR_RT
- | IA64_PSR_DFH
- | IA64_PSR_IS
- | IA64_PSR_BN
- | IA64_PSR_CPL_USER);
- frame->tf_r[FRAME_R12] = stack;
-
- codesel = LSEL(LUCODE_SEL, SEL_UPL);
- datasel = LSEL(LUDATA_SEL, SEL_UPL);
- ldtsel = GSEL(GLDT_SEL, SEL_UPL);
-
-#if 1
- frame->tf_r[FRAME_R16] = (datasel << 48) | (datasel << 32)
- | (datasel << 16) | datasel;
- frame->tf_r[FRAME_R17] = (ldtsel << 32) | (datasel << 16) | codesel;
-#else
- frame->tf_r[FRAME_R16] = datasel;
- frame->tf_r[FRAME_R17] = codesel;
- frame->tf_r[FRAME_R18] = datasel;
- frame->tf_r[FRAME_R19] = datasel;
- frame->tf_r[FRAME_R20] = datasel;
- frame->tf_r[FRAME_R21] = datasel;
- frame->tf_r[FRAME_R22] = ldtsel;
-#endif
+ load_cr0(rcr0() | CR0_MP | CR0_TS);
- /*
- * Build the GDT and LDT.
- */
- gdt = IA32_USRSTACK;
- vm_map_find(&vmspace->vm_map, 0, 0,
- &gdt, PAGE_SIZE, 0,
- VM_PROT_ALL, VM_PROT_ALL, 0);
- ldt = gdt + 4096;
-
- desc.sd_lolimit = 8*NLDT-1;
- desc.sd_lobase = ldt & 0xffffff;
- desc.sd_type = SDT_SYSLDT;
- desc.sd_dpl = SEL_UPL;
- desc.sd_p = 1;
- desc.sd_hilimit = 0;
- desc.sd_def32 = 0;
- desc.sd_gran = 0;
- desc.sd_hibase = ldt >> 24;
- copyout(&desc, (caddr_t) gdt + 8*GLDT_SEL, sizeof(desc));
-
- desc.sd_lolimit = ((IA32_USRSTACK >> 12) - 1) & 0xffff;
- desc.sd_lobase = 0;
- desc.sd_type = SDT_MEMERA;
- desc.sd_dpl = SEL_UPL;
- desc.sd_p = 1;
- desc.sd_hilimit = ((IA32_USRSTACK >> 12) - 1) >> 16;
- desc.sd_def32 = 1;
- desc.sd_gran = 1;
- desc.sd_hibase = 0;
- copyout(&desc, (caddr_t) ldt + 8*LUCODE_SEL, sizeof(desc));
- desc.sd_type = SDT_MEMRWA;
- copyout(&desc, (caddr_t) ldt + 8*LUDATA_SEL, sizeof(desc));
-
- codeseg = 0 /* base */
- + (((IA32_USRSTACK >> 12) - 1) << 32) /* limit */
- + ((long)SDT_MEMERA << 52)
- + ((long)SEL_UPL << 57)
- + (1L << 59) /* present */
- + (1L << 62) /* 32 bits */
- + (1L << 63); /* page granularity */
- dataseg = 0 /* base */
- + (((IA32_USRSTACK >> 12) - 1) << 32) /* limit */
- + ((long)SDT_MEMRWA << 52)
- + ((long)SEL_UPL << 57)
- + (1L << 59) /* present */
- + (1L << 62) /* 32 bits */
- + (1L << 63); /* page granularity */
- ia64_set_csd(codeseg);
- ia64_set_ssd(dataseg);
- frame->tf_r[FRAME_R24] = dataseg; /* ESD */
- frame->tf_r[FRAME_R27] = dataseg; /* DSD */
- frame->tf_r[FRAME_R28] = dataseg; /* FSD */
- frame->tf_r[FRAME_R29] = dataseg; /* GSD */
-
- gdtseg = gdt /* base */
- + ((8L*NGDT - 1) << 32) /* limit */
- + ((long)SDT_SYSNULL << 52)
- + ((long)SEL_UPL << 57)
- + (1L << 59) /* present */
- + (0L << 62) /* 16 bits */
- + (0L << 63); /* byte granularity */
- ldtseg = ldt /* base */
- + ((8L*NLDT - 1) << 32) /* limit */
- + ((long)SDT_SYSLDT << 52)
- + ((long)SEL_UPL << 57)
- + (1L << 59) /* present */
- + (0L << 62) /* 16 bits */
- + (0L << 63); /* byte granularity */
- frame->tf_r[FRAME_R30] = ldtseg; /* LDTD */
- frame->tf_r[FRAME_R31] = gdtseg; /* GDTD */
-
- ia64_set_eflag(PSL_USER);
-
- /* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */
- frame->tf_r[FRAME_R11] = IA32_PS_STRINGS;
+ fpstate_drop(td);
- /*
- * XXX - Linux emulator
- * Make sure sure edx is 0x0 on entry. Linux binaries depend
- * on it.
- */
+ /* 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_util.h b/sys/compat/ia32/ia32_util.h
index 23f2abae1ab2d..20a5b1e284160 100644
--- a/sys/compat/ia32/ia32_util.h
+++ b/sys/compat/ia32/ia32_util.h
@@ -44,7 +44,7 @@ struct ia32_ps_strings {
int ps_nenvstr; /* the number of environment strings */
};
-#define IA32_USRSTACK (4L*1024*1024*1024 - PAGE_SIZE)
+#define IA32_USRSTACK USRSTACK
#define IA32_PS_STRINGS (IA32_USRSTACK - sizeof(struct ia32_ps_strings))
static __inline caddr_t stackgap_init(void);