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