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