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.17 1997/03/23 03:36:16 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 = imgp->proc->p_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 for (i = 0; i < hdr->e_phnum; i++) { 531 switch(phdr[i].p_type) { 532 533 case PT_NULL: /* NULL section */ 534 UPRINTF ("ELF PT_NULL section\n"); 535 break; 536 case PT_LOAD: /* Loadable segment */ 537 { 538 UPRINTF ("ELF PT_LOAD section "); 539 if (phdr[i].p_flags & PF_X) 540 prot |= VM_PROT_EXECUTE; 541 if (phdr[i].p_flags & PF_W) 542 prot |= VM_PROT_WRITE; 543 if (phdr[i].p_flags & PF_R) 544 prot |= VM_PROT_READ; 545 546 if (error = elf_load_section(vmspace, imgp->vp, 547 phdr[i].p_offset, 548 (caddr_t)phdr[i].p_vaddr, 549 phdr[i].p_memsz, 550 phdr[i].p_filesz, prot)) 551 goto fail; 552 553 /* 554 * Is this .text or .data ?? 555 * 556 * We only handle one each of those yet XXX 557 */ 558 if (hdr->e_entry >= phdr[i].p_vaddr && 559 hdr->e_entry <(phdr[i].p_vaddr+phdr[i].p_memsz)) { 560 text_addr = trunc_page(phdr[i].p_vaddr); 561 text_size = round_page(phdr[i].p_memsz + 562 phdr[i].p_vaddr - 563 text_addr); 564 entry = (u_long)hdr->e_entry; 565 UPRINTF(".text <%08x,%08x> entry=%08x\n", 566 text_addr, text_size, entry); 567 } else { 568 data_addr = trunc_page(phdr[i].p_vaddr); 569 data_size = round_page(phdr[i].p_memsz + 570 phdr[i].p_vaddr - 571 data_addr); 572 UPRINTF(".data <%08x,%08x>\n", 573 data_addr, data_size); 574 } 575 } 576 break; 577 578 case PT_DYNAMIC:/* Dynamic link information */ 579 UPRINTF ("ELF PT_DYNAMIC section ??\n"); 580 break; 581 case PT_INTERP: /* Path to interpreter */ 582 UPRINTF ("ELF PT_INTERP section "); 583 if (phdr[i].p_filesz > MAXPATHLEN) { 584 error = ENOEXEC; 585 goto fail; 586 } 587 interp_len = MAXPATHLEN; 588 if (error = map_pages(imgp->vp, phdr[i].p_offset, 589 (vm_offset_t *)&interp, interp_len)) 590 goto fail; 591 UPRINTF("<%s>\n", interp); 592 break; 593 case PT_NOTE: /* Note section */ 594 UPRINTF ("ELF PT_NOTE section\n"); 595 break; 596 case PT_SHLIB: /* Shared lib section */ 597 UPRINTF ("ELF PT_SHLIB section\n"); 598 break; 599 case PT_PHDR: /* Program header table info */ 600 UPRINTF ("ELF PT_PHDR section <%x>\n", phdr[i].p_vaddr); 601 proghdr = phdr[i].p_vaddr; 602 break; 603 default: 604 UPRINTF ("ELF %d section ??\n", phdr[i].p_type); 605 } 606 } 607 608 vmspace->vm_tsize = text_size >> PAGE_SHIFT; 609 vmspace->vm_taddr = (caddr_t)text_addr; 610 vmspace->vm_dsize = data_size >> PAGE_SHIFT; 611 vmspace->vm_daddr = (caddr_t)data_addr; 612 613 addr = 2*MAXDSIZ; /* May depend on OS type XXX */ 614 615 imgp->entry_addr = entry; 616 617 /* 618 * So which kind (brand) of ELF binary do we have at hand 619 * FreeBSD, Linux, SVR4 or something else ?? 620 * If its has a interpreter section try that first 621 */ 622 if (interp) { 623 for (i=0; i<MAX_BRANDS; i++) { 624 if (elf_brand_list[i] != NULL) { 625 if (!strcmp(interp, elf_brand_list[i]->interp_path)) { 626 imgp->proc->p_sysent = 627 elf_brand_list[i]->sysvec; 628 strcpy(path, elf_brand_list[i]->emul_path); 629 strcat(path, elf_brand_list[i]->interp_path); 630 UPRINTF("interpreter=<%s> %s\n", 631 elf_brand_list[i]->interp_path, 632 elf_brand_list[i]->emul_path); 633 break; 634 } 635 } 636 } 637 } 638 639 /* 640 * If there is no interpreter, or recognition of it 641 * failed, se if the binary is branded. 642 */ 643 if (!interp || i == MAX_BRANDS) { 644 brand = (char *)&(hdr->e_ident[EI_BRAND]); 645 for (i=0; i<MAX_BRANDS; i++) { 646 if (elf_brand_list[i] != NULL) { 647 if (!strcmp(brand, elf_brand_list[i]->brand)) { 648 imgp->proc->p_sysent = elf_brand_list[i]->sysvec; 649 if (interp) { 650 strcpy(path, elf_brand_list[i]->emul_path); 651 strcat(path, elf_brand_list[i]->interp_path); 652 UPRINTF("interpreter=<%s> %s\n", 653 elf_brand_list[i]->interp_path, 654 elf_brand_list[i]->emul_path); 655 } 656 break; 657 } 658 } 659 } 660 } 661 if (i == MAX_BRANDS) { 662 uprintf("ELF binary type not known\n"); 663 error = ENOEXEC; 664 goto fail; 665 } 666 if (interp) { 667 if (error = elf_load_file(imgp->proc, 668 path, 669 &addr, /* XXX */ 670 &imgp->entry_addr)) { 671 uprintf("ELF interpreter %s not found\n", path); 672 goto fail; 673 } 674 } 675 676 UPRINTF("Executing %s binary\n", elf_brand_list[i]->brand); 677 678 /* 679 * Construct auxargs table (used by the fixup routine) 680 */ 681 elf_auxargs = malloc(sizeof(Elf32_Auxargs), M_TEMP, M_WAITOK); 682 elf_auxargs->execfd = -1; 683 elf_auxargs->phdr = proghdr; 684 elf_auxargs->phent = hdr->e_phentsize; 685 elf_auxargs->phnum = hdr->e_phnum; 686 elf_auxargs->pagesz = PAGE_SIZE; 687 elf_auxargs->base = addr; 688 elf_auxargs->flags = 0; 689 elf_auxargs->entry = entry; 690 elf_auxargs->trace = elf_trace; 691 692 imgp->auxargs = elf_auxargs; 693 imgp->interpreted = 0; 694 695 /* don't allow modifying the file while we run it */ 696 imgp->vp->v_flag |= VTEXT; 697 698 fail: 699 if (mapped_phdr) 700 unmap_pages((vm_offset_t)mapped_phdr, header_size); 701 if (interp) 702 unmap_pages((vm_offset_t)interp, interp_len); 703 704 return error; 705 } 706 707 static int 708 elf_freebsd_fixup(int **stack_base, struct image_params *imgp) 709 { 710 Elf32_Auxargs *args = (Elf32_Auxargs *)imgp->auxargs; 711 int *pos; 712 713 pos = *stack_base + (imgp->argc + imgp->envc + 2); 714 715 if (args->trace) { 716 AUXARGS_ENTRY(pos, AT_DEBUG, 1); 717 } 718 if (args->execfd != -1) { 719 AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); 720 } 721 AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); 722 AUXARGS_ENTRY(pos, AT_PHENT, args->phent); 723 AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum); 724 AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz); 725 AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); 726 AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); 727 AUXARGS_ENTRY(pos, AT_BASE, args->base); 728 AUXARGS_ENTRY(pos, AT_NULL, 0); 729 730 free(imgp->auxargs, M_TEMP); 731 imgp->auxargs = NULL; 732 733 (*stack_base)--; 734 **stack_base = (int)imgp->argc; 735 return 0; 736 } 737 738 /* 739 * Tell kern_execve.c about it, with a little help from the linker. 740 * Since `const' objects end up in the text segment, TEXT_SET is the 741 * correct directive to use. 742 */ 743 static const struct execsw elf_execsw = {exec_elf_imgact, "ELF"}; 744 TEXT_SET(execsw_set, elf_execsw); 745 746