ia32_sysvec.c revision 169846
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 169846 2007-05-22 02:22:58Z kan $"); 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 67163018Sdavidxu#include <compat/freebsd32/freebsd32_signal.h> 68119336Speter#include <compat/freebsd32/freebsd32_util.h> 69119336Speter#include <compat/freebsd32/freebsd32_proto.h> 70123422Speter#include <compat/freebsd32/freebsd32_syscall.h> 71119336Speter#include <compat/ia32/ia32_signal.h> 72123423Speter#ifdef __amd64__ 73114987Speter#include <machine/psl.h> 74114987Speter#include <machine/segments.h> 75114987Speter#include <machine/specialreg.h> 76123423Speter#else 77123423Speter#include <i386/include/psl.h> 78123423Speter#include <i386/include/segments.h> 79123423Speter#include <i386/include/specialreg.h> 80123423Speter#endif 81100384Speter#include <machine/frame.h> 82100384Speter#include <machine/md_var.h> 83114987Speter#include <machine/pcb.h> 84114987Speter#include <machine/cpufunc.h> 85100384Speter 86121720SpeterCTASSERT(sizeof(struct ia32_mcontext) == 640); 87121720SpeterCTASSERT(sizeof(struct ia32_ucontext) == 704); 88121720SpeterCTASSERT(sizeof(struct ia32_sigframe) == 800); 89163018SdavidxuCTASSERT(sizeof(struct siginfo32) == 64); 90121720Speter#ifdef COMPAT_FREEBSD4 91121720SpeterCTASSERT(sizeof(struct ia32_mcontext4) == 260); 92121720SpeterCTASSERT(sizeof(struct ia32_ucontext4) == 324); 93121720SpeterCTASSERT(sizeof(struct ia32_sigframe4) == 408); 94121720Speter#endif 95121720Speter 96100384Speterstatic register_t *ia32_copyout_strings(struct image_params *imgp); 97169565Sjhbstatic void ia32_fixlimit(struct rlimit *rl, int which); 98100384Speter 99119334Speterextern struct sysent freebsd32_sysent[]; 100100384Speter 101120422SpeterSYSCTL_NODE(_compat, OID_AUTO, ia32, CTLFLAG_RW, 0, "ia32 mode"); 102120422Speter 103100384Speterstruct sysentvec ia32_freebsd_sysvec = { 104123422Speter FREEBSD32_SYS_MAXSYSCALL, 105119334Speter freebsd32_sysent, 106100384Speter 0, 107100384Speter 0, 108102808Sjake NULL, 109100384Speter 0, 110102808Sjake NULL, 111102808Sjake NULL, 112100384Speter elf32_freebsd_fixup, 113114987Speter ia32_sendsig, 114100384Speter ia32_sigcode, 115114987Speter &sz_ia32_sigcode, 116102808Sjake NULL, 117114987Speter "FreeBSD ELF32", 118100384Speter elf32_coredump, 119100384Speter NULL, 120100384Speter MINSIGSTKSZ, 121123423Speter IA32_PAGE_SIZE, 122102808Sjake 0, 123119336Speter FREEBSD32_USRSTACK, 124119336Speter FREEBSD32_USRSTACK, 125119336Speter FREEBSD32_PS_STRINGS, 126102808Sjake VM_PROT_ALL, 127100384Speter ia32_copyout_strings, 128120422Speter ia32_setregs, 129169565Sjhb ia32_fixlimit 130100384Speter}; 131100384Speter 132114987Speter 133100384Speterstatic Elf32_Brandinfo ia32_brand_info = { 134100384Speter ELFOSABI_FREEBSD, 135100384Speter EM_386, 136100384Speter "FreeBSD", 137123742Speter NULL, 138123742Speter "/libexec/ld-elf.so.1", 139123742Speter &ia32_freebsd_sysvec, 140127251Speter "/libexec/ld-elf32.so.1", 141169846Skan BI_CAN_EXEC_DYN, 142100384Speter }; 143100384Speter 144100384SpeterSYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_ANY, 145100384Speter (sysinit_cfunc_t) elf32_insert_brand_entry, 146100384Speter &ia32_brand_info); 147100384Speter 148123742Speterstatic Elf32_Brandinfo ia32_brand_oinfo = { 149123742Speter ELFOSABI_FREEBSD, 150123742Speter EM_386, 151123742Speter "FreeBSD", 152123742Speter NULL, 153123742Speter "/usr/libexec/ld-elf.so.1", 154123742Speter &ia32_freebsd_sysvec, 155132263Sobrien "/libexec/ld-elf32.so.1", 156169846Skan BI_CAN_EXEC_DYN, 157123742Speter }; 158123742Speter 159123742SpeterSYSINIT(oia32, SI_SUB_EXEC, SI_ORDER_ANY, 160123742Speter (sysinit_cfunc_t) elf32_insert_brand_entry, 161123742Speter &ia32_brand_oinfo); 162123742Speter 163133464Smarcel 164133464Smarcelvoid 165133464Smarcelelf32_dump_thread(struct thread *td __unused, void *dst __unused, 166133464Smarcel size_t *off __unused) 167133464Smarcel{ 168133464Smarcel} 169133464Smarcel 170133464Smarcel 171119334Speter/* XXX may be freebsd32 MI */ 172100384Speterstatic register_t * 173100384Speteria32_copyout_strings(struct image_params *imgp) 174100384Speter{ 175100384Speter int argc, envc; 176100384Speter u_int32_t *vectp; 177100384Speter char *stringp, *destp; 178100384Speter u_int32_t *stack_base; 179119336Speter struct freebsd32_ps_strings *arginfo; 180100384Speter int szsigcode; 181100384Speter 182100384Speter /* 183100384Speter * Calculate string base and vector table pointers. 184100384Speter * Also deal with signal trampoline code for this exec type. 185100384Speter */ 186119336Speter arginfo = (struct freebsd32_ps_strings *)FREEBSD32_PS_STRINGS; 187100384Speter szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); 188100384Speter destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - 189140992Ssobomax roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *)); 190100384Speter 191100384Speter /* 192100384Speter * install sigcode 193100384Speter */ 194100384Speter if (szsigcode) 195100384Speter copyout(imgp->proc->p_sysent->sv_sigcode, 196100384Speter ((caddr_t)arginfo - szsigcode), szsigcode); 197100384Speter 198100384Speter /* 199100384Speter * If we have a valid auxargs ptr, prepare some room 200100384Speter * on the stack. 201100384Speter */ 202100384Speter if (imgp->auxargs) { 203100384Speter /* 204100384Speter * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for 205100384Speter * lower compatibility. 206100384Speter */ 207100384Speter imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size 208100384Speter : (AT_COUNT * 2); 209100384Speter /* 210100384Speter * The '+ 2' is for the null pointers at the end of each of 211100384Speter * the arg and env vector sets,and imgp->auxarg_size is room 212100384Speter * for argument of Runtime loader. 213100384Speter */ 214140992Ssobomax vectp = (u_int32_t *) (destp - (imgp->args->argc + imgp->args->envc + 2 + 215100384Speter imgp->auxarg_size) * sizeof(u_int32_t)); 216100384Speter 217100384Speter } else 218100384Speter /* 219100384Speter * The '+ 2' is for the null pointers at the end of each of 220100384Speter * the arg and env vector sets 221100384Speter */ 222100384Speter vectp = (u_int32_t *) 223140992Ssobomax (destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t)); 224100384Speter 225100384Speter /* 226100384Speter * vectp also becomes our initial stack base 227100384Speter */ 228100384Speter stack_base = vectp; 229100384Speter 230140992Ssobomax stringp = imgp->args->begin_argv; 231140992Ssobomax argc = imgp->args->argc; 232140992Ssobomax envc = imgp->args->envc; 233100384Speter /* 234100384Speter * Copy out strings - arguments and environment. 235100384Speter */ 236140992Ssobomax copyout(stringp, destp, ARG_MAX - imgp->args->stringspace); 237100384Speter 238100384Speter /* 239100384Speter * Fill in "ps_strings" struct for ps, w, etc. 240100384Speter */ 241100384Speter suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp); 242100384Speter suword32(&arginfo->ps_nargvstr, argc); 243100384Speter 244100384Speter /* 245100384Speter * Fill in argument portion of vector table. 246100384Speter */ 247100384Speter for (; argc > 0; --argc) { 248100384Speter suword32(vectp++, (u_int32_t)(intptr_t)destp); 249100384Speter while (*stringp++ != 0) 250100384Speter destp++; 251100384Speter destp++; 252100384Speter } 253100384Speter 254100384Speter /* a null vector table pointer separates the argp's from the envp's */ 255100384Speter suword32(vectp++, 0); 256100384Speter 257100384Speter suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp); 258100384Speter suword32(&arginfo->ps_nenvstr, envc); 259100384Speter 260100384Speter /* 261100384Speter * Fill in environment portion of vector table. 262100384Speter */ 263100384Speter for (; envc > 0; --envc) { 264100384Speter suword32(vectp++, (u_int32_t)(intptr_t)destp); 265100384Speter while (*stringp++ != 0) 266100384Speter destp++; 267100384Speter destp++; 268100384Speter } 269100384Speter 270100384Speter /* end of vector table is a null pointer */ 271100384Speter suword32(vectp, 0); 272100384Speter 273100384Speter return ((register_t *)stack_base); 274100384Speter} 275100384Speter 276120422Speterstatic u_long ia32_maxdsiz = IA32_MAXDSIZ; 277120422SpeterSYSCTL_ULONG(_compat_ia32, OID_AUTO, maxdsiz, CTLFLAG_RW, &ia32_maxdsiz, 0, ""); 278120422Speterstatic u_long ia32_maxssiz = IA32_MAXSSIZ; 279120422SpeterSYSCTL_ULONG(_compat_ia32, OID_AUTO, maxssiz, CTLFLAG_RW, &ia32_maxssiz, 0, ""); 280120422Speterstatic u_long ia32_maxvmem = IA32_MAXVMEM; 281120422SpeterSYSCTL_ULONG(_compat_ia32, OID_AUTO, maxvmem, CTLFLAG_RW, &ia32_maxvmem, 0, ""); 282120422Speter 283120422Speterstatic void 284169565Sjhbia32_fixlimit(struct rlimit *rl, int which) 285120422Speter{ 286120422Speter 287169565Sjhb switch (which) { 288169565Sjhb case RLIMIT_DATA: 289169565Sjhb if (ia32_maxdsiz != 0) { 290169565Sjhb if (rl->rlim_cur > ia32_maxdsiz) 291169565Sjhb rl->rlim_cur = ia32_maxdsiz; 292169565Sjhb if (rl->rlim_max > ia32_maxdsiz) 293169565Sjhb rl->rlim_max = ia32_maxdsiz; 294169565Sjhb } 295169565Sjhb break; 296169565Sjhb case RLIMIT_STACK: 297169565Sjhb if (ia32_maxssiz != 0) { 298169565Sjhb if (rl->rlim_cur > ia32_maxssiz) 299169565Sjhb rl->rlim_cur = ia32_maxssiz; 300169565Sjhb if (rl->rlim_max > ia32_maxssiz) 301169565Sjhb rl->rlim_max = ia32_maxssiz; 302169565Sjhb } 303169565Sjhb break; 304169565Sjhb case RLIMIT_VMEM: 305169565Sjhb if (ia32_maxvmem != 0) { 306169565Sjhb if (rl->rlim_cur > ia32_maxvmem) 307169565Sjhb rl->rlim_cur = ia32_maxvmem; 308169565Sjhb if (rl->rlim_max > ia32_maxvmem) 309169565Sjhb rl->rlim_max = ia32_maxvmem; 310169565Sjhb } 311169565Sjhb break; 312120422Speter } 313120422Speter} 314