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 ---