]> git.proxmox.com Git - mirror_qemu.git/blob - bsd-user/elfload.c
bsd-user: elf cleanup
[mirror_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 #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 }