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.11 1996/10/16 20:59:08 sos Exp $ 30 */ 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/resourcevar.h> 35 #include <sys/exec.h> 36 #include <sys/mman.h> 37 #include <sys/imgact.h> 38 #include <sys/imgact_elf.h> 39 #include <sys/kernel.h> 40 #include <sys/sysent.h> 41 #include <sys/file.h> 42 #include <sys/malloc.h> 43 #include <sys/mount.h> 44 #include <sys/namei.h> 45 #include <sys/proc.h> 46 #include <sys/sysproto.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 <vm/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 #include <i386/linux/linux_syscall.h> 63 #include <i386/linux/linux.h> 64 65 #define MAX_PHDR 32 /* XXX enough ? */ 66 67 static int map_pages __P((struct vnode *vp, vm_offset_t offset, vm_offset_t *buf, vm_size_t size)); 68 static void unmap_pages __P((vm_offset_t buf, vm_size_t size)); 69 static int elf_check_permissions __P((struct proc *p, struct vnode *vp)); 70 static int elf_check_header __P((const Elf32_Ehdr *hdr, int type)); 71 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)); 72 static int elf_load_file __P((struct proc *p, char *file, u_long *addr, u_long *entry)); 73 static int elf_freebsd_fixup __P((int **stack_base, struct image_params *imgp)); 74 int exec_elf_imgact __P((struct image_params *imgp)); 75 76 int elf_trace = 0; 77 SYSCTL_INT(_debug, 1, elf_trace, CTLFLAG_RW, &elf_trace, 0, ""); 78 #define UPRINTF if (elf_trace) uprintf 79 80 static struct sysentvec elf_freebsd_sysvec = { 81 SYS_MAXSYSCALL, 82 sysent, 83 0, 84 0, 85 0, 86 0, 87 0, 88 elf_freebsd_fixup, 89 sendsig, 90 sigcode, 91 &szsigcode, 92 0, 93 "FreeBSD ELF" 94 }; 95 96 static Elf32_Brandinfo freebsd_brand_info = { 97 "FreeBSD", 98 "", 99 "/usr/libexec/ld-elf.so.1", 100 &elf_freebsd_sysvec 101 }; 102 static Elf32_Brandinfo *elf_brand_list[MAX_BRANDS] = { 103 &freebsd_brand_info, 104 NULL, NULL, NULL, 105 NULL, NULL, NULL, NULL 106 }; 107 108 int 109 elf_insert_brand_entry(Elf32_Brandinfo *entry) 110 { 111 int i; 112 113 for (i=1; i<MAX_BRANDS; i++) { 114 if (elf_brand_list[i] == NULL) { 115 elf_brand_list[i] = entry; 116 break; 117 } 118 } 119 if (i == MAX_BRANDS) 120 return -1; 121 return 0; 122 } 123 124 int 125 elf_remove_brand_entry(Elf32_Brandinfo *entry) 126 { 127 int i; 128 129 for (i=1; i<MAX_BRANDS; i++) { 130 if (elf_brand_list[i] == entry) { 131 elf_brand_list[i] = NULL; 132 break; 133 } 134 } 135 if (i == MAX_BRANDS) 136 return -1; 137 return 0; 138 } 139 140 static int 141 map_pages(struct vnode *vp, vm_offset_t offset, 142 vm_offset_t *buf, vm_size_t size) 143 { 144 int error; 145 vm_offset_t kern_buf; 146 vm_size_t pageoff; 147 148 /* 149 * The request may not be aligned, and may even cross several 150 * page boundaries in the file... 151 */ 152 pageoff = (offset & PAGE_MASK); 153 offset -= pageoff; /* start of first aligned page to map */ 154 size += pageoff; 155 size = round_page(size); /* size of aligned pages to map */ 156 157 if (error = vm_mmap(kernel_map, 158 &kern_buf, 159 size, 160 VM_PROT_READ, 161 VM_PROT_READ, 162 0, 163 (caddr_t)vp, 164 offset)) 165 return error; 166 167 *buf = kern_buf + pageoff; 168 169 return 0; 170 } 171 172 static void 173 unmap_pages(vm_offset_t buf, vm_size_t size) 174 { 175 vm_size_t pageoff; 176 177 pageoff = (buf & PAGE_MASK); 178 buf -= pageoff; /* start of first aligned page to map */ 179 size += pageoff; 180 size = round_page(size);/* size of aligned pages to map */ 181 182 vm_map_remove(kernel_map, buf, buf + size); 183 } 184 185 static int 186 elf_check_permissions(struct proc *p, struct vnode *vp) 187 { 188 struct vattr attr; 189 int error; 190 191 /* 192 * Check number of open-for-writes on the file and deny execution 193 * if there are any. 194 */ 195 if (vp->v_writecount) { 196 return (ETXTBSY); 197 } 198 199 /* Get file attributes */ 200 error = VOP_GETATTR(vp, &attr, p->p_ucred, p); 201 if (error) 202 return (error); 203 204 /* 205 * 1) Check if file execution is disabled for the filesystem that this 206 * file resides on. 207 * 2) Insure that at least one execute bit is on - otherwise root 208 * will always succeed, and we don't want to happen unless the 209 * file really is executable. 210 * 3) Insure that the file is a regular file. 211 */ 212 if ((vp->v_mount->mnt_flag & MNT_NOEXEC) || 213 ((attr.va_mode & 0111) == 0) || 214 (attr.va_type != VREG)) { 215 return (EACCES); 216 } 217 218 /* 219 * Zero length files can't be exec'd 220 */ 221 if (attr.va_size == 0) 222 return (ENOEXEC); 223 224 /* 225 * Check for execute permission to file based on current credentials. 226 * Then call filesystem specific open routine (which does nothing 227 * in the general case). 228 */ 229 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); 230 if (error) 231 return (error); 232 233 error = VOP_OPEN(vp, FREAD, p->p_ucred, p); 234 if (error) 235 return (error); 236 237 return (0); 238 } 239 240 static int 241 elf_check_header(const Elf32_Ehdr *hdr, int type) 242 { 243 if (!(hdr->e_ident[EI_MAG0] == ELFMAG0 && 244 hdr->e_ident[EI_MAG1] == ELFMAG1 && 245 hdr->e_ident[EI_MAG2] == ELFMAG2 && 246 hdr->e_ident[EI_MAG3] == ELFMAG3)) 247 return ENOEXEC; 248 249 if (hdr->e_machine != EM_386 && hdr->e_machine != EM_486) 250 return ENOEXEC; 251 252 if (hdr->e_type != type) 253 return ENOEXEC; 254 255 return 0; 256 } 257 258 static int 259 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) 260 { 261 size_t map_len; 262 vm_offset_t map_addr; 263 int error; 264 unsigned char *data_buf = 0; 265 size_t copy_len; 266 267 map_addr = trunc_page(vmaddr); 268 269 if (memsz > filsz) 270 map_len = trunc_page(offset+filsz) - trunc_page(offset); 271 else 272 map_len = round_page(offset+filsz) - trunc_page(offset); 273 274 if (error = vm_mmap (&vmspace->vm_map, 275 &map_addr, 276 map_len, 277 prot, 278 VM_PROT_ALL, 279 MAP_PRIVATE | MAP_FIXED, 280 (caddr_t)vp, 281 trunc_page(offset))) 282 return error; 283 284 if (memsz == filsz) 285 return 0; 286 287 /* 288 * We have to map the remaining bit of the file into the kernel's 289 * memory map, allocate some anonymous memory, and copy that last 290 * bit into it. The remaining space should be .bss... 291 */ 292 copy_len = (offset + filsz) - trunc_page(offset + filsz); 293 map_addr = trunc_page(vmaddr + filsz); 294 map_len = round_page(vmaddr + memsz) - map_addr; 295 296 if (map_len != 0) { 297 if (error = vm_map_find(&vmspace->vm_map, NULL, 0, 298 &map_addr, map_len, FALSE, 299 VM_PROT_ALL, VM_PROT_ALL,0)) 300 return error; 301 } 302 303 if (error = vm_mmap(kernel_map, 304 (vm_offset_t *)&data_buf, 305 PAGE_SIZE, 306 VM_PROT_READ, 307 VM_PROT_READ, 308 0, 309 (caddr_t)vp, 310 trunc_page(offset + filsz))) 311 return error; 312 313 error = copyout(data_buf, (caddr_t)map_addr, copy_len); 314 315 vm_map_remove(kernel_map, (vm_offset_t)data_buf, 316 (vm_offset_t)data_buf + PAGE_SIZE); 317 318 /* 319 * set it to the specified protection 320 */ 321 vm_map_protect(&vmspace->vm_map, map_addr, map_addr + map_len, prot, 322 FALSE); 323 324 UPRINTF("bss size %d (%x)\n", map_len-copy_len, map_len-copy_len); 325 return error; 326 } 327 328 static int 329 elf_load_file(struct proc *p, char *file, u_long *addr, u_long *entry) 330 { 331 Elf32_Ehdr *hdr = NULL; 332 Elf32_Phdr *phdr = NULL; 333 struct nameidata nd; 334 struct vmspace *vmspace = p->p_vmspace; 335 vm_prot_t prot = 0; 336 unsigned long text_size = 0, data_size = 0; 337 unsigned long text_addr = 0, data_addr = 0; 338 int header_size = 0; 339 int error, i; 340 341 NDINIT(&nd, LOOKUP, LOCKLEAF|FOLLOW, UIO_SYSSPACE, file, p); 342 343 if (error = namei(&nd)) 344 goto fail; 345 346 if (nd.ni_vp == NULL) { 347 error = ENOEXEC; 348 goto fail; 349 } 350 351 /* 352 * Check permissions, modes, uid, etc on the file, and "open" it. 353 */ 354 error = elf_check_permissions(p, nd.ni_vp); 355 356 /* 357 * No longer need this, and it prevents demand paging. 358 */ 359 VOP_UNLOCK(nd.ni_vp); 360 361 if (error) 362 goto fail; 363 364 /* 365 * Map in the header 366 */ 367 if (error = map_pages(nd.ni_vp, 0, (vm_offset_t *)&hdr, sizeof(hdr))) 368 goto fail; 369 370 /* 371 * Do we have a valid ELF header ? 372 */ 373 if (error = elf_check_header(hdr, ET_DYN)) 374 goto fail; 375 376 /* 377 * ouch, need to bounds check in case user gives us a corrupted 378 * file with an insane header size 379 */ 380 if (hdr->e_phnum > MAX_PHDR) { /* XXX: ever more than this? */ 381 error = ENOEXEC; 382 goto fail; 383 } 384 385 header_size = hdr->e_phentsize * hdr->e_phnum; 386 387 if (error = map_pages(nd.ni_vp, hdr->e_phoff, (vm_offset_t *)&phdr, 388 header_size)) 389 goto fail; 390 391 for (i = 0; i < hdr->e_phnum; i++) { 392 switch(phdr[i].p_type) { 393 394 case PT_NULL: /* NULL section */ 395 UPRINTF ("ELF(file) PT_NULL section\n"); 396 break; 397 case PT_LOAD: /* Loadable segment */ 398 { 399 UPRINTF ("ELF(file) PT_LOAD section "); 400 if (phdr[i].p_flags & PF_X) 401 prot |= VM_PROT_EXECUTE; 402 if (phdr[i].p_flags & PF_W) 403 prot |= VM_PROT_WRITE; 404 if (phdr[i].p_flags & PF_R) 405 prot |= VM_PROT_READ; 406 407 if (error = elf_load_section(vmspace, nd.ni_vp, 408 phdr[i].p_offset, 409 (caddr_t)phdr[i].p_vaddr + 410 (*addr), 411 phdr[i].p_memsz, 412 phdr[i].p_filesz, prot)) 413 goto fail; 414 415 /* 416 * Is this .text or .data ?? 417 * 418 * We only handle one each of those yet XXX 419 */ 420 if (hdr->e_entry >= phdr[i].p_vaddr && 421 hdr->e_entry <(phdr[i].p_vaddr+phdr[i].p_memsz)) { 422 text_addr = trunc_page(phdr[i].p_vaddr+(*addr)); 423 text_size = round_page(phdr[i].p_memsz + 424 phdr[i].p_vaddr - 425 trunc_page(phdr[i].p_vaddr)); 426 *entry=(unsigned long)hdr->e_entry+(*addr); 427 UPRINTF(".text <%08x,%08x> entry=%08x\n", 428 text_addr, text_size, *entry); 429 } else { 430 data_addr = trunc_page(phdr[i].p_vaddr+(*addr)); 431 data_size = round_page(phdr[i].p_memsz + 432 phdr[i].p_vaddr - 433 trunc_page(phdr[i].p_vaddr)); 434 UPRINTF(".data <%08x,%08x>\n", 435 data_addr, data_size); 436 } 437 } 438 break; 439 440 case PT_DYNAMIC:/* Dynamic link information */ 441 UPRINTF ("ELF(file) PT_DYNAMIC section\n"); 442 break; 443 case PT_INTERP: /* Path to interpreter */ 444 UPRINTF ("ELF(file) PT_INTERP section\n"); 445 break; 446 case PT_NOTE: /* Note section */ 447 UPRINTF ("ELF(file) PT_NOTE section\n"); 448 break; 449 case PT_SHLIB: /* Shared lib section */ 450 UPRINTF ("ELF(file) PT_SHLIB section\n"); 451 break; 452 case PT_PHDR: /* Program header table info */ 453 UPRINTF ("ELF(file) PT_PHDR section\n"); 454 break; 455 default: 456 UPRINTF ("ELF(file) %d section ??\n", phdr[i].p_type ); 457 } 458 } 459 460 fail: 461 if (phdr) 462 unmap_pages((vm_offset_t)phdr, header_size); 463 if (hdr) 464 unmap_pages((vm_offset_t)hdr, sizeof(hdr)); 465 466 return error; 467 } 468 469 int 470 exec_elf_imgact(struct image_params *imgp) 471 { 472 const Elf32_Ehdr *hdr = (const Elf32_Ehdr *) imgp->image_header; 473 const Elf32_Phdr *phdr, *mapped_phdr = NULL; 474 Elf32_Auxargs *elf_auxargs = NULL; 475 struct vmspace *vmspace = imgp->proc->p_vmspace; 476 vm_prot_t prot = 0; 477 u_long text_size = 0, data_size = 0; 478 u_long text_addr = 0, data_addr = 0; 479 u_long addr, entry = 0, proghdr = 0; 480 int error, i, header_size = 0, interp_len = 0; 481 char *interp = NULL; 482 char *brand = NULL; 483 char path[MAXPATHLEN]; 484 485 /* 486 * Do we have a valid ELF header ? 487 */ 488 if (elf_check_header(hdr, ET_EXEC)) 489 return -1; 490 491 /* 492 * From here on down, we return an errno, not -1, as we've 493 * detected an ELF file. 494 */ 495 496 /* 497 * ouch, need to bounds check in case user gives us a corrupted 498 * file with an insane header size 499 */ 500 if (hdr->e_phnum > MAX_PHDR) { /* XXX: ever more than this? */ 501 return ENOEXEC; 502 } 503 504 header_size = hdr->e_phentsize * hdr->e_phnum; 505 506 if ((hdr->e_phoff > PAGE_SIZE) || 507 (hdr->e_phoff + header_size) > PAGE_SIZE) { 508 /* 509 * Ouch ! we only get one page full of header... 510 * Try to map it in ourselves, and see how we go. 511 */ 512 if (error = map_pages(imgp->vp, hdr->e_phoff, 513 (vm_offset_t *)&mapped_phdr, header_size)) 514 return (error); 515 /* 516 * Save manual mapping for cleanup 517 */ 518 phdr = mapped_phdr; 519 } else { 520 phdr = (const Elf32_Phdr*) 521 ((const char *)imgp->image_header + hdr->e_phoff); 522 } 523 524 /* 525 * From this point on, we may have resources that need to be freed. 526 */ 527 if (error = exec_extract_strings(imgp)) 528 goto fail; 529 530 exec_new_vmspace(imgp); 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 const struct execsw elf_execsw = {exec_elf_imgact, "ELF"}; 746 TEXT_SET(execsw_set, elf_execsw); 747 748