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