OSDN Git Service

bsd-user: Add target_os_user.h to capture the user/kernel structures
[qmiga/qemu.git] / bsd-user / elfload.c
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
562     load_addr = 0;
563     load_bias = 0;
564     elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */
565     bswap_ehdr(&elf_ex);
566
567     /* First of all, some simple consistency checks */
568     if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
569                                 (!elf_check_arch(elf_ex.e_machine))) {
570             return -ENOEXEC;
571     }
572
573     bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p);
574     bprm->p = copy_elf_strings(bprm->envc, bprm->envp, bprm->page,bprm->p);
575     bprm->p = copy_elf_strings(bprm->argc, bprm->argv, bprm->page,bprm->p);
576     if (!bprm->p) {
577         retval = -E2BIG;
578     }
579
580     /* Now read in all of the header information */
581     elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
582     if (elf_phdata == NULL) {
583         return -ENOMEM;
584     }
585
586     retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
587     if (retval > 0) {
588         retval = read(bprm->fd, (char *)elf_phdata,
589                                 elf_ex.e_phentsize * elf_ex.e_phnum);
590     }
591
592     if (retval < 0) {
593         perror("load_elf_binary");
594         exit(-1);
595         free(elf_phdata);
596         return -errno;
597     }
598
599     bswap_phdr(elf_phdata, elf_ex.e_phnum);
600
601     elf_ppnt = elf_phdata;
602
603     elf_bss = 0;
604     elf_brk = 0;
605
606
607     elf_interpreter = NULL;
608     start_code = ~((abi_ulong)0UL);
609     end_code = 0;
610     start_data = 0;
611     end_data = 0;
612
613     for (i = 0;i < elf_ex.e_phnum; i++) {
614         if (elf_ppnt->p_type == PT_INTERP) {
615             if (elf_interpreter != NULL)
616             {
617                 free(elf_phdata);
618                 free(elf_interpreter);
619                 close(bprm->fd);
620                 return -EINVAL;
621             }
622
623             /* This is the program interpreter used for
624              * shared libraries - for now assume that this
625              * is an a.out format binary
626              */
627
628             elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
629
630             if (elf_interpreter == NULL) {
631                 free(elf_phdata);
632                 close(bprm->fd);
633                 return -ENOMEM;
634             }
635
636             retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
637             if (retval >= 0) {
638                 retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
639             }
640             if (retval < 0) {
641                 perror("load_elf_binary2");
642                 exit(-1);
643             }
644
645             if (retval >= 0) {
646                 retval = open(path(elf_interpreter), O_RDONLY);
647                 if (retval >= 0) {
648                     interpreter_fd = retval;
649                 }
650                 else {
651                     perror(elf_interpreter);
652                     exit(-1);
653                     /* retval = -errno; */
654                 }
655             }
656
657             if (retval >= 0) {
658                 retval = lseek(interpreter_fd, 0, SEEK_SET);
659                 if (retval >= 0) {
660                     retval = read(interpreter_fd, bprm->buf, 128);
661                 }
662             }
663             if (retval >= 0) {
664                 interp_elf_ex = *((struct elfhdr *) bprm->buf); /* elf exec-header */
665             }
666             if (retval < 0) {
667                 perror("load_elf_binary3");
668                 exit(-1);
669                 free(elf_phdata);
670                 free(elf_interpreter);
671                 close(bprm->fd);
672                 return retval;
673             }
674         }
675         elf_ppnt++;
676     }
677
678     /* Some simple consistency checks for the interpreter */
679     if (elf_interpreter) {
680         if (interp_elf_ex.e_ident[0] != 0x7f ||
681             strncmp((char *)&interp_elf_ex.e_ident[1], "ELF", 3) != 0) {
682             free(elf_interpreter);
683             free(elf_phdata);
684             close(bprm->fd);
685             return -ELIBBAD;
686         }
687     }
688
689     /* OK, we are done with that, now set up the arg stuff,
690        and then start this sucker up */
691
692     if (!bprm->p) {
693         free(elf_interpreter);
694         free(elf_phdata);
695         close(bprm->fd);
696         return -E2BIG;
697     }
698
699     /* OK, This is the point of no return */
700     info->end_data = 0;
701     info->end_code = 0;
702     info->start_mmap = (abi_ulong)ELF_START_MMAP;
703     info->mmap = 0;
704     elf_entry = (abi_ulong) elf_ex.e_entry;
705
706     /* Do this so that we can load the interpreter, if need be.  We will
707        change some of these later */
708     info->rss = 0;
709     setup_arg_pages(bprm, info, &bprm->p, &bprm->stringp);
710     info->start_stack = bprm->p;
711
712     /* Now we do a little grungy work by mmaping the ELF image into
713      * the correct location in memory.  At this point, we assume that
714      * the image should be loaded at fixed address, not at a variable
715      * address.
716      */
717
718     for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
719         int elf_prot = 0;
720         int elf_flags = 0;
721         abi_ulong error;
722
723         if (elf_ppnt->p_type != PT_LOAD)
724             continue;
725
726         if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
727         if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
728         if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
729         elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
730         if (elf_ex.e_type == ET_EXEC || load_addr_set) {
731             elf_flags |= MAP_FIXED;
732         } else if (elf_ex.e_type == ET_DYN) {
733             /* Try and get dynamic programs out of the way of the default mmap
734                base, as well as whatever program they might try to exec.  This
735                is because the brk will follow the loader, and is not movable.  */
736             /* NOTE: for qemu, we do a big mmap to get enough space
737                without hardcoding any address */
738             error = target_mmap(0, ET_DYN_MAP_SIZE,
739                                 PROT_NONE, MAP_PRIVATE | MAP_ANON,
740                                 -1, 0);
741             if (error == -1) {
742                 perror("mmap");
743                 exit(-1);
744             }
745             load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
746         }
747
748         error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
749                             (elf_ppnt->p_filesz +
750                              TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
751                             elf_prot,
752                             (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
753                             bprm->fd,
754                             (elf_ppnt->p_offset -
755                              TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
756         if (error == -1) {
757             perror("mmap");
758             exit(-1);
759         }
760
761         if (!load_addr_set) {
762             load_addr_set = 1;
763             load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
764             if (elf_ex.e_type == ET_DYN) {
765                 load_bias += error -
766                     TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
767                 load_addr += load_bias;
768                 reloc_func_desc = load_bias;
769             }
770         }
771         k = elf_ppnt->p_vaddr;
772         if (k < start_code)
773             start_code = k;
774         if (start_data < k)
775             start_data = k;
776         k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
777         if (k > elf_bss)
778             elf_bss = k;
779         if ((elf_ppnt->p_flags & PF_X) && end_code <  k)
780             end_code = k;
781         if (end_data < k)
782             end_data = k;
783         k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
784         if (k > elf_brk) elf_brk = k;
785     }
786
787     elf_entry += load_bias;
788     elf_bss += load_bias;
789     elf_brk += load_bias;
790     start_code += load_bias;
791     end_code += load_bias;
792     start_data += load_bias;
793     end_data += load_bias;
794
795     if (elf_interpreter) {
796         elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
797                                     &interp_load_addr);
798         reloc_func_desc = interp_load_addr;
799
800         close(interpreter_fd);
801         free(elf_interpreter);
802
803         if (elf_entry == ~((abi_ulong)0UL)) {
804             printf("Unable to load interpreter\n");
805             free(elf_phdata);
806             exit(-1);
807             return 0;
808         }
809     }
810
811     free(elf_phdata);
812
813     if (qemu_log_enabled())
814         load_symbols(&elf_ex, bprm->fd);
815
816     close(bprm->fd);
817
818     bprm->p = target_create_elf_tables(bprm->p, bprm->argc, bprm->envc,
819                                        bprm->stringp, &elf_ex, load_addr,
820                                        load_bias, interp_load_addr, info);
821     info->load_addr = reloc_func_desc;
822     info->start_brk = info->brk = elf_brk;
823     info->end_code = end_code;
824     info->start_code = start_code;
825     info->start_data = start_data;
826     info->end_data = end_data;
827     info->start_stack = bprm->p;
828
829     /* Calling set_brk effectively mmaps the pages that we need for the bss and break
830        sections */
831     set_brk(elf_bss, elf_brk);
832
833     padzero(elf_bss, elf_brk);
834
835     info->entry = elf_entry;
836
837     return 0;
838 }
839
840 void do_init_thread(struct target_pt_regs *regs, struct image_info *infop)
841 {
842
843     target_thread_init(regs, infop);
844 }