aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/ia32
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/ia32')
-rw-r--r--sys/compat/ia32/ia32_genassym.c26
-rw-r--r--sys/compat/ia32/ia32_reg.h141
-rw-r--r--sys/compat/ia32/ia32_signal.h187
-rw-r--r--sys/compat/ia32/ia32_sysvec.c314
-rw-r--r--sys/compat/ia32/ia32_util.h49
5 files changed, 717 insertions, 0 deletions
diff --git a/sys/compat/ia32/ia32_genassym.c b/sys/compat/ia32/ia32_genassym.c
new file mode 100644
index 000000000000..84fb648f90ed
--- /dev/null
+++ b/sys/compat/ia32/ia32_genassym.c
@@ -0,0 +1,26 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_compat.h"
+
+#include <sys/param.h>
+#include <sys/assym.h>
+#include <sys/systm.h>
+#include <sys/signal.h>
+
+#include <compat/freebsd32/freebsd32_signal.h>
+#include <compat/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_sigframe4, 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_reg.h b/sys/compat/ia32/ia32_reg.h
new file mode 100644
index 000000000000..5a9cdf2eebf9
--- /dev/null
+++ b/sys/compat/ia32/ia32_reg.h
@@ -0,0 +1,141 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * from: @(#)reg.h 5.5 (Berkeley) 1/18/91
+ * $FreeBSD$
+ */
+
+#ifndef _COMPAT_IA32_IA32_REG_H_
+#define _COMPAT_IA32_IA32_REG_H_
+
+/*
+ * Register set accessible via /proc/$pid/regs and PT_{SET,GET}REGS.
+ */
+struct reg32 {
+ unsigned int r_fs;
+ unsigned int r_es;
+ unsigned int r_ds;
+ unsigned int r_edi;
+ unsigned int r_esi;
+ unsigned int r_ebp;
+ unsigned int r_isp;
+ unsigned int r_ebx;
+ unsigned int r_edx;
+ unsigned int r_ecx;
+ unsigned int r_eax;
+ unsigned int r_trapno;
+ unsigned int r_err;
+ unsigned int r_eip;
+ unsigned int r_cs;
+ unsigned int r_eflags;
+ unsigned int r_esp;
+ unsigned int r_ss;
+ unsigned int r_gs;
+};
+
+/*
+ * Register set accessible via /proc/$pid/fpregs.
+ */
+struct fpreg32 {
+ unsigned int fpr_env[7];
+ unsigned char fpr_acc[8][10];
+ unsigned int fpr_ex_sw;
+ unsigned char fpr_pad[64];
+};
+
+/*
+ * Register set accessible via /proc/$pid/dbregs.
+ */
+struct dbreg32 {
+ unsigned int dr[8]; /* debug registers */
+};
+
+/* Environment information of floating point unit */
+struct env87 {
+ int en_cw; /* control word (16bits) */
+ int en_sw; /* status word (16bits) */
+ int en_tw; /* tag word (16bits) */
+ int en_fip; /* floating point instruction pointer */
+ u_short en_fcs; /* floating code segment selector */
+ u_short en_opcode; /* opcode last executed (11 bits ) */
+ int en_foo; /* floating operand offset */
+ int en_fos; /* floating operand segment selector */
+};
+
+#ifdef __ia64__
+/* Layout of an x87 fpu register (amd64 gets this elsewhere) */
+struct fpacc87 {
+ u_char fp_bytes[10];
+};
+#endif
+
+/* Floating point context */
+struct save87 {
+ struct env87 sv_env; /* floating point control/status */
+ struct fpacc87 sv_ac[8]; /* accumulator contents, 0-7 */
+ u_char sv_pad0[4]; /* padding for (now unused) saved status word */
+ u_char sv_pad[64]; /* padding; used by emulators */
+};
+
+
+/*
+ * Alternative layouts for <sys/procfs.h>
+ * Used in core dumps, the reason for this file existing.
+ */
+struct prstatus32 {
+ int pr_version;
+ u_int pr_statussz;
+ u_int pr_gregsetsz;
+ u_int pr_fpregsetsz;
+ int pr_osreldate;
+ int pr_cursig;
+ pid_t pr_pid;
+ struct reg32 pr_reg;
+};
+
+struct prpsinfo32 {
+ int pr_version;
+ u_int pr_psinfosz;
+ char pr_fname[PRFNAMESZ+1];
+ char pr_psargs[PRARGSZ+1];
+};
+
+/*
+ * Wrappers and converters.
+ */
+int fill_regs32(struct thread *, struct reg32 *);
+int set_regs32(struct thread *, struct reg32 *);
+int fill_fpregs32(struct thread *, struct fpreg32 *);
+int set_fpregs32(struct thread *, struct fpreg32 *);
+int fill_dbregs32(struct thread *, struct dbreg32 *);
+int set_dbregs32(struct thread *, struct dbreg32 *);
+
+#endif /* !_COMPAT_IA32_IA32_REG_H_ */
diff --git a/sys/compat/ia32/ia32_signal.h b/sys/compat/ia32/ia32_signal.h
new file mode 100644
index 000000000000..f2be96d5100b
--- /dev/null
+++ b/sys/compat/ia32/ia32_signal.h
@@ -0,0 +1,187 @@
+/*-
+ * 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_mcontext {
+ u_int32_t mc_onstack; /* XXX - sigcontext compat. */
+ u_int32_t mc_gs; /* machine state (struct trapframe) */
+ u_int32_t mc_fs;
+ u_int32_t mc_es;
+ u_int32_t mc_ds;
+ u_int32_t mc_edi;
+ u_int32_t mc_esi;
+ u_int32_t mc_ebp;
+ u_int32_t mc_isp;
+ u_int32_t mc_ebx;
+ u_int32_t mc_edx;
+ u_int32_t mc_ecx;
+ u_int32_t mc_eax;
+ u_int32_t mc_trapno;
+ u_int32_t mc_err;
+ u_int32_t mc_eip;
+ u_int32_t mc_cs;
+ u_int32_t mc_eflags;
+ u_int32_t mc_esp;
+ u_int32_t mc_ss;
+ u_int32_t mc_len; /* sizeof(struct ia32_mcontext) */
+ /* We use the same values for fpformat and ownedfp */
+ u_int32_t mc_fpformat;
+ u_int32_t mc_ownedfp;
+ u_int32_t mc_spare1[1]; /* align next field to 16 bytes */
+ /*
+ * See <i386/include/npx.h> for the internals of mc_fpstate[].
+ */
+ u_int32_t mc_fpstate[128] __aligned(16);
+ u_int32_t mc_spare2[8];
+};
+
+struct ia32_ucontext {
+ sigset_t uc_sigmask;
+ struct ia32_mcontext uc_mcontext;
+ u_int32_t uc_link;
+ struct sigaltstack32 uc_stack;
+ u_int32_t uc_flags;
+ u_int32_t __spare__[4];
+};
+
+
+#if defined(COMPAT_FREEBSD4)
+struct ia32_mcontext4 {
+ u_int32_t mc_onstack; /* XXX - sigcontext compat. */
+ u_int32_t mc_gs; /* machine state (struct trapframe) */
+ u_int32_t mc_fs;
+ u_int32_t mc_es;
+ u_int32_t mc_ds;
+ u_int32_t mc_edi;
+ u_int32_t mc_esi;
+ u_int32_t mc_ebp;
+ u_int32_t mc_isp;
+ u_int32_t mc_ebx;
+ u_int32_t mc_edx;
+ u_int32_t mc_ecx;
+ u_int32_t mc_eax;
+ u_int32_t mc_trapno;
+ u_int32_t mc_err;
+ u_int32_t mc_eip;
+ u_int32_t mc_cs;
+ u_int32_t mc_eflags;
+ u_int32_t mc_esp;
+ u_int32_t mc_ss;
+ u_int32_t mc_fpregs[28];
+ u_int32_t __spare__[17];
+};
+
+struct ia32_ucontext4 {
+ sigset_t uc_sigmask;
+ struct ia32_mcontext4 uc_mcontext;
+ u_int32_t uc_link;
+ struct sigaltstack32 uc_stack;
+ u_int32_t __spare__[8];
+};
+#endif
+
+#ifdef COMPAT_FREEBSD3
+struct ia32_sigcontext3 {
+ u_int32_t sc_onstack;
+ u_int32_t sc_mask;
+ u_int32_t sc_esp;
+ u_int32_t sc_ebp;
+ u_int32_t sc_isp;
+ u_int32_t sc_eip;
+ u_int32_t sc_eflags;
+ u_int32_t sc_es;
+ u_int32_t sc_ds;
+ u_int32_t sc_cs;
+ u_int32_t sc_ss;
+ u_int32_t sc_edi;
+ u_int32_t sc_esi;
+ u_int32_t sc_ebx;
+ u_int32_t sc_edx;
+ u_int32_t sc_ecx;
+ u_int32_t sc_eax;
+ u_int32_t sc_gs;
+ u_int32_t sc_fs;
+ u_int32_t sc_trapno;
+ u_int32_t sc_err;
+};
+#endif
+
+/*
+ * Signal frames, arguments passed to application signal handlers.
+ */
+
+#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 siginfo32 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 */
+ /* Beware, hole due to ucontext being 16 byte aligned! */
+ struct ia32_ucontext sf_uc; /* = *sf_ucontext */
+ struct siginfo32 sf_si; /* = *sf_siginfo (SA_SIGINFO case) */
+};
+
+#ifdef COMPAT_FREEBSD3
+struct ia32_siginfo3 {
+ struct ia32_sigcontext3 si_sc;
+ int si_signo;
+ int si_code;
+ union sigval32 si_value;
+};
+struct ia32_sigframe3 {
+ int sf_signum;
+ u_int32_t sf_arg2; /* int or siginfo_t */
+ u_int32_t sf_scp;
+ u_int32_t sf_addr;
+ u_int32_t sf_ah; /* action/handler pointer */
+ struct ia32_siginfo3 sf_siginfo;
+};
+#endif
+
+struct ksiginfo;
+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, struct ksiginfo *, sigset_t *);
+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
new file mode 100644
index 000000000000..62779269e3a5
--- /dev/null
+++ b/sys/compat/ia32/ia32_sysvec.c
@@ -0,0 +1,314 @@
+/*-
+ * Copyright (c) 2002 Doug Rabson
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_compat.h"
+
+#define __ELF_WORD_SIZE 32
+
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/fcntl.h>
+#include <sys/imgact.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/mman.h>
+#include <sys/namei.h>
+#include <sys/pioctl.h>
+#include <sys/proc.h>
+#include <sys/procfs.h>
+#include <sys/resourcevar.h>
+#include <sys/systm.h>
+#include <sys/signalvar.h>
+#include <sys/stat.h>
+#include <sys/sx.h>
+#include <sys/syscall.h>
+#include <sys/sysctl.h>
+#include <sys/sysent.h>
+#include <sys/vnode.h>
+#include <sys/imgact_elf.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_extern.h>
+
+#include <compat/freebsd32/freebsd32_signal.h>
+#include <compat/freebsd32/freebsd32_util.h>
+#include <compat/freebsd32/freebsd32_proto.h>
+#include <compat/freebsd32/freebsd32_syscall.h>
+#include <compat/ia32/ia32_signal.h>
+#ifdef __amd64__
+#include <machine/psl.h>
+#include <machine/segments.h>
+#include <machine/specialreg.h>
+#else
+#include <i386/include/psl.h>
+#include <i386/include/segments.h>
+#include <i386/include/specialreg.h>
+#endif
+#include <machine/frame.h>
+#include <machine/md_var.h>
+#include <machine/pcb.h>
+#include <machine/cpufunc.h>
+
+CTASSERT(sizeof(struct ia32_mcontext) == 640);
+CTASSERT(sizeof(struct ia32_ucontext) == 704);
+CTASSERT(sizeof(struct ia32_sigframe) == 800);
+CTASSERT(sizeof(struct siginfo32) == 64);
+#ifdef COMPAT_FREEBSD4
+CTASSERT(sizeof(struct ia32_mcontext4) == 260);
+CTASSERT(sizeof(struct ia32_ucontext4) == 324);
+CTASSERT(sizeof(struct ia32_sigframe4) == 408);
+#endif
+
+static register_t *ia32_copyout_strings(struct image_params *imgp);
+static void ia32_fixlimit(struct rlimit *rl, int which);
+
+extern struct sysent freebsd32_sysent[];
+
+SYSCTL_NODE(_compat, OID_AUTO, ia32, CTLFLAG_RW, 0, "ia32 mode");
+
+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;
+SYSCTL_ULONG(_compat_ia32, OID_AUTO, maxssiz, CTLFLAG_RW, &ia32_maxssiz, 0, "");
+static u_long ia32_maxvmem = IA32_MAXVMEM;
+SYSCTL_ULONG(_compat_ia32, OID_AUTO, maxvmem, CTLFLAG_RW, &ia32_maxvmem, 0, "");
+
+struct sysentvec ia32_freebsd_sysvec = {
+ FREEBSD32_SYS_MAXSYSCALL,
+ freebsd32_sysent,
+ 0,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ elf32_freebsd_fixup,
+ ia32_sendsig,
+ ia32_sigcode,
+ &sz_ia32_sigcode,
+ NULL,
+ "FreeBSD ELF32",
+ elf32_coredump,
+ NULL,
+ MINSIGSTKSZ,
+ IA32_PAGE_SIZE,
+ 0,
+ FREEBSD32_USRSTACK,
+ FREEBSD32_USRSTACK,
+ FREEBSD32_PS_STRINGS,
+ VM_PROT_ALL,
+ ia32_copyout_strings,
+ ia32_setregs,
+ ia32_fixlimit,
+ &ia32_maxssiz
+};
+
+
+static Elf32_Brandinfo ia32_brand_info = {
+ ELFOSABI_FREEBSD,
+ EM_386,
+ "FreeBSD",
+ NULL,
+ "/libexec/ld-elf.so.1",
+ &ia32_freebsd_sysvec,
+ "/libexec/ld-elf32.so.1",
+ BI_CAN_EXEC_DYN,
+ };
+
+SYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_ANY,
+ (sysinit_cfunc_t) elf32_insert_brand_entry,
+ &ia32_brand_info);
+
+static Elf32_Brandinfo ia32_brand_oinfo = {
+ ELFOSABI_FREEBSD,
+ EM_386,
+ "FreeBSD",
+ NULL,
+ "/usr/libexec/ld-elf.so.1",
+ &ia32_freebsd_sysvec,
+ "/libexec/ld-elf32.so.1",
+ BI_CAN_EXEC_DYN,
+ };
+
+SYSINIT(oia32, SI_SUB_EXEC, SI_ORDER_ANY,
+ (sysinit_cfunc_t) elf32_insert_brand_entry,
+ &ia32_brand_oinfo);
+
+
+void
+elf32_dump_thread(struct thread *td __unused, void *dst __unused,
+ size_t *off __unused)
+{
+}
+
+
+/* XXX may be freebsd32 MI */
+static register_t *
+ia32_copyout_strings(struct image_params *imgp)
+{
+ int argc, envc;
+ u_int32_t *vectp;
+ char *stringp, *destp;
+ u_int32_t *stack_base;
+ struct freebsd32_ps_strings *arginfo;
+ int szsigcode;
+
+ /*
+ * Calculate string base and vector table pointers.
+ * Also deal with signal trampoline code for this exec type.
+ */
+ arginfo = (struct freebsd32_ps_strings *)FREEBSD32_PS_STRINGS;
+ szsigcode = *(imgp->proc->p_sysent->sv_szsigcode);
+ destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
+ roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
+
+ /*
+ * install sigcode
+ */
+ if (szsigcode)
+ copyout(imgp->proc->p_sysent->sv_sigcode,
+ ((caddr_t)arginfo - szsigcode), szsigcode);
+
+ /*
+ * If we have a valid auxargs ptr, prepare some room
+ * on the stack.
+ */
+ if (imgp->auxargs) {
+ /*
+ * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for
+ * lower compatibility.
+ */
+ imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size
+ : (AT_COUNT * 2);
+ /*
+ * The '+ 2' is for the null pointers at the end of each of
+ * the arg and env vector sets,and imgp->auxarg_size is room
+ * for argument of Runtime loader.
+ */
+ vectp = (u_int32_t *) (destp - (imgp->args->argc + imgp->args->envc + 2 +
+ imgp->auxarg_size) * sizeof(u_int32_t));
+
+ } else
+ /*
+ * The '+ 2' is for the null pointers at the end of each of
+ * the arg and env vector sets
+ */
+ vectp = (u_int32_t *)
+ (destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t));
+
+ /*
+ * vectp also becomes our initial stack base
+ */
+ stack_base = vectp;
+
+ stringp = imgp->args->begin_argv;
+ argc = imgp->args->argc;
+ envc = imgp->args->envc;
+ /*
+ * Copy out strings - arguments and environment.
+ */
+ copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);
+
+ /*
+ * Fill in "ps_strings" struct for ps, w, etc.
+ */
+ suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp);
+ suword32(&arginfo->ps_nargvstr, argc);
+
+ /*
+ * Fill in argument portion of vector table.
+ */
+ for (; argc > 0; --argc) {
+ suword32(vectp++, (u_int32_t)(intptr_t)destp);
+ while (*stringp++ != 0)
+ destp++;
+ destp++;
+ }
+
+ /* a null vector table pointer separates the argp's from the envp's */
+ suword32(vectp++, 0);
+
+ suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp);
+ suword32(&arginfo->ps_nenvstr, envc);
+
+ /*
+ * Fill in environment portion of vector table.
+ */
+ for (; envc > 0; --envc) {
+ suword32(vectp++, (u_int32_t)(intptr_t)destp);
+ while (*stringp++ != 0)
+ destp++;
+ destp++;
+ }
+
+ /* end of vector table is a null pointer */
+ suword32(vectp, 0);
+
+ return ((register_t *)stack_base);
+}
+
+static void
+ia32_fixlimit(struct rlimit *rl, int which)
+{
+
+ switch (which) {
+ case RLIMIT_DATA:
+ if (ia32_maxdsiz != 0) {
+ if (rl->rlim_cur > ia32_maxdsiz)
+ rl->rlim_cur = ia32_maxdsiz;
+ if (rl->rlim_max > ia32_maxdsiz)
+ rl->rlim_max = ia32_maxdsiz;
+ }
+ break;
+ case RLIMIT_STACK:
+ if (ia32_maxssiz != 0) {
+ if (rl->rlim_cur > ia32_maxssiz)
+ rl->rlim_cur = ia32_maxssiz;
+ if (rl->rlim_max > ia32_maxssiz)
+ rl->rlim_max = ia32_maxssiz;
+ }
+ break;
+ case RLIMIT_VMEM:
+ if (ia32_maxvmem != 0) {
+ if (rl->rlim_cur > ia32_maxvmem)
+ rl->rlim_cur = ia32_maxvmem;
+ if (rl->rlim_max > ia32_maxvmem)
+ rl->rlim_max = ia32_maxvmem;
+ }
+ break;
+ }
+}
diff --git a/sys/compat/ia32/ia32_util.h b/sys/compat/ia32/ia32_util.h
new file mode 100644
index 000000000000..a2b88cb4272e
--- /dev/null
+++ b/sys/compat/ia32/ia32_util.h
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 1998-1999 Andrew Gallatin
+ * 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 withough 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$
+ */
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+
+
+#include <sys/exec.h>
+#include <sys/sysent.h>
+#include <sys/cdefs.h>
+
+#ifdef __ia64__
+#define FREEBSD32_USRSTACK ((1ul << 32) - IA32_PAGE_SIZE * 2)
+#else
+#define FREEBSD32_USRSTACK ((1ul << 32) - IA32_PAGE_SIZE)
+#endif
+
+#define IA32_PAGE_SIZE 4096
+#define IA32_MAXDSIZ (512*1024*1024) /* 512MB */
+#define IA32_MAXSSIZ (64*1024*1024) /* 64MB */
+#define IA32_MAXVMEM 0 /* Unlimited */