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.19 1997/04/13 01:48:21 dyson 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 nd.ni_vp = NULL; 343 goto fail; 344 } 345 346 /* 347 * Check permissions, modes, uid, etc on the file, and "open" it. 348 */ 349 error = elf_check_permissions(p, nd.ni_vp); 350 351 /* 352 * No longer need this, and it prevents demand paging. 353 */ 354 VOP_UNLOCK(nd.ni_vp, 0, p); 355 356 if (error) 357 goto fail; 358 359 /* 360 * Map in the header 361 */ 362 if (error = map_pages(nd.ni_vp, 0, (vm_offset_t *)&hdr, sizeof(hdr))) 363 goto fail; 364 365 /* 366 * Do we have a valid ELF header ? 367 */ 368 if (error = elf_check_header(hdr, ET_DYN)) 369 goto fail; 370 371 /* 372 * ouch, need to bounds check in case user gives us a corrupted 373 * file with an insane header size 374 */ 375 if (hdr->e_phnum > MAX_PHDR) { /* XXX: ever more than this? */ 376 error = ENOEXEC; 377 goto fail; 378 } 379 380 header_size = hdr->e_phentsize * hdr->e_phnum; 381 382 if (error = map_pages(nd.ni_vp, hdr->e_phoff, (vm_offset_t *)&phdr, 383 header_size)) 384 goto fail; 385 386 for (i = 0; i < hdr->e_phnum; i++) { 387 switch(phdr[i].p_type) { 388 389 case PT_NULL: /* NULL section */ 390 UPRINTF ("ELF(file) PT_NULL section\n"); 391 break; 392 case PT_LOAD: /* Loadable segment */ 393 { 394 UPRINTF ("ELF(file) PT_LOAD section "); 395 if (phdr[i].p_flags & PF_X) 396 prot |= VM_PROT_EXECUTE; 397 if (phdr[i].p_flags & PF_W) 398 prot |= VM_PROT_WRITE; 399 if (phdr[i].p_flags & PF_R) 400 prot |= VM_PROT_READ; 401 402 if (error = elf_load_section(vmspace, nd.ni_vp, 403 phdr[i].p_offset, 404 (caddr_t)phdr[i].p_vaddr + 405 (*addr), 406 phdr[i].p_memsz, 407 phdr[i].p_filesz, prot)) 408 goto fail; 409 410 /* 411 * Is this .text or .data ?? 412 * 413 * We only handle one each of those yet XXX 414 */ 415 if (hdr->e_entry >= phdr[i].p_vaddr && 416 hdr->e_entry <(phdr[i].p_vaddr+phdr[i].p_memsz)) { 417 text_addr = trunc_page(phdr[i].p_vaddr+(*addr)); 418 text_size = round_page(phdr[i].p_memsz + 419 phdr[i].p_vaddr - 420 trunc_page(phdr[i].p_vaddr)); 421 *entry=(unsigned long)hdr->e_entry+(*addr); 422 UPRINTF(".text <%08x,%08x> entry=%08x\n", 423 text_addr, text_size, *entry); 424 } else { 425 data_addr = trunc_page(phdr[i].p_vaddr+(*addr)); 426 data_size = round_page(phdr[i].p_memsz + 427 phdr[i].p_vaddr - 428 trunc_page(phdr[i].p_vaddr)); 429 UPRINTF(".data <%08x,%08x>\n", 430 data_addr, data_size); 431 } 432 } 433 break; 434 435 case PT_DYNAMIC:/* Dynamic link information */ 436 UPRINTF ("ELF(file) PT_DYNAMIC section\n"); 437 break; 438 case PT_INTERP: /* Path to interpreter */ 439 UPRINTF ("ELF(file) PT_INTERP section\n"); 440 break; 441 case PT_NOTE: /* Note section */ 442 UPRINTF ("ELF(file) PT_NOTE section\n"); 443 break; 444 case PT_SHLIB: /* Shared lib section */ 445 UPRINTF ("ELF(file) PT_SHLIB section\n"); 446 break; 447 case PT_PHDR: /* Program header table info */ 448 UPRINTF ("ELF(file) PT_PHDR section\n"); 449 break; 450 default: 451 UPRINTF ("ELF(file) %d section ??\n", phdr[i].p_type ); 452 } 453 } 454 455 fail: 456 if (phdr) 457 unmap_pages((vm_offset_t)phdr, header_size); 458 if (hdr) 459 unmap_pages((vm_offset_t)hdr, sizeof(hdr)); 460 if (nd.ni_vp) 461 vrele(nd.ni_vp); 462 463 return error; 464 } 465 466 int 467 exec_elf_imgact(struct image_params *imgp) 468 { 469 const Elf32_Ehdr *hdr = (const Elf32_Ehdr *) imgp->image_header; 470 const Elf32_Phdr *phdr, *mapped_phdr = NULL; 471 Elf32_Auxargs *elf_auxargs = NULL; 472 struct vmspace *vmspace; 473 vm_prot_t prot = 0; 474 u_long text_size = 0, data_size = 0; 475 u_long text_addr = 0, data_addr = 0; 476 u_long addr, entry = 0, proghdr = 0; 477 int error, i, header_size = 0, interp_len = 0; 478 char *interp = NULL; 479 char *brand = NULL; 480 char path[MAXPATHLEN]; 481 482 /* 483 * Do we have a valid ELF header ? 484 */ 485 if (elf_check_header(hdr, ET_EXEC)) 486 return -1; 487 488 /* 489 * From here on down, we return an errno, not -1, as we've 490 * detected an ELF file. 491 */ 492 493 /* 494 * ouch, need to bounds check in case user gives us a corrupted 495 * file with an insane header size 496 */ 497 if (hdr->e_phnum > MAX_PHDR) { /* XXX: ever more than this? */ 498 return ENOEXEC; 499 } 500 501 header_size = hdr->e_phentsize * hdr->e_phnum; 502 503 if ((hdr->e_phoff > PAGE_SIZE) || 504 (hdr->e_phoff + header_size) > PAGE_SIZE) { 505 /* 506 * Ouch ! we only get one page full of header... 507 * Try to map it in ourselves, and see how we go. 508 */ 509 if (error = map_pages(imgp->vp, hdr->e_phoff, 510 (vm_offset_t *)&mapped_phdr, header_size)) 511 return (error); 512 /* 513 * Save manual mapping for cleanup 514 */ 515 phdr = mapped_phdr; 516 } else { 517 phdr = (const Elf32_Phdr*) 518 ((const char *)imgp->image_header + hdr->e_phoff); 519 } 520 521 /* 522 * From this point on, we may have resources that need to be freed. 523 */ 524 if (error = exec_extract_strings(imgp)) 525 goto fail; 526 527 exec_new_vmspace(imgp); 528 529 vmspace = imgp->proc->p_vmspace; 530 531 for (i = 0; i < hdr->e_phnum; i++) { 532 switch(phdr[i].p_type) { 533 534 case PT_NULL: /* NULL section */ 535 UPRINTF ("ELF PT_NULL section\n"); 536 break; 537 case PT_LOAD: /* Loadable segment */ 538 { 539 UPRINTF ("ELF PT_LOAD section "); 540 if (phdr[i].p_flags & PF_X) 541 prot |= VM_PROT_EXECUTE; 542 if (phdr[i].p_flags & PF_W) 543 prot |= VM_PROT_WRITE; 544 if (phdr[i].p_flags & PF_R) 545 prot |= VM_PROT_READ; 546 547 if (error = elf_load_section(vmspace, imgp->vp, 548 phdr[i].p_offset, 549 (caddr_t)phdr[i].p_vaddr, 550 phdr[i].p_memsz, 551 phdr[i].p_filesz, prot)) 552 goto fail; 553 554 /* 555 * Is this .text or .data ?? 556 * 557 * We only handle one each of those yet XXX 558 */ 559 if (hdr->e_entry >= phdr[i].p_vaddr && 560 hdr->e_entry <(phdr[i].p_vaddr+phdr[i].p_memsz)) { 561 text_addr = trunc_page(phdr[i].p_vaddr); 562 text_size = round_page(phdr[i].p_memsz + 563 phdr[i].p_vaddr - 564 text_addr); 565 entry = (u_long)hdr->e_entry; 566 UPRINTF(".text <%08x,%08x> entry=%08x\n", 567 text_addr, text_size, entry); 568 } else { 569 data_addr = trunc_page(phdr[i].p_vaddr); 570 data_size = round_page(phdr[i].p_memsz + 571 phdr[i].p_vaddr - 572 data_addr); 573 UPRINTF(".data <%08x,%08x>\n", 574 data_addr, data_size); 575 } 576 } 577 break; 578 579 case PT_DYNAMIC:/* Dynamic link information */ 580 UPRINTF ("ELF PT_DYNAMIC section ??\n"); 581 break; 582 case PT_INTERP: /* Path to interpreter */ 583 UPRINTF ("ELF PT_INTERP section "); 584 if (phdr[i].p_filesz > MAXPATHLEN) { 585 error = ENOEXEC; 586 goto fail; 587 } 588 interp_len = MAXPATHLEN; 589 if (error = map_pages(imgp->vp, phdr[i].p_offset, 590 (vm_offset_t *)&interp, interp_len)) 591 goto fail; 592 UPRINTF("<%s>\n", interp); 593 break; 594 case PT_NOTE: /* Note section */ 595 UPRINTF ("ELF PT_NOTE section\n"); 596 break; 597 case PT_SHLIB: /* Shared lib section */ 598 UPRINTF ("ELF PT_SHLIB section\n"); 599 break; 600 case PT_PHDR: /* Program header table info */ 601 UPRINTF ("ELF PT_PHDR section <%x>\n", phdr[i].p_vaddr); 602 proghdr = phdr[i].p_vaddr; 603 break; 604 default: 605 UPRINTF ("ELF %d section ??\n", phdr[i].p_type); 606 } 607 } 608 609 vmspace->vm_tsize = text_size >> PAGE_SHIFT; 610 vmspace->vm_taddr = (caddr_t)text_addr; 611 vmspace->vm_dsize = data_size >> PAGE_SHIFT; 612 vmspace->vm_daddr = (caddr_t)data_addr; 613 614 addr = 2*MAXDSIZ; /* May depend on OS type XXX */ 615 616 imgp->entry_addr = entry; 617 618 /* 619 * So which kind (brand) of ELF binary do we have at hand 620 * FreeBSD, Linux, SVR4 or something else ?? 621 * If its has a interpreter section try that first 622 */ 623 if (interp) { 624 for (i=0; i<MAX_BRANDS; i++) { 625 if (elf_brand_list[i] != NULL) { 626 if (!strcmp(interp, elf_brand_list[i]->interp_path)) { 627 imgp->proc->p_sysent = 628 elf_brand_list[i]->sysvec; 629 strcpy(path, elf_brand_list[i]->emul_path); 630 strcat(path, elf_brand_list[i]->interp_path); 631 UPRINTF("interpreter=<%s> %s\n", 632 elf_brand_list[i]->interp_path, 633 elf_brand_list[i]->emul_path); 634 break; 635 } 636 } 637 } 638 } 639 640 /* 641 * If there is no interpreter, or recognition of it 642 * failed, se if the binary is branded. 643 */ 644 if (!interp || i == MAX_BRANDS) { 645 brand = (char *)&(hdr->e_ident[EI_BRAND]); 646 for (i=0; i<MAX_BRANDS; i++) { 647 if (elf_brand_list[i] != NULL) { 648 if (!strcmp(brand, elf_brand_list[i]->brand)) { 649 imgp->proc->p_sysent = elf_brand_list[i]->sysvec; 650 if (interp) { 651 strcpy(path, elf_brand_list[i]->emul_path); 652 strcat(path, elf_brand_list[i]->interp_path); 653 UPRINTF("interpreter=<%s> %s\n", 654 elf_brand_list[i]->interp_path, 655 elf_brand_list[i]->emul_path); 656 } 657 break; 658 } 659 } 660 } 661 } 662 if (i == MAX_BRANDS) { 663 uprintf("ELF binary type not known\n"); 664 error = ENOEXEC; 665 goto fail; 666 } 667 if (interp) { 668 if (error = elf_load_file(imgp->proc, 669 path, 670 &addr, /* XXX */ 671 &imgp->entry_addr)) { 672 uprintf("ELF interpreter %s not found\n", path); 673 goto fail; 674 } 675 } 676 677 UPRINTF("Executing %s binary\n", elf_brand_list[i]->brand); 678 679 /* 680 * Construct auxargs table (used by the fixup routine) 681 */ 682 elf_auxargs = malloc(sizeof(Elf32_Auxargs), M_TEMP, M_WAITOK); 683 elf_auxargs->execfd = -1; 684 elf_auxargs->phdr = proghdr; 685 elf_auxargs->phent = hdr->e_phentsize; 686 elf_auxargs->phnum = hdr->e_phnum; 687 elf_auxargs->pagesz = PAGE_SIZE; 688 elf_auxargs->base = addr; 689 elf_auxargs->flags = 0; 690 elf_auxargs->entry = entry; 691 elf_auxargs->trace = elf_trace; 692 693 imgp->auxargs = elf_auxargs; 694 imgp->interpreted = 0; 695 696 /* don't allow modifying the file while we run it */ 697 imgp->vp->v_flag |= VTEXT; 698 699 fail: 700 if (mapped_phdr) 701 unmap_pages((vm_offset_t)mapped_phdr, header_size); 702 if (interp) 703 unmap_pages((vm_offset_t)interp, interp_len); 704 705 return error; 706 } 707 708 static int 709 elf_freebsd_fixup(int **stack_base, struct image_params *imgp) 710 { 711 Elf32_Auxargs *args = (Elf32_Auxargs *)imgp->auxargs; 712 int *pos; 713 714 pos = *stack_base + (imgp->argc + imgp->envc + 2); 715 716 if (args->trace) { 717 AUXARGS_ENTRY(pos, AT_DEBUG, 1); 718 } 719 if (args->execfd != -1) { 720 AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); 721 } 722 AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); 723 AUXARGS_ENTRY(pos, AT_PHENT, args->phent); 724 AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum); 725 AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz); 726 AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); 727 AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); 728 AUXARGS_ENTRY(pos, AT_BASE, args->base); 729 AUXARGS_ENTRY(pos, AT_NULL, 0); 730 731 free(imgp->auxargs, M_TEMP); 732 imgp->auxargs = NULL; 733 734 (*stack_base)--; 735 **stack_base = (int)imgp->argc; 736 return 0; 737 } 738 739 /* 740 * Tell kern_execve.c about it, with a little help from the linker. 741 * Since `const' objects end up in the text segment, TEXT_SET is the 742 * correct directive to use. 743 */ 744 static const struct execsw elf_execsw = {exec_elf_imgact, "ELF"}; 745 TEXT_SET(execsw_set, elf_execsw); 746 747