xref: /openbmc/qemu/bsd-user/elfload.c (revision 98b34d354b5da78880cb39dc3a7db91c790f7c7d)
1 /*
2  *  ELF loading code
3  *
4  *  Copyright (c) 2013 Stacey D. Son
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "qemu/osdep.h"
21 
22 #include "qemu.h"
23 #include "disas/disas.h"
24 #include "qemu/path.h"
25 
26 static abi_ulong target_auxents;   /* Where the AUX entries are in target */
27 static size_t target_auxents_sz;   /* Size of AUX entries including AT_NULL */
28 
29 #include "target_os_elf.h"
30 #include "target_os_stack.h"
31 #include "target_os_thread.h"
32 
33 #include "elf.h"
34 
35 abi_ulong target_stksiz;
36 abi_ulong target_stkbas;
37 
38 static inline void memcpy_fromfs(void *to, const void *from, unsigned long n)
39 {
40     memcpy(to, from, n);
41 }
42 
43 #ifdef BSWAP_NEEDED
44 static void bswap_ehdr(struct elfhdr *ehdr)
45 {
46     bswap16s(&ehdr->e_type);            /* Object file type */
47     bswap16s(&ehdr->e_machine);         /* Architecture */
48     bswap32s(&ehdr->e_version);         /* Object file version */
49     bswaptls(&ehdr->e_entry);           /* Entry point virtual address */
50     bswaptls(&ehdr->e_phoff);           /* Program header table file offset */
51     bswaptls(&ehdr->e_shoff);           /* Section header table file offset */
52     bswap32s(&ehdr->e_flags);           /* Processor-specific flags */
53     bswap16s(&ehdr->e_ehsize);          /* ELF header size in bytes */
54     bswap16s(&ehdr->e_phentsize);       /* Program header table entry size */
55     bswap16s(&ehdr->e_phnum);           /* Program header table entry count */
56     bswap16s(&ehdr->e_shentsize);       /* Section header table entry size */
57     bswap16s(&ehdr->e_shnum);           /* Section header table entry count */
58     bswap16s(&ehdr->e_shstrndx);        /* Section header string table index */
59 }
60 
61 static void bswap_phdr(struct elf_phdr *phdr, int phnum)
62 {
63     int i;
64 
65     for (i = 0; i < phnum; i++, phdr++) {
66         bswap32s(&phdr->p_type);        /* Segment type */
67         bswap32s(&phdr->p_flags);       /* Segment flags */
68         bswaptls(&phdr->p_offset);      /* Segment file offset */
69         bswaptls(&phdr->p_vaddr);       /* Segment virtual address */
70         bswaptls(&phdr->p_paddr);       /* Segment physical address */
71         bswaptls(&phdr->p_filesz);      /* Segment size in file */
72         bswaptls(&phdr->p_memsz);       /* Segment size in memory */
73         bswaptls(&phdr->p_align);       /* Segment alignment */
74     }
75 }
76 
77 static void bswap_shdr(struct elf_shdr *shdr, int shnum)
78 {
79     int i;
80 
81     for (i = 0; i < shnum; i++, shdr++) {
82         bswap32s(&shdr->sh_name);
83         bswap32s(&shdr->sh_type);
84         bswaptls(&shdr->sh_flags);
85         bswaptls(&shdr->sh_addr);
86         bswaptls(&shdr->sh_offset);
87         bswaptls(&shdr->sh_size);
88         bswap32s(&shdr->sh_link);
89         bswap32s(&shdr->sh_info);
90         bswaptls(&shdr->sh_addralign);
91         bswaptls(&shdr->sh_entsize);
92     }
93 }
94 
95 static void bswap_sym(struct elf_sym *sym)
96 {
97     bswap32s(&sym->st_name);
98     bswaptls(&sym->st_value);
99     bswaptls(&sym->st_size);
100     bswap16s(&sym->st_shndx);
101 }
102 
103 #else /* ! BSWAP_NEEDED */
104 
105 static void bswap_ehdr(struct elfhdr *ehdr) { }
106 static void bswap_phdr(struct elf_phdr *phdr, int phnum) { }
107 static void bswap_shdr(struct elf_shdr *shdr, int shnum) { }
108 static void bswap_sym(struct elf_sym *sym) { }
109 
110 #endif /* ! BSWAP_NEEDED */
111 
112 /*
113  * 'copy_elf_strings()' copies argument/envelope strings from user
114  * memory to free pages in kernel mem. These are in a format ready
115  * to be put directly into the top of new user memory.
116  *
117  */
118 static abi_ulong copy_elf_strings(int argc, char **argv, void **page,
119                                   abi_ulong p)
120 {
121     char *tmp, *tmp1, *pag = NULL;
122     int len, offset = 0;
123 
124     if (!p) {
125         return 0;       /* bullet-proofing */
126     }
127     while (argc-- > 0) {
128         tmp = argv[argc];
129         if (!tmp) {
130             fprintf(stderr, "VFS: argc is wrong");
131             exit(-1);
132         }
133         tmp1 = tmp;
134         while (*tmp++);
135         len = tmp - tmp1;
136         if (p < len) {  /* this shouldn't happen - 128kB */
137                 return 0;
138         }
139         while (len) {
140             --p; --tmp; --len;
141             if (--offset < 0) {
142                 offset = p % TARGET_PAGE_SIZE;
143                 pag = (char *)page[p / TARGET_PAGE_SIZE];
144                 if (!pag) {
145                     pag = g_try_malloc0(TARGET_PAGE_SIZE);
146                     page[p / TARGET_PAGE_SIZE] = pag;
147                     if (!pag)
148                         return 0;
149                 }
150             }
151             if (len == 0 || offset == 0) {
152                 *(pag + offset) = *tmp;
153             }
154             else {
155               int bytes_to_copy = (len > offset) ? offset : len;
156               tmp -= bytes_to_copy;
157               p -= bytes_to_copy;
158               offset -= bytes_to_copy;
159               len -= bytes_to_copy;
160               memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
161             }
162         }
163     }
164     return p;
165 }
166 
167 static void setup_arg_pages(struct bsd_binprm *bprm, struct image_info *info,
168                             abi_ulong *stackp, abi_ulong *stringp)
169 {
170     abi_ulong stack_base, size;
171     abi_long addr;
172 
173     /* Create enough stack to hold everything.  If we don't use
174      * it for args, we'll use it for something else...
175      */
176     size = target_dflssiz;
177     stack_base = TARGET_USRSTACK - size;
178     addr = target_mmap(stack_base,
179                         size + qemu_host_page_size,
180                         PROT_READ | PROT_WRITE,
181                         MAP_PRIVATE | MAP_ANON,
182                         -1, 0);
183     if (addr == -1) {
184         perror("stk mmap");
185         exit(-1);
186     }
187     /* we reserve one extra page at the top of the stack as guard */
188     target_mprotect(addr + size, qemu_host_page_size, PROT_NONE);
189 
190     target_stksiz = size;
191     target_stkbas = addr;
192 
193     if (setup_initial_stack(bprm, stackp, stringp) != 0) {
194         perror("stk setup");
195         exit(-1);
196     }
197 }
198 
199 static void set_brk(abi_ulong start, abi_ulong end)
200 {
201         /* page-align the start and end addresses... */
202         start = HOST_PAGE_ALIGN(start);
203         end = HOST_PAGE_ALIGN(end);
204         if (end <= start)
205                 return;
206         if (target_mmap(start, end - start,
207                        PROT_READ | PROT_WRITE | PROT_EXEC,
208                        MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0) == -1) {
209             perror("cannot mmap brk");
210             exit(-1);
211         }
212 }
213 
214 
215 /* We need to explicitly zero any fractional pages after the data
216    section (i.e. bss).  This would contain the junk from the file that
217    should not be in memory. */
218 static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
219 {
220         abi_ulong nbyte;
221 
222         if (elf_bss >= last_bss)
223                 return;
224 
225         /* XXX: this is really a hack : if the real host page size is
226            smaller than the target page size, some pages after the end
227            of the file may not be mapped. A better fix would be to
228            patch target_mmap(), but it is more complicated as the file
229            size must be known */
230         if (qemu_real_host_page_size < qemu_host_page_size) {
231             abi_ulong end_addr, end_addr1;
232             end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss);
233             end_addr = HOST_PAGE_ALIGN(elf_bss);
234             if (end_addr1 < end_addr) {
235                 mmap((void *)g2h_untagged(end_addr1), end_addr - end_addr1,
236                      PROT_READ | PROT_WRITE | PROT_EXEC,
237                      MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
238             }
239         }
240 
241         nbyte = elf_bss & (qemu_host_page_size - 1);
242         if (nbyte) {
243             nbyte = qemu_host_page_size - nbyte;
244             do {
245                 /* FIXME - what to do if put_user() fails? */
246                 put_user_u8(0, elf_bss);
247                 elf_bss++;
248             } while (--nbyte);
249         }
250 }
251 
252 static abi_ulong load_elf_interp(struct elfhdr *interp_elf_ex,
253                                  int interpreter_fd,
254                                  abi_ulong *interp_load_addr)
255 {
256     struct elf_phdr *elf_phdata  =  NULL;
257     struct elf_phdr *eppnt;
258     abi_ulong load_addr = 0;
259     int load_addr_set = 0;
260     int retval;
261     abi_ulong last_bss, elf_bss;
262     abi_ulong error;
263     int i;
264 
265     elf_bss = 0;
266     last_bss = 0;
267     error = 0;
268 
269     bswap_ehdr(interp_elf_ex);
270     /* First of all, some simple consistency checks */
271     if ((interp_elf_ex->e_type != ET_EXEC &&
272          interp_elf_ex->e_type != ET_DYN) ||
273         !elf_check_arch(interp_elf_ex->e_machine)) {
274         return ~((abi_ulong)0UL);
275     }
276 
277 
278     /* Now read in all of the header information */
279 
280     if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
281         return ~(abi_ulong)0UL;
282 
283     elf_phdata =  (struct elf_phdr *)
284         malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
285 
286     if (!elf_phdata)
287         return ~((abi_ulong)0UL);
288 
289     /*
290      * If the size of this structure has changed, then punt, since
291      * we will be doing the wrong thing.
292      */
293     if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
294         free(elf_phdata);
295         return ~((abi_ulong)0UL);
296     }
297 
298     retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
299     if (retval >= 0) {
300         retval = read(interpreter_fd,
301                       (char *) elf_phdata,
302                       sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
303     }
304     if (retval < 0) {
305         perror("load_elf_interp");
306         exit(-1);
307         free(elf_phdata);
308         return retval;
309     }
310     bswap_phdr(elf_phdata, interp_elf_ex->e_phnum);
311 
312     if (interp_elf_ex->e_type == ET_DYN) {
313         /* in order to avoid hardcoding the interpreter load
314            address in qemu, we allocate a big enough memory zone */
315         error = target_mmap(0, INTERP_MAP_SIZE,
316                             PROT_NONE, MAP_PRIVATE | MAP_ANON,
317                             -1, 0);
318         if (error == -1) {
319             perror("mmap");
320             exit(-1);
321         }
322         load_addr = error;
323         load_addr_set = 1;
324     }
325 
326     eppnt = elf_phdata;
327     for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++)
328         if (eppnt->p_type == PT_LOAD) {
329             int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
330             int elf_prot = 0;
331             abi_ulong vaddr = 0;
332             abi_ulong k;
333 
334             if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
335             if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
336             if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
337             if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
338                 elf_type |= MAP_FIXED;
339                 vaddr = eppnt->p_vaddr;
340             }
341             error = target_mmap(load_addr + TARGET_ELF_PAGESTART(vaddr),
342                                 eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
343                                 elf_prot,
344                                 elf_type,
345                                 interpreter_fd,
346                                 eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
347 
348             if (error == -1) {
349                 /* Real error */
350                 close(interpreter_fd);
351                 free(elf_phdata);
352                 return ~((abi_ulong)0UL);
353             }
354 
355             if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
356                 load_addr = error;
357                 load_addr_set = 1;
358             }
359 
360             /*
361              * Find the end of the file  mapping for this phdr, and keep
362              * track of the largest address we see for this.
363              */
364             k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
365             if (k > elf_bss) elf_bss = k;
366 
367             /*
368              * Do the same thing for the memory mapping - between
369              * elf_bss and last_bss is the bss section.
370              */
371             k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
372             if (k > last_bss) last_bss = k;
373         }
374 
375     /* Now use mmap to map the library into memory. */
376 
377     close(interpreter_fd);
378 
379     /*
380      * Now fill out the bss section.  First pad the last page up
381      * to the page boundary, and then perform a mmap to make sure
382      * that there are zeromapped pages up to and including the last
383      * bss page.
384      */
385     padzero(elf_bss, last_bss);
386     elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); /* What we have mapped so far */
387 
388     /* Map the last of the bss segment */
389     if (last_bss > elf_bss) {
390         target_mmap(elf_bss, last_bss - elf_bss,
391                     PROT_READ | PROT_WRITE | PROT_EXEC,
392                     MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
393     }
394     free(elf_phdata);
395 
396     *interp_load_addr = load_addr;
397     return ((abi_ulong) interp_elf_ex->e_entry) + load_addr;
398 }
399 
400 static int symfind(const void *s0, const void *s1)
401 {
402     target_ulong addr = *(target_ulong *)s0;
403     struct elf_sym *sym = (struct elf_sym *)s1;
404     int result = 0;
405     if (addr < sym->st_value) {
406         result = -1;
407     } else if (addr >= sym->st_value + sym->st_size) {
408         result = 1;
409     }
410     return result;
411 }
412 
413 static const char *lookup_symbolxx(struct syminfo *s, target_ulong orig_addr)
414 {
415 #if ELF_CLASS == ELFCLASS32
416     struct elf_sym *syms = s->disas_symtab.elf32;
417 #else
418     struct elf_sym *syms = s->disas_symtab.elf64;
419 #endif
420 
421     // binary search
422     struct elf_sym *sym;
423 
424     sym = bsearch(&orig_addr, syms, s->disas_num_syms, sizeof(*syms), symfind);
425     if (sym != NULL) {
426         return s->disas_strtab + sym->st_name;
427     }
428 
429     return "";
430 }
431 
432 /* FIXME: This should use elf_ops.h  */
433 static int symcmp(const void *s0, const void *s1)
434 {
435     struct elf_sym *sym0 = (struct elf_sym *)s0;
436     struct elf_sym *sym1 = (struct elf_sym *)s1;
437     return (sym0->st_value < sym1->st_value)
438         ? -1
439         : ((sym0->st_value > sym1->st_value) ? 1 : 0);
440 }
441 
442 /* Best attempt to load symbols from this ELF object. */
443 static void load_symbols(struct elfhdr *hdr, int fd)
444 {
445     unsigned int i, nsyms;
446     struct elf_shdr sechdr, symtab, strtab;
447     char *strings;
448     struct syminfo *s;
449     struct elf_sym *syms, *new_syms;
450 
451     lseek(fd, hdr->e_shoff, SEEK_SET);
452     for (i = 0; i < hdr->e_shnum; i++) {
453         if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
454             return;
455         bswap_shdr(&sechdr, 1);
456         if (sechdr.sh_type == SHT_SYMTAB) {
457             symtab = sechdr;
458             lseek(fd, hdr->e_shoff
459                   + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
460             if (read(fd, &strtab, sizeof(strtab))
461                 != sizeof(strtab))
462                 return;
463             bswap_shdr(&strtab, 1);
464             goto found;
465         }
466     }
467     return; /* Shouldn't happen... */
468 
469  found:
470     /* Now know where the strtab and symtab are.  Snarf them. */
471     s = malloc(sizeof(*s));
472     syms = malloc(symtab.sh_size);
473     if (!syms) {
474         free(s);
475         return;
476     }
477     s->disas_strtab = strings = malloc(strtab.sh_size);
478     if (!s->disas_strtab) {
479         free(s);
480         free(syms);
481         return;
482     }
483 
484     lseek(fd, symtab.sh_offset, SEEK_SET);
485     if (read(fd, syms, symtab.sh_size) != symtab.sh_size) {
486         free(s);
487         free(syms);
488         free(strings);
489         return;
490     }
491 
492     nsyms = symtab.sh_size / sizeof(struct elf_sym);
493 
494     i = 0;
495     while (i < nsyms) {
496         bswap_sym(syms + i);
497         // Throw away entries which we do not need.
498         if (syms[i].st_shndx == SHN_UNDEF ||
499                 syms[i].st_shndx >= SHN_LORESERVE ||
500                 ELF_ST_TYPE(syms[i].st_info) != STT_FUNC) {
501             nsyms--;
502             if (i < nsyms) {
503                 syms[i] = syms[nsyms];
504             }
505             continue;
506         }
507         i++;
508     }
509 
510      /* Attempt to free the storage associated with the local symbols
511         that we threw away.  Whether or not this has any effect on the
512         memory allocation depends on the malloc implementation and how
513         many symbols we managed to discard. */
514     new_syms = realloc(syms, nsyms * sizeof(*syms));
515     if (new_syms == NULL) {
516         free(s);
517         free(syms);
518         free(strings);
519         return;
520     }
521     syms = new_syms;
522 
523     qsort(syms, nsyms, sizeof(*syms), symcmp);
524 
525     lseek(fd, strtab.sh_offset, SEEK_SET);
526     if (read(fd, strings, strtab.sh_size) != strtab.sh_size) {
527         free(s);
528         free(syms);
529         free(strings);
530         return;
531     }
532     s->disas_num_syms = nsyms;
533 #if ELF_CLASS == ELFCLASS32
534     s->disas_symtab.elf32 = syms;
535     s->lookup_symbol = (lookup_symbol_t)lookup_symbolxx;
536 #else
537     s->disas_symtab.elf64 = syms;
538     s->lookup_symbol = (lookup_symbol_t)lookup_symbolxx;
539 #endif
540     s->next = syminfos;
541     syminfos = s;
542 }
543 
544 int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
545                     struct image_info *info)
546 {
547     struct elfhdr elf_ex;
548     struct elfhdr interp_elf_ex;
549     int interpreter_fd = -1; /* avoid warning */
550     abi_ulong load_addr, load_bias;
551     int load_addr_set = 0;
552     int i;
553     struct elf_phdr * elf_ppnt;
554     struct elf_phdr *elf_phdata;
555     abi_ulong elf_bss, k, elf_brk;
556     int retval;
557     char * elf_interpreter;
558     abi_ulong elf_entry, interp_load_addr = 0;
559     abi_ulong start_code, end_code, start_data, end_data;
560     abi_ulong reloc_func_desc = 0;
561 #ifdef LOW_ELF_STACK
562     abi_ulong elf_stack = ~((abi_ulong)0UL);
563 #endif
564 
565     load_addr = 0;
566     load_bias = 0;
567     elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */
568     bswap_ehdr(&elf_ex);
569 
570     /* First of all, some simple consistency checks */
571     if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
572                                 (!elf_check_arch(elf_ex.e_machine))) {
573             return -ENOEXEC;
574     }
575 
576     bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p);
577     bprm->p = copy_elf_strings(bprm->envc, bprm->envp, bprm->page,bprm->p);
578     bprm->p = copy_elf_strings(bprm->argc, bprm->argv, bprm->page,bprm->p);
579     if (!bprm->p) {
580         retval = -E2BIG;
581     }
582 
583     /* Now read in all of the header information */
584     elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
585     if (elf_phdata == NULL) {
586         return -ENOMEM;
587     }
588 
589     retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
590     if (retval > 0) {
591         retval = read(bprm->fd, (char *)elf_phdata,
592                                 elf_ex.e_phentsize * elf_ex.e_phnum);
593     }
594 
595     if (retval < 0) {
596         perror("load_elf_binary");
597         exit(-1);
598         free(elf_phdata);
599         return -errno;
600     }
601 
602     bswap_phdr(elf_phdata, elf_ex.e_phnum);
603 
604     elf_ppnt = elf_phdata;
605 
606     elf_bss = 0;
607     elf_brk = 0;
608 
609 
610     elf_interpreter = NULL;
611     start_code = ~((abi_ulong)0UL);
612     end_code = 0;
613     start_data = 0;
614     end_data = 0;
615 
616     for (i = 0;i < elf_ex.e_phnum; i++) {
617         if (elf_ppnt->p_type == PT_INTERP) {
618             if (elf_interpreter != NULL)
619             {
620                 free(elf_phdata);
621                 free(elf_interpreter);
622                 close(bprm->fd);
623                 return -EINVAL;
624             }
625 
626             /* This is the program interpreter used for
627              * shared libraries - for now assume that this
628              * is an a.out format binary
629              */
630 
631             elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
632 
633             if (elf_interpreter == NULL) {
634                 free(elf_phdata);
635                 close(bprm->fd);
636                 return -ENOMEM;
637             }
638 
639             retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
640             if (retval >= 0) {
641                 retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
642             }
643             if (retval < 0) {
644                 perror("load_elf_binary2");
645                 exit(-1);
646             }
647 
648             if (retval >= 0) {
649                 retval = open(path(elf_interpreter), O_RDONLY);
650                 if (retval >= 0) {
651                     interpreter_fd = retval;
652                 }
653                 else {
654                     perror(elf_interpreter);
655                     exit(-1);
656                     /* retval = -errno; */
657                 }
658             }
659 
660             if (retval >= 0) {
661                 retval = lseek(interpreter_fd, 0, SEEK_SET);
662                 if (retval >= 0) {
663                     retval = read(interpreter_fd, bprm->buf, 128);
664                 }
665             }
666             if (retval >= 0) {
667                 interp_elf_ex = *((struct elfhdr *) bprm->buf); /* elf exec-header */
668             }
669             if (retval < 0) {
670                 perror("load_elf_binary3");
671                 exit(-1);
672                 free(elf_phdata);
673                 free(elf_interpreter);
674                 close(bprm->fd);
675                 return retval;
676             }
677         }
678         elf_ppnt++;
679     }
680 
681     /* Some simple consistency checks for the interpreter */
682     if (elf_interpreter) {
683         if (interp_elf_ex.e_ident[0] != 0x7f ||
684             strncmp((char *)&interp_elf_ex.e_ident[1], "ELF", 3) != 0) {
685             free(elf_interpreter);
686             free(elf_phdata);
687             close(bprm->fd);
688             return -ELIBBAD;
689         }
690     }
691 
692     /* OK, we are done with that, now set up the arg stuff,
693        and then start this sucker up */
694 
695     if (!bprm->p) {
696         free(elf_interpreter);
697         free(elf_phdata);
698         close(bprm->fd);
699         return -E2BIG;
700     }
701 
702     /* OK, This is the point of no return */
703     info->end_data = 0;
704     info->end_code = 0;
705     info->start_mmap = (abi_ulong)ELF_START_MMAP;
706     info->mmap = 0;
707     elf_entry = (abi_ulong) elf_ex.e_entry;
708 
709     /* Do this so that we can load the interpreter, if need be.  We will
710        change some of these later */
711     info->rss = 0;
712     setup_arg_pages(bprm, info, &bprm->p, &bprm->stringp);
713     info->start_stack = bprm->p;
714 
715     /* Now we do a little grungy work by mmaping the ELF image into
716      * the correct location in memory.  At this point, we assume that
717      * the image should be loaded at fixed address, not at a variable
718      * address.
719      */
720 
721     for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
722         int elf_prot = 0;
723         int elf_flags = 0;
724         abi_ulong error;
725 
726         if (elf_ppnt->p_type != PT_LOAD)
727             continue;
728 
729         if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
730         if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
731         if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
732         elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
733         if (elf_ex.e_type == ET_EXEC || load_addr_set) {
734             elf_flags |= MAP_FIXED;
735         } else if (elf_ex.e_type == ET_DYN) {
736             /* Try and get dynamic programs out of the way of the default mmap
737                base, as well as whatever program they might try to exec.  This
738                is because the brk will follow the loader, and is not movable.  */
739             /* NOTE: for qemu, we do a big mmap to get enough space
740                without hardcoding any address */
741             error = target_mmap(0, ET_DYN_MAP_SIZE,
742                                 PROT_NONE, MAP_PRIVATE | MAP_ANON,
743                                 -1, 0);
744             if (error == -1) {
745                 perror("mmap");
746                 exit(-1);
747             }
748             load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
749         }
750 
751         error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
752                             (elf_ppnt->p_filesz +
753                              TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
754                             elf_prot,
755                             (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
756                             bprm->fd,
757                             (elf_ppnt->p_offset -
758                              TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
759         if (error == -1) {
760             perror("mmap");
761             exit(-1);
762         }
763 
764 #ifdef LOW_ELF_STACK
765         if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
766             elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr);
767 #endif
768 
769         if (!load_addr_set) {
770             load_addr_set = 1;
771             load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
772             if (elf_ex.e_type == ET_DYN) {
773                 load_bias += error -
774                     TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
775                 load_addr += load_bias;
776                 reloc_func_desc = load_bias;
777             }
778         }
779         k = elf_ppnt->p_vaddr;
780         if (k < start_code)
781             start_code = k;
782         if (start_data < k)
783             start_data = k;
784         k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
785         if (k > elf_bss)
786             elf_bss = k;
787         if ((elf_ppnt->p_flags & PF_X) && end_code <  k)
788             end_code = k;
789         if (end_data < k)
790             end_data = k;
791         k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
792         if (k > elf_brk) elf_brk = k;
793     }
794 
795     elf_entry += load_bias;
796     elf_bss += load_bias;
797     elf_brk += load_bias;
798     start_code += load_bias;
799     end_code += load_bias;
800     start_data += load_bias;
801     end_data += load_bias;
802 
803     if (elf_interpreter) {
804         elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
805                                     &interp_load_addr);
806         reloc_func_desc = interp_load_addr;
807 
808         close(interpreter_fd);
809         free(elf_interpreter);
810 
811         if (elf_entry == ~((abi_ulong)0UL)) {
812             printf("Unable to load interpreter\n");
813             free(elf_phdata);
814             exit(-1);
815             return 0;
816         }
817     }
818 
819     free(elf_phdata);
820 
821     if (qemu_log_enabled())
822         load_symbols(&elf_ex, bprm->fd);
823 
824     close(bprm->fd);
825 
826 #ifdef LOW_ELF_STACK
827     info->start_stack = bprm->p = elf_stack - 4;
828 #endif
829     bprm->p = target_create_elf_tables(bprm->p, bprm->argc, bprm->envc,
830                                        bprm->stringp, &elf_ex, load_addr,
831                                        load_bias, interp_load_addr, info);
832     info->load_addr = reloc_func_desc;
833     info->start_brk = info->brk = elf_brk;
834     info->end_code = end_code;
835     info->start_code = start_code;
836     info->start_data = start_data;
837     info->end_data = end_data;
838     info->start_stack = bprm->p;
839 
840     /* Calling set_brk effectively mmaps the pages that we need for the bss and break
841        sections */
842     set_brk(elf_bss, elf_brk);
843 
844     padzero(elf_bss, elf_brk);
845 
846 #if 0
847     printf("(start_brk) %x\n" , info->start_brk);
848     printf("(end_code) %x\n" , info->end_code);
849     printf("(start_code) %x\n" , info->start_code);
850     printf("(end_data) %x\n" , info->end_data);
851     printf("(start_stack) %x\n" , info->start_stack);
852     printf("(brk) %x\n" , info->brk);
853 #endif
854 
855     info->entry = elf_entry;
856 
857     return 0;
858 }
859 
860 void do_init_thread(struct target_pt_regs *regs, struct image_info *infop)
861 {
862 
863     target_thread_init(regs, infop);
864 }
865