1 /*- 2 * Copyright (c) 2002 Doug Rabson 3 * Copyright (c) 2003 Peter Wemm 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include "opt_compat.h" 32 33 #define __ELF_WORD_SIZE 32 34 35 #include <sys/param.h> 36 #include <sys/exec.h> 37 #include <sys/fcntl.h> 38 #include <sys/imgact.h> 39 #include <sys/kernel.h> 40 #include <sys/lock.h> 41 #include <sys/malloc.h> 42 #include <sys/mutex.h> 43 #include <sys/mman.h> 44 #include <sys/namei.h> 45 #include <sys/pioctl.h> 46 #include <sys/proc.h> 47 #include <sys/procfs.h> 48 #include <sys/resourcevar.h> 49 #include <sys/systm.h> 50 #include <sys/signalvar.h> 51 #include <sys/stat.h> 52 #include <sys/sx.h> 53 #include <sys/syscall.h> 54 #include <sys/sysctl.h> 55 #include <sys/sysent.h> 56 #include <sys/vnode.h> 57 #include <sys/imgact_elf.h> 58 59 #include <vm/vm.h> 60 #include <vm/vm_kern.h> 61 #include <vm/vm_param.h> 62 #include <vm/pmap.h> 63 #include <vm/vm_map.h> 64 #include <vm/vm_object.h> 65 #include <vm/vm_extern.h> 66 67 #include <compat/freebsd32/freebsd32_util.h> 68 #include <compat/freebsd32/freebsd32_proto.h> 69 #include <compat/ia32/ia32_signal.h> 70 #include <machine/psl.h> 71 #include <machine/segments.h> 72 #include <machine/specialreg.h> 73 #include <machine/frame.h> 74 #include <machine/md_var.h> 75 #include <machine/pcb.h> 76 #include <machine/cpufunc.h> 77 78 static register_t *ia32_copyout_strings(struct image_params *imgp); 79 static void ia32_setregs(struct thread *td, u_long entry, u_long stack, 80 u_long ps_strings); 81 82 extern struct sysent freebsd32_sysent[]; 83 84 struct sysentvec ia32_freebsd_sysvec = { 85 SYS_MAXSYSCALL, 86 freebsd32_sysent, 87 0, 88 0, 89 NULL, 90 0, 91 NULL, 92 NULL, 93 elf32_freebsd_fixup, 94 ia32_sendsig, 95 ia32_sigcode, 96 &sz_ia32_sigcode, 97 NULL, 98 "FreeBSD ELF32", 99 elf32_coredump, 100 NULL, 101 MINSIGSTKSZ, 102 PAGE_SIZE, 103 0, 104 FREEBSD32_USRSTACK, 105 FREEBSD32_USRSTACK, 106 FREEBSD32_PS_STRINGS, 107 VM_PROT_ALL, 108 ia32_copyout_strings, 109 ia32_setregs 110 }; 111 112 113 const char freebsd32_emul_path[] = "/compat/ia32"; 114 115 static Elf32_Brandinfo ia32_brand_info = { 116 ELFOSABI_FREEBSD, 117 EM_386, 118 "FreeBSD", 119 "/compat/ia32", 120 "/usr/libexec/ld-elf.so.1", 121 &ia32_freebsd_sysvec 122 }; 123 124 SYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_ANY, 125 (sysinit_cfunc_t) elf32_insert_brand_entry, 126 &ia32_brand_info); 127 128 /* XXX may be freebsd32 MI */ 129 static register_t * 130 ia32_copyout_strings(struct image_params *imgp) 131 { 132 int argc, envc; 133 u_int32_t *vectp; 134 char *stringp, *destp; 135 u_int32_t *stack_base; 136 struct freebsd32_ps_strings *arginfo; 137 int szsigcode; 138 139 /* 140 * Calculate string base and vector table pointers. 141 * Also deal with signal trampoline code for this exec type. 142 */ 143 arginfo = (struct freebsd32_ps_strings *)FREEBSD32_PS_STRINGS; 144 szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); 145 destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - 146 roundup((ARG_MAX - imgp->stringspace), sizeof(char *)); 147 148 /* 149 * install sigcode 150 */ 151 if (szsigcode) 152 copyout(imgp->proc->p_sysent->sv_sigcode, 153 ((caddr_t)arginfo - szsigcode), szsigcode); 154 155 /* 156 * If we have a valid auxargs ptr, prepare some room 157 * on the stack. 158 */ 159 if (imgp->auxargs) { 160 /* 161 * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for 162 * lower compatibility. 163 */ 164 imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size 165 : (AT_COUNT * 2); 166 /* 167 * The '+ 2' is for the null pointers at the end of each of 168 * the arg and env vector sets,and imgp->auxarg_size is room 169 * for argument of Runtime loader. 170 */ 171 vectp = (u_int32_t *) (destp - (imgp->argc + imgp->envc + 2 + 172 imgp->auxarg_size) * sizeof(u_int32_t)); 173 174 } else 175 /* 176 * The '+ 2' is for the null pointers at the end of each of 177 * the arg and env vector sets 178 */ 179 vectp = (u_int32_t *) 180 (destp - (imgp->argc + imgp->envc + 2) * sizeof(u_int32_t)); 181 182 /* 183 * vectp also becomes our initial stack base 184 */ 185 stack_base = vectp; 186 187 stringp = imgp->stringbase; 188 argc = imgp->argc; 189 envc = imgp->envc; 190 /* 191 * Copy out strings - arguments and environment. 192 */ 193 copyout(stringp, destp, ARG_MAX - imgp->stringspace); 194 195 /* 196 * Fill in "ps_strings" struct for ps, w, etc. 197 */ 198 suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp); 199 suword32(&arginfo->ps_nargvstr, argc); 200 201 /* 202 * Fill in argument portion of vector table. 203 */ 204 for (; argc > 0; --argc) { 205 suword32(vectp++, (u_int32_t)(intptr_t)destp); 206 while (*stringp++ != 0) 207 destp++; 208 destp++; 209 } 210 211 /* a null vector table pointer separates the argp's from the envp's */ 212 suword32(vectp++, 0); 213 214 suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp); 215 suword32(&arginfo->ps_nenvstr, envc); 216 217 /* 218 * Fill in environment portion of vector table. 219 */ 220 for (; envc > 0; --envc) { 221 suword32(vectp++, (u_int32_t)(intptr_t)destp); 222 while (*stringp++ != 0) 223 destp++; 224 destp++; 225 } 226 227 /* end of vector table is a null pointer */ 228 suword32(vectp, 0); 229 230 return ((register_t *)stack_base); 231 } 232 233 /* 234 * Clear registers on exec 235 * XXX backend MD 236 */ 237 extern int _ucode32sel, _udatasel; 238 void 239 ia32_setregs(td, entry, stack, ps_strings) 240 struct thread *td; 241 u_long entry; 242 u_long stack; 243 u_long ps_strings; 244 { 245 struct trapframe *regs = td->td_frame; 246 struct pcb *pcb = td->td_pcb; 247 248 wrmsr(MSR_FSBASE, 0); 249 wrmsr(MSR_KGSBASE, 0); /* User value while we're in the kernel */ 250 pcb->pcb_fsbase = 0; 251 pcb->pcb_gsbase = 0; 252 load_ds(_udatasel); 253 load_es(_udatasel); 254 load_fs(_udatasel); 255 load_gs(_udatasel); 256 pcb->pcb_ds = _udatasel; 257 pcb->pcb_es = _udatasel; 258 pcb->pcb_fs = _udatasel; 259 pcb->pcb_gs = _udatasel; 260 261 bzero((char *)regs, sizeof(struct trapframe)); 262 regs->tf_rip = entry; 263 regs->tf_rsp = stack; 264 regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T); 265 regs->tf_ss = _udatasel; 266 regs->tf_cs = _ucode32sel; 267 regs->tf_rbx = ps_strings; 268 269 /* 270 * Arrange to trap the next npx or `fwait' instruction (see npx.c 271 * for why fwait must be trapped at least if there is an npx or an 272 * emulator). This is mainly to handle the case where npx0 is not 273 * configured, since the npx routines normally set up the trap 274 * otherwise. It should be done only at boot time, but doing it 275 * here allows modifying `npx_exists' for testing the emulator on 276 * systems with an npx. 277 */ 278 load_cr0(rcr0() | CR0_MP | CR0_TS); 279 280 fpstate_drop(td); 281 282 /* Return via doreti so that we can change to a different %cs */ 283 pcb->pcb_flags |= PCB_FULLCTX; 284 td->td_retval[1] = 0; 285 } 286