1 /* $OpenBSD: exec_elf.c,v 1.34 2001/08/11 23:14:22 art Exp $ */ 2 3 /* 4 * Copyright (c) 1996 Per Fogelstrom 5 * All rights reserved. 6 * 7 * Copyright (c) 1994 Christos Zoulas 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 */ 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/proc.h> 38 #include <sys/malloc.h> 39 #include <sys/mount.h> 40 #include <sys/namei.h> 41 #include <sys/vnode.h> 42 #include <sys/exec.h> 43 44 #if defined(_KERN_DO_ELF) 45 46 #include <sys/exec_elf.h> 47 #include <sys/exec_olf.h> 48 #include <sys/file.h> 49 #include <sys/syscall.h> 50 #include <sys/signalvar.h> 51 #include <sys/stat.h> 52 53 #include <sys/mman.h> 54 #include <vm/vm.h> 55 56 #include <machine/cpu.h> 57 #include <machine/reg.h> 58 #include <machine/exec.h> 59 60 #ifdef COMPAT_LINUX 61 #include <compat/linux/linux_exec.h> 62 #endif 63 64 #ifdef COMPAT_SVR4 65 #include <compat/svr4/svr4_exec.h> 66 #endif 67 68 #ifdef COMPAT_FREEBSD 69 #include <compat/freebsd/freebsd_exec.h> 70 #endif 71 72 struct elf_probe_entry { 73 int (*func) __P((struct proc *, struct exec_package *, char *, 74 u_long *, u_int8_t *)); 75 int os_mask; 76 } elf_probes[] = { 77 #ifdef COMPAT_FREEBSD 78 { freebsd_elf_probe, 1 << OOS_FREEBSD }, 79 #endif 80 #ifdef COMPAT_SVR4 81 { svr4_elf_probe, 82 1 << OOS_SVR4 | 1 << OOS_ESIX | 1 << OOS_SOLARIS | 1 << OOS_SCO | 83 1 << OOS_DELL | 1 << OOS_NCR }, 84 #endif 85 #ifdef COMPAT_LINUX 86 { linux_elf_probe, 1 << OOS_LINUX }, 87 #endif 88 { 0, 1 << OOS_OPENBSD } 89 }; 90 91 int elf_load_file __P((struct proc *, char *, struct exec_package *, 92 struct elf_args *, u_long *)); 93 94 int elf_check_header __P((Elf32_Ehdr *, int)); 95 int olf_check_header __P((Elf32_Ehdr *, int, u_int8_t *)); 96 int elf_read_from __P((struct proc *, struct vnode *, u_long, caddr_t, int)); 97 void elf_load_psection __P((struct exec_vmcmd_set *, struct vnode *, 98 Elf32_Phdr *, u_long *, u_long *, int *)); 99 100 int exec_elf_fixup __P((struct proc *, struct exec_package *)); 101 102 #define ELF_ALIGN(a, b) ((a) & ~((b) - 1)) 103 104 /* 105 * This is the basic elf emul. elf_probe_funcs may change to other emuls. 106 */ 107 108 extern char sigcode[], esigcode[]; 109 #ifdef SYSCALL_DEBUG 110 extern char *syscallnames[]; 111 #endif 112 113 struct emul emul_elf = { 114 "native", 115 NULL, 116 sendsig, 117 SYS_syscall, 118 SYS_MAXSYSCALL, 119 sysent, 120 #ifdef SYSCALL_DEBUG 121 syscallnames, 122 #else 123 NULL, 124 #endif 125 sizeof (AuxInfo) * ELF_AUX_ENTRIES, 126 elf_copyargs, 127 setregs, 128 exec_elf_fixup, 129 sigcode, 130 esigcode, 131 }; 132 133 134 /* 135 * Copy arguments onto the stack in the normal way, but add some 136 * space for extra information in case of dynamic binding. 137 */ 138 void * 139 elf_copyargs(pack, arginfo, stack, argp) 140 struct exec_package *pack; 141 struct ps_strings *arginfo; 142 void *stack; 143 void *argp; 144 { 145 stack = copyargs(pack, arginfo, stack, argp); 146 if (!stack) 147 return (NULL); 148 149 /* 150 * Push space for extra arguments on the stack needed by 151 * dynamically linked binaries 152 */ 153 if (pack->ep_interp != NULL) { 154 pack->ep_emul_argp = stack; 155 stack += ELF_AUX_ENTRIES * sizeof (AuxInfo); 156 } 157 return (stack); 158 } 159 160 /* 161 * elf_check_header(): 162 * 163 * Check header for validity; return 0 for ok, ENOEXEC if error 164 */ 165 int 166 elf_check_header(ehdr, type) 167 Elf32_Ehdr *ehdr; 168 int type; 169 { 170 /* 171 * We need to check magic, class size, endianess, and version before 172 * we look at the rest of the Elf32_Ehdr structure. These few elements 173 * are represented in a machine independant fashion. 174 */ 175 if (!IS_ELF(*ehdr) || 176 ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || 177 ehdr->e_ident[EI_DATA] != ELF_TARG_DATA || 178 ehdr->e_ident[EI_VERSION] != ELF_TARG_VER) 179 return (ENOEXEC); 180 181 /* Now check the machine dependant header */ 182 if (ehdr->e_machine != ELF_TARG_MACH || 183 ehdr->e_version != ELF_TARG_VER) 184 return (ENOEXEC); 185 186 /* Check the type */ 187 if (ehdr->e_type != type) 188 return (ENOEXEC); 189 190 /* Don't allow an insane amount of sections. */ 191 if (ehdr->e_phnum > 128) 192 return (ENOEXEC); 193 194 return (0); 195 } 196 197 /* 198 * olf_check_header(): 199 * 200 * Check header for validity; return 0 for ok, ENOEXEC if error. 201 * Remeber OS tag for callers sake. 202 */ 203 int 204 olf_check_header(ehdr, type, os) 205 Elf32_Ehdr *ehdr; 206 int type; 207 u_int8_t *os; 208 { 209 int i; 210 211 /* 212 * We need to check magic, class size, endianess, version, and OS 213 * before we look at the rest of the Elf32_Ehdr structure. These few 214 * elements are represented in a machine independant fashion. 215 */ 216 if (!IS_OLF(*ehdr) || 217 ehdr->e_ident[OI_CLASS] != ELF_TARG_CLASS || 218 ehdr->e_ident[OI_DATA] != ELF_TARG_DATA || 219 ehdr->e_ident[OI_VERSION] != ELF_TARG_VER) 220 return (ENOEXEC); 221 222 for (i = 0; i < sizeof elf_probes / sizeof elf_probes[0]; i++) 223 if ((1 << ehdr->e_ident[OI_OS]) & elf_probes[i].os_mask) 224 goto os_ok; 225 return (ENOEXEC); 226 227 os_ok: 228 /* Now check the machine dependant header */ 229 if (ehdr->e_machine != ELF_TARG_MACH || 230 ehdr->e_version != ELF_TARG_VER) 231 return (ENOEXEC); 232 233 /* Check the type */ 234 if (ehdr->e_type != type) 235 return (ENOEXEC); 236 237 /* Don't allow an insane amount of sections. */ 238 if (ehdr->e_phnum > 128) 239 return (ENOEXEC); 240 241 *os = ehdr->e_ident[OI_OS]; 242 return (0); 243 } 244 245 /* 246 * elf_load_psection(): 247 * 248 * Load a psection at the appropriate address 249 */ 250 void 251 elf_load_psection(vcset, vp, ph, addr, size, prot) 252 struct exec_vmcmd_set *vcset; 253 struct vnode *vp; 254 Elf32_Phdr *ph; 255 u_long *addr; 256 u_long *size; 257 int *prot; 258 { 259 u_long uaddr, msize, psize, rm, rf; 260 long diff, offset; 261 262 /* 263 * If the user specified an address, then we load there. 264 */ 265 if (*addr != ELF32_NO_ADDR) { 266 if (ph->p_align > 1) { 267 *addr = ELF_ALIGN(*addr + ph->p_align, ph->p_align); 268 uaddr = ELF_ALIGN(ph->p_vaddr, ph->p_align); 269 } else 270 uaddr = ph->p_vaddr; 271 diff = ph->p_vaddr - uaddr; 272 } else { 273 *addr = uaddr = ph->p_vaddr; 274 if (ph->p_align > 1) 275 *addr = ELF_ALIGN(uaddr, ph->p_align); 276 diff = uaddr - *addr; 277 } 278 279 *prot |= (ph->p_flags & PF_R) ? VM_PROT_READ : 0; 280 *prot |= (ph->p_flags & PF_W) ? VM_PROT_WRITE : 0; 281 *prot |= (ph->p_flags & PF_X) ? VM_PROT_EXECUTE : 0; 282 283 offset = ph->p_offset - diff; 284 *size = ph->p_filesz + diff; 285 msize = ph->p_memsz + diff; 286 psize = round_page(*size); 287 288 /* 289 * Because the pagedvn pager can't handle zero fill of the last 290 * data page if it's not page aligned we map the las page readvn. 291 */ 292 if (ph->p_flags & PF_W) { 293 psize = trunc_page(*size); 294 NEW_VMCMD(vcset, vmcmd_map_pagedvn, psize, *addr, vp, 295 offset, *prot); 296 if (psize != *size) { 297 NEW_VMCMD(vcset, vmcmd_map_readvn, *size - psize, 298 *addr + psize, vp, offset + psize, *prot); 299 } 300 } else { 301 NEW_VMCMD(vcset, vmcmd_map_pagedvn, psize, *addr, vp, offset, 302 *prot); 303 } 304 305 /* 306 * Check if we need to extend the size of the segment 307 */ 308 rm = round_page(*addr + msize); 309 rf = round_page(*addr + *size); 310 311 if (rm != rf) { 312 NEW_VMCMD(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP, 0, 313 *prot); 314 *size = msize; 315 } 316 } 317 318 /* 319 * elf_read_from(): 320 * 321 * Read from vnode into buffer at offset. 322 */ 323 int 324 elf_read_from(p, vp, off, buf, size) 325 struct proc *p; 326 struct vnode *vp; 327 u_long off; 328 caddr_t buf; 329 int size; 330 { 331 int error; 332 size_t resid; 333 334 if ((error = vn_rdwr(UIO_READ, vp, buf, size, off, UIO_SYSSPACE, 335 IO_NODELOCKED, p->p_ucred, &resid, p)) != 0) 336 return error; 337 /* 338 * See if we got all of it 339 */ 340 if (resid != 0) 341 return (ENOEXEC); 342 return (0); 343 } 344 345 /* 346 * elf_load_file(): 347 * 348 * Load a file (interpreter/library) pointed to by path [stolen from 349 * coff_load_shlib()]. Made slightly generic so it might be used externally. 350 */ 351 int 352 elf_load_file(p, path, epp, ap, last) 353 struct proc *p; 354 char *path; 355 struct exec_package *epp; 356 struct elf_args *ap; 357 u_long *last; 358 { 359 int error, i; 360 struct nameidata nd; 361 Elf32_Ehdr eh; 362 Elf32_Phdr *ph = NULL; 363 u_long phsize; 364 char *bp = NULL; 365 u_long addr = *last; 366 struct vnode *vp; 367 u_int8_t os; /* Just a dummy in this routine */ 368 369 bp = path; 370 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); 371 if ((error = namei(&nd)) != 0) { 372 return (error); 373 } 374 vp = nd.ni_vp; 375 if (vp->v_type != VREG) { 376 error = EACCES; 377 goto bad; 378 } 379 if ((error = VOP_GETATTR(vp, epp->ep_vap, p->p_ucred, p)) != 0) 380 goto bad; 381 if (vp->v_mount->mnt_flag & MNT_NOEXEC) { 382 error = EACCES; 383 goto bad; 384 } 385 if ((error = VOP_ACCESS(vp, VREAD, p->p_ucred, p)) != 0) 386 goto bad1; 387 if ((error = elf_read_from(p, nd.ni_vp, 0, 388 (caddr_t)&eh, sizeof(eh))) != 0) 389 goto bad1; 390 391 if (elf_check_header(&eh, ET_DYN) && 392 olf_check_header(&eh, ET_DYN, &os)) { 393 error = ENOEXEC; 394 goto bad1; 395 } 396 397 phsize = eh.e_phnum * sizeof(Elf32_Phdr); 398 ph = (Elf32_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 399 400 if ((error = elf_read_from(p, nd.ni_vp, eh.e_phoff, (caddr_t)ph, 401 phsize)) != 0) 402 goto bad1; 403 404 /* 405 * Load all the necessary sections 406 */ 407 for (i = 0; i < eh.e_phnum; i++) { 408 u_long size = 0; 409 int prot = 0; 410 #if defined(__mips__) 411 if (*last == ELF32_NO_ADDR) 412 addr = ELF32_NO_ADDR; /* GRRRRR!!!!! */ 413 #endif 414 415 switch (ph[i].p_type) { 416 case PT_LOAD: 417 elf_load_psection(&epp->ep_vmcmds, nd.ni_vp, &ph[i], 418 &addr, &size, &prot); 419 /* If entry is within this section it must be text */ 420 if (eh.e_entry >= ph[i].p_vaddr && 421 eh.e_entry < (ph[i].p_vaddr + size)) { 422 epp->ep_entry = addr + eh.e_entry - 423 ELF_ALIGN(ph[i].p_vaddr,ph[i].p_align); 424 ap->arg_interp = addr; 425 } 426 addr += size; 427 break; 428 429 case PT_DYNAMIC: 430 case PT_PHDR: 431 case PT_NOTE: 432 break; 433 434 default: 435 break; 436 } 437 } 438 439 bad1: 440 VOP_CLOSE(nd.ni_vp, FREAD, p->p_ucred, p); 441 bad: 442 if (ph != NULL) 443 free((char *)ph, M_TEMP); 444 445 *last = addr; 446 vput(nd.ni_vp); 447 return (error); 448 } 449 450 /* 451 * exec_elf_makecmds(): Prepare an Elf binary's exec package 452 * 453 * First, set of the various offsets/lengths in the exec package. 454 * 455 * Then, mark the text image busy (so it can be demand paged) or error out if 456 * this is not possible. Finally, set up vmcmds for the text, data, bss, and 457 * stack segments. 458 */ 459 int 460 exec_elf_makecmds(p, epp) 461 struct proc *p; 462 struct exec_package *epp; 463 { 464 Elf32_Ehdr *eh = epp->ep_hdr; 465 Elf32_Phdr *ph, *pp; 466 Elf32_Addr phdr = 0; 467 int error, i, nload; 468 char interp[MAXPATHLEN]; 469 u_long pos = 0, phsize; 470 u_int8_t os = OOS_NULL; 471 472 if (epp->ep_hdrvalid < sizeof(Elf32_Ehdr)) 473 return (ENOEXEC); 474 475 if (elf_check_header(eh, ET_EXEC) && 476 olf_check_header(eh, ET_EXEC, &os)) 477 return (ENOEXEC); 478 479 /* 480 * check if vnode is in open for writing, because we want to demand- 481 * page out of it. if it is, don't do it, for various reasons. 482 */ 483 if (epp->ep_vp->v_writecount != 0) { 484 #ifdef DIAGNOSTIC 485 if (epp->ep_vp->v_flag & VTEXT) 486 panic("exec: a VTEXT vnode has writecount != 0"); 487 #endif 488 return (ETXTBSY); 489 } 490 /* 491 * Allocate space to hold all the program headers, and read them 492 * from the file 493 */ 494 phsize = eh->e_phnum * sizeof(Elf32_Phdr); 495 ph = (Elf32_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 496 497 if ((error = elf_read_from(p, epp->ep_vp, eh->e_phoff, (caddr_t)ph, 498 phsize)) != 0) 499 goto bad; 500 501 epp->ep_tsize = ELF32_NO_ADDR; 502 epp->ep_dsize = ELF32_NO_ADDR; 503 504 interp[0] = '\0'; 505 506 for (i = 0; i < eh->e_phnum; i++) { 507 pp = &ph[i]; 508 if (pp->p_type == PT_INTERP) { 509 if (pp->p_filesz >= sizeof(interp)) 510 goto bad; 511 if ((error = elf_read_from(p, epp->ep_vp, pp->p_offset, 512 (caddr_t)interp, pp->p_filesz)) != 0) 513 goto bad; 514 break; 515 } 516 } 517 518 /* 519 * OK, we want a slightly different twist of the 520 * standard emulation package for "real" elf. 521 */ 522 epp->ep_emul = &emul_elf; 523 pos = ELF32_NO_ADDR; 524 525 /* 526 * On the same architecture, we may be emulating different systems. 527 * See which one will accept this executable. This currently only 528 * applies to Linux and SVR4 on the i386. 529 * 530 * Probe functions would normally see if the interpreter (if any) 531 * exists. Emulation packages may possibly replace the interpreter in 532 * interp[] with a changed path (/emul/xxx/<path>), and also 533 * set the ep_emul field in the exec package structure. 534 */ 535 error = ENOEXEC; 536 p->p_os = OOS_OPENBSD; 537 for (i = 0; i < sizeof elf_probes / sizeof elf_probes[0] && error; i++) 538 if (os == OOS_NULL || ((1 << os) & elf_probes[i].os_mask)) 539 error = elf_probes[i].func ? 540 (*elf_probes[i].func)(p, epp, interp, &pos, &os) : 541 0; 542 if (!error) 543 p->p_os = os; 544 #ifndef NATIVE_EXEC_ELF 545 else 546 goto bad; 547 #endif /* NATIVE_EXEC_ELF */ 548 549 /* 550 * Load all the necessary sections 551 */ 552 for (i = nload = 0; i < eh->e_phnum; i++) { 553 u_long addr = ELF32_NO_ADDR, size = 0; 554 int prot = 0; 555 556 pp = &ph[i]; 557 558 switch (ph[i].p_type) { 559 case PT_LOAD: 560 /* 561 * XXX 562 * Can handle only 2 sections: text and data 563 */ 564 if (nload++ == 2) 565 goto bad; 566 elf_load_psection(&epp->ep_vmcmds, epp->ep_vp, &ph[i], 567 &addr, &size, &prot); 568 /* 569 * Decide whether it's text or data by looking 570 * at the entry point. 571 */ 572 if (eh->e_entry >= addr && 573 eh->e_entry < (addr + size)) { 574 epp->ep_taddr = addr; 575 epp->ep_tsize = size; 576 } else { 577 epp->ep_daddr = addr; 578 epp->ep_dsize = size; 579 } 580 break; 581 582 case PT_SHLIB: 583 error = ENOEXEC; 584 goto bad; 585 586 case PT_INTERP: 587 /* Already did this one */ 588 case PT_DYNAMIC: 589 case PT_NOTE: 590 break; 591 592 case PT_PHDR: 593 /* Note address of program headers (in text segment) */ 594 phdr = pp->p_vaddr; 595 break; 596 597 default: 598 /* 599 * Not fatal, we don't need to understand everything 600 * :-) 601 */ 602 break; 603 } 604 } 605 606 #if !defined(__mips__) 607 /* 608 * If no position to load the interpreter was set by a probe 609 * function, pick the same address that a non-fixed mmap(0, ..) 610 * would (i.e. something safely out of the way). 611 */ 612 if (pos == ELF32_NO_ADDR) 613 pos = round_page(epp->ep_daddr + MAXDSIZ); 614 #endif 615 616 /* 617 * Check if we found a dynamically linked binary and arrange to load 618 * it's interpreter when the exec file is released. 619 */ 620 if (interp[0]) { 621 char *ip; 622 struct elf_args *ap; 623 624 ip = (char *)malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 625 ap = (struct elf_args *) 626 malloc(sizeof(struct elf_args), M_TEMP, M_WAITOK); 627 628 bcopy(interp, ip, MAXPATHLEN); 629 epp->ep_interp = ip; 630 epp->ep_interp_pos = pos; 631 632 ap->arg_phaddr = phdr; 633 ap->arg_phentsize = eh->e_phentsize; 634 ap->arg_phnum = eh->e_phnum; 635 ap->arg_entry = eh->e_entry; 636 ap->arg_os = os; 637 638 epp->ep_emul_arg = ap; 639 epp->ep_entry = eh->e_entry; /* keep check_exec() happy */ 640 } else { 641 epp->ep_interp = NULL; 642 epp->ep_entry = eh->e_entry; 643 } 644 645 #if defined(COMPAT_SVR4) && defined(i386) 646 #ifndef ELF_MAP_PAGE_ZERO 647 /* Dell SVR4 maps page zero, yeuch! */ 648 if (p->p_os == OOS_DELL) 649 #endif 650 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, PAGE_SIZE, 0, 651 epp->ep_vp, 0, VM_PROT_READ); 652 #endif 653 654 free((char *)ph, M_TEMP); 655 epp->ep_vp->v_flag |= VTEXT; 656 return (exec_setup_stack(p, epp)); 657 658 bad: 659 free((char *)ph, M_TEMP); 660 kill_vmcmds(&epp->ep_vmcmds); 661 return (ENOEXEC); 662 } 663 664 /* 665 * Phase II of load. It is now safe to load the interpreter. Info collected 666 * when loading the program is available for setup of the interpreter. 667 */ 668 int 669 exec_elf_fixup(p, epp) 670 struct proc *p; 671 struct exec_package *epp; 672 { 673 char *interp; 674 int error, i; 675 struct elf_args *ap; 676 AuxInfo ai[ELF_AUX_ENTRIES], *a; 677 u_long pos = epp->ep_interp_pos; 678 679 if (epp->ep_interp == 0) { 680 return (0); 681 } 682 683 interp = (char *)epp->ep_interp; 684 ap = (struct elf_args *)epp->ep_emul_arg; 685 686 if ((error = elf_load_file(p, interp, epp, ap, &pos)) != 0) { 687 free((char *)ap, M_TEMP); 688 free((char *)interp, M_TEMP); 689 kill_vmcmds(&epp->ep_vmcmds); 690 return (error); 691 } 692 /* 693 * We have to do this ourselves... 694 */ 695 for (i = 0; i < epp->ep_vmcmds.evs_used && !error; i++) { 696 struct exec_vmcmd *vcp; 697 698 vcp = &epp->ep_vmcmds.evs_cmds[i]; 699 error = (*vcp->ev_proc)(p, vcp); 700 } 701 kill_vmcmds(&epp->ep_vmcmds); 702 703 /* 704 * Push extra arguments on the stack needed by dynamically 705 * linked binaries 706 */ 707 if (error == 0) { 708 a = ai; 709 710 a->au_id = AUX_phdr; 711 a->au_v = ap->arg_phaddr; 712 a++; 713 714 a->au_id = AUX_phent; 715 a->au_v = ap->arg_phentsize; 716 a++; 717 718 a->au_id = AUX_phnum; 719 a->au_v = ap->arg_phnum; 720 a++; 721 722 a->au_id = AUX_pagesz; 723 a->au_v = PAGE_SIZE; 724 a++; 725 726 a->au_id = AUX_base; 727 a->au_v = ap->arg_interp; 728 a++; 729 730 a->au_id = AUX_flags; 731 a->au_v = 0; 732 a++; 733 734 a->au_id = AUX_entry; 735 a->au_v = ap->arg_entry; 736 a++; 737 738 a->au_id = AUX_null; 739 a->au_v = 0; 740 a++; 741 742 error = copyout(ai, epp->ep_emul_argp, sizeof ai); 743 } 744 free((char *)ap, M_TEMP); 745 free((char *)interp, M_TEMP); 746 return (error); 747 } 748 749 char * 750 elf_check_brand(eh) 751 Elf32_Ehdr *eh; 752 { 753 if (eh->e_ident[EI_BRAND] == '\0') 754 return (NULL); 755 return (&eh->e_ident[EI_BRAND]); 756 } 757 758 #endif /* _KERN_DO_ELF */ 759