c692ea371b1e7aaf59ed0795b961590d6b2c13b7
[qemu] / linux-user / elfload.c
1 /* This is the Linux kernel elf-loading code, ported into user space */
2
3 #include <stdio.h>
4 #include <sys/types.h>
5 #include <fcntl.h>
6 #include <sys/stat.h>
7 #include <errno.h>
8 #include <unistd.h>
9 #include <sys/mman.h>
10 #include <stdlib.h>
11 #include <string.h>
12
13 #include "qemu.h"
14
15 #ifdef TARGET_I386
16
17 #define ELF_START_MMAP 0x80000000
18
19 typedef uint32_t  elf_greg_t;
20
21 #define ELF_NGREG (sizeof (struct target_pt_regs) / sizeof(elf_greg_t))
22 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
23
24 typedef struct user_i387_struct elf_fpregset_t;
25
26 /*
27  * This is used to ensure we don't load something for the wrong architecture.
28  */
29 #define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
30
31 /*
32  * These are used to set parameters in the core dumps.
33  */
34 #define ELF_CLASS       ELFCLASS32
35 #define ELF_DATA        ELFDATA2LSB
36 #define ELF_ARCH        EM_386
37
38         /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
39            starts %edx contains a pointer to a function which might be
40            registered using `atexit'.  This provides a mean for the
41            dynamic linker to call DT_FINI functions for shared libraries
42            that have been loaded before the code runs.
43
44            A value of 0 tells we have no such handler.  */
45 #define ELF_PLAT_INIT(_r)       _r->edx = 0
46
47 #define USE_ELF_CORE_DUMP
48 #define ELF_EXEC_PAGESIZE       4096
49
50 #endif
51
52 #include "elf.h"
53
54 /*
55  * MAX_ARG_PAGES defines the number of pages allocated for arguments
56  * and envelope for the new program. 32 should suffice, this gives
57  * a maximum env+arg of 128kB w/4KB pages!
58  */
59 #define MAX_ARG_PAGES 32
60
61 /*
62  * This structure is used to hold the arguments that are 
63  * used when loading binaries.
64  */
65 struct linux_binprm {
66         char buf[128];
67         unsigned long page[MAX_ARG_PAGES];
68         unsigned long p;
69         int sh_bang;
70         int fd;
71         int e_uid, e_gid;
72         int argc, envc;
73         char * interp_prefix;   /* prefix for interpreter */
74         char * filename;        /* Name of binary */
75         unsigned long loader, exec;
76         int dont_iput;          /* binfmt handler has put inode */
77 };
78
79 struct exec
80 {
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 */
89 };
90
91
92 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
93 #define OMAGIC 0407
94 #define NMAGIC 0410
95 #define ZMAGIC 0413
96 #define QMAGIC 0314
97
98 #define X86_STACK_TOP 0x7d000000
99
100 /* max code+data+bss space allocated to elf interpreter */
101 #define INTERP_MAP_SIZE (32 * 1024 * 1024)
102
103 /* max code+data+bss+brk space allocated to ET_DYN executables */
104 #define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
105
106 /* from personality.h */
107
108 /* Flags for bug emulation. These occupy the top three bytes. */
109 #define STICKY_TIMEOUTS         0x4000000
110 #define WHOLE_SECONDS           0x2000000
111
112 /* Personality types. These go in the low byte. Avoid using the top bit,
113  * it will conflict with error returns.
114  */
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)
124
125 /* Necessary parameters */
126 #define ALPHA_PAGE_SIZE 4096
127 #define X86_PAGE_SIZE 4096
128
129 #define ALPHA_PAGE_MASK (~(ALPHA_PAGE_SIZE-1))
130 #define X86_PAGE_MASK (~(X86_PAGE_SIZE-1))
131
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)
134
135 #define NGROUPS 32
136
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))
140
141 #define ALPHA_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ALPHA_PAGE_SIZE-1))
142 #define ALPHA_ELF_PAGEOFFSET(_v) ((_v) & (ALPHA_PAGE_SIZE-1))
143
144 #define INTERPRETER_NONE 0
145 #define INTERPRETER_AOUT 1
146 #define INTERPRETER_ELF 2
147
148 #define DLINFO_ITEMS 12
149
150 #define put_user(x,ptr) (void)(*(ptr) = (typeof(*ptr))(x))
151 #define get_user(ptr) (typeof(*ptr))(*(ptr))
152
153 static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
154 {
155         memcpy(to, from, n);
156 }
157
158 static inline void memcpy_tofs(void * to, const void * from, unsigned long n)
159 {
160         memcpy(to, from, n);
161 }
162
163 //extern void * mmap4k();
164 #define mmap4k(a, b, c, d, e, f) mmap((void *)(a), b, c, d, e, f)
165
166 extern unsigned long x86_stack_size;
167
168 static int load_aout_interp(void * exptr, int interp_fd);
169
170 #ifdef BSWAP_NEEDED
171 static void bswap_ehdr(Elf32_Ehdr *ehdr)
172 {
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 */
186 }
187
188 static void bswap_phdr(Elf32_Phdr *phdr)
189 {
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 */
198 }
199 #endif
200
201 static void * get_free_page(void)
202 {
203     void *      retval;
204
205     /* User-space version of kernel get_free_page.  Returns a page-aligned
206      * page-sized chunk of memory.
207      */
208     retval = mmap4k(0, ALPHA_PAGE_SIZE, PROT_READ|PROT_WRITE, 
209                         MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
210
211     if((long)retval == -1) {
212         perror("get_free_page");
213         exit(-1);
214     }
215     else {
216         return(retval);
217     }
218 }
219
220 static void free_page(void * pageaddr)
221 {
222     (void)munmap(pageaddr, ALPHA_PAGE_SIZE);
223 }
224
225 /*
226  * 'copy_string()' copies argument/envelope strings from user
227  * memory to free pages in kernel mem. These are in a format ready
228  * to be put directly into the top of new user memory.
229  *
230  */
231 static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
232                 unsigned long p)
233 {
234     char *tmp, *tmp1, *pag = NULL;
235     int len, offset = 0;
236
237     if (!p) {
238         return 0;       /* bullet-proofing */
239     }
240     while (argc-- > 0) {
241         if (!(tmp1 = tmp = get_user(argv+argc))) {
242             fprintf(stderr, "VFS: argc is wrong");
243             exit(-1);
244         }
245         while (get_user(tmp++));
246         len = tmp - tmp1;
247         if (p < len) {  /* this shouldn't happen - 128kB */
248                 return 0;
249         }
250         while (len) {
251             --p; --tmp; --len;
252             if (--offset < 0) {
253                 offset = p % X86_PAGE_SIZE;
254                 if (!(pag = (char *) page[p/X86_PAGE_SIZE]) &&
255                     !(pag = (char *) page[p/X86_PAGE_SIZE] =
256                       (unsigned long *) get_free_page())) {
257                         return 0;
258                 }
259             }
260             if (len == 0 || offset == 0) {
261                 *(pag + offset) = get_user(tmp);
262             }
263             else {
264               int bytes_to_copy = (len > offset) ? offset : len;
265               tmp -= bytes_to_copy;
266               p -= bytes_to_copy;
267               offset -= bytes_to_copy;
268               len -= bytes_to_copy;
269               memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
270             }
271         }
272     }
273     return p;
274 }
275
276 static int in_group_p(gid_t g)
277 {
278     /* return TRUE if we're in the specified group, FALSE otherwise */
279     int         ngroup;
280     int         i;
281     gid_t       grouplist[NGROUPS];
282
283     ngroup = getgroups(NGROUPS, grouplist);
284     for(i = 0; i < ngroup; i++) {
285         if(grouplist[i] == g) {
286             return 1;
287         }
288     }
289     return 0;
290 }
291
292 static int count(char ** vec)
293 {
294     int         i;
295
296     for(i = 0; *vec; i++) {
297         vec++;
298     }
299
300     return(i);
301 }
302
303 static int prepare_binprm(struct linux_binprm *bprm)
304 {
305     struct stat         st;
306     int mode;
307     int retval, id_change;
308
309     if(fstat(bprm->fd, &st) < 0) {
310         return(-errno);
311     }
312
313     mode = st.st_mode;
314     if(!S_ISREG(mode)) {        /* Must be regular file */
315         return(-EACCES);
316     }
317     if(!(mode & 0111)) {        /* Must have at least one execute bit set */
318         return(-EACCES);
319     }
320
321     bprm->e_uid = geteuid();
322     bprm->e_gid = getegid();
323     id_change = 0;
324
325     /* Set-uid? */
326     if(mode & S_ISUID) {
327         bprm->e_uid = st.st_uid;
328         if(bprm->e_uid != geteuid()) {
329             id_change = 1;
330         }
331     }
332
333     /* Set-gid? */
334     /*
335      * If setgid is set but no group execute bit then this
336      * is a candidate for mandatory locking, not a setgid
337      * executable.
338      */
339     if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
340         bprm->e_gid = st.st_gid;
341         if (!in_group_p(bprm->e_gid)) {
342                 id_change = 1;
343         }
344     }
345
346     memset(bprm->buf, 0, sizeof(bprm->buf));
347     retval = lseek(bprm->fd, 0L, SEEK_SET);
348     if(retval >= 0) {
349         retval = read(bprm->fd, bprm->buf, 128);
350     }
351     if(retval < 0) {
352         perror("prepare_binprm");
353         exit(-1);
354         /* return(-errno); */
355     }
356     else {
357         return(retval);
358     }
359 }
360
361 unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm,
362                                                 struct image_info * info)
363 {
364     unsigned long stack_base, size, error;
365     int i;
366
367     /* Create enough stack to hold everything.  If we don't use
368      * it for args, we'll use it for something else...
369      */
370     size = x86_stack_size;
371     if (size < MAX_ARG_PAGES*X86_PAGE_SIZE)
372         size = MAX_ARG_PAGES*X86_PAGE_SIZE;
373     error = (unsigned long)mmap4k(NULL, 
374                                   size + X86_PAGE_SIZE,
375                                   PROT_READ | PROT_WRITE,
376                                   MAP_PRIVATE | MAP_ANONYMOUS,
377                                   -1, 0);
378     if (error == -1) {
379         perror("stk mmap");
380         exit(-1);
381     }
382     /* we reserve one extra page at the top of the stack as guard */
383     mprotect((void *)(error + size), X86_PAGE_SIZE, PROT_NONE);
384
385     stack_base = error + size - MAX_ARG_PAGES*X86_PAGE_SIZE;
386     p += stack_base;
387
388     if (bprm->loader) {
389         bprm->loader += stack_base;
390     }
391     bprm->exec += stack_base;
392
393     for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
394         if (bprm->page[i]) {
395             info->rss++;
396
397             memcpy((void *)stack_base, (void *)bprm->page[i], X86_PAGE_SIZE);
398             free_page((void *)bprm->page[i]);
399         }
400         stack_base += X86_PAGE_SIZE;
401     }
402     return p;
403 }
404
405 static void set_brk(unsigned long start, unsigned long end)
406 {
407         /* page-align the start and end addresses... */
408         start = ALPHA_PAGE_ALIGN(start);
409         end = ALPHA_PAGE_ALIGN(end);
410         if (end <= start)
411                 return;
412         if((long)mmap4k(start, end - start,
413                 PROT_READ | PROT_WRITE | PROT_EXEC,
414                 MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
415             perror("cannot mmap brk");
416             exit(-1);
417         }
418 }
419
420
421 /* We need to explicitly zero any fractional pages
422    after the data section (i.e. bss).  This would
423    contain the junk from the file that should not
424    be in memory */
425
426
427 static void padzero(unsigned long elf_bss)
428 {
429         unsigned long nbyte;
430         char * fpnt;
431
432         nbyte = elf_bss & (ALPHA_PAGE_SIZE-1);  /* was X86_PAGE_SIZE - JRP */
433         if (nbyte) {
434             nbyte = ALPHA_PAGE_SIZE - nbyte;
435             fpnt = (char *) elf_bss;
436             do {
437                 *fpnt++ = 0;
438             } while (--nbyte);
439         }
440 }
441
442 static unsigned int * create_elf_tables(char *p, int argc, int envc,
443                                         struct elfhdr * exec,
444                                         unsigned long load_addr,
445                                         unsigned long load_bias,
446                                         unsigned long interp_load_addr, int ibcs,
447                                         struct image_info *info)
448 {
449         target_ulong *argv, *envp, *dlinfo;
450         target_ulong *sp;
451
452         /*
453          * Force 16 byte alignment here for generality.
454          */
455         sp = (unsigned int *) (~15UL & (unsigned long) p);
456         sp -= exec ? DLINFO_ITEMS*2 : 2;
457         dlinfo = sp;
458         sp -= envc+1;
459         envp = sp;
460         sp -= argc+1;
461         argv = sp;
462         if (!ibcs) {
463                 put_user(tswapl((target_ulong)envp),--sp);
464                 put_user(tswapl((target_ulong)argv),--sp);
465         }
466
467 #define NEW_AUX_ENT(id, val) \
468           put_user (tswapl(id), dlinfo++); \
469           put_user (tswapl(val), dlinfo++)
470
471         if (exec) { /* Put this here for an ELF program interpreter */
472           NEW_AUX_ENT (AT_PHDR, (target_ulong)(load_addr + exec->e_phoff));
473           NEW_AUX_ENT (AT_PHENT, (target_ulong)(sizeof (struct elf_phdr)));
474           NEW_AUX_ENT (AT_PHNUM, (target_ulong)(exec->e_phnum));
475           NEW_AUX_ENT (AT_PAGESZ, (target_ulong)(ALPHA_PAGE_SIZE));
476           NEW_AUX_ENT (AT_BASE, (target_ulong)(interp_load_addr));
477           NEW_AUX_ENT (AT_FLAGS, (target_ulong)0);
478           NEW_AUX_ENT (AT_ENTRY, load_bias + exec->e_entry);
479           NEW_AUX_ENT (AT_UID, (target_ulong) getuid());
480           NEW_AUX_ENT (AT_EUID, (target_ulong) geteuid());
481           NEW_AUX_ENT (AT_GID, (target_ulong) getgid());
482           NEW_AUX_ENT (AT_EGID, (target_ulong) getegid());
483         }
484         NEW_AUX_ENT (AT_NULL, 0);
485 #undef NEW_AUX_ENT
486         put_user(tswapl(argc),--sp);
487         info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff);
488         while (argc-->0) {
489                 put_user(tswapl((target_ulong)p),argv++);
490                 while (get_user(p++)) /* nothing */ ;
491         }
492         put_user(0,argv);
493         info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff);
494         while (envc-->0) {
495                 put_user(tswapl((target_ulong)p),envp++);
496                 while (get_user(p++)) /* nothing */ ;
497         }
498         put_user(0,envp);
499         info->env_end = (unsigned int)((unsigned long)p & 0xffffffff);
500         return sp;
501 }
502
503
504
505 static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
506                                      int interpreter_fd,
507                                      unsigned long *interp_load_addr)
508 {
509         struct elf_phdr *elf_phdata  =  NULL;
510         struct elf_phdr *eppnt;
511         unsigned long load_addr = 0;
512         int load_addr_set = 0;
513         int retval;
514         unsigned long last_bss, elf_bss;
515         unsigned long error;
516         int i;
517         
518         elf_bss = 0;
519         last_bss = 0;
520         error = 0;
521
522 #ifdef BSWAP_NEEDED
523         bswap_ehdr(interp_elf_ex);
524 #endif
525         /* First of all, some simple consistency checks */
526         if ((interp_elf_ex->e_type != ET_EXEC && 
527              interp_elf_ex->e_type != ET_DYN) || 
528            !elf_check_arch(interp_elf_ex->e_machine)) {
529                 return ~0UL;
530         }
531         
532
533         /* Now read in all of the header information */
534         
535         if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > X86_PAGE_SIZE)
536             return ~0UL;
537         
538         elf_phdata =  (struct elf_phdr *) 
539                 malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
540
541         if (!elf_phdata)
542           return ~0UL;
543         
544         /*
545          * If the size of this structure has changed, then punt, since
546          * we will be doing the wrong thing.
547          */
548         if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
549             free(elf_phdata);
550             return ~0UL;
551         }
552
553         retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
554         if(retval >= 0) {
555             retval = read(interpreter_fd,
556                            (char *) elf_phdata,
557                            sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
558         }
559         if (retval < 0) {
560                 perror("load_elf_interp");
561                 exit(-1);
562                 free (elf_phdata);
563                 return retval;
564         }
565 #ifdef BSWAP_NEEDED
566         eppnt = elf_phdata;
567         for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
568             bswap_phdr(eppnt);
569         }
570 #endif
571
572         if (interp_elf_ex->e_type == ET_DYN) {
573             /* in order to avoid harcoding the interpreter load
574                address in qemu, we allocate a big enough memory zone */
575             error = (unsigned long)mmap4k(NULL, INTERP_MAP_SIZE,
576                                           PROT_NONE, MAP_PRIVATE | MAP_ANON, 
577                                           -1, 0);
578             if (error == -1) {
579                 perror("mmap");
580                 exit(-1);
581             }
582             load_addr = error;
583             load_addr_set = 1;
584         }
585
586         eppnt = elf_phdata;
587         for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
588           if (eppnt->p_type == PT_LOAD) {
589             int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
590             int elf_prot = 0;
591             unsigned long vaddr = 0;
592             unsigned long k;
593
594             if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
595             if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
596             if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
597             if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
598                 elf_type |= MAP_FIXED;
599                 vaddr = eppnt->p_vaddr;
600             }
601             error = (unsigned long)mmap4k(load_addr+X86_ELF_PAGESTART(vaddr),
602                  eppnt->p_filesz + X86_ELF_PAGEOFFSET(eppnt->p_vaddr),
603                  elf_prot,
604                  elf_type,
605                  interpreter_fd,
606                  eppnt->p_offset - X86_ELF_PAGEOFFSET(eppnt->p_vaddr));
607             
608             if (error > -1024UL) {
609               /* Real error */
610               close(interpreter_fd);
611               free(elf_phdata);
612               return ~0UL;
613             }
614
615             if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
616               load_addr = error;
617               load_addr_set = 1;
618             }
619
620             /*
621              * Find the end of the file  mapping for this phdr, and keep
622              * track of the largest address we see for this.
623              */
624             k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
625             if (k > elf_bss) elf_bss = k;
626
627             /*
628              * Do the same thing for the memory mapping - between
629              * elf_bss and last_bss is the bss section.
630              */
631             k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
632             if (k > last_bss) last_bss = k;
633           }
634         
635         /* Now use mmap to map the library into memory. */
636
637         close(interpreter_fd);
638
639         /*
640          * Now fill out the bss section.  First pad the last page up
641          * to the page boundary, and then perform a mmap to make sure
642          * that there are zeromapped pages up to and including the last
643          * bss page.
644          */
645         padzero(elf_bss);
646         elf_bss = X86_ELF_PAGESTART(elf_bss + ALPHA_PAGE_SIZE - 1); /* What we have mapped so far */
647
648         /* Map the last of the bss segment */
649         if (last_bss > elf_bss) {
650           mmap4k(elf_bss, last_bss-elf_bss,
651                   PROT_READ|PROT_WRITE|PROT_EXEC,
652                   MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
653         }
654         free(elf_phdata);
655
656         *interp_load_addr = load_addr;
657         return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
658 }
659
660
661
662 static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
663                            struct image_info * info)
664 {
665     struct elfhdr elf_ex;
666     struct elfhdr interp_elf_ex;
667     struct exec interp_ex;
668     int interpreter_fd = -1; /* avoid warning */
669     unsigned long load_addr, load_bias;
670     int load_addr_set = 0;
671     unsigned int interpreter_type = INTERPRETER_NONE;
672     unsigned char ibcs2_interpreter;
673     int i;
674     void * mapped_addr;
675     struct elf_phdr * elf_ppnt;
676     struct elf_phdr *elf_phdata;
677     unsigned long elf_bss, k, elf_brk;
678     int retval;
679     char * elf_interpreter;
680     unsigned long elf_entry, interp_load_addr = 0;
681     int status;
682     unsigned long start_code, end_code, end_data;
683     unsigned long elf_stack;
684     char passed_fileno[6];
685
686     ibcs2_interpreter = 0;
687     status = 0;
688     load_addr = 0;
689     load_bias = 0;
690     elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */
691 #ifdef BSWAP_NEEDED
692     bswap_ehdr(&elf_ex);
693 #endif
694
695     if (elf_ex.e_ident[0] != 0x7f ||
696         strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
697             return  -ENOEXEC;
698     }
699
700     /* First of all, some simple consistency checks */
701     if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
702                                 (! elf_check_arch(elf_ex.e_machine))) {
703             return -ENOEXEC;
704     }
705
706     /* Now read in all of the header information */
707
708     elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
709     if (elf_phdata == NULL) {
710         return -ENOMEM;
711     }
712
713     retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
714     if(retval > 0) {
715         retval = read(bprm->fd, (char *) elf_phdata, 
716                                 elf_ex.e_phentsize * elf_ex.e_phnum);
717     }
718
719     if (retval < 0) {
720         perror("load_elf_binary");
721         exit(-1);
722         free (elf_phdata);
723         return -errno;
724     }
725
726 #ifdef BSWAP_NEEDED
727     elf_ppnt = elf_phdata;
728     for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
729         bswap_phdr(elf_ppnt);
730     }
731 #endif
732     elf_ppnt = elf_phdata;
733
734     elf_bss = 0;
735     elf_brk = 0;
736
737
738     elf_stack = ~0UL;
739     elf_interpreter = NULL;
740     start_code = ~0UL;
741     end_code = 0;
742     end_data = 0;
743
744     for(i=0;i < elf_ex.e_phnum; i++) {
745         if (elf_ppnt->p_type == PT_INTERP) {
746             if ( elf_interpreter != NULL )
747             {
748                 free (elf_phdata);
749                 free(elf_interpreter);
750                 close(bprm->fd);
751                 return -EINVAL;
752             }
753
754             /* This is the program interpreter used for
755              * shared libraries - for now assume that this
756              * is an a.out format binary
757              */
758
759             elf_interpreter = (char *)malloc(elf_ppnt->p_filesz+
760                                              strlen(bprm->interp_prefix));
761
762             if (elf_interpreter == NULL) {
763                 free (elf_phdata);
764                 close(bprm->fd);
765                 return -ENOMEM;
766             }
767
768             strcpy(elf_interpreter, bprm->interp_prefix);
769             retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
770             if(retval >= 0) {
771                 retval = read(bprm->fd, 
772                               elf_interpreter+strlen(bprm->interp_prefix), 
773                               elf_ppnt->p_filesz);
774             }
775             if(retval < 0) {
776                 perror("load_elf_binary2");
777                 exit(-1);
778             }   
779
780             /* If the program interpreter is one of these two,
781                then assume an iBCS2 image. Otherwise assume
782                a native linux image. */
783
784             /* JRP - Need to add X86 lib dir stuff here... */
785
786             if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
787                 strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
788               ibcs2_interpreter = 1;
789             }
790
791 #if 0
792             printf("Using ELF interpreter %s\n", elf_interpreter);
793 #endif
794             if (retval >= 0) {
795                 retval = open(elf_interpreter, O_RDONLY);
796                 if(retval >= 0) {
797                     interpreter_fd = retval;
798                 }
799                 else {
800                     perror(elf_interpreter);
801                     exit(-1);
802                     /* retval = -errno; */
803                 }
804             }
805
806             if (retval >= 0) {
807                 retval = lseek(interpreter_fd, 0, SEEK_SET);
808                 if(retval >= 0) {
809                     retval = read(interpreter_fd,bprm->buf,128);
810                 }
811             }
812             if (retval >= 0) {
813                 interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */
814                 interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */
815             }
816             if (retval < 0) {
817                 perror("load_elf_binary3");
818                 exit(-1);
819                 free (elf_phdata);
820                 free(elf_interpreter);
821                 close(bprm->fd);
822                 return retval;
823             }
824         }
825         elf_ppnt++;
826     }
827
828     /* Some simple consistency checks for the interpreter */
829     if (elf_interpreter){
830         interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
831
832         /* Now figure out which format our binary is */
833         if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
834                 (N_MAGIC(interp_ex) != QMAGIC)) {
835           interpreter_type = INTERPRETER_ELF;
836         }
837
838         if (interp_elf_ex.e_ident[0] != 0x7f ||
839                 strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
840             interpreter_type &= ~INTERPRETER_ELF;
841         }
842
843         if (!interpreter_type) {
844             free(elf_interpreter);
845             free(elf_phdata);
846             close(bprm->fd);
847             return -ELIBBAD;
848         }
849     }
850
851     /* OK, we are done with that, now set up the arg stuff,
852        and then start this sucker up */
853
854     if (!bprm->sh_bang) {
855         char * passed_p;
856
857         if (interpreter_type == INTERPRETER_AOUT) {
858             sprintf(passed_fileno, "%d", bprm->fd);
859             passed_p = passed_fileno;
860
861             if (elf_interpreter) {
862                 bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p);
863                 bprm->argc++;
864             }
865         }
866         if (!bprm->p) {
867             if (elf_interpreter) {
868                 free(elf_interpreter);
869             }
870             free (elf_phdata);
871             close(bprm->fd);
872             return -E2BIG;
873         }
874     }
875
876     /* OK, This is the point of no return */
877     info->end_data = 0;
878     info->end_code = 0;
879     info->start_mmap = (unsigned long)ELF_START_MMAP;
880     info->mmap = 0;
881     elf_entry = (unsigned long) elf_ex.e_entry;
882
883     /* Do this so that we can load the interpreter, if need be.  We will
884        change some of these later */
885     info->rss = 0;
886     bprm->p = setup_arg_pages(bprm->p, bprm, info);
887     info->start_stack = bprm->p;
888
889     /* Now we do a little grungy work by mmaping the ELF image into
890      * the correct location in memory.  At this point, we assume that
891      * the image should be loaded at fixed address, not at a variable
892      * address.
893      */
894
895     for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
896         int elf_prot = 0;
897         int elf_flags = 0;
898         unsigned long error;
899         
900         if (elf_ppnt->p_type != PT_LOAD)
901             continue;
902         
903         if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
904         if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
905         if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
906         elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
907         if (elf_ex.e_type == ET_EXEC || load_addr_set) {
908             elf_flags |= MAP_FIXED;
909         } else if (elf_ex.e_type == ET_DYN) {
910             /* Try and get dynamic programs out of the way of the default mmap
911                base, as well as whatever program they might try to exec.  This
912                is because the brk will follow the loader, and is not movable.  */
913             /* NOTE: for qemu, we do a big mmap to get enough space
914                without harcoding any address */
915             error = (unsigned long)mmap4k(NULL, ET_DYN_MAP_SIZE,
916                                           PROT_NONE, MAP_PRIVATE | MAP_ANON, 
917                                           -1, 0);
918             if (error == -1) {
919                 perror("mmap");
920                 exit(-1);
921             }
922             load_bias = X86_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
923         }
924         
925         error = (unsigned long)mmap4k(
926                                       X86_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
927                                       (elf_ppnt->p_filesz +
928                                        X86_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
929                                       elf_prot,
930                                       (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
931                                       bprm->fd,
932                                       (elf_ppnt->p_offset - 
933                                        X86_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
934         if (error == -1) {
935             perror("mmap");
936             exit(-1);
937         }
938
939 #ifdef LOW_ELF_STACK
940         if (X86_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
941             elf_stack = X86_ELF_PAGESTART(elf_ppnt->p_vaddr);
942 #endif
943         
944         if (!load_addr_set) {
945             load_addr_set = 1;
946             load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
947             if (elf_ex.e_type == ET_DYN) {
948                 load_bias += error -
949                     X86_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
950                 load_addr += load_bias;
951             }
952         }
953         k = elf_ppnt->p_vaddr;
954         if (k < start_code) 
955             start_code = k;
956         k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
957         if (k > elf_bss) 
958             elf_bss = k;
959         if ((elf_ppnt->p_flags & PF_X) && end_code <  k)
960             end_code = k;
961         if (end_data < k) 
962             end_data = k;
963         k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
964         if (k > elf_brk) elf_brk = k;
965     }
966
967     elf_entry += load_bias;
968     elf_bss += load_bias;
969     elf_brk += load_bias;
970     start_code += load_bias;
971     end_code += load_bias;
972     //    start_data += load_bias;
973     end_data += load_bias;
974
975     if (elf_interpreter) {
976         if (interpreter_type & 1) {
977             elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
978         }
979         else if (interpreter_type & 2) {
980             elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
981                                             &interp_load_addr);
982         }
983
984         close(interpreter_fd);
985         free(elf_interpreter);
986
987         if (elf_entry == ~0UL) {
988             printf("Unable to load interpreter\n");
989             free(elf_phdata);
990             exit(-1);
991             return 0;
992         }
993     }
994
995     free(elf_phdata);
996
997     if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
998     info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
999
1000 #ifdef LOW_ELF_STACK
1001     info->start_stack = bprm->p = elf_stack - 4;
1002 #endif
1003     bprm->p = (unsigned long)
1004       create_elf_tables((char *)bprm->p,
1005                     bprm->argc,
1006                     bprm->envc,
1007                     (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
1008                     load_addr, load_bias,
1009                     interp_load_addr,
1010                     (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
1011                     info);
1012     if (interpreter_type == INTERPRETER_AOUT)
1013       info->arg_start += strlen(passed_fileno) + 1;
1014     info->start_brk = info->brk = elf_brk;
1015     info->end_code = end_code;
1016     info->start_code = start_code;
1017     info->end_data = end_data;
1018     info->start_stack = bprm->p;
1019
1020     /* Calling set_brk effectively mmaps the pages that we need for the bss and break
1021        sections */
1022     set_brk(elf_bss, elf_brk);
1023
1024     padzero(elf_bss);
1025
1026 #if 0
1027     printf("(start_brk) %x\n" , info->start_brk);
1028     printf("(end_code) %x\n" , info->end_code);
1029     printf("(start_code) %x\n" , info->start_code);
1030     printf("(end_data) %x\n" , info->end_data);
1031     printf("(start_stack) %x\n" , info->start_stack);
1032     printf("(brk) %x\n" , info->brk);
1033 #endif
1034
1035     if ( info->personality == PER_SVR4 )
1036     {
1037             /* Why this, you ask???  Well SVr4 maps page 0 as read-only,
1038                and some applications "depend" upon this behavior.
1039                Since we do not have the power to recompile these, we
1040                emulate the SVr4 behavior.  Sigh.  */
1041             mapped_addr = mmap4k(NULL, ALPHA_PAGE_SIZE, PROT_READ | PROT_EXEC,
1042                             MAP_FIXED | MAP_PRIVATE, -1, 0);
1043     }
1044
1045 #ifdef ELF_PLAT_INIT
1046     /*
1047      * The ABI may specify that certain registers be set up in special
1048      * ways (on i386 %edx is the address of a DT_FINI function, for
1049      * example.  This macro performs whatever initialization to
1050      * the regs structure is required.
1051      */
1052     ELF_PLAT_INIT(regs);
1053 #endif
1054
1055
1056     info->entry = elf_entry;
1057
1058     return 0;
1059 }
1060
1061
1062
1063 int elf_exec(const char *interp_prefix, 
1064              const char * filename, char ** argv, char ** envp, 
1065              struct target_pt_regs * regs, struct image_info *infop)
1066 {
1067         struct linux_binprm bprm;
1068         int retval;
1069         int i;
1070
1071         bprm.p = X86_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
1072         for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
1073                 bprm.page[i] = 0;
1074         retval = open(filename, O_RDONLY);
1075         if (retval == -1) {
1076             perror(filename);
1077             exit(-1);
1078             /* return retval; */
1079         }
1080         else {
1081             bprm.fd = retval;
1082         }
1083         bprm.interp_prefix = (char *)interp_prefix;
1084         bprm.filename = (char *)filename;
1085         bprm.sh_bang = 0;
1086         bprm.loader = 0;
1087         bprm.exec = 0;
1088         bprm.dont_iput = 0;
1089         bprm.argc = count(argv);
1090         bprm.envc = count(envp);
1091
1092         retval = prepare_binprm(&bprm);
1093
1094         if(retval>=0) {
1095             bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p);
1096             bprm.exec = bprm.p;
1097             bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p);
1098             bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p);
1099             if (!bprm.p) {
1100                 retval = -E2BIG;
1101             }
1102         }
1103
1104         if(retval>=0) {
1105             retval = load_elf_binary(&bprm,regs,infop);
1106         }
1107         if(retval>=0) {
1108             /* success.  Initialize important registers */
1109             regs->esp = infop->start_stack;
1110             regs->eip = infop->entry;
1111             return retval;
1112         }
1113
1114         /* Something went wrong, return the inode and free the argument pages*/
1115         for (i=0 ; i<MAX_ARG_PAGES ; i++) {
1116             free_page((void *)bprm.page[i]);
1117         }
1118         return(retval);
1119 }
1120
1121
1122 static int load_aout_interp(void * exptr, int interp_fd)
1123 {
1124     printf("a.out interpreter not yet supported\n");
1125     return(0);
1126 }
1127