imgact_elf.c revision 18959
159093Sdfr/*- 2121129Sdfr * Copyright (c) 1995-1996 S�ren Schmidt 359093Sdfr * Copyright (c) 1996 Peter Wemm 459093Sdfr * All rights reserved. 559093Sdfr * 659093Sdfr * Redistribution and use in source and binary forms, with or without 759093Sdfr * modification, are permitted provided that the following conditions 859093Sdfr * are met: 959093Sdfr * 1. Redistributions of source code must retain the above copyright 1059093Sdfr * notice, this list of conditions and the following disclaimer 1159093Sdfr * in this position and unchanged. 1259093Sdfr * 2. Redistributions in binary form must reproduce the above copyright 1359093Sdfr * notice, this list of conditions and the following disclaimer in the 1459093Sdfr * documentation and/or other materials provided with the distribution. 1559093Sdfr * 3. The name of the author may not be used to endorse or promote products 1659093Sdfr * derived from this software withough specific prior written permission 1759093Sdfr * 1859093Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1959093Sdfr * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2059093Sdfr * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2159093Sdfr * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2259093Sdfr * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2359093Sdfr * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2459093Sdfr * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2559093Sdfr * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2659093Sdfr * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27116182Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28116182Sobrien * 29116182Sobrien * $Id: imgact_elf.c,v 1.9 1996/10/03 06:14:48 peter Exp $ 3059093Sdfr */ 31121129Sdfr 32121129Sdfr#include <sys/param.h> 33121129Sdfr#include <sys/systm.h> 3459093Sdfr#include <sys/resourcevar.h> 35121129Sdfr#include <sys/exec.h> 36118921Scg#include <sys/mman.h> 3759093Sdfr#include <sys/imgact.h> 3859093Sdfr#include <sys/imgact_elf.h> 3959093Sdfr#include <sys/kernel.h> 4059093Sdfr#include <sys/sysent.h> 4159093Sdfr#include <sys/file.h> 4259093Sdfr#include <sys/malloc.h> 4359093Sdfr#include <sys/mount.h> 4459093Sdfr#include <sys/namei.h> 4559093Sdfr#include <sys/proc.h> 4659093Sdfr#include <sys/sysproto.h> 4759093Sdfr#include <sys/syscall.h> 4859093Sdfr#include <sys/signalvar.h> 4998105Skbyanc#include <sys/sysctl.h> 5098105Skbyanc#include <sys/vnode.h> 5159093Sdfr 5298105Skbyanc#include <vm/vm.h> 53118921Scg#include <vm/vm_kern.h> 5498105Skbyanc#include <vm/vm_param.h> 55118921Scg#include <vm/pmap.h> 5659093Sdfr#include <vm/lock.h> 5759093Sdfr#include <vm/vm_map.h> 5859093Sdfr#include <vm/vm_prot.h> 59121129Sdfr#include <vm/vm_extern.h> 60148811Sgrehan 6159093Sdfr#include <machine/md_var.h> 6259093Sdfr#include <i386/linux/linux_syscall.h> 63186347Snwhitehorn#include <i386/linux/linux.h> 64186347Snwhitehorn 65186347Snwhitehorn#define MAX_PHDR 32 /* XXX enough ? */ 66186347Snwhitehorn 67186347Snwhitehornstatic int map_pages __P((struct vnode *vp, vm_offset_t offset, vm_offset_t *buf, vm_size_t size)); 68186347Snwhitehornstatic void unmap_pages __P((vm_offset_t buf, vm_size_t size)); 69186347Snwhitehornstatic int elf_check_permissions __P((struct proc *p, struct vnode *vp)); 70186347Snwhitehornstatic int elf_check_header __P((const Elf32_Ehdr *hdr, int type)); 71186347Snwhitehornstatic 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)); 72186347Snwhitehornstatic int elf_load_file __P((struct proc *p, char *file, u_long *addr, u_long *entry)); 73186347Snwhitehornstatic int elf_freebsd_fixup __P((int **stack_base, struct image_params *imgp)); 74186347Snwhitehornint exec_elf_imgact __P((struct image_params *imgp)); 75186347Snwhitehorn 76217326Smdfint elf_trace = 0; 77118921ScgSYSCTL_INT(_debug, 1, elf_trace, CTLFLAG_RW, &elf_trace, 0, ""); 78118921Scg#define UPRINTF if (elf_trace) uprintf 79121129Sdfr 80121129Sdfrstatic struct sysentvec elf_freebsd_sysvec = { 81121129Sdfr SYS_MAXSYSCALL, 82148811Sgrehan sysent, 83148811Sgrehan 0, 84148811Sgrehan 0, 85148811Sgrehan 0, 86121129Sdfr 0, 87121129Sdfr 0, 88121129Sdfr elf_freebsd_fixup, 89121129Sdfr sendsig, 90121129Sdfr sigcode, 91121129Sdfr &szsigcode, 92121129Sdfr 0, 93121129Sdfr "FreeBSD ELF" 94121129Sdfr}; 95121129Sdfr 96121129Sdfrstatic Elf32_Brandinfo freebsd_brand_info = { 97121129Sdfr "FreeBSD", 98121129Sdfr "", 99121129Sdfr "/usr/libexec/ld-elf.so.1", 10059093Sdfr &elf_freebsd_sysvec 10159093Sdfr }; 102121129Sdfrstatic Elf32_Brandinfo *elf_brand_list[MAX_BRANDS] = { 10359093Sdfr &freebsd_brand_info, 10459093Sdfr NULL, NULL, NULL, 10559093Sdfr NULL, NULL, NULL, NULL 10659093Sdfr }; 10759093Sdfr 10859093Sdfrint 109186347Snwhitehornelf_insert_brand_entry(Elf32_Brandinfo *entry) 110121129Sdfr{ 111118921Scg int i; 11259093Sdfr 113118921Scg for (i=1; i<MAX_BRANDS; i++) { 11459093Sdfr if (elf_brand_list[i] == NULL) { 11559093Sdfr elf_brand_list[i] = entry; 11659093Sdfr break; 11759093Sdfr } 11859093Sdfr } 11959093Sdfr if (i == MAX_BRANDS) 12059093Sdfr return -1; 12165173Sdfr return 0; 12265173Sdfr} 12359093Sdfr 12459093Sdfrint 12559093Sdfrelf_remove_brand_entry(Elf32_Brandinfo *entry) 12659093Sdfr{ 127186347Snwhitehorn int i; 128121129Sdfr 12959093Sdfr for (i=1; i<MAX_BRANDS; i++) { 13059093Sdfr if (elf_brand_list[i] == entry) { 13159093Sdfr elf_brand_list[i] = NULL; 13259093Sdfr break; 13359093Sdfr } 13459093Sdfr } 13559093Sdfr if (i == MAX_BRANDS) 13659093Sdfr return -1; 13759093Sdfr return 0; 13859093Sdfr} 13959093Sdfr 14059093Sdfrstatic int 14159093Sdfrmap_pages(struct vnode *vp, vm_offset_t offset, 14265173Sdfr vm_offset_t *buf, vm_size_t size) 14359093Sdfr{ 144121129Sdfr int error; 145121129Sdfr vm_offset_t kern_buf; 14659093Sdfr vm_size_t pageoff; 14759093Sdfr 14859093Sdfr /* 14959093Sdfr * The request may not be aligned, and may even cross several 15059093Sdfr * page boundaries in the file... 15165173Sdfr */ 15265173Sdfr pageoff = (offset & PAGE_MASK); 15365173Sdfr offset -= pageoff; /* start of first aligned page to map */ 15465173Sdfr size += pageoff; 155186347Snwhitehorn size = round_page(size); /* size of aligned pages to map */ 156121129Sdfr 15765173Sdfr if (error = vm_mmap(kernel_map, 15865173Sdfr &kern_buf, 15965173Sdfr size, 16065173Sdfr VM_PROT_READ, 16165173Sdfr VM_PROT_READ, 16265173Sdfr 0, 163121129Sdfr (caddr_t)vp, 164186347Snwhitehorn offset)) 165121129Sdfr return error; 166121129Sdfr 167121129Sdfr *buf = kern_buf + pageoff; 168121129Sdfr 169121129Sdfr return 0; 170121129Sdfr} 171121129Sdfr 172186347Snwhitehornstatic void 173121129Sdfrunmap_pages(vm_offset_t buf, vm_size_t size) 174121129Sdfr{ 175121129Sdfr vm_size_t pageoff; 176121129Sdfr 17765173Sdfr pageoff = (buf & PAGE_MASK); 178186347Snwhitehorn buf -= pageoff; /* start of first aligned page to map */ 17965173Sdfr size += pageoff; 18065173Sdfr size = round_page(size);/* size of aligned pages to map */ 18165173Sdfr 18265173Sdfr vm_map_remove(kernel_map, buf, buf + size); 18365173Sdfr} 184121129Sdfr 185186347Snwhitehornstatic int 186121129Sdfrelf_check_permissions(struct proc *p, struct vnode *vp) 18765173Sdfr{ 18865173Sdfr struct vattr attr; 18965173Sdfr int error; 190186347Snwhitehorn 191186347Snwhitehorn /* 19265173Sdfr * Check number of open-for-writes on the file and deny execution 19365173Sdfr * if there are any. 194186347Snwhitehorn */ 195186347Snwhitehorn if (vp->v_writecount) { 19665173Sdfr return (ETXTBSY); 19765173Sdfr } 198121129Sdfr 199121129Sdfr /* Get file attributes */ 20059093Sdfr error = VOP_GETATTR(vp, &attr, p->p_ucred, p); 201121129Sdfr if (error) 202121129Sdfr return (error); 203121129Sdfr 204121129Sdfr /* 205121129Sdfr * 1) Check if file execution is disabled for the filesystem that this 206121129Sdfr * file resides on. 20759093Sdfr * 2) Insure that at least one execute bit is on - otherwise root 20859093Sdfr * will always succeed, and we don't want to happen unless the 209121129Sdfr * file really is executable. 210188063Simp * 3) Insure that the file is a regular file. 21159093Sdfr */ 21259093Sdfr if ((vp->v_mount->mnt_flag & MNT_NOEXEC) || 213121129Sdfr ((attr.va_mode & 0111) == 0) || 214121129Sdfr (attr.va_type != VREG)) { 215121129Sdfr return (EACCES); 216121129Sdfr } 217121129Sdfr 218121129Sdfr /* 219121129Sdfr * Zero length files can't be exec'd 220121129Sdfr */ 221121129Sdfr if (attr.va_size == 0) 222121129Sdfr return (ENOEXEC); 223121129Sdfr 224121129Sdfr /* 225121129Sdfr * Check for execute permission to file based on current credentials. 226121129Sdfr * Then call filesystem specific open routine (which does nothing 227121129Sdfr * in the general case). 228121129Sdfr */ 229121129Sdfr error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); 230121129Sdfr if (error) 231121129Sdfr return (error); 232121129Sdfr 233188063Simp error = VOP_OPEN(vp, FREAD, p->p_ucred, p); 234121129Sdfr if (error) 235121129Sdfr return (error); 236121129Sdfr 237121129Sdfr return (0); 238121129Sdfr} 239121129Sdfr 240121129Sdfrstatic int 241121129Sdfrelf_check_header(const Elf32_Ehdr *hdr, int type) 242121129Sdfr{ 243121129Sdfr if (!(hdr->e_ident[EI_MAG0] == ELFMAG0 && 244121129Sdfr hdr->e_ident[EI_MAG1] == ELFMAG1 && 245121129Sdfr hdr->e_ident[EI_MAG2] == ELFMAG2 && 246121129Sdfr hdr->e_ident[EI_MAG3] == ELFMAG3)) 247121129Sdfr return ENOEXEC; 248121129Sdfr 249153844Sjhb if (hdr->e_machine != EM_386 && hdr->e_machine != EM_486) 250121129Sdfr return ENOEXEC; 251121129Sdfr 252121129Sdfr if (hdr->e_type != type) 253121129Sdfr return ENOEXEC; 254121129Sdfr 255121129Sdfr return 0; 256121129Sdfr} 257121129Sdfr 258121129Sdfrstatic int 25959093Sdfrelf_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) 26059093Sdfr{ 26159093Sdfr size_t map_len; 26259093Sdfr vm_offset_t map_addr; 26359093Sdfr int error; 264188063Simp unsigned char *data_buf = 0; 26559093Sdfr size_t copy_len; 266186347Snwhitehorn 267186347Snwhitehorn map_addr = trunc_page(vmaddr); 268121129Sdfr 26959093Sdfr if (memsz > filsz) 270121129Sdfr map_len = trunc_page(offset+filsz) - trunc_page(offset); 271121129Sdfr else 27259093Sdfr map_len = round_page(offset+filsz) - trunc_page(offset); 273121129Sdfr 274121129Sdfr if (error = vm_mmap (&vmspace->vm_map, 275121129Sdfr &map_addr, 276121129Sdfr map_len, 277121129Sdfr prot, 278121129Sdfr VM_PROT_ALL, 27959093Sdfr MAP_PRIVATE | MAP_FIXED, 280121129Sdfr (caddr_t)vp, 281121129Sdfr trunc_page(offset))) 282121129Sdfr return error; 283121129Sdfr 284188063Simp if (memsz == filsz) 285121129Sdfr return 0; 286121129Sdfr 287186347Snwhitehorn /* 288121129Sdfr * We have to map the remaining bit of the file into the kernel's 289121129Sdfr * memory map, allocate some anonymous memory, and copy that last 290121129Sdfr * bit into it. The remaining space should be .bss... 29159093Sdfr */ 29259093Sdfr copy_len = (offset + filsz) - trunc_page(offset + filsz); 29359093Sdfr map_addr = trunc_page(vmaddr + filsz); 29459093Sdfr map_len = round_page(vmaddr + memsz) - map_addr; 29559093Sdfr 29659093Sdfr if (map_len != 0) { 29759093Sdfr if (error = vm_map_find(&vmspace->vm_map, NULL, 0, 29859093Sdfr &map_addr, map_len, FALSE, 29959093Sdfr VM_PROT_ALL, VM_PROT_ALL,0)) 30059093Sdfr return error; 30159093Sdfr } 30259093Sdfr 30369781Sdwmalone if (error = vm_mmap(kernel_map, 30459093Sdfr (vm_offset_t *)&data_buf, 305188063Simp PAGE_SIZE, 30659093Sdfr VM_PROT_READ, 30759093Sdfr VM_PROT_READ, 30859093Sdfr 0, 30959093Sdfr (caddr_t)vp, 31059093Sdfr trunc_page(offset + filsz))) 31159093Sdfr return error; 31259093Sdfr 31359093Sdfr error = copyout(data_buf, (caddr_t)map_addr, copy_len); 314186347Snwhitehorn 315121129Sdfr vm_map_remove(kernel_map, (vm_offset_t)data_buf, 316186347Snwhitehorn (vm_offset_t)data_buf + PAGE_SIZE); 317121129Sdfr 31859093Sdfr /* 31959093Sdfr * set it to the specified protection 32059093Sdfr */ 321121129Sdfr vm_map_protect(&vmspace->vm_map, map_addr, map_addr + map_len, prot, 322121129Sdfr FALSE); 323121129Sdfr 324121129Sdfr UPRINTF("bss size %d (%x)\n", map_len-copy_len, map_len-copy_len); 325121129Sdfr return error; 326121129Sdfr} 327186347Snwhitehorn 32859093Sdfrstatic int 329121129Sdfrelf_load_file(struct proc *p, char *file, u_long *addr, u_long *entry) 330121129Sdfr{ 33159093Sdfr Elf32_Ehdr *hdr = NULL; 33259093Sdfr Elf32_Phdr *phdr = NULL; 33359820Sdfr struct nameidata nd; 334121129Sdfr struct vmspace *vmspace = p->p_vmspace; 335186347Snwhitehorn vm_prot_t prot = 0; 33659093Sdfr unsigned long text_size = 0, data_size = 0; 33759093Sdfr unsigned long text_addr = 0, data_addr = 0; 33859093Sdfr int header_size = 0; 33959093Sdfr int error, i; 34059093Sdfr 34159093Sdfr NDINIT(&nd, LOOKUP, LOCKLEAF|FOLLOW, UIO_SYSSPACE, file, p); 342121129Sdfr 34359093Sdfr if (error = namei(&nd)) 34459093Sdfr goto fail; 34559093Sdfr 34659093Sdfr if (nd.ni_vp == NULL) { 34759093Sdfr error = ENOEXEC; 34859093Sdfr goto fail; 349186347Snwhitehorn } 350186347Snwhitehorn 35159820Sdfr /* 352121129Sdfr * Check permissions, modes, uid, etc on the file, and "open" it. 353186347Snwhitehorn */ 354121129Sdfr error = elf_check_permissions(p, nd.ni_vp); 355121129Sdfr 35659093Sdfr /* 35759093Sdfr * No longer need this, and it prevents demand paging. 358188063Simp */ 35959093Sdfr VOP_UNLOCK(nd.ni_vp); 36059093Sdfr 36159093Sdfr 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 460fail: 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 469int 470exec_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 } 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 699fail: 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 708static int 709elf_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 */ 744const struct execsw elf_execsw = {exec_elf_imgact, "ELF"}; 745TEXT_SET(execsw_set, elf_execsw); 746 747