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