1 /*- 2 * Copyright (c) 1995-1996 S�ren Schmidt 3 * Copyright (c) 1996 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 * in this position and unchanged. 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 withough 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 * $Id: imgact_elf.c,v 1.18 1997/04/01 10:41:48 bde Exp $ 30 */ 31 32 #include "opt_rlimit.h" 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/exec.h> 37 #include <sys/mman.h> 38 #include <sys/imgact.h> 39 #include <sys/imgact_elf.h> 40 #include <sys/kernel.h> 41 #include <sys/sysent.h> 42 #include <sys/fcntl.h> 43 #include <sys/malloc.h> 44 #include <sys/mount.h> 45 #include <sys/namei.h> 46 #include <sys/proc.h> 47 #include <sys/syscall.h> 48 #include <sys/signalvar.h> 49 #include <sys/sysctl.h> 50 #include <sys/vnode.h> 51 52 #include <vm/vm.h> 53 #include <vm/vm_kern.h> 54 #include <vm/vm_param.h> 55 #include <vm/pmap.h> 56 #include <sys/lock.h> 57 #include <vm/vm_map.h> 58 #include <vm/vm_prot.h> 59 #include <vm/vm_extern.h> 60 61 #include <machine/md_var.h> 62 63 #define MAX_PHDR 32 /* XXX enough ? */ 64 65 static int map_pages __P((struct vnode *vp, vm_offset_t offset, vm_offset_t *buf, vm_size_t size)); 66 static void unmap_pages __P((vm_offset_t buf, vm_size_t size)); 67 static int elf_check_permissions __P((struct proc *p, struct vnode *vp)); 68 static int elf_check_header __P((const Elf32_Ehdr *hdr, int type)); 69 static int elf_load_section __P((struct vmspace *vmspace, struct vnode *vp, vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot)); 70 static int elf_load_file __P((struct proc *p, char *file, u_long *addr, u_long *entry)); 71 static int elf_freebsd_fixup __P((int **stack_base, struct image_params *imgp)); 72 int exec_elf_imgact __P((struct image_params *imgp)); 73 74 static int elf_trace = 0; 75 SYSCTL_INT(_debug, OID_AUTO, elf_trace, CTLFLAG_RW, &elf_trace, 0, ""); 76 #define UPRINTF if (elf_trace) uprintf 77 78 static struct sysentvec elf_freebsd_sysvec = { 79 SYS_MAXSYSCALL, 80 sysent, 81 0, 82 0, 83 0, 84 0, 85 0, 86 elf_freebsd_fixup, 87 sendsig, 88 sigcode, 89 &szsigcode, 90 0, 91 "FreeBSD ELF" 92 }; 93 94 static Elf32_Brandinfo freebsd_brand_info = { 95 "FreeBSD", 96 "", 97 "/usr/libexec/ld-elf.so.1", 98 &elf_freebsd_sysvec 99 }; 100 static Elf32_Brandinfo *elf_brand_list[MAX_BRANDS] = { 101 &freebsd_brand_info, 102 NULL, NULL, NULL, 103 NULL, NULL, NULL, NULL 104 }; 105 106 int 107 elf_insert_brand_entry(Elf32_Brandinfo *entry) 108 { 109 int i; 110 111 for (i=1; i<MAX_BRANDS; i++) { 112 if (elf_brand_list[i] == NULL) { 113 elf_brand_list[i] = entry; 114 break; 115 } 116 } 117 if (i == MAX_BRANDS) 118 return -1; 119 return 0; 120 } 121 122 int 123 elf_remove_brand_entry(Elf32_Brandinfo *entry) 124 { 125 int i; 126 127 for (i=1; i<MAX_BRANDS; i++) { 128 if (elf_brand_list[i] == entry) { 129 elf_brand_list[i] = NULL; 130 break; 131 } 132 } 133 if (i == MAX_BRANDS) 134 return -1; 135 return 0; 136 } 137 138 static int 139 map_pages(struct vnode *vp, vm_offset_t offset, 140 vm_offset_t *buf, vm_size_t size) 141 { 142 int error; 143 vm_offset_t kern_buf; 144 vm_size_t pageoff; 145 146 /* 147 * The request may not be aligned, and may even cross several 148 * page boundaries in the file... 149 */ 150 pageoff = (offset & PAGE_MASK); 151 offset -= pageoff; /* start of first aligned page to map */ 152 size += pageoff; 153 size = round_page(size); /* size of aligned pages to map */ 154 155 if (error = vm_mmap(kernel_map, 156 &kern_buf, 157 size, 158 VM_PROT_READ, 159 VM_PROT_READ, 160 0, 161 (caddr_t)vp, 162 offset)) 163 return error; 164 165 *buf = kern_buf + pageoff; 166 167 return 0; 168 } 169 170 static void 171 unmap_pages(vm_offset_t buf, vm_size_t size) 172 { 173 vm_size_t pageoff; 174 175 pageoff = (buf & PAGE_MASK); 176 buf -= pageoff; /* start of first aligned page to map */ 177 size += pageoff; 178 size = round_page(size);/* size of aligned pages to map */ 179 180 vm_map_remove(kernel_map, buf, buf + size); 181 } 182 183 static int 184 elf_check_permissions(struct proc *p, struct vnode *vp) 185 { 186 struct vattr attr; 187 int error; 188 189 /* 190 * Check number of open-for-writes on the file and deny execution 191 * if there are any. 192 */ 193 if (vp->v_writecount) { 194 return (ETXTBSY); 195 } 196 197 /* Get file attributes */ 198 error = VOP_GETATTR(vp, &attr, p->p_ucred, p); 199 if (error) 200 return (error); 201 202 /* 203 * 1) Check if file execution is disabled for the filesystem that this 204 * file resides on. 205 * 2) Insure that at least one execute bit is on - otherwise root 206 * will always succeed, and we don't want to happen unless the 207 * file really is executable. 208 * 3) Insure that the file is a regular file. 209 */ 210 if ((vp->v_mount->mnt_flag & MNT_NOEXEC) || 211 ((attr.va_mode & 0111) == 0) || 212 (attr.va_type != VREG)) { 213 return (EACCES); 214 } 215 216 /* 217 * Zero length files can't be exec'd 218 */ 219 if (attr.va_size == 0) 220 return (ENOEXEC); 221 222 /* 223 * Check for execute permission to file based on current credentials. 224 * Then call filesystem specific open routine (which does nothing 225 * in the general case). 226 */ 227 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); 228 if (error) 229 return (error); 230 231 error = VOP_OPEN(vp, FREAD, p->p_ucred, p); 232 if (error) 233 return (error); 234 235 return (0); 236 } 237 238 static int 239 elf_check_header(const Elf32_Ehdr *hdr, int type) 240 { 241 if (!(hdr->e_ident[EI_MAG0] == ELFMAG0 && 242 hdr->e_ident[EI_MAG1] == ELFMAG1 && 243 hdr->e_ident[EI_MAG2] == ELFMAG2 && 244 hdr->e_ident[EI_MAG3] == ELFMAG3)) 245 return ENOEXEC; 246 247 if (hdr->e_machine != EM_386 && hdr->e_machine != EM_486) 248 return ENOEXEC; 249 250 if (hdr->e_type != type) 251 return ENOEXEC; 252 253 return 0; 254 } 255 256 static int 257 elf_load_section(struct vmspace *vmspace, struct vnode *vp, vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot) 258 { 259 size_t map_len; 260 vm_offset_t map_addr; 261 int error; 262 unsigned char *data_buf = 0; 263 size_t copy_len; 264 265 map_addr = trunc_page(vmaddr); 266 267 if (memsz > filsz) 268 map_len = trunc_page(offset+filsz) - trunc_page(offset); 269 else 270 map_len = round_page(offset+filsz) - trunc_page(offset); 271 272 if (error = vm_mmap (&vmspace->vm_map, 273 &map_addr, 274 map_len, 275 prot, 276 VM_PROT_ALL, 277 MAP_PRIVATE | MAP_FIXED, 278 (caddr_t)vp, 279 trunc_page(offset))) 280 return error; 281 282 if (memsz == filsz) 283 return 0; 284 285 /* 286 * We have to map the remaining bit of the file into the kernel's 287 * memory map, allocate some anonymous memory, and copy that last 288 * bit into it. The remaining space should be .bss... 289 */ 290 copy_len = (offset + filsz) - trunc_page(offset + filsz); 291 map_addr = trunc_page(vmaddr + filsz); 292 map_len = round_page(vmaddr + memsz) - map_addr; 293 294 if (map_len != 0) { 295 if (error = vm_map_find(&vmspace->vm_map, NULL, 0, 296 &map_addr, map_len, FALSE, 297 VM_PROT_ALL, VM_PROT_ALL,0)) 298 return error; 299 } 300 301 if (error = vm_mmap(kernel_map, 302 (vm_offset_t *)&data_buf, 303 PAGE_SIZE, 304 VM_PROT_READ, 305 VM_PROT_READ, 306 0, 307 (caddr_t)vp, 308 trunc_page(offset + filsz))) 309 return error; 310 311 error = copyout(data_buf, (caddr_t)map_addr, copy_len); 312 313 vm_map_remove(kernel_map, (vm_offset_t)data_buf, 314 (vm_offset_t)data_buf + PAGE_SIZE); 315 316 /* 317 * set it to the specified protection 318 */ 319 vm_map_protect(&vmspace->vm_map, map_addr, map_addr + map_len, prot, 320 FALSE); 321 322 UPRINTF("bss size %d (%x)\n", map_len-copy_len, map_len-copy_len); 323 return error; 324 } 325 326 static int 327 elf_load_file(struct proc *p, char *file, u_long *addr, u_long *entry) 328 { 329 Elf32_Ehdr *hdr = NULL; 330 Elf32_Phdr *phdr = NULL; 331 struct nameidata nd; 332 struct vmspace *vmspace = p->p_vmspace; 333 vm_prot_t prot = 0; 334 unsigned long text_size = 0, data_size = 0; 335 unsigned long text_addr = 0, data_addr = 0; 336 int header_size = 0; 337 int error, i; 338 339 NDINIT(&nd, LOOKUP, LOCKLEAF|FOLLOW, UIO_SYSSPACE, file, p); 340 341 if (error = namei(&nd)) 342 goto fail; 343 344 if (nd.ni_vp == NULL) { 345 error = ENOEXEC; 346 goto fail; 347 } 348 349 /* 350 * Check permissions, modes, uid, etc on the file, and "open" it. 351 */ 352 error = elf_check_permissions(p, nd.ni_vp); 353 354 /* 355 * No longer need this, and it prevents demand paging. 356 */ 357 VOP_UNLOCK(nd.ni_vp, 0, p); 358 359 if (error) 360 goto fail; 361 362 /* 363 * Map in the header 364 */ 365 if (error = map_pages(nd.ni_vp, 0, (vm_offset_t *)&hdr, sizeof(hdr))) 366 goto fail; 367 368 /* 369 * Do we have a valid ELF header ? 370 */ 371 if (error = elf_check_header(hdr, ET_DYN)) 372 goto fail; 373 374 /* 375 * ouch, need to bounds check in case user gives us a corrupted 376 * file with an insane header size 377 */ 378 if (hdr->e_phnum > MAX_PHDR) { /* XXX: ever more than this? */ 379 error = ENOEXEC; 380 goto fail; 381 } 382 383 header_size = hdr->e_phentsize * hdr->e_phnum; 384 385 if (error = map_pages(nd.ni_vp, hdr->e_phoff, (vm_offset_t *)&phdr, 386 header_size)) 387 goto fail; 388 389 for (i = 0; i < hdr->e_phnum; i++) { 390 switch(phdr[i].p_type) { 391 392 case PT_NULL: /* NULL section */ 393 UPRINTF ("ELF(file) PT_NULL section\n"); 394 break; 395 case PT_LOAD: /* Loadable segment */ 396 { 397 UPRINTF ("ELF(file) PT_LOAD section "); 398 if (phdr[i].p_flags & PF_X) 399 prot |= VM_PROT_EXECUTE; 400 if (phdr[i].p_flags & PF_W) 401 prot |= VM_PROT_WRITE; 402 if (phdr[i].p_flags & PF_R) 403 prot |= VM_PROT_READ; 404 405 if (error = elf_load_section(vmspace, nd.ni_vp, 406 phdr[i].p_offset, 407 (caddr_t)phdr[i].p_vaddr + 408 (*addr), 409 phdr[i].p_memsz, 410 phdr[i].p_filesz, prot)) 411 goto fail; 412 413 /* 414 * Is this .text or .data ?? 415 * 416 * We only handle one each of those yet XXX 417 */ 418 if (hdr->e_entry >= phdr[i].p_vaddr && 419 hdr->e_entry <(phdr[i].p_vaddr+phdr[i].p_memsz)) { 420 text_addr = trunc_page(phdr[i].p_vaddr+(*addr)); 421 text_size = round_page(phdr[i].p_memsz + 422 phdr[i].p_vaddr - 423 trunc_page(phdr[i].p_vaddr)); 424 *entry=(unsigned long)hdr->e_entry+(*addr); 425 UPRINTF(".text <%08x,%08x> entry=%08x\n", 426 text_addr, text_size, *entry); 427 } else { 428 data_addr = trunc_page(phdr[i].p_vaddr+(*addr)); 429 data_size = round_page(phdr[i].p_memsz + 430 phdr[i].p_vaddr - 431 trunc_page(phdr[i].p_vaddr)); 432 UPRINTF(".data <%08x,%08x>\n", 433 data_addr, data_size); 434 } 435 } 436 break; 437 438 case PT_DYNAMIC:/* Dynamic link information */ 439 UPRINTF ("ELF(file) PT_DYNAMIC section\n"); 440 break; 441 case PT_INTERP: /* Path to interpreter */ 442 UPRINTF ("ELF(file) PT_INTERP section\n"); 443 break; 444 case PT_NOTE: /* Note section */ 445 UPRINTF ("ELF(file) PT_NOTE section\n"); 446 break; 447 case PT_SHLIB: /* Shared lib section */ 448 UPRINTF ("ELF(file) PT_SHLIB section\n"); 449 break; 450 case PT_PHDR: /* Program header table info */ 451 UPRINTF ("ELF(file) PT_PHDR section\n"); 452 break; 453 default: 454 UPRINTF ("ELF(file) %d section ??\n", phdr[i].p_type ); 455 } 456 } 457 458 fail: 459 if (phdr) 460 unmap_pages((vm_offset_t)phdr, header_size); 461 if (hdr) 462 unmap_pages((vm_offset_t)hdr, sizeof(hdr)); 463 464 return error; 465 } 466 467 int 468 exec_elf_imgact(struct image_params *imgp) 469 { 470 const Elf32_Ehdr *hdr = (const Elf32_Ehdr *) imgp->image_header; 471 const Elf32_Phdr *phdr, *mapped_phdr = NULL; 472 Elf32_Auxargs *elf_auxargs = NULL; 473 struct vmspace *vmspace; 474 vm_prot_t prot = 0; 475 u_long text_size = 0, data_size = 0; 476 u_long text_addr = 0, data_addr = 0; 477 u_long addr, entry = 0, proghdr = 0; 478 int error, i, header_size = 0, interp_len = 0; 479 char *interp = NULL; 480 char *brand = NULL; 481 char path[MAXPATHLEN]; 482 483 /* 484 * Do we have a valid ELF header ? 485 */ 486 if (elf_check_header(hdr, ET_EXEC)) 487 return -1; 488 489 /* 490 * From here on down, we return an errno, not -1, as we've 491 * detected an ELF file. 492 */ 493 494 /* 495 * ouch, need to bounds check in case user gives us a corrupted 496 * file with an insane header size 497 */ 498 if (hdr->e_phnum > MAX_PHDR) { /* XXX: ever more than this? */ 499 return ENOEXEC; 500 } 501 502 header_size = hdr->e_phentsize * hdr->e_phnum; 503 504 if ((hdr->e_phoff > PAGE_SIZE) || 505 (hdr->e_phoff + header_size) > PAGE_SIZE) { 506 /* 507 * Ouch ! we only get one page full of header... 508 * Try to map it in ourselves, and see how we go. 509 */ 510 if (error = map_pages(imgp->vp, hdr->e_phoff, 511 (vm_offset_t *)&mapped_phdr, header_size)) 512 return (error); 513 /* 514 * Save manual mapping for cleanup 515 */ 516 phdr = mapped_phdr; 517 } else { 518 phdr = (const Elf32_Phdr*) 519 ((const char *)imgp->image_header + hdr->e_phoff); 520 } 521 522 /* 523 * From this point on, we may have resources that need to be freed. 524 */ 525 if (error = exec_extract_strings(imgp)) 526 goto fail; 527 528 exec_new_vmspace(imgp); 529 530 vmspace = imgp->proc->p_vmspace; 531 532 for (i = 0; i < hdr->e_phnum; i++) { 533 switch(phdr[i].p_type) { 534 535 case PT_NULL: /* NULL section */ 536 UPRINTF ("ELF PT_NULL section\n"); 537 break; 538 case PT_LOAD: /* Loadable segment */ 539 { 540 UPRINTF ("ELF PT_LOAD section "); 541 if (phdr[i].p_flags & PF_X) 542 prot |= VM_PROT_EXECUTE; 543 if (phdr[i].p_flags & PF_W) 544 prot |= VM_PROT_WRITE; 545 if (phdr[i].p_flags & PF_R) 546 prot |= VM_PROT_READ; 547 548 if (error = elf_load_section(vmspace, imgp->vp, 549 phdr[i].p_offset, 550 (caddr_t)phdr[i].p_vaddr, 551 phdr[i].p_memsz, 552 phdr[i].p_filesz, prot)) 553 goto fail; 554 555 /* 556 * Is this .text or .data ?? 557 * 558 * We only handle one each of those yet XXX 559 */ 560 if (hdr->e_entry >= phdr[i].p_vaddr && 561 hdr->e_entry <(phdr[i].p_vaddr+phdr[i].p_memsz)) { 562 text_addr = trunc_page(phdr[i].p_vaddr); 563 text_size = round_page(phdr[i].p_memsz + 564 phdr[i].p_vaddr - 565 text_addr); 566 entry = (u_long)hdr->e_entry; 567 UPRINTF(".text <%08x,%08x> entry=%08x\n", 568 text_addr, text_size, entry); 569 } else { 570 data_addr = trunc_page(phdr[i].p_vaddr); 571 data_size = round_page(phdr[i].p_memsz + 572 phdr[i].p_vaddr - 573 data_addr); 574 UPRINTF(".data <%08x,%08x>\n", 575 data_addr, data_size); 576 } 577 } 578 break; 579 580 case PT_DYNAMIC:/* Dynamic link information */ 581 UPRINTF ("ELF PT_DYNAMIC section ??\n"); 582 break; 583 case PT_INTERP: /* Path to interpreter */ 584 UPRINTF ("ELF PT_INTERP section "); 585 if (phdr[i].p_filesz > MAXPATHLEN) { 586 error = ENOEXEC; 587 goto fail; 588 } 589 interp_len = MAXPATHLEN; 590 if (error = map_pages(imgp->vp, phdr[i].p_offset, 591 (vm_offset_t *)&interp, interp_len)) 592 goto fail; 593 UPRINTF("<%s>\n", interp); 594 break; 595 case PT_NOTE: /* Note section */ 596 UPRINTF ("ELF PT_NOTE section\n"); 597 break; 598 case PT_SHLIB: /* Shared lib section */ 599 UPRINTF ("ELF PT_SHLIB section\n"); 600 break; 601 case PT_PHDR: /* Program header table info */ 602 UPRINTF ("ELF PT_PHDR section <%x>\n", phdr[i].p_vaddr); 603 proghdr = phdr[i].p_vaddr; 604 break; 605 default: 606 UPRINTF ("ELF %d section ??\n", phdr[i].p_type); 607 } 608 } 609 610 vmspace->vm_tsize = text_size >> PAGE_SHIFT; 611 vmspace->vm_taddr = (caddr_t)text_addr; 612 vmspace->vm_dsize = data_size >> PAGE_SHIFT; 613 vmspace->vm_daddr = (caddr_t)data_addr; 614 615 addr = 2*MAXDSIZ; /* May depend on OS type XXX */ 616 617 imgp->entry_addr = entry; 618 619 /* 620 * So which kind (brand) of ELF binary do we have at hand 621 * FreeBSD, Linux, SVR4 or something else ?? 622 * If its has a interpreter section try that first 623 */ 624 if (interp) { 625 for (i=0; i<MAX_BRANDS; i++) { 626 if (elf_brand_list[i] != NULL) { 627 if (!strcmp(interp, elf_brand_list[i]->interp_path)) { 628 imgp->proc->p_sysent = 629 elf_brand_list[i]->sysvec; 630 strcpy(path, elf_brand_list[i]->emul_path); 631 strcat(path, elf_brand_list[i]->interp_path); 632 UPRINTF("interpreter=<%s> %s\n", 633 elf_brand_list[i]->interp_path, 634 elf_brand_list[i]->emul_path); 635 break; 636 } 637 } 638 } 639 } 640 641 /* 642 * If there is no interpreter, or recognition of it 643 * failed, se if the binary is branded. 644 */ 645 if (!interp || i == MAX_BRANDS) { 646 brand = (char *)&(hdr->e_ident[EI_BRAND]); 647 for (i=0; i<MAX_BRANDS; i++) { 648 if (elf_brand_list[i] != NULL) { 649 if (!strcmp(brand, elf_brand_list[i]->brand)) { 650 imgp->proc->p_sysent = elf_brand_list[i]->sysvec; 651 if (interp) { 652 strcpy(path, elf_brand_list[i]->emul_path); 653 strcat(path, elf_brand_list[i]->interp_path); 654 UPRINTF("interpreter=<%s> %s\n", 655 elf_brand_list[i]->interp_path, 656 elf_brand_list[i]->emul_path); 657 } 658 break; 659 } 660 } 661 } 662 } 663 if (i == MAX_BRANDS) { 664 uprintf("ELF binary type not known\n"); 665 error = ENOEXEC; 666 goto fail; 667 } 668 if (interp) { 669 if (error = elf_load_file(imgp->proc, 670 path, 671 &addr, /* XXX */ 672 &imgp->entry_addr)) { 673 uprintf("ELF interpreter %s not found\n", path); 674 goto fail; 675 } 676 } 677 678 UPRINTF("Executing %s binary\n", elf_brand_list[i]->brand); 679 680 /* 681 * Construct auxargs table (used by the fixup routine) 682 */ 683 elf_auxargs = malloc(sizeof(Elf32_Auxargs), M_TEMP, M_WAITOK); 684 elf_auxargs->execfd = -1; 685 elf_auxargs->phdr = proghdr; 686 elf_auxargs->phent = hdr->e_phentsize; 687 elf_auxargs->phnum = hdr->e_phnum; 688 elf_auxargs->pagesz = PAGE_SIZE; 689 elf_auxargs->base = addr; 690 elf_auxargs->flags = 0; 691 elf_auxargs->entry = entry; 692 elf_auxargs->trace = elf_trace; 693 694 imgp->auxargs = elf_auxargs; 695 imgp->interpreted = 0; 696 697 /* don't allow modifying the file while we run it */ 698 imgp->vp->v_flag |= VTEXT; 699 700 fail: 701 if (mapped_phdr) 702 unmap_pages((vm_offset_t)mapped_phdr, header_size); 703 if (interp) 704 unmap_pages((vm_offset_t)interp, interp_len); 705 706 return error; 707 } 708 709 static int 710 elf_freebsd_fixup(int **stack_base, struct image_params *imgp) 711 { 712 Elf32_Auxargs *args = (Elf32_Auxargs *)imgp->auxargs; 713 int *pos; 714 715 pos = *stack_base + (imgp->argc + imgp->envc + 2); 716 717 if (args->trace) { 718 AUXARGS_ENTRY(pos, AT_DEBUG, 1); 719 } 720 if (args->execfd != -1) { 721 AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); 722 } 723 AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); 724 AUXARGS_ENTRY(pos, AT_PHENT, args->phent); 725 AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum); 726 AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz); 727 AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); 728 AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); 729 AUXARGS_ENTRY(pos, AT_BASE, args->base); 730 AUXARGS_ENTRY(pos, AT_NULL, 0); 731 732 free(imgp->auxargs, M_TEMP); 733 imgp->auxargs = NULL; 734 735 (*stack_base)--; 736 **stack_base = (int)imgp->argc; 737 return 0; 738 } 739 740 /* 741 * Tell kern_execve.c about it, with a little help from the linker. 742 * Since `const' objects end up in the text segment, TEXT_SET is the 743 * correct directive to use. 744 */ 745 static const struct execsw elf_execsw = {exec_elf_imgact, "ELF"}; 746 TEXT_SET(execsw_set, elf_execsw); 747 748