imgact_elf.c (77ac690c97ab18c1c4882a42ebeff370dbcac072) | imgact_elf.c (c815a20cb23f53317c4d23d1884cd5e486dee876) |
---|---|
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: --- 51 unchanged lines hidden (view full) --- 60#include <vm/vm_map.h> 61#include <vm/vm_object.h> 62#include <vm/vm_extern.h> 63#include <vm/vm_zone.h> 64 65#include <machine/elf.h> 66#include <machine/md_var.h> 67 | 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: --- 51 unchanged lines hidden (view full) --- 60#include <vm/vm_map.h> 61#include <vm/vm_object.h> 62#include <vm/vm_extern.h> 63#include <vm/vm_zone.h> 64 65#include <machine/elf.h> 66#include <machine/md_var.h> 67 |
68#define OLD_EI_BRAND 8 69 |
|
68__ElfType(Brandinfo); 69__ElfType(Auxargs); 70 71static int elf_check_header __P((const Elf_Ehdr *hdr)); 72static int elf_freebsd_fixup __P((register_t **stack_base, 73 struct image_params *imgp)); 74static int elf_load_file __P((struct proc *p, const char *file, u_long *addr, 75 u_long *entry)); 76static int elf_load_section __P((struct proc *p, 77 struct vmspace *vmspace, struct vnode *vp, 78 vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, 79 vm_prot_t prot)); 80static int exec_elf_imgact __P((struct image_params *imgp)); 81 82static int elf_trace = 0; 83SYSCTL_INT(_debug, OID_AUTO, elf_trace, CTLFLAG_RW, &elf_trace, 0, ""); 84 | 70__ElfType(Brandinfo); 71__ElfType(Auxargs); 72 73static int elf_check_header __P((const Elf_Ehdr *hdr)); 74static int elf_freebsd_fixup __P((register_t **stack_base, 75 struct image_params *imgp)); 76static int elf_load_file __P((struct proc *p, const char *file, u_long *addr, 77 u_long *entry)); 78static int elf_load_section __P((struct proc *p, 79 struct vmspace *vmspace, struct vnode *vp, 80 vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, 81 vm_prot_t prot)); 82static int exec_elf_imgact __P((struct image_params *imgp)); 83 84static int elf_trace = 0; 85SYSCTL_INT(_debug, OID_AUTO, elf_trace, CTLFLAG_RW, &elf_trace, 0, ""); 86 |
85/* 86 * XXX Maximum length of an ELF brand (sysctl wants a statically-allocated 87 * buffer). 88 */ 89#define MAXBRANDLEN 16 90 | |
91static struct sysentvec elf_freebsd_sysvec = { 92 SYS_MAXSYSCALL, 93 sysent, 94 0, 95 0, 96 0, 97 0, 98 0, 99 0, 100 elf_freebsd_fixup, 101 sendsig, 102 sigcode, 103 &szsigcode, 104 0, 105 "FreeBSD ELF", 106 elf_coredump 107}; 108 109static Elf_Brandinfo freebsd_brand_info = { | 87static struct sysentvec elf_freebsd_sysvec = { 88 SYS_MAXSYSCALL, 89 sysent, 90 0, 91 0, 92 0, 93 0, 94 0, 95 0, 96 elf_freebsd_fixup, 97 sendsig, 98 sigcode, 99 &szsigcode, 100 0, 101 "FreeBSD ELF", 102 elf_coredump 103}; 104 105static Elf_Brandinfo freebsd_brand_info = { |
110 "FreeBSD", | 106 ELFOSABI_FREEBSD, |
111 "", 112 "/usr/libexec/ld-elf.so.1", 113 &elf_freebsd_sysvec 114 }; 115static Elf_Brandinfo *elf_brand_list[MAX_BRANDS] = { 116 &freebsd_brand_info, 117 NULL, NULL, NULL, 118 NULL, NULL, NULL, NULL --- 288 unchanged lines hidden (view full) --- 407 kmem_free_wakeup(exec_map, (vm_offset_t)imgp->image_header, 408 PAGE_SIZE); 409 if (nd.ni_vp) 410 vrele(nd.ni_vp); 411 412 return error; 413} 414 | 107 "", 108 "/usr/libexec/ld-elf.so.1", 109 &elf_freebsd_sysvec 110 }; 111static Elf_Brandinfo *elf_brand_list[MAX_BRANDS] = { 112 &freebsd_brand_info, 113 NULL, NULL, NULL, 114 NULL, NULL, NULL, NULL --- 288 unchanged lines hidden (view full) --- 403 kmem_free_wakeup(exec_map, (vm_offset_t)imgp->image_header, 404 PAGE_SIZE); 405 if (nd.ni_vp) 406 vrele(nd.ni_vp); 407 408 return error; 409} 410 |
415static char fallback_elf_brand[MAXBRANDLEN+1] = { "none" }; 416SYSCTL_STRING(_kern, OID_AUTO, fallback_elf_brand, CTLFLAG_RW, 417 fallback_elf_brand, sizeof(fallback_elf_brand), | 411static int fallback_elf_brand = ELFOSABI_FREEBSD; 412SYSCTL_INT(_kern, OID_AUTO, fallback_elf_brand, CTLFLAG_RW, 413 &fallback_elf_brand, ELFOSABI_FREEBSD, |
418 "ELF brand of last resort"); 419 420static int 421exec_elf_imgact(struct image_params *imgp) 422{ 423 const Elf_Ehdr *hdr = (const Elf_Ehdr *) imgp->image_header; 424 const Elf_Phdr *phdr; 425 Elf_Auxargs *elf_auxargs = NULL; 426 struct vmspace *vmspace; 427 vm_prot_t prot; 428 u_long text_size = 0, data_size = 0; 429 u_long text_addr = 0, data_addr = 0; 430 u_long addr, entry = 0, proghdr = 0; 431 int error, i; 432 const char *interp = NULL; 433 Elf_Brandinfo *brand_info; | 414 "ELF brand of last resort"); 415 416static int 417exec_elf_imgact(struct image_params *imgp) 418{ 419 const Elf_Ehdr *hdr = (const Elf_Ehdr *) imgp->image_header; 420 const Elf_Phdr *phdr; 421 Elf_Auxargs *elf_auxargs = NULL; 422 struct vmspace *vmspace; 423 vm_prot_t prot; 424 u_long text_size = 0, data_size = 0; 425 u_long text_addr = 0, data_addr = 0; 426 u_long addr, entry = 0, proghdr = 0; 427 int error, i; 428 const char *interp = NULL; 429 Elf_Brandinfo *brand_info; |
434 const char *brand; | |
435 char path[MAXPATHLEN]; 436 437 /* 438 * Do we have a valid ELF header ? 439 */ 440 if (elf_check_header(hdr) != 0 || hdr->e_type != ET_EXEC) 441 return -1; 442 --- 78 unchanged lines hidden (view full) --- 521 vmspace->vm_taddr = (caddr_t)(uintptr_t)text_addr; 522 vmspace->vm_dsize = data_size >> PAGE_SHIFT; 523 vmspace->vm_daddr = (caddr_t)(uintptr_t)data_addr; 524 525 addr = ELF_RTLD_ADDR(vmspace); 526 527 imgp->entry_addr = entry; 528 | 430 char path[MAXPATHLEN]; 431 432 /* 433 * Do we have a valid ELF header ? 434 */ 435 if (elf_check_header(hdr) != 0 || hdr->e_type != ET_EXEC) 436 return -1; 437 --- 78 unchanged lines hidden (view full) --- 516 vmspace->vm_taddr = (caddr_t)(uintptr_t)text_addr; 517 vmspace->vm_dsize = data_size >> PAGE_SHIFT; 518 vmspace->vm_daddr = (caddr_t)(uintptr_t)data_addr; 519 520 addr = ELF_RTLD_ADDR(vmspace); 521 522 imgp->entry_addr = entry; 523 |
529 /* If the executable has a brand, search for it in the brand list. */ | |
530 brand_info = NULL; | 524 brand_info = NULL; |
531 brand = (const char *)&hdr->e_ident[EI_BRAND]; 532 if (brand[0] != '\0') { | 525 526 /* XXX For now we look for the magic "FreeBSD" that we used to put 527 * into the ELF header at the EI_ABIVERSION location. If found use 528 * that information rather than figuring out the ABI from proper 529 * branding. This should be removed for 5.0-RELEASE. The Linux caes 530 * can be figured out from the `interp_path' field. 531 */ 532 if (strcmp("FreeBSD", (const char *)&hdr->e_ident[OLD_EI_BRAND]) == 0) 533 brand_info = &freebsd_brand_info; 534 535 /* If the executable has a brand, search for it in the brand list. */ 536 if (brand_info == NULL) { |
533 for (i = 0; i < MAX_BRANDS; i++) { 534 Elf_Brandinfo *bi = elf_brand_list[i]; 535 | 537 for (i = 0; i < MAX_BRANDS; i++) { 538 Elf_Brandinfo *bi = elf_brand_list[i]; 539 |
536 if (bi != NULL && strcmp(brand, bi->brand) == 0) { | 540 if (bi != NULL && hdr->e_ident[EI_OSABI] == bi->brand) { |
537 brand_info = bi; 538 break; 539 } 540 } 541 } 542 543 /* Lacking a known brand, search for a recognized interpreter. */ 544 if (brand_info == NULL && interp != NULL) { --- 4 unchanged lines hidden (view full) --- 549 strcmp(interp, bi->interp_path) == 0) { 550 brand_info = bi; 551 break; 552 } 553 } 554 } 555 556 /* Lacking a recognized interpreter, try the default brand */ | 541 brand_info = bi; 542 break; 543 } 544 } 545 } 546 547 /* Lacking a known brand, search for a recognized interpreter. */ 548 if (brand_info == NULL && interp != NULL) { --- 4 unchanged lines hidden (view full) --- 553 strcmp(interp, bi->interp_path) == 0) { 554 brand_info = bi; 555 break; 556 } 557 } 558 } 559 560 /* Lacking a recognized interpreter, try the default brand */ |
557 if (brand_info == NULL && fallback_elf_brand[0] != '\0') { | 561 if (brand_info == NULL) { |
558 for (i = 0; i < MAX_BRANDS; i++) { 559 Elf_Brandinfo *bi = elf_brand_list[i]; 560 | 562 for (i = 0; i < MAX_BRANDS; i++) { 563 Elf_Brandinfo *bi = elf_brand_list[i]; 564 |
561 if (bi != NULL 562 && strcmp(fallback_elf_brand, bi->brand) == 0) { | 565 if (bi != NULL && fallback_elf_brand == bi->brand) { |
563 brand_info = bi; 564 break; 565 } 566 } 567 } 568 | 566 brand_info = bi; 567 break; 568 } 569 } 570 } 571 |
569#ifdef __alpha__ 570 /* XXX - Assume FreeBSD on the alpha. */ | 572 /* XXX - Assume FreeBSD after the branding method change. */ |
571 if (brand_info == NULL) 572 brand_info = &freebsd_brand_info; | 573 if (brand_info == NULL) 574 brand_info = &freebsd_brand_info; |
573#endif | |
574 575 if (brand_info == NULL) { | 575 576 if (brand_info == NULL) { |
576 if (brand[0] == 0) 577 uprintf("ELF binary type not known." 578 " Use \"brandelf\" to brand it.\n"); 579 else 580 uprintf("ELF binary type \"%.*s\" not known.\n", 581 EI_NIDENT - EI_BRAND, brand); | 577 uprintf("ELF binary type \"%u\" not known.\n", 578 hdr->e_ident[EI_OSABI]); |
582 error = ENOEXEC; 583 goto fail; 584 } 585 586 imgp->proc->p_sysent = brand_info->sysvec; 587 if (interp != NULL) { 588 snprintf(path, sizeof(path), "%s%s", 589 brand_info->emul_path, interp); --- 337 unchanged lines hidden (view full) --- 927 ehdr = (Elf_Ehdr *)((char *)dst + ehoff); 928 ehdr->e_ident[EI_MAG0] = ELFMAG0; 929 ehdr->e_ident[EI_MAG1] = ELFMAG1; 930 ehdr->e_ident[EI_MAG2] = ELFMAG2; 931 ehdr->e_ident[EI_MAG3] = ELFMAG3; 932 ehdr->e_ident[EI_CLASS] = ELF_CLASS; 933 ehdr->e_ident[EI_DATA] = ELF_DATA; 934 ehdr->e_ident[EI_VERSION] = EV_CURRENT; | 579 error = ENOEXEC; 580 goto fail; 581 } 582 583 imgp->proc->p_sysent = brand_info->sysvec; 584 if (interp != NULL) { 585 snprintf(path, sizeof(path), "%s%s", 586 brand_info->emul_path, interp); --- 337 unchanged lines hidden (view full) --- 924 ehdr = (Elf_Ehdr *)((char *)dst + ehoff); 925 ehdr->e_ident[EI_MAG0] = ELFMAG0; 926 ehdr->e_ident[EI_MAG1] = ELFMAG1; 927 ehdr->e_ident[EI_MAG2] = ELFMAG2; 928 ehdr->e_ident[EI_MAG3] = ELFMAG3; 929 ehdr->e_ident[EI_CLASS] = ELF_CLASS; 930 ehdr->e_ident[EI_DATA] = ELF_DATA; 931 ehdr->e_ident[EI_VERSION] = EV_CURRENT; |
932 ehdr->e_ident[EI_OSABI] = ELFOSABI_FREEBSD; 933 ehdr->e_ident[EI_ABIVERSION] = 0; |
|
935 ehdr->e_ident[EI_PAD] = 0; | 934 ehdr->e_ident[EI_PAD] = 0; |
936 strncpy(ehdr->e_ident + EI_BRAND, "FreeBSD", 937 EI_NIDENT - EI_BRAND); | |
938 ehdr->e_type = ET_CORE; 939 ehdr->e_machine = ELF_ARCH; 940 ehdr->e_version = EV_CURRENT; 941 ehdr->e_entry = 0; 942 ehdr->e_phoff = phoff; 943 ehdr->e_flags = 0; 944 ehdr->e_ehsize = sizeof(Elf_Ehdr); 945 ehdr->e_phentsize = sizeof(Elf_Phdr); --- 53 unchanged lines hidden --- | 935 ehdr->e_type = ET_CORE; 936 ehdr->e_machine = ELF_ARCH; 937 ehdr->e_version = EV_CURRENT; 938 ehdr->e_entry = 0; 939 ehdr->e_phoff = phoff; 940 ehdr->e_flags = 0; 941 ehdr->e_ehsize = sizeof(Elf_Ehdr); 942 ehdr->e_phentsize = sizeof(Elf_Phdr); --- 53 unchanged lines hidden --- |