ia32_sysvec.c revision 115006
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 * $FreeBSD: head/sys/compat/ia32/ia32_sysvec.c 115006 2003-05-15 00:23:40Z peter $ 28100384Speter */ 29100384Speter 30114987Speter#include "opt_compat.h" 31114987Speter 32100384Speter#define __ELF_WORD_SIZE 32 33100384Speter 34100384Speter#include <sys/param.h> 35100384Speter#include <sys/exec.h> 36100384Speter#include <sys/fcntl.h> 37100384Speter#include <sys/imgact.h> 38100384Speter#include <sys/kernel.h> 39100384Speter#include <sys/lock.h> 40100384Speter#include <sys/malloc.h> 41100384Speter#include <sys/mutex.h> 42100384Speter#include <sys/mman.h> 43100384Speter#include <sys/namei.h> 44100384Speter#include <sys/pioctl.h> 45100384Speter#include <sys/proc.h> 46100384Speter#include <sys/procfs.h> 47100384Speter#include <sys/resourcevar.h> 48100384Speter#include <sys/systm.h> 49100384Speter#include <sys/signalvar.h> 50100384Speter#include <sys/stat.h> 51100384Speter#include <sys/sx.h> 52100384Speter#include <sys/syscall.h> 53100384Speter#include <sys/sysctl.h> 54100384Speter#include <sys/sysent.h> 55100384Speter#include <sys/vnode.h> 56100384Speter#include <sys/imgact_elf.h> 57100384Speter 58100384Speter#include <vm/vm.h> 59100384Speter#include <vm/vm_kern.h> 60100384Speter#include <vm/vm_param.h> 61100384Speter#include <vm/pmap.h> 62100384Speter#include <vm/vm_map.h> 63100384Speter#include <vm/vm_object.h> 64100384Speter#include <vm/vm_extern.h> 65100384Speter 66114987Speter#include <amd64/ia32/ia32_util.h> 67114987Speter#include <amd64/ia32/ia32_proto.h> 68114987Speter#include <amd64/ia32/ia32_signal.h> 69114987Speter#include <machine/psl.h> 70114987Speter#include <machine/segments.h> 71114987Speter#include <machine/specialreg.h> 72100384Speter#include <machine/frame.h> 73100384Speter#include <machine/md_var.h> 74114987Speter#include <machine/pcb.h> 75114987Speter#include <machine/cpufunc.h> 76100384Speter 77100384Speterstatic register_t *ia32_copyout_strings(struct image_params *imgp); 78100384Speterstatic void ia32_setregs(struct thread *td, u_long entry, u_long stack, 79100384Speter u_long ps_strings); 80100384Speter 81100384Speterextern struct sysent ia32_sysent[]; 82100384Speter 83100384Speterstruct sysentvec ia32_freebsd_sysvec = { 84100384Speter SYS_MAXSYSCALL, 85100384Speter ia32_sysent, 86100384Speter 0, 87100384Speter 0, 88102808Sjake NULL, 89100384Speter 0, 90102808Sjake NULL, 91102808Sjake NULL, 92100384Speter elf32_freebsd_fixup, 93114987Speter ia32_sendsig, 94100384Speter ia32_sigcode, 95114987Speter &sz_ia32_sigcode, 96102808Sjake NULL, 97114987Speter "FreeBSD ELF32", 98100384Speter elf32_coredump, 99100384Speter NULL, 100100384Speter MINSIGSTKSZ, 101114987Speter PAGE_SIZE, 102102808Sjake 0, 103114987Speter USRSTACK, 104114987Speter USRSTACK, 105114987Speter PS_STRINGS, 106102808Sjake VM_PROT_ALL, 107100384Speter ia32_copyout_strings, 108100384Speter ia32_setregs 109100384Speter}; 110100384Speter 111114987Speter 112114987Speter 113100384Speterstatic Elf32_Brandinfo ia32_brand_info = { 114100384Speter ELFOSABI_FREEBSD, 115100384Speter EM_386, 116100384Speter "FreeBSD", 117100384Speter "/compat/ia32", 118100384Speter "/usr/libexec/ld-elf.so.1", 119100384Speter &ia32_freebsd_sysvec 120100384Speter }; 121100384Speter 122100384SpeterSYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_ANY, 123100384Speter (sysinit_cfunc_t) elf32_insert_brand_entry, 124100384Speter &ia32_brand_info); 125100384Speter 126114987Speterextern int _ucode32sel, _udatasel; 127114987Speter 128100384Speterstatic register_t * 129100384Speteria32_copyout_strings(struct image_params *imgp) 130100384Speter{ 131100384Speter int argc, envc; 132100384Speter u_int32_t *vectp; 133100384Speter char *stringp, *destp; 134100384Speter u_int32_t *stack_base; 135100384Speter struct ia32_ps_strings *arginfo; 136100384Speter int szsigcode; 137100384Speter 138100384Speter /* 139100384Speter * Calculate string base and vector table pointers. 140100384Speter * Also deal with signal trampoline code for this exec type. 141100384Speter */ 142114987Speter arginfo = (struct ia32_ps_strings *)PS_STRINGS; 143100384Speter szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); 144100384Speter destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - 145100384Speter roundup((ARG_MAX - imgp->stringspace), sizeof(char *)); 146100384Speter 147100384Speter /* 148100384Speter * install sigcode 149100384Speter */ 150100384Speter if (szsigcode) 151100384Speter copyout(imgp->proc->p_sysent->sv_sigcode, 152100384Speter ((caddr_t)arginfo - szsigcode), szsigcode); 153100384Speter 154100384Speter /* 155100384Speter * If we have a valid auxargs ptr, prepare some room 156100384Speter * on the stack. 157100384Speter */ 158100384Speter if (imgp->auxargs) { 159100384Speter /* 160100384Speter * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for 161100384Speter * lower compatibility. 162100384Speter */ 163100384Speter imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size 164100384Speter : (AT_COUNT * 2); 165100384Speter /* 166100384Speter * The '+ 2' is for the null pointers at the end of each of 167100384Speter * the arg and env vector sets,and imgp->auxarg_size is room 168100384Speter * for argument of Runtime loader. 169100384Speter */ 170100384Speter vectp = (u_int32_t *) (destp - (imgp->argc + imgp->envc + 2 + 171100384Speter imgp->auxarg_size) * sizeof(u_int32_t)); 172100384Speter 173100384Speter } else 174100384Speter /* 175100384Speter * The '+ 2' is for the null pointers at the end of each of 176100384Speter * the arg and env vector sets 177100384Speter */ 178100384Speter vectp = (u_int32_t *) 179100384Speter (destp - (imgp->argc + imgp->envc + 2) * sizeof(u_int32_t)); 180100384Speter 181100384Speter /* 182100384Speter * vectp also becomes our initial stack base 183100384Speter */ 184100384Speter stack_base = vectp; 185100384Speter 186100384Speter stringp = imgp->stringbase; 187100384Speter argc = imgp->argc; 188100384Speter envc = imgp->envc; 189100384Speter /* 190100384Speter * Copy out strings - arguments and environment. 191100384Speter */ 192100384Speter copyout(stringp, destp, ARG_MAX - imgp->stringspace); 193100384Speter 194100384Speter /* 195100384Speter * Fill in "ps_strings" struct for ps, w, etc. 196100384Speter */ 197100384Speter suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp); 198100384Speter suword32(&arginfo->ps_nargvstr, argc); 199100384Speter 200100384Speter /* 201100384Speter * Fill in argument portion of vector table. 202100384Speter */ 203100384Speter for (; argc > 0; --argc) { 204100384Speter suword32(vectp++, (u_int32_t)(intptr_t)destp); 205100384Speter while (*stringp++ != 0) 206100384Speter destp++; 207100384Speter destp++; 208100384Speter } 209100384Speter 210100384Speter /* a null vector table pointer separates the argp's from the envp's */ 211100384Speter suword32(vectp++, 0); 212100384Speter 213100384Speter suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp); 214100384Speter suword32(&arginfo->ps_nenvstr, envc); 215100384Speter 216100384Speter /* 217100384Speter * Fill in environment portion of vector table. 218100384Speter */ 219100384Speter for (; envc > 0; --envc) { 220100384Speter suword32(vectp++, (u_int32_t)(intptr_t)destp); 221100384Speter while (*stringp++ != 0) 222100384Speter destp++; 223100384Speter destp++; 224100384Speter } 225100384Speter 226100384Speter /* end of vector table is a null pointer */ 227100384Speter suword32(vectp, 0); 228100384Speter 229100384Speter return ((register_t *)stack_base); 230100384Speter} 231100384Speter 232114987Speter/* 233114987Speter * Clear registers on exec 234114987Speter */ 235114987Spetervoid 236114987Speteria32_setregs(td, entry, stack, ps_strings) 237114987Speter struct thread *td; 238114987Speter u_long entry; 239114987Speter u_long stack; 240114987Speter u_long ps_strings; 241100384Speter{ 242114987Speter struct trapframe *regs = td->td_frame; 243114987Speter struct pcb *pcb = td->td_pcb; 244114987Speter 245114987Speter wrmsr(MSR_FSBASE, 0); 246114987Speter wrmsr(MSR_KGSBASE, 0); /* User value while we're in the kernel */ 247114987Speter pcb->pcb_fsbase = 0; 248114987Speter pcb->pcb_gsbase = 0; 249114987Speter load_ds(_udatasel); 250114987Speter load_es(_udatasel); 251114987Speter load_fs(_udatasel); 252115006Speter load_gs(_udatasel); 253114987Speter pcb->pcb_ds = _udatasel; 254114987Speter pcb->pcb_es = _udatasel; 255114987Speter pcb->pcb_fs = _udatasel; 256114987Speter pcb->pcb_gs = _udatasel; 257100384Speter 258114987Speter bzero((char *)regs, sizeof(struct trapframe)); 259114987Speter regs->tf_rip = entry; 260114987Speter regs->tf_rsp = stack; 261114987Speter regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T); 262114987Speter regs->tf_ss = _udatasel; 263114987Speter regs->tf_cs = _ucode32sel; 264114987Speter regs->tf_rbx = ps_strings; 265100384Speter 266100384Speter /* 267114987Speter * Arrange to trap the next npx or `fwait' instruction (see npx.c 268114987Speter * for why fwait must be trapped at least if there is an npx or an 269114987Speter * emulator). This is mainly to handle the case where npx0 is not 270114987Speter * configured, since the npx routines normally set up the trap 271114987Speter * otherwise. It should be done only at boot time, but doing it 272114987Speter * here allows modifying `npx_exists' for testing the emulator on 273114987Speter * systems with an npx. 274100384Speter */ 275114987Speter load_cr0(rcr0() | CR0_MP | CR0_TS); 276100384Speter 277114987Speter fpstate_drop(td); 278100384Speter 279114987Speter /* Return via doreti so that we can change to a different %cs */ 280114987Speter pcb->pcb_flags |= PCB_FULLCTX; 281100384Speter td->td_retval[1] = 0; 282100384Speter} 283