1 /* $NetBSD: exec_elf.c,v 1.8 1996/06/14 18:15:55 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1994 Christos Zoulas 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 */ 30 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/kernel.h> 34 #include <sys/proc.h> 35 #include <sys/malloc.h> 36 #include <sys/namei.h> 37 #include <sys/vnode.h> 38 #include <sys/exec.h> 39 #include <sys/exec_elf.h> 40 #include <sys/syscall.h> 41 #include <sys/signalvar.h> 42 43 #include <sys/mman.h> 44 #include <vm/vm.h> 45 #include <vm/vm_param.h> 46 #include <vm/vm_map.h> 47 48 #include <machine/cpu.h> 49 #include <machine/reg.h> 50 #include <machine/exec.h> 51 52 #ifdef COMPAT_LINUX 53 #include <compat/linux/linux_exec.h> 54 #endif 55 56 #ifdef COMPAT_SVR4 57 #include <compat/svr4/svr4_exec.h> 58 #endif 59 60 int (*elf_probe_funcs[]) __P((struct proc *, struct exec_package *, 61 Elf32_Ehdr *, char *, u_long *)) = { 62 #ifdef COMPAT_LINUX 63 linux_elf_probe, 64 #endif 65 #ifdef COMPAT_SVR4 66 svr4_elf_probe, 67 #endif 68 }; 69 70 int elf_check_header __P((Elf32_Ehdr *, int)); 71 int elf_load_file __P((struct proc *, char *, struct exec_vmcmd_set *, 72 u_long *, struct elf_args *, u_long *)); 73 74 static void elf_load_psection __P((struct exec_vmcmd_set *, 75 struct vnode *, Elf32_Phdr *, u_long *, u_long *, int *)); 76 77 #define ELF_ALIGN(a, b) ((a) & ~((b) - 1)) 78 79 /* 80 * This is the basic elf emul. elf_probe_funcs may change to other emuls. 81 */ 82 extern char sigcode[], esigcode[]; 83 #ifdef SYSCALL_DEBUG 84 extern char *syscallnames[]; 85 #endif 86 87 struct emul emul_elf = { 88 "netbsd", 89 NULL, 90 sendsig, 91 SYS_syscall, 92 SYS_MAXSYSCALL, 93 sysent, 94 #ifdef SYSCALL_DEBUG 95 syscallnames, 96 #else 97 NULL, 98 #endif 99 sizeof(AuxInfo) * ELF_AUX_ENTRIES, 100 elf_copyargs, 101 setregs, 102 sigcode, 103 esigcode, 104 }; 105 106 107 /* 108 * Copy arguments onto the stack in the normal way, but add some 109 * extra information in case of dynamic binding. 110 */ 111 void * 112 elf_copyargs(pack, arginfo, stack, argp) 113 struct exec_package *pack; 114 struct ps_strings *arginfo; 115 void *stack; 116 void *argp; 117 { 118 size_t len; 119 AuxInfo ai[ELF_AUX_ENTRIES], *a; 120 struct elf_args *ap; 121 122 stack = copyargs(pack, arginfo, stack, argp); 123 if (!stack) 124 return NULL; 125 126 /* 127 * Push extra arguments on the stack needed by dynamically 128 * linked binaries 129 */ 130 if ((ap = (struct elf_args *) pack->ep_emul_arg)) { 131 a = ai; 132 133 a->au_id = AUX_phdr; 134 a->au_v = ap->arg_phaddr; 135 a++; 136 137 a->au_id = AUX_phent; 138 a->au_v = ap->arg_phentsize; 139 a++; 140 141 a->au_id = AUX_phnum; 142 a->au_v = ap->arg_phnum; 143 a++; 144 145 a->au_id = AUX_pagesz; 146 a->au_v = NBPG; 147 a++; 148 149 a->au_id = AUX_base; 150 a->au_v = ap->arg_interp; 151 a++; 152 153 a->au_id = AUX_flags; 154 a->au_v = 0; 155 a++; 156 157 a->au_id = AUX_entry; 158 a->au_v = ap->arg_entry; 159 a++; 160 161 a->au_id = AUX_null; 162 a->au_v = 0; 163 a++; 164 165 free((char *) ap, M_TEMP); 166 len = ELF_AUX_ENTRIES * sizeof (AuxInfo); 167 if (copyout(ai, stack, len)) 168 return NULL; 169 stack += len; 170 } 171 return stack; 172 } 173 174 /* 175 * elf_check_header(): 176 * 177 * Check header for validity; return 0 of ok ENOEXEC if error 178 * 179 * XXX machine type needs to be moved to <machine/param.h> so 180 * just one comparison can be done. Unfortunately, there is both 181 * em_486 and em_386, so this would not work on the i386. 182 */ 183 int 184 elf_check_header(eh, type) 185 Elf32_Ehdr *eh; 186 int type; 187 { 188 189 if (bcmp(eh->e_ident, Elf32_e_ident, Elf32_e_siz) != 0) 190 return ENOEXEC; 191 192 switch (eh->e_machine) { 193 /* XXX */ 194 #ifdef i386 195 case Elf32_em_386: 196 case Elf32_em_486: 197 #endif 198 #ifdef sparc 199 case Elf32_em_sparc: 200 #endif 201 #ifdef mips 202 case Elf32_em_mips: 203 #endif 204 break; 205 206 default: 207 return ENOEXEC; 208 } 209 210 if (eh->e_type != type) 211 return ENOEXEC; 212 213 return 0; 214 } 215 216 /* 217 * elf_load_psection(): 218 * 219 * Load a psection at the appropriate address 220 */ 221 static void 222 elf_load_psection(vcset, vp, ph, addr, size, prot) 223 struct exec_vmcmd_set *vcset; 224 struct vnode *vp; 225 Elf32_Phdr *ph; 226 u_long *addr; 227 u_long *size; 228 int *prot; 229 { 230 u_long uaddr, msize, psize, rm, rf; 231 long diff, offset; 232 233 /* 234 * If the user specified an address, then we load there. 235 */ 236 if (*addr != ELF32_NO_ADDR) { 237 if (ph->p_align > 1) { 238 *addr = ELF_ALIGN(*addr + ph->p_align, ph->p_align); 239 uaddr = ELF_ALIGN(ph->p_vaddr, ph->p_align); 240 } else 241 uaddr = ph->p_vaddr; 242 diff = ph->p_vaddr - uaddr; 243 } else { 244 *addr = uaddr = ph->p_vaddr; 245 if (ph->p_align > 1) 246 *addr = ELF_ALIGN(uaddr, ph->p_align); 247 diff = uaddr - *addr; 248 } 249 250 *prot |= (ph->p_flags & Elf32_pf_r) ? VM_PROT_READ : 0; 251 *prot |= (ph->p_flags & Elf32_pf_w) ? VM_PROT_WRITE : 0; 252 *prot |= (ph->p_flags & Elf32_pf_x) ? VM_PROT_EXECUTE : 0; 253 254 offset = ph->p_offset - diff; 255 *size = ph->p_filesz + diff; 256 msize = ph->p_memsz + diff; 257 psize = round_page(*size); 258 259 if ((ph->p_flags & Elf32_pf_w) != 0) { 260 /* 261 * Because the pagedvn pager can't handle zero fill of the last 262 * data page if it's not page aligned we map the last page 263 * readvn. 264 */ 265 psize = trunc_page(*size); 266 NEW_VMCMD(vcset, vmcmd_map_pagedvn, psize, *addr, vp, 267 offset, *prot); 268 if(psize != *size) 269 NEW_VMCMD(vcset, vmcmd_map_readvn, *size - psize, 270 *addr + psize, vp, offset + psize, *prot); 271 } 272 else 273 NEW_VMCMD(vcset, vmcmd_map_pagedvn, psize, *addr, vp, 274 offset, *prot); 275 276 /* 277 * Check if we need to extend the size of the segment 278 */ 279 rm = round_page(*addr + msize); 280 rf = round_page(*addr + *size); 281 282 if (rm != rf) { 283 NEW_VMCMD(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP, 0, *prot); 284 *size = msize; 285 } 286 } 287 288 /* 289 * elf_read_from(): 290 * 291 * Read from vnode into buffer at offset. 292 */ 293 int 294 elf_read_from(p, vp, off, buf, size) 295 struct vnode *vp; 296 u_long off; 297 struct proc *p; 298 caddr_t buf; 299 int size; 300 { 301 int error; 302 int resid; 303 304 if ((error = vn_rdwr(UIO_READ, vp, buf, size, 305 off, UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, 306 &resid, p)) != 0) 307 return error; 308 /* 309 * See if we got all of it 310 */ 311 if (resid != 0) 312 return ENOEXEC; 313 return 0; 314 } 315 316 /* 317 * elf_load_file(): 318 * 319 * Load a file (interpreter/library) pointed to by path 320 * [stolen from coff_load_shlib()]. Made slightly generic 321 * so it might be used externally. 322 */ 323 int 324 elf_load_file(p, path, vcset, entry, ap, last) 325 struct proc *p; 326 char *path; 327 struct exec_vmcmd_set *vcset; 328 u_long *entry; 329 struct elf_args *ap; 330 u_long *last; 331 { 332 int error, i; 333 struct nameidata nd; 334 Elf32_Ehdr eh; 335 Elf32_Phdr *ph = NULL; 336 u_long phsize; 337 char *bp = NULL; 338 u_long addr = *last; 339 340 bp = path; 341 /* 342 * 1. open file 343 * 2. read filehdr 344 * 3. map text, data, and bss out of it using VM_* 345 */ 346 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path, p); 347 if ((error = namei(&nd)) != 0) { 348 return error; 349 } 350 if ((error = elf_read_from(p, nd.ni_vp, 0, (caddr_t) &eh, 351 sizeof(eh))) != 0) 352 goto bad; 353 354 if ((error = elf_check_header(&eh, Elf32_et_dyn)) != 0) 355 goto bad; 356 357 phsize = eh.e_phnum * sizeof(Elf32_Phdr); 358 ph = (Elf32_Phdr *) malloc(phsize, M_TEMP, M_WAITOK); 359 360 if ((error = elf_read_from(p, nd.ni_vp, eh.e_phoff, 361 (caddr_t) ph, phsize)) != 0) 362 goto bad; 363 364 /* 365 * Load all the necessary sections 366 */ 367 for (i = 0; i < eh.e_phnum; i++) { 368 u_long size = 0; 369 int prot = 0; 370 371 switch (ph[i].p_type) { 372 case Elf32_pt_load: 373 elf_load_psection(vcset, nd.ni_vp, &ph[i], &addr, 374 &size, &prot); 375 /* If entry is within this section it must be text */ 376 if (eh.e_entry >= ph[i].p_vaddr && 377 eh.e_entry < (ph[i].p_vaddr + size)) { 378 *entry = addr + eh.e_entry; 379 ap->arg_interp = addr; 380 } 381 addr += size; 382 break; 383 384 case Elf32_pt_dynamic: 385 case Elf32_pt_phdr: 386 case Elf32_pt_note: 387 break; 388 389 default: 390 break; 391 } 392 } 393 394 bad: 395 if (ph != NULL) 396 free((char *) ph, M_TEMP); 397 398 *last = addr; 399 vrele(nd.ni_vp); 400 return error; 401 } 402 403 /* 404 * exec_elf_makecmds(): Prepare an Elf binary's exec package 405 * 406 * First, set of the various offsets/lengths in the exec package. 407 * 408 * Then, mark the text image busy (so it can be demand paged) or error 409 * out if this is not possible. Finally, set up vmcmds for the 410 * text, data, bss, and stack segments. 411 */ 412 int 413 exec_elf_makecmds(p, epp) 414 struct proc *p; 415 struct exec_package *epp; 416 { 417 Elf32_Ehdr *eh = epp->ep_hdr; 418 Elf32_Phdr *ph, *pp; 419 Elf32_Addr phdr = 0; 420 int error, i, n, nload; 421 char interp[MAXPATHLEN]; 422 u_long pos = 0, phsize; 423 424 if (epp->ep_hdrvalid < sizeof(Elf32_Ehdr)) 425 return ENOEXEC; 426 427 if (elf_check_header(eh, Elf32_et_exec)) 428 return ENOEXEC; 429 430 /* 431 * check if vnode is in open for writing, because we want to 432 * demand-page out of it. if it is, don't do it, for various 433 * reasons 434 */ 435 if (epp->ep_vp->v_writecount != 0) { 436 #ifdef DIAGNOSTIC 437 if (epp->ep_vp->v_flag & VTEXT) 438 panic("exec: a VTEXT vnode has writecount != 0\n"); 439 #endif 440 return ETXTBSY; 441 } 442 /* 443 * Allocate space to hold all the program headers, and read them 444 * from the file 445 */ 446 phsize = eh->e_phnum * sizeof(Elf32_Phdr); 447 ph = (Elf32_Phdr *) malloc(phsize, M_TEMP, M_WAITOK); 448 449 if ((error = elf_read_from(p, epp->ep_vp, eh->e_phoff, 450 (caddr_t) ph, phsize)) != 0) 451 goto bad; 452 453 epp->ep_tsize = ELF32_NO_ADDR; 454 epp->ep_dsize = ELF32_NO_ADDR; 455 456 interp[0] = '\0'; 457 458 for (i = 0; i < eh->e_phnum; i++) { 459 pp = &ph[i]; 460 if (pp->p_type == Elf32_pt_interp) { 461 if (pp->p_filesz >= sizeof(interp)) 462 goto bad; 463 if ((error = elf_read_from(p, epp->ep_vp, pp->p_offset, 464 (caddr_t) interp, pp->p_filesz)) != 0) 465 goto bad; 466 break; 467 } 468 } 469 470 /* 471 * Setup things for native emulation. 472 */ 473 epp->ep_emul = &emul_elf; 474 pos = ELF32_NO_ADDR; 475 476 /* 477 * On the same architecture, we may be emulating different systems. 478 * See which one will accept this executable. This currently only 479 * applies to Linux and SVR4 on the i386. 480 * 481 * Probe functions would normally see if the interpreter (if any) 482 * exists. Emulation packages may possibly replace the interpreter in 483 * interp[] with a changed path (/emul/xxx/<path>), and also 484 * set the ep_emul field in the exec package structure. 485 */ 486 if ((n = sizeof elf_probe_funcs / sizeof elf_probe_funcs[0])) { 487 error = ENOEXEC; 488 for (i = 0; i < n && error; i++) 489 error = elf_probe_funcs[i](p, epp, eh, interp, &pos); 490 491 #ifdef notyet 492 /* 493 * We should really use a signature in our native binaries 494 * and have our own probe function for matching binaries, 495 * before trying the emulations. For now, if the emulation 496 * probes failed we default to native. 497 */ 498 if (error) 499 goto bad; 500 #endif 501 } 502 503 /* 504 * Load all the necessary sections 505 */ 506 for (i = nload = 0; i < eh->e_phnum; i++) { 507 u_long addr = ELF32_NO_ADDR, size = 0; 508 int prot = 0; 509 510 pp = &ph[i]; 511 512 switch (ph[i].p_type) { 513 case Elf32_pt_load: 514 /* 515 * XXX 516 * Can handle only 2 sections: text and data 517 */ 518 if (nload++ == 2) 519 goto bad; 520 elf_load_psection(&epp->ep_vmcmds, epp->ep_vp, 521 &ph[i], &addr, &size, &prot); 522 /* 523 * Decide whether it's text or data by looking 524 * at the entry point. 525 */ 526 if (eh->e_entry >= addr && eh->e_entry < (addr + size)){ 527 epp->ep_taddr = addr; 528 epp->ep_tsize = size; 529 } else { 530 epp->ep_daddr = addr; 531 epp->ep_dsize = size; 532 } 533 break; 534 535 case Elf32_pt_shlib: 536 error = ENOEXEC; 537 goto bad; 538 539 case Elf32_pt_interp: 540 /* Already did this one */ 541 case Elf32_pt_dynamic: 542 case Elf32_pt_note: 543 break; 544 545 case Elf32_pt_phdr: 546 /* Note address of program headers (in text segment) */ 547 phdr = pp->p_vaddr; 548 break; 549 550 default: 551 /* 552 * Not fatal, we don't need to understand everything 553 * :-) 554 */ 555 break; 556 } 557 } 558 559 /* 560 * If no position to load the interpreter was set by a probe 561 * function, pick the same address that a non-fixed mmap(0, ..) 562 * would (i.e. something safely out of the way). 563 */ 564 if (pos == ELF32_NO_ADDR && epp->ep_emul == &emul_elf) 565 pos = round_page(epp->ep_daddr + MAXDSIZ); 566 567 /* 568 * Check if we found a dynamically linked binary and arrange to load 569 * it's interpreter 570 */ 571 if (interp[0]) { 572 struct elf_args *ap; 573 574 ap = (struct elf_args *) malloc(sizeof(struct elf_args), 575 M_TEMP, M_WAITOK); 576 if ((error = elf_load_file(p, interp, &epp->ep_vmcmds, 577 &epp->ep_entry, ap, &pos)) != 0) { 578 free((char *) ap, M_TEMP); 579 goto bad; 580 } 581 pos += phsize; 582 ap->arg_phaddr = phdr; 583 584 ap->arg_phentsize = eh->e_phentsize; 585 ap->arg_phnum = eh->e_phnum; 586 ap->arg_entry = eh->e_entry; 587 588 epp->ep_emul_arg = ap; 589 } else 590 epp->ep_entry = eh->e_entry; 591 592 #ifdef ELF_MAP_PAGE_ZERO 593 /* Dell SVR4 maps page zero, yeuch! */ 594 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, NBPG, 0, epp->ep_vp, 0, 595 VM_PROT_READ); 596 #endif 597 free((char *) ph, M_TEMP); 598 epp->ep_vp->v_flag |= VTEXT; 599 return exec_aout_setup_stack(p, epp); 600 601 bad: 602 free((char *) ph, M_TEMP); 603 kill_vmcmds(&epp->ep_vmcmds); 604 return ENOEXEC; 605 } 606