ia32_sysvec.c revision 172316
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 172316 2007-09-24 20:49:39Z jhb $"); 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 103171410Sjhbstatic u_long ia32_maxdsiz = IA32_MAXDSIZ; 104171410SjhbSYSCTL_ULONG(_compat_ia32, OID_AUTO, maxdsiz, CTLFLAG_RW, &ia32_maxdsiz, 0, ""); 105172316SjhbTUNABLE_ULONG("compat.ia32.maxdsiz", &ia32_maxdsiz); 106171410Sjhbstatic u_long ia32_maxssiz = IA32_MAXSSIZ; 107171410SjhbSYSCTL_ULONG(_compat_ia32, OID_AUTO, maxssiz, CTLFLAG_RW, &ia32_maxssiz, 0, ""); 108172316SjhbTUNABLE_ULONG("compat.ia32.maxssiz", &ia32_maxssiz); 109171410Sjhbstatic u_long ia32_maxvmem = IA32_MAXVMEM; 110171410SjhbSYSCTL_ULONG(_compat_ia32, OID_AUTO, maxvmem, CTLFLAG_RW, &ia32_maxvmem, 0, ""); 111172316SjhbTUNABLE_ULONG("compat.ia32.maxvmem", &ia32_maxvmem); 112171410Sjhb 113100384Speterstruct sysentvec ia32_freebsd_sysvec = { 114123422Speter FREEBSD32_SYS_MAXSYSCALL, 115119334Speter freebsd32_sysent, 116100384Speter 0, 117100384Speter 0, 118102808Sjake NULL, 119100384Speter 0, 120102808Sjake NULL, 121102808Sjake NULL, 122100384Speter elf32_freebsd_fixup, 123114987Speter ia32_sendsig, 124100384Speter ia32_sigcode, 125114987Speter &sz_ia32_sigcode, 126102808Sjake NULL, 127114987Speter "FreeBSD ELF32", 128100384Speter elf32_coredump, 129100384Speter NULL, 130100384Speter MINSIGSTKSZ, 131123423Speter IA32_PAGE_SIZE, 132102808Sjake 0, 133119336Speter FREEBSD32_USRSTACK, 134119336Speter FREEBSD32_USRSTACK, 135119336Speter FREEBSD32_PS_STRINGS, 136102808Sjake VM_PROT_ALL, 137100384Speter ia32_copyout_strings, 138120422Speter ia32_setregs, 139171410Sjhb ia32_fixlimit, 140171410Sjhb &ia32_maxssiz 141100384Speter}; 142100384Speter 143114987Speter 144100384Speterstatic Elf32_Brandinfo ia32_brand_info = { 145100384Speter ELFOSABI_FREEBSD, 146100384Speter EM_386, 147100384Speter "FreeBSD", 148123742Speter NULL, 149123742Speter "/libexec/ld-elf.so.1", 150123742Speter &ia32_freebsd_sysvec, 151127251Speter "/libexec/ld-elf32.so.1", 152169846Skan BI_CAN_EXEC_DYN, 153100384Speter }; 154100384Speter 155100384SpeterSYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_ANY, 156100384Speter (sysinit_cfunc_t) elf32_insert_brand_entry, 157100384Speter &ia32_brand_info); 158100384Speter 159123742Speterstatic Elf32_Brandinfo ia32_brand_oinfo = { 160123742Speter ELFOSABI_FREEBSD, 161123742Speter EM_386, 162123742Speter "FreeBSD", 163123742Speter NULL, 164123742Speter "/usr/libexec/ld-elf.so.1", 165123742Speter &ia32_freebsd_sysvec, 166132263Sobrien "/libexec/ld-elf32.so.1", 167169846Skan BI_CAN_EXEC_DYN, 168123742Speter }; 169123742Speter 170123742SpeterSYSINIT(oia32, SI_SUB_EXEC, SI_ORDER_ANY, 171123742Speter (sysinit_cfunc_t) elf32_insert_brand_entry, 172123742Speter &ia32_brand_oinfo); 173123742Speter 174133464Smarcel 175133464Smarcelvoid 176133464Smarcelelf32_dump_thread(struct thread *td __unused, void *dst __unused, 177133464Smarcel size_t *off __unused) 178133464Smarcel{ 179133464Smarcel} 180133464Smarcel 181133464Smarcel 182119334Speter/* XXX may be freebsd32 MI */ 183100384Speterstatic register_t * 184100384Speteria32_copyout_strings(struct image_params *imgp) 185100384Speter{ 186100384Speter int argc, envc; 187100384Speter u_int32_t *vectp; 188100384Speter char *stringp, *destp; 189100384Speter u_int32_t *stack_base; 190119336Speter struct freebsd32_ps_strings *arginfo; 191100384Speter int szsigcode; 192100384Speter 193100384Speter /* 194100384Speter * Calculate string base and vector table pointers. 195100384Speter * Also deal with signal trampoline code for this exec type. 196100384Speter */ 197119336Speter arginfo = (struct freebsd32_ps_strings *)FREEBSD32_PS_STRINGS; 198100384Speter szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); 199100384Speter destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - 200140992Ssobomax roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *)); 201100384Speter 202100384Speter /* 203100384Speter * install sigcode 204100384Speter */ 205100384Speter if (szsigcode) 206100384Speter copyout(imgp->proc->p_sysent->sv_sigcode, 207100384Speter ((caddr_t)arginfo - szsigcode), szsigcode); 208100384Speter 209100384Speter /* 210100384Speter * If we have a valid auxargs ptr, prepare some room 211100384Speter * on the stack. 212100384Speter */ 213100384Speter if (imgp->auxargs) { 214100384Speter /* 215100384Speter * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for 216100384Speter * lower compatibility. 217100384Speter */ 218100384Speter imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size 219100384Speter : (AT_COUNT * 2); 220100384Speter /* 221100384Speter * The '+ 2' is for the null pointers at the end of each of 222100384Speter * the arg and env vector sets,and imgp->auxarg_size is room 223100384Speter * for argument of Runtime loader. 224100384Speter */ 225140992Ssobomax vectp = (u_int32_t *) (destp - (imgp->args->argc + imgp->args->envc + 2 + 226100384Speter imgp->auxarg_size) * sizeof(u_int32_t)); 227100384Speter 228100384Speter } else 229100384Speter /* 230100384Speter * The '+ 2' is for the null pointers at the end of each of 231100384Speter * the arg and env vector sets 232100384Speter */ 233100384Speter vectp = (u_int32_t *) 234140992Ssobomax (destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t)); 235100384Speter 236100384Speter /* 237100384Speter * vectp also becomes our initial stack base 238100384Speter */ 239100384Speter stack_base = vectp; 240100384Speter 241140992Ssobomax stringp = imgp->args->begin_argv; 242140992Ssobomax argc = imgp->args->argc; 243140992Ssobomax envc = imgp->args->envc; 244100384Speter /* 245100384Speter * Copy out strings - arguments and environment. 246100384Speter */ 247140992Ssobomax copyout(stringp, destp, ARG_MAX - imgp->args->stringspace); 248100384Speter 249100384Speter /* 250100384Speter * Fill in "ps_strings" struct for ps, w, etc. 251100384Speter */ 252100384Speter suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp); 253100384Speter suword32(&arginfo->ps_nargvstr, argc); 254100384Speter 255100384Speter /* 256100384Speter * Fill in argument portion of vector table. 257100384Speter */ 258100384Speter for (; argc > 0; --argc) { 259100384Speter suword32(vectp++, (u_int32_t)(intptr_t)destp); 260100384Speter while (*stringp++ != 0) 261100384Speter destp++; 262100384Speter destp++; 263100384Speter } 264100384Speter 265100384Speter /* a null vector table pointer separates the argp's from the envp's */ 266100384Speter suword32(vectp++, 0); 267100384Speter 268100384Speter suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp); 269100384Speter suword32(&arginfo->ps_nenvstr, envc); 270100384Speter 271100384Speter /* 272100384Speter * Fill in environment portion of vector table. 273100384Speter */ 274100384Speter for (; envc > 0; --envc) { 275100384Speter suword32(vectp++, (u_int32_t)(intptr_t)destp); 276100384Speter while (*stringp++ != 0) 277100384Speter destp++; 278100384Speter destp++; 279100384Speter } 280100384Speter 281100384Speter /* end of vector table is a null pointer */ 282100384Speter suword32(vectp, 0); 283100384Speter 284100384Speter return ((register_t *)stack_base); 285100384Speter} 286100384Speter 287120422Speterstatic void 288169565Sjhbia32_fixlimit(struct rlimit *rl, int which) 289120422Speter{ 290120422Speter 291169565Sjhb switch (which) { 292169565Sjhb case RLIMIT_DATA: 293169565Sjhb if (ia32_maxdsiz != 0) { 294169565Sjhb if (rl->rlim_cur > ia32_maxdsiz) 295169565Sjhb rl->rlim_cur = ia32_maxdsiz; 296169565Sjhb if (rl->rlim_max > ia32_maxdsiz) 297169565Sjhb rl->rlim_max = ia32_maxdsiz; 298169565Sjhb } 299169565Sjhb break; 300169565Sjhb case RLIMIT_STACK: 301169565Sjhb if (ia32_maxssiz != 0) { 302169565Sjhb if (rl->rlim_cur > ia32_maxssiz) 303169565Sjhb rl->rlim_cur = ia32_maxssiz; 304169565Sjhb if (rl->rlim_max > ia32_maxssiz) 305169565Sjhb rl->rlim_max = ia32_maxssiz; 306169565Sjhb } 307169565Sjhb break; 308169565Sjhb case RLIMIT_VMEM: 309169565Sjhb if (ia32_maxvmem != 0) { 310169565Sjhb if (rl->rlim_cur > ia32_maxvmem) 311169565Sjhb rl->rlim_cur = ia32_maxvmem; 312169565Sjhb if (rl->rlim_max > ia32_maxvmem) 313169565Sjhb rl->rlim_max = ia32_maxvmem; 314169565Sjhb } 315169565Sjhb break; 316120422Speter } 317120422Speter} 318