]> git.proxmox.com Git - mirror_qemu.git/blame_incremental - bsd-user/elfload.c
bsd-user: Add target_os_user.h to capture the user/kernel structures
[mirror_qemu.git] / bsd-user / elfload.c
... / ...
CommitLineData
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
26static abi_ulong target_auxents; /* Where the AUX entries are in target */
27static 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
35abi_ulong target_stksiz;
36abi_ulong target_stkbas;
37
38static inline void memcpy_fromfs(void *to, const void *from, unsigned long n)
39{
40 memcpy(to, from, n);
41}
42
43#ifdef BSWAP_NEEDED
44static 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
61static 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
77static 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
95static 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
105static void bswap_ehdr(struct elfhdr *ehdr) { }
106static void bswap_phdr(struct elf_phdr *phdr, int phnum) { }
107static void bswap_shdr(struct elf_shdr *shdr, int shnum) { }
108static 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 */
118static 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
167static 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
199static 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. */
218static 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
252static 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
400static 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
413static 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 */
433static 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. */
443static 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
544int 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
840void do_init_thread(struct target_pt_regs *regs, struct image_info *infop)
841{
842
843 target_thread_init(regs, infop);
844}