1 /* This is the Linux kernel elf-loading code, ported into user space */
18 #define ELF_START_MMAP 0x80000000
20 typedef uint32_t elf_greg_t;
22 #define ELF_NGREG (sizeof (struct target_pt_regs) / sizeof(elf_greg_t))
23 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
25 typedef struct user_i387_struct elf_fpregset_t;
28 * This is used to ensure we don't load something for the wrong architecture.
30 #define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
33 * These are used to set parameters in the core dumps.
35 #define ELF_CLASS ELFCLASS32
36 #define ELF_DATA ELFDATA2LSB
37 #define ELF_ARCH EM_386
39 /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
40 starts %edx contains a pointer to a function which might be
41 registered using `atexit'. This provides a mean for the
42 dynamic linker to call DT_FINI functions for shared libraries
43 that have been loaded before the code runs.
45 A value of 0 tells we have no such handler. */
46 #define ELF_PLAT_INIT(_r) _r->edx = 0
48 #define USE_ELF_CORE_DUMP
49 #define ELF_EXEC_PAGESIZE 4096
56 * MAX_ARG_PAGES defines the number of pages allocated for arguments
57 * and envelope for the new program. 32 should suffice, this gives
58 * a maximum env+arg of 128kB w/4KB pages!
60 #define MAX_ARG_PAGES 32
63 * This structure is used to hold the arguments that are
64 * used when loading binaries.
68 unsigned long page[MAX_ARG_PAGES];
74 char * filename; /* Name of binary */
75 unsigned long loader, exec;
76 int dont_iput; /* binfmt handler has put inode */
81 unsigned int a_info; /* Use macros N_MAGIC, etc for access */
82 unsigned int a_text; /* length of text, in bytes */
83 unsigned int a_data; /* length of data, in bytes */
84 unsigned int a_bss; /* length of uninitialized data area, in bytes */
85 unsigned int a_syms; /* length of symbol table data in file, in bytes */
86 unsigned int a_entry; /* start address */
87 unsigned int a_trsize; /* length of relocation info for text, in bytes */
88 unsigned int a_drsize; /* length of relocation info for data, in bytes */
92 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
98 #define X86_STACK_TOP 0x7d000000
100 /* max code+data+bss space allocated to elf interpreter */
101 #define INTERP_MAP_SIZE (32 * 1024 * 1024)
103 /* max code+data+bss+brk space allocated to ET_DYN executables */
104 #define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
106 /* from personality.h */
108 /* Flags for bug emulation. These occupy the top three bytes. */
109 #define STICKY_TIMEOUTS 0x4000000
110 #define WHOLE_SECONDS 0x2000000
112 /* Personality types. These go in the low byte. Avoid using the top bit,
113 * it will conflict with error returns.
115 #define PER_MASK (0x00ff)
116 #define PER_LINUX (0x0000)
117 #define PER_SVR4 (0x0001 | STICKY_TIMEOUTS)
118 #define PER_SVR3 (0x0002 | STICKY_TIMEOUTS)
119 #define PER_SCOSVR3 (0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS)
120 #define PER_WYSEV386 (0x0004 | STICKY_TIMEOUTS)
121 #define PER_ISCR4 (0x0005 | STICKY_TIMEOUTS)
122 #define PER_BSD (0x0006)
123 #define PER_XENIX (0x0007 | STICKY_TIMEOUTS)
125 /* Necessary parameters */
126 #define ALPHA_PAGE_SIZE 4096
127 #define X86_PAGE_SIZE 4096
129 #define ALPHA_PAGE_MASK (~(ALPHA_PAGE_SIZE-1))
130 #define X86_PAGE_MASK (~(X86_PAGE_SIZE-1))
132 #define ALPHA_PAGE_ALIGN(addr) ((((addr)+ALPHA_PAGE_SIZE)-1)&ALPHA_PAGE_MASK)
133 #define X86_PAGE_ALIGN(addr) ((((addr)+X86_PAGE_SIZE)-1)&X86_PAGE_MASK)
137 #define X86_ELF_EXEC_PAGESIZE X86_PAGE_SIZE
138 #define X86_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(X86_ELF_EXEC_PAGESIZE-1))
139 #define X86_ELF_PAGEOFFSET(_v) ((_v) & (X86_ELF_EXEC_PAGESIZE-1))
141 #define ALPHA_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ALPHA_PAGE_SIZE-1))
142 #define ALPHA_ELF_PAGEOFFSET(_v) ((_v) & (ALPHA_PAGE_SIZE-1))
144 #define INTERPRETER_NONE 0
145 #define INTERPRETER_AOUT 1
146 #define INTERPRETER_ELF 2
148 #define DLINFO_ITEMS 12
150 #define put_user(x,ptr) (void)(*(ptr) = (typeof(*ptr))(x))
151 #define get_user(ptr) (typeof(*ptr))(*(ptr))
153 static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
158 static inline void memcpy_tofs(void * to, const void * from, unsigned long n)
163 //extern void * mmap4k();
164 #define mmap4k(a, b, c, d, e, f) mmap((void *)(a), b, c, d, e, f)
166 extern unsigned long x86_stack_size;
168 static int load_aout_interp(void * exptr, int interp_fd);
171 static void bswap_ehdr(Elf32_Ehdr *ehdr)
173 bswap16s(&ehdr->e_type); /* Object file type */
174 bswap16s(&ehdr->e_machine); /* Architecture */
175 bswap32s(&ehdr->e_version); /* Object file version */
176 bswap32s(&ehdr->e_entry); /* Entry point virtual address */
177 bswap32s(&ehdr->e_phoff); /* Program header table file offset */
178 bswap32s(&ehdr->e_shoff); /* Section header table file offset */
179 bswap32s(&ehdr->e_flags); /* Processor-specific flags */
180 bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
181 bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
182 bswap16s(&ehdr->e_phnum); /* Program header table entry count */
183 bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
184 bswap16s(&ehdr->e_shnum); /* Section header table entry count */
185 bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
188 static void bswap_phdr(Elf32_Phdr *phdr)
190 bswap32s(&phdr->p_type); /* Segment type */
191 bswap32s(&phdr->p_offset); /* Segment file offset */
192 bswap32s(&phdr->p_vaddr); /* Segment virtual address */
193 bswap32s(&phdr->p_paddr); /* Segment physical address */
194 bswap32s(&phdr->p_filesz); /* Segment size in file */
195 bswap32s(&phdr->p_memsz); /* Segment size in memory */
196 bswap32s(&phdr->p_flags); /* Segment flags */
197 bswap32s(&phdr->p_align); /* Segment alignment */
200 static void bswap_shdr(Elf32_Shdr *shdr)
202 bswap32s(&shdr->sh_name);
203 bswap32s(&shdr->sh_type);
204 bswap32s(&shdr->sh_flags);
205 bswap32s(&shdr->sh_addr);
206 bswap32s(&shdr->sh_offset);
207 bswap32s(&shdr->sh_size);
208 bswap32s(&shdr->sh_link);
209 bswap32s(&shdr->sh_info);
210 bswap32s(&shdr->sh_addralign);
211 bswap32s(&shdr->sh_entsize);
214 static void bswap_sym(Elf32_Sym *sym)
216 bswap32s(&sym->st_name);
217 bswap32s(&sym->st_value);
218 bswap32s(&sym->st_size);
219 bswap16s(&sym->st_shndx);
223 static void * get_free_page(void)
227 /* User-space version of kernel get_free_page. Returns a page-aligned
228 * page-sized chunk of memory.
230 retval = mmap4k(0, ALPHA_PAGE_SIZE, PROT_READ|PROT_WRITE,
231 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
233 if((long)retval == -1) {
234 perror("get_free_page");
242 static void free_page(void * pageaddr)
244 (void)munmap(pageaddr, ALPHA_PAGE_SIZE);
248 * 'copy_string()' copies argument/envelope strings from user
249 * memory to free pages in kernel mem. These are in a format ready
250 * to be put directly into the top of new user memory.
253 static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
256 char *tmp, *tmp1, *pag = NULL;
260 return 0; /* bullet-proofing */
263 if (!(tmp1 = tmp = get_user(argv+argc))) {
264 fprintf(stderr, "VFS: argc is wrong");
267 while (get_user(tmp++));
269 if (p < len) { /* this shouldn't happen - 128kB */
275 offset = p % X86_PAGE_SIZE;
276 if (!(pag = (char *) page[p/X86_PAGE_SIZE]) &&
277 !(pag = (char *) page[p/X86_PAGE_SIZE] =
278 (unsigned long *) get_free_page())) {
282 if (len == 0 || offset == 0) {
283 *(pag + offset) = get_user(tmp);
286 int bytes_to_copy = (len > offset) ? offset : len;
287 tmp -= bytes_to_copy;
289 offset -= bytes_to_copy;
290 len -= bytes_to_copy;
291 memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
298 static int in_group_p(gid_t g)
300 /* return TRUE if we're in the specified group, FALSE otherwise */
303 gid_t grouplist[NGROUPS];
305 ngroup = getgroups(NGROUPS, grouplist);
306 for(i = 0; i < ngroup; i++) {
307 if(grouplist[i] == g) {
314 static int count(char ** vec)
318 for(i = 0; *vec; i++) {
325 static int prepare_binprm(struct linux_binprm *bprm)
329 int retval, id_change;
331 if(fstat(bprm->fd, &st) < 0) {
336 if(!S_ISREG(mode)) { /* Must be regular file */
339 if(!(mode & 0111)) { /* Must have at least one execute bit set */
343 bprm->e_uid = geteuid();
344 bprm->e_gid = getegid();
349 bprm->e_uid = st.st_uid;
350 if(bprm->e_uid != geteuid()) {
357 * If setgid is set but no group execute bit then this
358 * is a candidate for mandatory locking, not a setgid
361 if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
362 bprm->e_gid = st.st_gid;
363 if (!in_group_p(bprm->e_gid)) {
368 memset(bprm->buf, 0, sizeof(bprm->buf));
369 retval = lseek(bprm->fd, 0L, SEEK_SET);
371 retval = read(bprm->fd, bprm->buf, 128);
374 perror("prepare_binprm");
376 /* return(-errno); */
383 unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm,
384 struct image_info * info)
386 unsigned long stack_base, size, error;
389 /* Create enough stack to hold everything. If we don't use
390 * it for args, we'll use it for something else...
392 size = x86_stack_size;
393 if (size < MAX_ARG_PAGES*X86_PAGE_SIZE)
394 size = MAX_ARG_PAGES*X86_PAGE_SIZE;
395 error = (unsigned long)mmap4k(NULL,
396 size + X86_PAGE_SIZE,
397 PROT_READ | PROT_WRITE,
398 MAP_PRIVATE | MAP_ANONYMOUS,
404 /* we reserve one extra page at the top of the stack as guard */
405 mprotect((void *)(error + size), X86_PAGE_SIZE, PROT_NONE);
407 stack_base = error + size - MAX_ARG_PAGES*X86_PAGE_SIZE;
411 bprm->loader += stack_base;
413 bprm->exec += stack_base;
415 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
419 memcpy((void *)stack_base, (void *)bprm->page[i], X86_PAGE_SIZE);
420 free_page((void *)bprm->page[i]);
422 stack_base += X86_PAGE_SIZE;
427 static void set_brk(unsigned long start, unsigned long end)
429 /* page-align the start and end addresses... */
430 start = ALPHA_PAGE_ALIGN(start);
431 end = ALPHA_PAGE_ALIGN(end);
434 if((long)mmap4k(start, end - start,
435 PROT_READ | PROT_WRITE | PROT_EXEC,
436 MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
437 perror("cannot mmap brk");
443 /* We need to explicitly zero any fractional pages
444 after the data section (i.e. bss). This would
445 contain the junk from the file that should not
449 static void padzero(unsigned long elf_bss)
454 nbyte = elf_bss & (ALPHA_PAGE_SIZE-1); /* was X86_PAGE_SIZE - JRP */
456 nbyte = ALPHA_PAGE_SIZE - nbyte;
457 fpnt = (char *) elf_bss;
464 static unsigned int * create_elf_tables(char *p, int argc, int envc,
465 struct elfhdr * exec,
466 unsigned long load_addr,
467 unsigned long load_bias,
468 unsigned long interp_load_addr, int ibcs,
469 struct image_info *info)
471 target_ulong *argv, *envp, *dlinfo;
475 * Force 16 byte alignment here for generality.
477 sp = (unsigned int *) (~15UL & (unsigned long) p);
478 sp -= exec ? DLINFO_ITEMS*2 : 2;
485 put_user(tswapl((target_ulong)envp),--sp);
486 put_user(tswapl((target_ulong)argv),--sp);
489 #define NEW_AUX_ENT(id, val) \
490 put_user (tswapl(id), dlinfo++); \
491 put_user (tswapl(val), dlinfo++)
493 if (exec) { /* Put this here for an ELF program interpreter */
494 NEW_AUX_ENT (AT_PHDR, (target_ulong)(load_addr + exec->e_phoff));
495 NEW_AUX_ENT (AT_PHENT, (target_ulong)(sizeof (struct elf_phdr)));
496 NEW_AUX_ENT (AT_PHNUM, (target_ulong)(exec->e_phnum));
497 NEW_AUX_ENT (AT_PAGESZ, (target_ulong)(ALPHA_PAGE_SIZE));
498 NEW_AUX_ENT (AT_BASE, (target_ulong)(interp_load_addr));
499 NEW_AUX_ENT (AT_FLAGS, (target_ulong)0);
500 NEW_AUX_ENT (AT_ENTRY, load_bias + exec->e_entry);
501 NEW_AUX_ENT (AT_UID, (target_ulong) getuid());
502 NEW_AUX_ENT (AT_EUID, (target_ulong) geteuid());
503 NEW_AUX_ENT (AT_GID, (target_ulong) getgid());
504 NEW_AUX_ENT (AT_EGID, (target_ulong) getegid());
506 NEW_AUX_ENT (AT_NULL, 0);
508 put_user(tswapl(argc),--sp);
509 info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff);
511 put_user(tswapl((target_ulong)p),argv++);
512 while (get_user(p++)) /* nothing */ ;
515 info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff);
517 put_user(tswapl((target_ulong)p),envp++);
518 while (get_user(p++)) /* nothing */ ;
521 info->env_end = (unsigned int)((unsigned long)p & 0xffffffff);
527 static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
529 unsigned long *interp_load_addr)
531 struct elf_phdr *elf_phdata = NULL;
532 struct elf_phdr *eppnt;
533 unsigned long load_addr = 0;
534 int load_addr_set = 0;
536 unsigned long last_bss, elf_bss;
545 bswap_ehdr(interp_elf_ex);
547 /* First of all, some simple consistency checks */
548 if ((interp_elf_ex->e_type != ET_EXEC &&
549 interp_elf_ex->e_type != ET_DYN) ||
550 !elf_check_arch(interp_elf_ex->e_machine)) {
555 /* Now read in all of the header information */
557 if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > X86_PAGE_SIZE)
560 elf_phdata = (struct elf_phdr *)
561 malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
567 * If the size of this structure has changed, then punt, since
568 * we will be doing the wrong thing.
570 if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
575 retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
577 retval = read(interpreter_fd,
579 sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
582 perror("load_elf_interp");
589 for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
594 if (interp_elf_ex->e_type == ET_DYN) {
595 /* in order to avoid harcoding the interpreter load
596 address in qemu, we allocate a big enough memory zone */
597 error = (unsigned long)mmap4k(NULL, INTERP_MAP_SIZE,
598 PROT_NONE, MAP_PRIVATE | MAP_ANON,
609 for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
610 if (eppnt->p_type == PT_LOAD) {
611 int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
613 unsigned long vaddr = 0;
616 if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
617 if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
618 if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
619 if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
620 elf_type |= MAP_FIXED;
621 vaddr = eppnt->p_vaddr;
623 error = (unsigned long)mmap4k(load_addr+X86_ELF_PAGESTART(vaddr),
624 eppnt->p_filesz + X86_ELF_PAGEOFFSET(eppnt->p_vaddr),
628 eppnt->p_offset - X86_ELF_PAGEOFFSET(eppnt->p_vaddr));
630 if (error > -1024UL) {
632 close(interpreter_fd);
637 if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
643 * Find the end of the file mapping for this phdr, and keep
644 * track of the largest address we see for this.
646 k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
647 if (k > elf_bss) elf_bss = k;
650 * Do the same thing for the memory mapping - between
651 * elf_bss and last_bss is the bss section.
653 k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
654 if (k > last_bss) last_bss = k;
657 /* Now use mmap to map the library into memory. */
659 close(interpreter_fd);
662 * Now fill out the bss section. First pad the last page up
663 * to the page boundary, and then perform a mmap to make sure
664 * that there are zeromapped pages up to and including the last
668 elf_bss = X86_ELF_PAGESTART(elf_bss + ALPHA_PAGE_SIZE - 1); /* What we have mapped so far */
670 /* Map the last of the bss segment */
671 if (last_bss > elf_bss) {
672 mmap4k(elf_bss, last_bss-elf_bss,
673 PROT_READ|PROT_WRITE|PROT_EXEC,
674 MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
678 *interp_load_addr = load_addr;
679 return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
682 /* Best attempt to load symbols from this ELF object. */
683 static void load_symbols(struct elfhdr *hdr, int fd)
686 struct elf_shdr sechdr, symtab, strtab;
689 lseek(fd, hdr->e_shoff, SEEK_SET);
690 for (i = 0; i < hdr->e_shnum; i++) {
691 if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
696 if (sechdr.sh_type == SHT_SYMTAB) {
698 lseek(fd, hdr->e_shoff
699 + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
700 if (read(fd, &strtab, sizeof(strtab))
709 return; /* Shouldn't happen... */
712 /* Now know where the strtab and symtab are. Snarf them. */
713 disas_symtab = malloc(symtab.sh_size);
714 disas_strtab = strings = malloc(strtab.sh_size);
715 if (!disas_symtab || !disas_strtab)
718 lseek(fd, symtab.sh_offset, SEEK_SET);
719 if (read(fd, disas_symtab, symtab.sh_size) != symtab.sh_size)
723 for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++)
724 bswap_sym(disas_symtab + sizeof(struct elf_sym)*i);
727 lseek(fd, strtab.sh_offset, SEEK_SET);
728 if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
730 disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);
733 static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
734 struct image_info * info)
736 struct elfhdr elf_ex;
737 struct elfhdr interp_elf_ex;
738 struct exec interp_ex;
739 int interpreter_fd = -1; /* avoid warning */
740 unsigned long load_addr, load_bias;
741 int load_addr_set = 0;
742 unsigned int interpreter_type = INTERPRETER_NONE;
743 unsigned char ibcs2_interpreter;
746 struct elf_phdr * elf_ppnt;
747 struct elf_phdr *elf_phdata;
748 unsigned long elf_bss, k, elf_brk;
750 char * elf_interpreter;
751 unsigned long elf_entry, interp_load_addr = 0;
753 unsigned long start_code, end_code, end_data;
754 unsigned long elf_stack;
755 char passed_fileno[6];
757 ibcs2_interpreter = 0;
761 elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */
766 if (elf_ex.e_ident[0] != 0x7f ||
767 strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
771 /* First of all, some simple consistency checks */
772 if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
773 (! elf_check_arch(elf_ex.e_machine))) {
777 /* Now read in all of the header information */
779 elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
780 if (elf_phdata == NULL) {
784 retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
786 retval = read(bprm->fd, (char *) elf_phdata,
787 elf_ex.e_phentsize * elf_ex.e_phnum);
791 perror("load_elf_binary");
798 elf_ppnt = elf_phdata;
799 for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
800 bswap_phdr(elf_ppnt);
803 elf_ppnt = elf_phdata;
810 elf_interpreter = NULL;
815 for(i=0;i < elf_ex.e_phnum; i++) {
816 if (elf_ppnt->p_type == PT_INTERP) {
817 if ( elf_interpreter != NULL )
820 free(elf_interpreter);
825 /* This is the program interpreter used for
826 * shared libraries - for now assume that this
827 * is an a.out format binary
830 elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
832 if (elf_interpreter == NULL) {
838 retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
840 retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
843 perror("load_elf_binary2");
847 /* If the program interpreter is one of these two,
848 then assume an iBCS2 image. Otherwise assume
849 a native linux image. */
851 /* JRP - Need to add X86 lib dir stuff here... */
853 if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
854 strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
855 ibcs2_interpreter = 1;
859 printf("Using ELF interpreter %s\n", elf_interpreter);
862 retval = open(path(elf_interpreter), O_RDONLY);
864 interpreter_fd = retval;
867 perror(elf_interpreter);
869 /* retval = -errno; */
874 retval = lseek(interpreter_fd, 0, SEEK_SET);
876 retval = read(interpreter_fd,bprm->buf,128);
880 interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */
881 interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */
884 perror("load_elf_binary3");
887 free(elf_interpreter);
895 /* Some simple consistency checks for the interpreter */
896 if (elf_interpreter){
897 interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
899 /* Now figure out which format our binary is */
900 if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
901 (N_MAGIC(interp_ex) != QMAGIC)) {
902 interpreter_type = INTERPRETER_ELF;
905 if (interp_elf_ex.e_ident[0] != 0x7f ||
906 strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
907 interpreter_type &= ~INTERPRETER_ELF;
910 if (!interpreter_type) {
911 free(elf_interpreter);
918 /* OK, we are done with that, now set up the arg stuff,
919 and then start this sucker up */
921 if (!bprm->sh_bang) {
924 if (interpreter_type == INTERPRETER_AOUT) {
925 sprintf(passed_fileno, "%d", bprm->fd);
926 passed_p = passed_fileno;
928 if (elf_interpreter) {
929 bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p);
934 if (elf_interpreter) {
935 free(elf_interpreter);
943 /* OK, This is the point of no return */
946 info->start_mmap = (unsigned long)ELF_START_MMAP;
948 elf_entry = (unsigned long) elf_ex.e_entry;
950 /* Do this so that we can load the interpreter, if need be. We will
951 change some of these later */
953 bprm->p = setup_arg_pages(bprm->p, bprm, info);
954 info->start_stack = bprm->p;
956 /* Now we do a little grungy work by mmaping the ELF image into
957 * the correct location in memory. At this point, we assume that
958 * the image should be loaded at fixed address, not at a variable
962 for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
967 if (elf_ppnt->p_type != PT_LOAD)
970 if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
971 if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
972 if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
973 elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
974 if (elf_ex.e_type == ET_EXEC || load_addr_set) {
975 elf_flags |= MAP_FIXED;
976 } else if (elf_ex.e_type == ET_DYN) {
977 /* Try and get dynamic programs out of the way of the default mmap
978 base, as well as whatever program they might try to exec. This
979 is because the brk will follow the loader, and is not movable. */
980 /* NOTE: for qemu, we do a big mmap to get enough space
981 without harcoding any address */
982 error = (unsigned long)mmap4k(NULL, ET_DYN_MAP_SIZE,
983 PROT_NONE, MAP_PRIVATE | MAP_ANON,
989 load_bias = X86_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
992 error = (unsigned long)mmap4k(
993 X86_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
994 (elf_ppnt->p_filesz +
995 X86_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
997 (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
999 (elf_ppnt->p_offset -
1000 X86_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
1006 #ifdef LOW_ELF_STACK
1007 if (X86_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
1008 elf_stack = X86_ELF_PAGESTART(elf_ppnt->p_vaddr);
1011 if (!load_addr_set) {
1013 load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
1014 if (elf_ex.e_type == ET_DYN) {
1015 load_bias += error -
1016 X86_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
1017 load_addr += load_bias;
1020 k = elf_ppnt->p_vaddr;
1023 k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
1026 if ((elf_ppnt->p_flags & PF_X) && end_code < k)
1030 k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
1031 if (k > elf_brk) elf_brk = k;
1034 elf_entry += load_bias;
1035 elf_bss += load_bias;
1036 elf_brk += load_bias;
1037 start_code += load_bias;
1038 end_code += load_bias;
1039 // start_data += load_bias;
1040 end_data += load_bias;
1042 if (elf_interpreter) {
1043 if (interpreter_type & 1) {
1044 elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
1046 else if (interpreter_type & 2) {
1047 elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
1051 close(interpreter_fd);
1052 free(elf_interpreter);
1054 if (elf_entry == ~0UL) {
1055 printf("Unable to load interpreter\n");
1065 load_symbols(&elf_ex, bprm->fd);
1067 if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
1068 info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
1070 #ifdef LOW_ELF_STACK
1071 info->start_stack = bprm->p = elf_stack - 4;
1073 bprm->p = (unsigned long)
1074 create_elf_tables((char *)bprm->p,
1077 (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
1078 load_addr, load_bias,
1080 (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
1082 if (interpreter_type == INTERPRETER_AOUT)
1083 info->arg_start += strlen(passed_fileno) + 1;
1084 info->start_brk = info->brk = elf_brk;
1085 info->end_code = end_code;
1086 info->start_code = start_code;
1087 info->end_data = end_data;
1088 info->start_stack = bprm->p;
1090 /* Calling set_brk effectively mmaps the pages that we need for the bss and break
1092 set_brk(elf_bss, elf_brk);
1097 printf("(start_brk) %x\n" , info->start_brk);
1098 printf("(end_code) %x\n" , info->end_code);
1099 printf("(start_code) %x\n" , info->start_code);
1100 printf("(end_data) %x\n" , info->end_data);
1101 printf("(start_stack) %x\n" , info->start_stack);
1102 printf("(brk) %x\n" , info->brk);
1105 if ( info->personality == PER_SVR4 )
1107 /* Why this, you ask??? Well SVr4 maps page 0 as read-only,
1108 and some applications "depend" upon this behavior.
1109 Since we do not have the power to recompile these, we
1110 emulate the SVr4 behavior. Sigh. */
1111 mapped_addr = mmap4k(NULL, ALPHA_PAGE_SIZE, PROT_READ | PROT_EXEC,
1112 MAP_FIXED | MAP_PRIVATE, -1, 0);
1115 #ifdef ELF_PLAT_INIT
1117 * The ABI may specify that certain registers be set up in special
1118 * ways (on i386 %edx is the address of a DT_FINI function, for
1119 * example. This macro performs whatever initialization to
1120 * the regs structure is required.
1122 ELF_PLAT_INIT(regs);
1126 info->entry = elf_entry;
1133 int elf_exec(const char * filename, char ** argv, char ** envp,
1134 struct target_pt_regs * regs, struct image_info *infop)
1136 struct linux_binprm bprm;
1140 bprm.p = X86_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
1141 for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */
1143 retval = open(filename, O_RDONLY);
1147 /* return retval; */
1152 bprm.filename = (char *)filename;
1157 bprm.argc = count(argv);
1158 bprm.envc = count(envp);
1160 retval = prepare_binprm(&bprm);
1163 bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p);
1165 bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p);
1166 bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p);
1173 retval = load_elf_binary(&bprm,regs,infop);
1176 /* success. Initialize important registers */
1177 regs->esp = infop->start_stack;
1178 regs->eip = infop->entry;
1182 /* Something went wrong, return the inode and free the argument pages*/
1183 for (i=0 ; i<MAX_ARG_PAGES ; i++) {
1184 free_page((void *)bprm.page[i]);
1190 static int load_aout_interp(void * exptr, int interp_fd)
1192 printf("a.out interpreter not yet supported\n");