1 /*- 2 * Copyright (c) 2002 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #define __ELF_WORD_SIZE 32 30 31 #include <sys/param.h> 32 #include <sys/exec.h> 33 #include <sys/fcntl.h> 34 #include <sys/imgact.h> 35 #include <sys/kernel.h> 36 #include <sys/lock.h> 37 #include <sys/malloc.h> 38 #include <sys/mutex.h> 39 #include <sys/mman.h> 40 #include <sys/namei.h> 41 #include <sys/pioctl.h> 42 #include <sys/proc.h> 43 #include <sys/procfs.h> 44 #include <sys/resourcevar.h> 45 #include <sys/systm.h> 46 #include <sys/signalvar.h> 47 #include <sys/stat.h> 48 #include <sys/sx.h> 49 #include <sys/syscall.h> 50 #include <sys/sysctl.h> 51 #include <sys/sysent.h> 52 #include <sys/vnode.h> 53 #include <sys/imgact_elf.h> 54 55 #include <vm/vm.h> 56 #include <vm/vm_kern.h> 57 #include <vm/vm_param.h> 58 #include <vm/pmap.h> 59 #include <vm/vm_map.h> 60 #include <vm/vm_object.h> 61 #include <vm/vm_extern.h> 62 63 #include <ia64/ia32/ia32_util.h> 64 #include <i386/include/psl.h> 65 #include <i386/include/segments.h> 66 #include <i386/include/specialreg.h> 67 #include <machine/frame.h> 68 #include <machine/md_var.h> 69 70 static register_t *ia32_copyout_strings(struct image_params *imgp); 71 static void ia32_setregs(struct thread *td, u_long entry, u_long stack, 72 u_long ps_strings); 73 74 extern struct sysent ia32_sysent[]; 75 76 static char ia32_sigcode[] = { 77 0xff, 0x54, 0x24, 0x10, /* call *SIGF_HANDLER(%esp) */ 78 0x8d, 0x44, 0x24, 0x14, /* lea SIGF_UC(%esp),%eax */ 79 0x50, /* pushl %eax */ 80 0xf7, 0x40, 0x54, 0x00, 0x00, 0x02, 0x02, /* testl $PSL_VM,UC_EFLAGS(%eax) */ 81 0x75, 0x03, /* jne 9f */ 82 0x8e, 0x68, 0x14, /* movl UC_GS(%eax),%gs */ 83 0xb8, 0x57, 0x01, 0x00, 0x00, /* 9: movl $SYS_sigreturn,%eax */ 84 0x50, /* pushl %eax */ 85 0xcd, 0x80, /* int $0x80 */ 86 0xeb, 0xfe, /* 0: jmp 0b */ 87 0, 0, 0, 0 88 }; 89 static int ia32_szsigcode = sizeof(ia32_sigcode) & ~3; 90 91 struct sysentvec ia32_freebsd_sysvec = { 92 SYS_MAXSYSCALL, 93 ia32_sysent, 94 0, 95 0, 96 0, 97 0, 98 0, 99 0, 100 elf32_freebsd_fixup, 101 sendsig, 102 ia32_sigcode, 103 &ia32_szsigcode, 104 0, 105 "FreeBSD ELF", 106 elf32_coredump, 107 NULL, 108 MINSIGSTKSZ, 109 4096, 110 IA32_USRSTACK, 111 IA32_USRSTACK, 112 ia32_copyout_strings, 113 ia32_setregs 114 }; 115 116 static Elf32_Brandinfo ia32_brand_info = { 117 ELFOSABI_FREEBSD, 118 EM_386, 119 "FreeBSD", 120 "/compat/ia32", 121 "/usr/libexec/ld-elf.so.1", 122 &ia32_freebsd_sysvec 123 }; 124 125 SYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_ANY, 126 (sysinit_cfunc_t) elf32_insert_brand_entry, 127 &ia32_brand_info); 128 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 ia32_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 ia32_ps_strings *)IA32_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 /* 192 * Copy out strings - arguments and environment. 193 */ 194 copyout(stringp, destp, ARG_MAX - imgp->stringspace); 195 196 /* 197 * Fill in "ps_strings" struct for ps, w, etc. 198 */ 199 suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp); 200 suword32(&arginfo->ps_nargvstr, argc); 201 202 /* 203 * Fill in argument portion of vector table. 204 */ 205 for (; argc > 0; --argc) { 206 suword32(vectp++, (u_int32_t)(intptr_t)destp); 207 while (*stringp++ != 0) 208 destp++; 209 destp++; 210 } 211 212 /* a null vector table pointer separates the argp's from the envp's */ 213 suword32(vectp++, 0); 214 215 suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp); 216 suword32(&arginfo->ps_nenvstr, envc); 217 218 /* 219 * Fill in environment portion of vector table. 220 */ 221 for (; envc > 0; --envc) { 222 suword32(vectp++, (u_int32_t)(intptr_t)destp); 223 while (*stringp++ != 0) 224 destp++; 225 destp++; 226 } 227 228 /* end of vector table is a null pointer */ 229 suword32(vectp, 0); 230 231 return ((register_t *)stack_base); 232 } 233 234 static void 235 ia32_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) 236 { 237 struct trapframe *frame = td->td_frame; 238 vm_offset_t gdt, ldt; 239 u_int64_t codesel, datasel, ldtsel; 240 u_int64_t codeseg, dataseg, gdtseg, ldtseg; 241 struct segment_descriptor desc; 242 struct vmspace *vmspace = td->td_proc->p_vmspace; 243 244 /* 245 * Make sure that we restore the entire trapframe after an 246 * execve. 247 */ 248 frame->tf_flags &= ~FRAME_SYSCALL; 249 250 bzero(frame->tf_r, sizeof(frame->tf_r)); 251 bzero(frame->tf_f, sizeof(frame->tf_f)); 252 253 frame->tf_cr_iip = entry; 254 frame->tf_cr_ipsr = (IA64_PSR_IC 255 | IA64_PSR_I 256 | IA64_PSR_IT 257 | IA64_PSR_DT 258 | IA64_PSR_RT 259 | IA64_PSR_DFH 260 | IA64_PSR_IS 261 | IA64_PSR_BN 262 | IA64_PSR_CPL_USER); 263 frame->tf_r[FRAME_R12] = stack; 264 265 codesel = LSEL(LUCODE_SEL, SEL_UPL); 266 datasel = LSEL(LUDATA_SEL, SEL_UPL); 267 ldtsel = GSEL(GLDT_SEL, SEL_UPL); 268 269 #if 1 270 frame->tf_r[FRAME_R16] = (datasel << 48) | (datasel << 32) 271 | (datasel << 16) | datasel; 272 frame->tf_r[FRAME_R17] = (ldtsel << 32) | (datasel << 16) | codesel; 273 #else 274 frame->tf_r[FRAME_R16] = datasel; 275 frame->tf_r[FRAME_R17] = codesel; 276 frame->tf_r[FRAME_R18] = datasel; 277 frame->tf_r[FRAME_R19] = datasel; 278 frame->tf_r[FRAME_R20] = datasel; 279 frame->tf_r[FRAME_R21] = datasel; 280 frame->tf_r[FRAME_R22] = ldtsel; 281 #endif 282 283 /* 284 * Build the GDT and LDT. 285 */ 286 gdt = IA32_USRSTACK; 287 vm_map_find(&vmspace->vm_map, 0, 0, 288 &gdt, PAGE_SIZE, 0, 289 VM_PROT_ALL, VM_PROT_ALL, 0); 290 ldt = gdt + 4096; 291 292 desc.sd_lolimit = 8*NLDT-1; 293 desc.sd_lobase = ldt & 0xffffff; 294 desc.sd_type = SDT_SYSLDT; 295 desc.sd_dpl = SEL_UPL; 296 desc.sd_p = 1; 297 desc.sd_hilimit = 0; 298 desc.sd_def32 = 0; 299 desc.sd_gran = 0; 300 desc.sd_hibase = ldt >> 24; 301 copyout(&desc, (caddr_t) gdt + 8*GLDT_SEL, sizeof(desc)); 302 303 desc.sd_lolimit = ((IA32_USRSTACK >> 12) - 1) & 0xffff; 304 desc.sd_lobase = 0; 305 desc.sd_type = SDT_MEMERA; 306 desc.sd_dpl = SEL_UPL; 307 desc.sd_p = 1; 308 desc.sd_hilimit = ((IA32_USRSTACK >> 12) - 1) >> 16; 309 desc.sd_def32 = 1; 310 desc.sd_gran = 1; 311 desc.sd_hibase = 0; 312 copyout(&desc, (caddr_t) ldt + 8*LUCODE_SEL, sizeof(desc)); 313 desc.sd_type = SDT_MEMRWA; 314 copyout(&desc, (caddr_t) ldt + 8*LUDATA_SEL, sizeof(desc)); 315 316 codeseg = 0 /* base */ 317 + (((IA32_USRSTACK >> 12) - 1) << 32) /* limit */ 318 + ((long)SDT_MEMERA << 52) 319 + ((long)SEL_UPL << 57) 320 + (1L << 59) /* present */ 321 + (1L << 62) /* 32 bits */ 322 + (1L << 63); /* page granularity */ 323 dataseg = 0 /* base */ 324 + (((IA32_USRSTACK >> 12) - 1) << 32) /* limit */ 325 + ((long)SDT_MEMRWA << 52) 326 + ((long)SEL_UPL << 57) 327 + (1L << 59) /* present */ 328 + (1L << 62) /* 32 bits */ 329 + (1L << 63); /* page granularity */ 330 ia64_set_csd(codeseg); 331 ia64_set_ssd(dataseg); 332 frame->tf_r[FRAME_R24] = dataseg; /* ESD */ 333 frame->tf_r[FRAME_R27] = dataseg; /* DSD */ 334 frame->tf_r[FRAME_R28] = dataseg; /* FSD */ 335 frame->tf_r[FRAME_R29] = dataseg; /* GSD */ 336 337 gdtseg = gdt /* base */ 338 + ((8L*NGDT - 1) << 32) /* limit */ 339 + ((long)SDT_SYSNULL << 52) 340 + ((long)SEL_UPL << 57) 341 + (1L << 59) /* present */ 342 + (0L << 62) /* 16 bits */ 343 + (0L << 63); /* byte granularity */ 344 ldtseg = ldt /* base */ 345 + ((8L*NLDT - 1) << 32) /* limit */ 346 + ((long)SDT_SYSLDT << 52) 347 + ((long)SEL_UPL << 57) 348 + (1L << 59) /* present */ 349 + (0L << 62) /* 16 bits */ 350 + (0L << 63); /* byte granularity */ 351 frame->tf_r[FRAME_R30] = ldtseg; /* LDTD */ 352 frame->tf_r[FRAME_R31] = gdtseg; /* GDTD */ 353 354 ia64_set_eflag(PSL_USER); 355 356 /* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */ 357 frame->tf_r[FRAME_R11] = IA32_PS_STRINGS; 358 359 /* 360 * XXX - Linux emulator 361 * Make sure sure edx is 0x0 on entry. Linux binaries depend 362 * on it. 363 */ 364 td->td_retval[1] = 0; 365 } 366