ia32_sysvec.c revision 123742
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 123742 2003-12-23 02:42:39Z peter $"); 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); 96120422Speterstatic void ia32_fixlimits(struct image_params *imgp); 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, 139123742Speter "/libexec/ld-elf-32.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, 153123742Speter "/usr/libexec/ld-elf-32.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 160119334Speter/* XXX may be freebsd32 MI */ 161100384Speterstatic register_t * 162100384Speteria32_copyout_strings(struct image_params *imgp) 163100384Speter{ 164100384Speter int argc, envc; 165100384Speter u_int32_t *vectp; 166100384Speter char *stringp, *destp; 167100384Speter u_int32_t *stack_base; 168119336Speter struct freebsd32_ps_strings *arginfo; 169100384Speter int szsigcode; 170100384Speter 171100384Speter /* 172100384Speter * Calculate string base and vector table pointers. 173100384Speter * Also deal with signal trampoline code for this exec type. 174100384Speter */ 175119336Speter arginfo = (struct freebsd32_ps_strings *)FREEBSD32_PS_STRINGS; 176100384Speter szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); 177100384Speter destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - 178100384Speter roundup((ARG_MAX - imgp->stringspace), sizeof(char *)); 179100384Speter 180100384Speter /* 181100384Speter * install sigcode 182100384Speter */ 183100384Speter if (szsigcode) 184100384Speter copyout(imgp->proc->p_sysent->sv_sigcode, 185100384Speter ((caddr_t)arginfo - szsigcode), szsigcode); 186100384Speter 187100384Speter /* 188100384Speter * If we have a valid auxargs ptr, prepare some room 189100384Speter * on the stack. 190100384Speter */ 191100384Speter if (imgp->auxargs) { 192100384Speter /* 193100384Speter * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for 194100384Speter * lower compatibility. 195100384Speter */ 196100384Speter imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size 197100384Speter : (AT_COUNT * 2); 198100384Speter /* 199100384Speter * The '+ 2' is for the null pointers at the end of each of 200100384Speter * the arg and env vector sets,and imgp->auxarg_size is room 201100384Speter * for argument of Runtime loader. 202100384Speter */ 203100384Speter vectp = (u_int32_t *) (destp - (imgp->argc + imgp->envc + 2 + 204100384Speter imgp->auxarg_size) * sizeof(u_int32_t)); 205100384Speter 206100384Speter } else 207100384Speter /* 208100384Speter * The '+ 2' is for the null pointers at the end of each of 209100384Speter * the arg and env vector sets 210100384Speter */ 211100384Speter vectp = (u_int32_t *) 212100384Speter (destp - (imgp->argc + imgp->envc + 2) * sizeof(u_int32_t)); 213100384Speter 214100384Speter /* 215100384Speter * vectp also becomes our initial stack base 216100384Speter */ 217100384Speter stack_base = vectp; 218100384Speter 219100384Speter stringp = imgp->stringbase; 220100384Speter argc = imgp->argc; 221100384Speter envc = imgp->envc; 222100384Speter /* 223100384Speter * Copy out strings - arguments and environment. 224100384Speter */ 225100384Speter copyout(stringp, destp, ARG_MAX - imgp->stringspace); 226100384Speter 227100384Speter /* 228100384Speter * Fill in "ps_strings" struct for ps, w, etc. 229100384Speter */ 230100384Speter suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp); 231100384Speter suword32(&arginfo->ps_nargvstr, argc); 232100384Speter 233100384Speter /* 234100384Speter * Fill in argument portion of vector table. 235100384Speter */ 236100384Speter for (; argc > 0; --argc) { 237100384Speter suword32(vectp++, (u_int32_t)(intptr_t)destp); 238100384Speter while (*stringp++ != 0) 239100384Speter destp++; 240100384Speter destp++; 241100384Speter } 242100384Speter 243100384Speter /* a null vector table pointer separates the argp's from the envp's */ 244100384Speter suword32(vectp++, 0); 245100384Speter 246100384Speter suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp); 247100384Speter suword32(&arginfo->ps_nenvstr, envc); 248100384Speter 249100384Speter /* 250100384Speter * Fill in environment portion of vector table. 251100384Speter */ 252100384Speter for (; envc > 0; --envc) { 253100384Speter suword32(vectp++, (u_int32_t)(intptr_t)destp); 254100384Speter while (*stringp++ != 0) 255100384Speter destp++; 256100384Speter destp++; 257100384Speter } 258100384Speter 259100384Speter /* end of vector table is a null pointer */ 260100384Speter suword32(vectp, 0); 261100384Speter 262100384Speter return ((register_t *)stack_base); 263100384Speter} 264100384Speter 265120422Speterstatic u_long ia32_maxdsiz = IA32_MAXDSIZ; 266120422SpeterSYSCTL_ULONG(_compat_ia32, OID_AUTO, maxdsiz, CTLFLAG_RW, &ia32_maxdsiz, 0, ""); 267120422Speterstatic u_long ia32_maxssiz = IA32_MAXSSIZ; 268120422SpeterSYSCTL_ULONG(_compat_ia32, OID_AUTO, maxssiz, CTLFLAG_RW, &ia32_maxssiz, 0, ""); 269120422Speterstatic u_long ia32_maxvmem = IA32_MAXVMEM; 270120422SpeterSYSCTL_ULONG(_compat_ia32, OID_AUTO, maxvmem, CTLFLAG_RW, &ia32_maxvmem, 0, ""); 271120422Speter 272120422Speterstatic void 273120422Speteria32_fixlimits(struct image_params *imgp) 274120422Speter{ 275120422Speter struct proc *p = imgp->proc; 276120422Speter 277120422Speter if (ia32_maxdsiz != 0) { 278120422Speter if (p->p_rlimit[RLIMIT_DATA].rlim_cur > ia32_maxdsiz || 279120422Speter p->p_rlimit[RLIMIT_DATA].rlim_max > ia32_maxdsiz) { 280120422Speter if (p->p_limit->p_refcnt > 1) { 281120422Speter p->p_limit->p_refcnt--; 282120422Speter p->p_limit = limcopy(p->p_limit); 283120422Speter } 284120422Speter if (p->p_rlimit[RLIMIT_DATA].rlim_cur > ia32_maxdsiz) 285120422Speter p->p_rlimit[RLIMIT_DATA].rlim_cur = 286120422Speter ia32_maxdsiz; 287120422Speter if (p->p_rlimit[RLIMIT_DATA].rlim_max > ia32_maxdsiz) 288120422Speter p->p_rlimit[RLIMIT_DATA].rlim_max = 289120422Speter ia32_maxdsiz; 290120422Speter } 291120422Speter } 292120422Speter if (ia32_maxssiz != 0) { 293120422Speter if (p->p_rlimit[RLIMIT_STACK].rlim_cur > ia32_maxssiz || 294120422Speter p->p_rlimit[RLIMIT_STACK].rlim_max > ia32_maxssiz) { 295120422Speter if (p->p_limit->p_refcnt > 1) { 296120422Speter p->p_limit->p_refcnt--; 297120422Speter p->p_limit = limcopy(p->p_limit); 298120422Speter } 299120422Speter if (p->p_rlimit[RLIMIT_STACK].rlim_cur > ia32_maxssiz) 300120422Speter p->p_rlimit[RLIMIT_STACK].rlim_cur = 301120422Speter ia32_maxssiz; 302120422Speter if (p->p_rlimit[RLIMIT_STACK].rlim_max > ia32_maxssiz) 303120422Speter p->p_rlimit[RLIMIT_STACK].rlim_max = 304120422Speter ia32_maxssiz; 305120422Speter } 306120422Speter } 307120422Speter if (ia32_maxvmem != 0) { 308120422Speter if (p->p_rlimit[RLIMIT_VMEM].rlim_cur > ia32_maxvmem || 309120422Speter p->p_rlimit[RLIMIT_VMEM].rlim_max > ia32_maxvmem) { 310120422Speter if (p->p_limit->p_refcnt > 1) { 311120422Speter p->p_limit->p_refcnt--; 312120422Speter p->p_limit = limcopy(p->p_limit); 313120422Speter } 314120422Speter if (p->p_rlimit[RLIMIT_VMEM].rlim_cur > ia32_maxvmem) 315120422Speter p->p_rlimit[RLIMIT_VMEM].rlim_cur = 316120422Speter ia32_maxvmem; 317120422Speter if (p->p_rlimit[RLIMIT_VMEM].rlim_max > ia32_maxvmem) 318120422Speter p->p_rlimit[RLIMIT_VMEM].rlim_max = 319120422Speter ia32_maxvmem; 320120422Speter } 321120422Speter } 322120422Speter} 323