ia32_sysvec.c revision 151980
1100384Speter/*- 2100384Speter * Copyright (c) 2002 Doug Rabson 3114987Speter * Copyright (c) 2003 Peter Wemm 4100384Speter * All rights reserved. 5100384Speter * 6100384Speter * Redistribution and use in source and binary forms, with or without 7100384Speter * modification, are permitted provided that the following conditions 8100384Speter * are met: 9100384Speter * 1. Redistributions of source code must retain the above copyright 10100384Speter * notice, this list of conditions and the following disclaimer. 11100384Speter * 2. Redistributions in binary form must reproduce the above copyright 12100384Speter * notice, this list of conditions and the following disclaimer in the 13100384Speter * documentation and/or other materials provided with the distribution. 14100384Speter * 15100384Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16100384Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17100384Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18100384Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19100384Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20100384Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21100384Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22100384Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23100384Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24100384Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25100384Speter * SUCH DAMAGE. 26100384Speter */ 27100384Speter 28118031Sobrien#include <sys/cdefs.h> 29118031Sobrien__FBSDID("$FreeBSD: head/sys/compat/ia32/ia32_sysvec.c 151980 2005-11-02 21:18:07Z ps $"); 30118031Sobrien 31114987Speter#include "opt_compat.h" 32114987Speter 33100384Speter#define __ELF_WORD_SIZE 32 34100384Speter 35100384Speter#include <sys/param.h> 36100384Speter#include <sys/exec.h> 37100384Speter#include <sys/fcntl.h> 38100384Speter#include <sys/imgact.h> 39100384Speter#include <sys/kernel.h> 40100384Speter#include <sys/lock.h> 41100384Speter#include <sys/malloc.h> 42100384Speter#include <sys/mutex.h> 43100384Speter#include <sys/mman.h> 44100384Speter#include <sys/namei.h> 45100384Speter#include <sys/pioctl.h> 46100384Speter#include <sys/proc.h> 47100384Speter#include <sys/procfs.h> 48100384Speter#include <sys/resourcevar.h> 49100384Speter#include <sys/systm.h> 50100384Speter#include <sys/signalvar.h> 51100384Speter#include <sys/stat.h> 52100384Speter#include <sys/sx.h> 53100384Speter#include <sys/syscall.h> 54100384Speter#include <sys/sysctl.h> 55100384Speter#include <sys/sysent.h> 56100384Speter#include <sys/vnode.h> 57100384Speter#include <sys/imgact_elf.h> 58100384Speter 59100384Speter#include <vm/vm.h> 60100384Speter#include <vm/vm_kern.h> 61100384Speter#include <vm/vm_param.h> 62100384Speter#include <vm/pmap.h> 63100384Speter#include <vm/vm_map.h> 64100384Speter#include <vm/vm_object.h> 65100384Speter#include <vm/vm_extern.h> 66100384Speter 67119336Speter#include <compat/freebsd32/freebsd32_util.h> 68119336Speter#include <compat/freebsd32/freebsd32_proto.h> 69123422Speter#include <compat/freebsd32/freebsd32_syscall.h> 70119336Speter#include <compat/ia32/ia32_signal.h> 71123423Speter#ifdef __amd64__ 72114987Speter#include <machine/psl.h> 73114987Speter#include <machine/segments.h> 74114987Speter#include <machine/specialreg.h> 75123423Speter#else 76123423Speter#include <i386/include/psl.h> 77123423Speter#include <i386/include/segments.h> 78123423Speter#include <i386/include/specialreg.h> 79123423Speter#endif 80100384Speter#include <machine/frame.h> 81100384Speter#include <machine/md_var.h> 82114987Speter#include <machine/pcb.h> 83114987Speter#include <machine/cpufunc.h> 84100384Speter 85121720SpeterCTASSERT(sizeof(struct ia32_mcontext) == 640); 86121720SpeterCTASSERT(sizeof(struct ia32_ucontext) == 704); 87121720SpeterCTASSERT(sizeof(struct ia32_sigframe) == 800); 88121720SpeterCTASSERT(sizeof(struct ia32_siginfo) == 64); 89121720Speter#ifdef COMPAT_FREEBSD4 90121720SpeterCTASSERT(sizeof(struct ia32_mcontext4) == 260); 91121720SpeterCTASSERT(sizeof(struct ia32_ucontext4) == 324); 92121720SpeterCTASSERT(sizeof(struct ia32_sigframe4) == 408); 93121720Speter#endif 94121720Speter 95100384Speterstatic register_t *ia32_copyout_strings(struct image_params *imgp); 96151980Spsstatic void ia32_fixlimits(struct proc *p); 97100384Speter 98119334Speterextern struct sysent freebsd32_sysent[]; 99100384Speter 100120422SpeterSYSCTL_NODE(_compat, OID_AUTO, ia32, CTLFLAG_RW, 0, "ia32 mode"); 101120422Speter 102100384Speterstruct sysentvec ia32_freebsd_sysvec = { 103123422Speter FREEBSD32_SYS_MAXSYSCALL, 104119334Speter freebsd32_sysent, 105100384Speter 0, 106100384Speter 0, 107102808Sjake NULL, 108100384Speter 0, 109102808Sjake NULL, 110102808Sjake NULL, 111100384Speter elf32_freebsd_fixup, 112114987Speter ia32_sendsig, 113100384Speter ia32_sigcode, 114114987Speter &sz_ia32_sigcode, 115102808Sjake NULL, 116114987Speter "FreeBSD ELF32", 117100384Speter elf32_coredump, 118100384Speter NULL, 119100384Speter MINSIGSTKSZ, 120123423Speter IA32_PAGE_SIZE, 121102808Sjake 0, 122119336Speter FREEBSD32_USRSTACK, 123119336Speter FREEBSD32_USRSTACK, 124119336Speter FREEBSD32_PS_STRINGS, 125102808Sjake VM_PROT_ALL, 126100384Speter ia32_copyout_strings, 127120422Speter ia32_setregs, 128120422Speter ia32_fixlimits 129100384Speter}; 130100384Speter 131114987Speter 132100384Speterstatic Elf32_Brandinfo ia32_brand_info = { 133100384Speter ELFOSABI_FREEBSD, 134100384Speter EM_386, 135100384Speter "FreeBSD", 136123742Speter NULL, 137123742Speter "/libexec/ld-elf.so.1", 138123742Speter &ia32_freebsd_sysvec, 139127251Speter "/libexec/ld-elf32.so.1", 140100384Speter }; 141100384Speter 142100384SpeterSYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_ANY, 143100384Speter (sysinit_cfunc_t) elf32_insert_brand_entry, 144100384Speter &ia32_brand_info); 145100384Speter 146123742Speterstatic Elf32_Brandinfo ia32_brand_oinfo = { 147123742Speter ELFOSABI_FREEBSD, 148123742Speter EM_386, 149123742Speter "FreeBSD", 150123742Speter NULL, 151123742Speter "/usr/libexec/ld-elf.so.1", 152123742Speter &ia32_freebsd_sysvec, 153132263Sobrien "/libexec/ld-elf32.so.1", 154123742Speter }; 155123742Speter 156123742SpeterSYSINIT(oia32, SI_SUB_EXEC, SI_ORDER_ANY, 157123742Speter (sysinit_cfunc_t) elf32_insert_brand_entry, 158123742Speter &ia32_brand_oinfo); 159123742Speter 160133464Smarcel 161133464Smarcelvoid 162133464Smarcelelf32_dump_thread(struct thread *td __unused, void *dst __unused, 163133464Smarcel size_t *off __unused) 164133464Smarcel{ 165133464Smarcel} 166133464Smarcel 167133464Smarcel 168119334Speter/* XXX may be freebsd32 MI */ 169100384Speterstatic register_t * 170100384Speteria32_copyout_strings(struct image_params *imgp) 171100384Speter{ 172100384Speter int argc, envc; 173100384Speter u_int32_t *vectp; 174100384Speter char *stringp, *destp; 175100384Speter u_int32_t *stack_base; 176119336Speter struct freebsd32_ps_strings *arginfo; 177100384Speter int szsigcode; 178100384Speter 179100384Speter /* 180100384Speter * Calculate string base and vector table pointers. 181100384Speter * Also deal with signal trampoline code for this exec type. 182100384Speter */ 183119336Speter arginfo = (struct freebsd32_ps_strings *)FREEBSD32_PS_STRINGS; 184100384Speter szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); 185100384Speter destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - 186140992Ssobomax roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *)); 187100384Speter 188100384Speter /* 189100384Speter * install sigcode 190100384Speter */ 191100384Speter if (szsigcode) 192100384Speter copyout(imgp->proc->p_sysent->sv_sigcode, 193100384Speter ((caddr_t)arginfo - szsigcode), szsigcode); 194100384Speter 195100384Speter /* 196100384Speter * If we have a valid auxargs ptr, prepare some room 197100384Speter * on the stack. 198100384Speter */ 199100384Speter if (imgp->auxargs) { 200100384Speter /* 201100384Speter * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for 202100384Speter * lower compatibility. 203100384Speter */ 204100384Speter imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size 205100384Speter : (AT_COUNT * 2); 206100384Speter /* 207100384Speter * The '+ 2' is for the null pointers at the end of each of 208100384Speter * the arg and env vector sets,and imgp->auxarg_size is room 209100384Speter * for argument of Runtime loader. 210100384Speter */ 211140992Ssobomax vectp = (u_int32_t *) (destp - (imgp->args->argc + imgp->args->envc + 2 + 212100384Speter imgp->auxarg_size) * sizeof(u_int32_t)); 213100384Speter 214100384Speter } else 215100384Speter /* 216100384Speter * The '+ 2' is for the null pointers at the end of each of 217100384Speter * the arg and env vector sets 218100384Speter */ 219100384Speter vectp = (u_int32_t *) 220140992Ssobomax (destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t)); 221100384Speter 222100384Speter /* 223100384Speter * vectp also becomes our initial stack base 224100384Speter */ 225100384Speter stack_base = vectp; 226100384Speter 227140992Ssobomax stringp = imgp->args->begin_argv; 228140992Ssobomax argc = imgp->args->argc; 229140992Ssobomax envc = imgp->args->envc; 230100384Speter /* 231100384Speter * Copy out strings - arguments and environment. 232100384Speter */ 233140992Ssobomax copyout(stringp, destp, ARG_MAX - imgp->args->stringspace); 234100384Speter 235100384Speter /* 236100384Speter * Fill in "ps_strings" struct for ps, w, etc. 237100384Speter */ 238100384Speter suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp); 239100384Speter suword32(&arginfo->ps_nargvstr, argc); 240100384Speter 241100384Speter /* 242100384Speter * Fill in argument portion of vector table. 243100384Speter */ 244100384Speter for (; argc > 0; --argc) { 245100384Speter suword32(vectp++, (u_int32_t)(intptr_t)destp); 246100384Speter while (*stringp++ != 0) 247100384Speter destp++; 248100384Speter destp++; 249100384Speter } 250100384Speter 251100384Speter /* a null vector table pointer separates the argp's from the envp's */ 252100384Speter suword32(vectp++, 0); 253100384Speter 254100384Speter suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp); 255100384Speter suword32(&arginfo->ps_nenvstr, envc); 256100384Speter 257100384Speter /* 258100384Speter * Fill in environment portion of vector table. 259100384Speter */ 260100384Speter for (; envc > 0; --envc) { 261100384Speter suword32(vectp++, (u_int32_t)(intptr_t)destp); 262100384Speter while (*stringp++ != 0) 263100384Speter destp++; 264100384Speter destp++; 265100384Speter } 266100384Speter 267100384Speter /* end of vector table is a null pointer */ 268100384Speter suword32(vectp, 0); 269100384Speter 270100384Speter return ((register_t *)stack_base); 271100384Speter} 272100384Speter 273120422Speterstatic u_long ia32_maxdsiz = IA32_MAXDSIZ; 274120422SpeterSYSCTL_ULONG(_compat_ia32, OID_AUTO, maxdsiz, CTLFLAG_RW, &ia32_maxdsiz, 0, ""); 275120422Speterstatic u_long ia32_maxssiz = IA32_MAXSSIZ; 276120422SpeterSYSCTL_ULONG(_compat_ia32, OID_AUTO, maxssiz, CTLFLAG_RW, &ia32_maxssiz, 0, ""); 277120422Speterstatic u_long ia32_maxvmem = IA32_MAXVMEM; 278120422SpeterSYSCTL_ULONG(_compat_ia32, OID_AUTO, maxvmem, CTLFLAG_RW, &ia32_maxvmem, 0, ""); 279120422Speter 280120422Speterstatic void 281151980Spsia32_fixlimits(struct proc *p) 282120422Speter{ 283125454Sjhb struct plimit *oldlim, *newlim; 284120422Speter 285125454Sjhb if (ia32_maxdsiz == 0 && ia32_maxssiz == 0 && ia32_maxvmem == 0) 286125454Sjhb return; 287125454Sjhb newlim = lim_alloc(); 288125454Sjhb PROC_LOCK(p); 289125454Sjhb oldlim = p->p_limit; 290125454Sjhb lim_copy(newlim, oldlim); 291120422Speter if (ia32_maxdsiz != 0) { 292125454Sjhb if (newlim->pl_rlimit[RLIMIT_DATA].rlim_cur > ia32_maxdsiz) 293125454Sjhb newlim->pl_rlimit[RLIMIT_DATA].rlim_cur = ia32_maxdsiz; 294125454Sjhb if (newlim->pl_rlimit[RLIMIT_DATA].rlim_max > ia32_maxdsiz) 295125454Sjhb newlim->pl_rlimit[RLIMIT_DATA].rlim_max = ia32_maxdsiz; 296120422Speter } 297120422Speter if (ia32_maxssiz != 0) { 298125454Sjhb if (newlim->pl_rlimit[RLIMIT_STACK].rlim_cur > ia32_maxssiz) 299125454Sjhb newlim->pl_rlimit[RLIMIT_STACK].rlim_cur = ia32_maxssiz; 300125454Sjhb if (newlim->pl_rlimit[RLIMIT_STACK].rlim_max > ia32_maxssiz) 301125454Sjhb newlim->pl_rlimit[RLIMIT_STACK].rlim_max = ia32_maxssiz; 302120422Speter } 303120422Speter if (ia32_maxvmem != 0) { 304125454Sjhb if (newlim->pl_rlimit[RLIMIT_VMEM].rlim_cur > ia32_maxvmem) 305125454Sjhb newlim->pl_rlimit[RLIMIT_VMEM].rlim_cur = ia32_maxvmem; 306125454Sjhb if (newlim->pl_rlimit[RLIMIT_VMEM].rlim_max > ia32_maxvmem) 307125454Sjhb newlim->pl_rlimit[RLIMIT_VMEM].rlim_max = ia32_maxvmem; 308120422Speter } 309125454Sjhb p->p_limit = newlim; 310125454Sjhb PROC_UNLOCK(p); 311125454Sjhb lim_free(oldlim); 312120422Speter} 313