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