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