ia32_sysvec.c revision 153741
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 153741 2005-12-26 21:23:57Z sobomax $"); 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", 140153741Ssobomax 0, 141100384Speter }; 142100384Speter 143100384SpeterSYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_ANY, 144100384Speter (sysinit_cfunc_t) elf32_insert_brand_entry, 145100384Speter &ia32_brand_info); 146100384Speter 147123742Speterstatic Elf32_Brandinfo ia32_brand_oinfo = { 148123742Speter ELFOSABI_FREEBSD, 149123742Speter EM_386, 150123742Speter "FreeBSD", 151123742Speter NULL, 152123742Speter "/usr/libexec/ld-elf.so.1", 153123742Speter &ia32_freebsd_sysvec, 154132263Sobrien "/libexec/ld-elf32.so.1", 155153741Ssobomax 0, 156123742Speter }; 157123742Speter 158123742SpeterSYSINIT(oia32, SI_SUB_EXEC, SI_ORDER_ANY, 159123742Speter (sysinit_cfunc_t) elf32_insert_brand_entry, 160123742Speter &ia32_brand_oinfo); 161123742Speter 162133464Smarcel 163133464Smarcelvoid 164133464Smarcelelf32_dump_thread(struct thread *td __unused, void *dst __unused, 165133464Smarcel size_t *off __unused) 166133464Smarcel{ 167133464Smarcel} 168133464Smarcel 169133464Smarcel 170119334Speter/* XXX may be freebsd32 MI */ 171100384Speterstatic register_t * 172100384Speteria32_copyout_strings(struct image_params *imgp) 173100384Speter{ 174100384Speter int argc, envc; 175100384Speter u_int32_t *vectp; 176100384Speter char *stringp, *destp; 177100384Speter u_int32_t *stack_base; 178119336Speter struct freebsd32_ps_strings *arginfo; 179100384Speter int szsigcode; 180100384Speter 181100384Speter /* 182100384Speter * Calculate string base and vector table pointers. 183100384Speter * Also deal with signal trampoline code for this exec type. 184100384Speter */ 185119336Speter arginfo = (struct freebsd32_ps_strings *)FREEBSD32_PS_STRINGS; 186100384Speter szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); 187100384Speter destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - 188140992Ssobomax roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *)); 189100384Speter 190100384Speter /* 191100384Speter * install sigcode 192100384Speter */ 193100384Speter if (szsigcode) 194100384Speter copyout(imgp->proc->p_sysent->sv_sigcode, 195100384Speter ((caddr_t)arginfo - szsigcode), szsigcode); 196100384Speter 197100384Speter /* 198100384Speter * If we have a valid auxargs ptr, prepare some room 199100384Speter * on the stack. 200100384Speter */ 201100384Speter if (imgp->auxargs) { 202100384Speter /* 203100384Speter * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for 204100384Speter * lower compatibility. 205100384Speter */ 206100384Speter imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size 207100384Speter : (AT_COUNT * 2); 208100384Speter /* 209100384Speter * The '+ 2' is for the null pointers at the end of each of 210100384Speter * the arg and env vector sets,and imgp->auxarg_size is room 211100384Speter * for argument of Runtime loader. 212100384Speter */ 213140992Ssobomax vectp = (u_int32_t *) (destp - (imgp->args->argc + imgp->args->envc + 2 + 214100384Speter imgp->auxarg_size) * sizeof(u_int32_t)); 215100384Speter 216100384Speter } else 217100384Speter /* 218100384Speter * The '+ 2' is for the null pointers at the end of each of 219100384Speter * the arg and env vector sets 220100384Speter */ 221100384Speter vectp = (u_int32_t *) 222140992Ssobomax (destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t)); 223100384Speter 224100384Speter /* 225100384Speter * vectp also becomes our initial stack base 226100384Speter */ 227100384Speter stack_base = vectp; 228100384Speter 229140992Ssobomax stringp = imgp->args->begin_argv; 230140992Ssobomax argc = imgp->args->argc; 231140992Ssobomax envc = imgp->args->envc; 232100384Speter /* 233100384Speter * Copy out strings - arguments and environment. 234100384Speter */ 235140992Ssobomax copyout(stringp, destp, ARG_MAX - imgp->args->stringspace); 236100384Speter 237100384Speter /* 238100384Speter * Fill in "ps_strings" struct for ps, w, etc. 239100384Speter */ 240100384Speter suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp); 241100384Speter suword32(&arginfo->ps_nargvstr, argc); 242100384Speter 243100384Speter /* 244100384Speter * Fill in argument portion of vector table. 245100384Speter */ 246100384Speter for (; argc > 0; --argc) { 247100384Speter suword32(vectp++, (u_int32_t)(intptr_t)destp); 248100384Speter while (*stringp++ != 0) 249100384Speter destp++; 250100384Speter destp++; 251100384Speter } 252100384Speter 253100384Speter /* a null vector table pointer separates the argp's from the envp's */ 254100384Speter suword32(vectp++, 0); 255100384Speter 256100384Speter suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp); 257100384Speter suword32(&arginfo->ps_nenvstr, envc); 258100384Speter 259100384Speter /* 260100384Speter * Fill in environment portion of vector table. 261100384Speter */ 262100384Speter for (; envc > 0; --envc) { 263100384Speter suword32(vectp++, (u_int32_t)(intptr_t)destp); 264100384Speter while (*stringp++ != 0) 265100384Speter destp++; 266100384Speter destp++; 267100384Speter } 268100384Speter 269100384Speter /* end of vector table is a null pointer */ 270100384Speter suword32(vectp, 0); 271100384Speter 272100384Speter return ((register_t *)stack_base); 273100384Speter} 274100384Speter 275120422Speterstatic u_long ia32_maxdsiz = IA32_MAXDSIZ; 276120422SpeterSYSCTL_ULONG(_compat_ia32, OID_AUTO, maxdsiz, CTLFLAG_RW, &ia32_maxdsiz, 0, ""); 277120422Speterstatic u_long ia32_maxssiz = IA32_MAXSSIZ; 278120422SpeterSYSCTL_ULONG(_compat_ia32, OID_AUTO, maxssiz, CTLFLAG_RW, &ia32_maxssiz, 0, ""); 279120422Speterstatic u_long ia32_maxvmem = IA32_MAXVMEM; 280120422SpeterSYSCTL_ULONG(_compat_ia32, OID_AUTO, maxvmem, CTLFLAG_RW, &ia32_maxvmem, 0, ""); 281120422Speter 282120422Speterstatic void 283151980Spsia32_fixlimits(struct proc *p) 284120422Speter{ 285125454Sjhb struct plimit *oldlim, *newlim; 286120422Speter 287125454Sjhb if (ia32_maxdsiz == 0 && ia32_maxssiz == 0 && ia32_maxvmem == 0) 288125454Sjhb return; 289125454Sjhb newlim = lim_alloc(); 290125454Sjhb PROC_LOCK(p); 291125454Sjhb oldlim = p->p_limit; 292125454Sjhb lim_copy(newlim, oldlim); 293120422Speter if (ia32_maxdsiz != 0) { 294125454Sjhb if (newlim->pl_rlimit[RLIMIT_DATA].rlim_cur > ia32_maxdsiz) 295125454Sjhb newlim->pl_rlimit[RLIMIT_DATA].rlim_cur = ia32_maxdsiz; 296125454Sjhb if (newlim->pl_rlimit[RLIMIT_DATA].rlim_max > ia32_maxdsiz) 297125454Sjhb newlim->pl_rlimit[RLIMIT_DATA].rlim_max = ia32_maxdsiz; 298120422Speter } 299120422Speter if (ia32_maxssiz != 0) { 300125454Sjhb if (newlim->pl_rlimit[RLIMIT_STACK].rlim_cur > ia32_maxssiz) 301125454Sjhb newlim->pl_rlimit[RLIMIT_STACK].rlim_cur = ia32_maxssiz; 302125454Sjhb if (newlim->pl_rlimit[RLIMIT_STACK].rlim_max > ia32_maxssiz) 303125454Sjhb newlim->pl_rlimit[RLIMIT_STACK].rlim_max = ia32_maxssiz; 304120422Speter } 305120422Speter if (ia32_maxvmem != 0) { 306125454Sjhb if (newlim->pl_rlimit[RLIMIT_VMEM].rlim_cur > ia32_maxvmem) 307125454Sjhb newlim->pl_rlimit[RLIMIT_VMEM].rlim_cur = ia32_maxvmem; 308125454Sjhb if (newlim->pl_rlimit[RLIMIT_VMEM].rlim_max > ia32_maxvmem) 309125454Sjhb newlim->pl_rlimit[RLIMIT_VMEM].rlim_max = ia32_maxvmem; 310120422Speter } 311125454Sjhb p->p_limit = newlim; 312125454Sjhb PROC_UNLOCK(p); 313125454Sjhb lim_free(oldlim); 314120422Speter} 315