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