]> git.proxmox.com Git - mirror_qemu.git/blame - bsd-user/elfload.c
bsd-user: Move per-cpu code into target_arch_cpu.h
[mirror_qemu.git] / bsd-user / elfload.c
CommitLineData
310df056
WL
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 */
84778508 19
2231197c 20#include "qemu/osdep.h"
84778508
BS
21
22#include "qemu.h"
76cad711 23#include "disas/disas.h"
f348b6d1 24#include "qemu/path.h"
84778508 25
66ef252f
WL
26#include "target_arch_elf.h"
27
84778508
BS
28/* this flag is uneffective under linux too, should be deleted */
29#ifndef MAP_DENYWRITE
30#define MAP_DENYWRITE 0
31#endif
32
33/* should probably go in elf.h */
34#ifndef ELIBBAD
35#define ELIBBAD 80
36#endif
37
84778508
BS
38#ifndef ELF_PLATFORM
39#define ELF_PLATFORM (NULL)
40#endif
41
42#ifndef ELF_HWCAP
43#define ELF_HWCAP 0
44#endif
45
46#ifdef TARGET_ABI32
47#undef ELF_CLASS
48#define ELF_CLASS ELFCLASS32
49#undef bswaptls
50#define bswaptls(ptr) bswap32s(ptr)
51#endif
52
53#include "elf.h"
54
84778508
BS
55/* max code+data+bss space allocated to elf interpreter */
56#define INTERP_MAP_SIZE (32 * 1024 * 1024)
57
58/* max code+data+bss+brk space allocated to ET_DYN executables */
59#define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
60
61/* Necessary parameters */
62#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
b4bebeee
WL
63#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE - 1))
64#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE - 1))
84778508 65
84778508
BS
66#define DLINFO_ITEMS 12
67
b4bebeee 68static inline void memcpy_fromfs(void *to, const void *from, unsigned long n)
84778508 69{
b62f790c 70 memcpy(to, from, n);
84778508
BS
71}
72
84778508
BS
73#ifdef BSWAP_NEEDED
74static void bswap_ehdr(struct elfhdr *ehdr)
75{
b62f790c 76 bswap16s(&ehdr->e_type); /* Object file type */
84778508
BS
77 bswap16s(&ehdr->e_machine); /* Architecture */
78 bswap32s(&ehdr->e_version); /* Object file version */
79 bswaptls(&ehdr->e_entry); /* Entry point virtual address */
80 bswaptls(&ehdr->e_phoff); /* Program header table file offset */
81 bswaptls(&ehdr->e_shoff); /* Section header table file offset */
82 bswap32s(&ehdr->e_flags); /* Processor-specific flags */
83 bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
b62f790c 84 bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
84778508 85 bswap16s(&ehdr->e_phnum); /* Program header table entry count */
b62f790c 86 bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
84778508 87 bswap16s(&ehdr->e_shnum); /* Section header table entry count */
b62f790c 88 bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
84778508
BS
89}
90
b62f790c 91static void bswap_phdr(struct elf_phdr *phdr, int phnum)
84778508 92{
b62f790c
WL
93 int i;
94
95 for (i = 0; i < phnum; i++, phdr++) {
96 bswap32s(&phdr->p_type); /* Segment type */
97 bswap32s(&phdr->p_flags); /* Segment flags */
98 bswaptls(&phdr->p_offset); /* Segment file offset */
99 bswaptls(&phdr->p_vaddr); /* Segment virtual address */
100 bswaptls(&phdr->p_paddr); /* Segment physical address */
101 bswaptls(&phdr->p_filesz); /* Segment size in file */
102 bswaptls(&phdr->p_memsz); /* Segment size in memory */
103 bswaptls(&phdr->p_align); /* Segment alignment */
104 }
84778508
BS
105}
106
b62f790c 107static void bswap_shdr(struct elf_shdr *shdr, int shnum)
84778508 108{
b62f790c
WL
109 int i;
110
111 for (i = 0; i < shnum; i++, shdr++) {
112 bswap32s(&shdr->sh_name);
113 bswap32s(&shdr->sh_type);
114 bswaptls(&shdr->sh_flags);
115 bswaptls(&shdr->sh_addr);
116 bswaptls(&shdr->sh_offset);
117 bswaptls(&shdr->sh_size);
118 bswap32s(&shdr->sh_link);
119 bswap32s(&shdr->sh_info);
120 bswaptls(&shdr->sh_addralign);
121 bswaptls(&shdr->sh_entsize);
122 }
84778508
BS
123}
124
125static void bswap_sym(struct elf_sym *sym)
126{
127 bswap32s(&sym->st_name);
128 bswaptls(&sym->st_value);
129 bswaptls(&sym->st_size);
130 bswap16s(&sym->st_shndx);
131}
b62f790c
WL
132
133#else /* ! BSWAP_NEEDED */
134
135static void bswap_ehdr(struct elfhdr *ehdr) { }
136static void bswap_phdr(struct elf_phdr *phdr, int phnum) { }
137static void bswap_shdr(struct elf_shdr *shdr, int shnum) { }
138static void bswap_sym(struct elf_sym *sym) { }
139
140#endif /* ! BSWAP_NEEDED */
84778508
BS
141
142/*
143 * 'copy_elf_strings()' copies argument/envelope strings from user
144 * memory to free pages in kernel mem. These are in a format ready
145 * to be put directly into the top of new user memory.
146 *
147 */
b4bebeee 148static abi_ulong copy_elf_strings(int argc, char **argv, void **page,
84778508
BS
149 abi_ulong p)
150{
151 char *tmp, *tmp1, *pag = NULL;
152 int len, offset = 0;
153
154 if (!p) {
155 return 0; /* bullet-proofing */
156 }
157 while (argc-- > 0) {
158 tmp = argv[argc];
159 if (!tmp) {
9bb93180 160 fprintf(stderr, "VFS: argc is wrong");
84778508
BS
161 exit(-1);
162 }
163 tmp1 = tmp;
164 while (*tmp++);
165 len = tmp - tmp1;
166 if (p < len) { /* this shouldn't happen - 128kB */
167 return 0;
168 }
169 while (len) {
170 --p; --tmp; --len;
171 if (--offset < 0) {
172 offset = p % TARGET_PAGE_SIZE;
b4bebeee 173 pag = (char *)page[p / TARGET_PAGE_SIZE];
84778508 174 if (!pag) {
c580dee4 175 pag = g_try_malloc0(TARGET_PAGE_SIZE);
b4bebeee 176 page[p / TARGET_PAGE_SIZE] = pag;
84778508
BS
177 if (!pag)
178 return 0;
179 }
180 }
181 if (len == 0 || offset == 0) {
182 *(pag + offset) = *tmp;
183 }
184 else {
185 int bytes_to_copy = (len > offset) ? offset : len;
186 tmp -= bytes_to_copy;
187 p -= bytes_to_copy;
188 offset -= bytes_to_copy;
189 len -= bytes_to_copy;
190 memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
191 }
192 }
193 }
194 return p;
195}
196
afcbcff8 197static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm,
84778508
BS
198 struct image_info *info)
199{
200 abi_ulong stack_base, size, error;
201 int i;
202
203 /* Create enough stack to hold everything. If we don't use
204 * it for args, we'll use it for something else...
205 */
206 size = x86_stack_size;
b4bebeee
WL
207 if (size < MAX_ARG_PAGES * TARGET_PAGE_SIZE)
208 size = MAX_ARG_PAGES * TARGET_PAGE_SIZE;
84778508
BS
209 error = target_mmap(0,
210 size + qemu_host_page_size,
211 PROT_READ | PROT_WRITE,
212 MAP_PRIVATE | MAP_ANON,
213 -1, 0);
214 if (error == -1) {
215 perror("stk mmap");
216 exit(-1);
217 }
218 /* we reserve one extra page at the top of the stack as guard */
219 target_mprotect(error + size, qemu_host_page_size, PROT_NONE);
220
b4bebeee 221 stack_base = error + size - MAX_ARG_PAGES * TARGET_PAGE_SIZE;
84778508
BS
222 p += stack_base;
223
224 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
225 if (bprm->page[i]) {
226 info->rss++;
227 /* FIXME - check return value of memcpy_to_target() for failure */
228 memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);
c580dee4 229 g_free(bprm->page[i]);
84778508
BS
230 }
231 stack_base += TARGET_PAGE_SIZE;
232 }
233 return p;
234}
235
236static void set_brk(abi_ulong start, abi_ulong end)
237{
238 /* page-align the start and end addresses... */
239 start = HOST_PAGE_ALIGN(start);
240 end = HOST_PAGE_ALIGN(end);
241 if (end <= start)
242 return;
b4bebeee 243 if (target_mmap(start, end - start,
84778508
BS
244 PROT_READ | PROT_WRITE | PROT_EXEC,
245 MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0) == -1) {
246 perror("cannot mmap brk");
247 exit(-1);
248 }
249}
250
251
252/* We need to explicitly zero any fractional pages after the data
253 section (i.e. bss). This would contain the junk from the file that
254 should not be in memory. */
255static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
256{
257 abi_ulong nbyte;
258
259 if (elf_bss >= last_bss)
260 return;
261
262 /* XXX: this is really a hack : if the real host page size is
263 smaller than the target page size, some pages after the end
264 of the file may not be mapped. A better fix would be to
265 patch target_mmap(), but it is more complicated as the file
266 size must be known */
267 if (qemu_real_host_page_size < qemu_host_page_size) {
268 abi_ulong end_addr, end_addr1;
0c2d70c4 269 end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss);
84778508
BS
270 end_addr = HOST_PAGE_ALIGN(elf_bss);
271 if (end_addr1 < end_addr) {
3e8f1628 272 mmap((void *)g2h_untagged(end_addr1), end_addr - end_addr1,
b4bebeee
WL
273 PROT_READ | PROT_WRITE | PROT_EXEC,
274 MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
84778508
BS
275 }
276 }
277
b4bebeee 278 nbyte = elf_bss & (qemu_host_page_size - 1);
84778508
BS
279 if (nbyte) {
280 nbyte = qemu_host_page_size - nbyte;
281 do {
282 /* FIXME - what to do if put_user() fails? */
283 put_user_u8(0, elf_bss);
284 elf_bss++;
285 } while (--nbyte);
286 }
287}
288
289
290static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
291 struct elfhdr * exec,
292 abi_ulong load_addr,
293 abi_ulong load_bias,
ffa03665 294 abi_ulong interp_load_addr,
84778508
BS
295 struct image_info *info)
296{
297 abi_ulong sp;
298 int size;
299 abi_ulong u_platform;
300 const char *k_platform;
301 const int n = sizeof(elf_addr_t);
302
303 sp = p;
304 u_platform = 0;
305 k_platform = ELF_PLATFORM;
306 if (k_platform) {
307 size_t len = strlen(k_platform) + 1;
308 sp -= (len + n - 1) & ~(n - 1);
309 u_platform = sp;
310 /* FIXME - check return value of memcpy_to_target() for failure */
311 memcpy_to_target(sp, k_platform, len);
312 }
313 /*
314 * Force 16 byte _final_ alignment here for generality.
315 */
b4bebeee 316 sp = sp & ~(abi_ulong)15;
84778508
BS
317 size = (DLINFO_ITEMS + 1) * 2;
318 if (k_platform)
b4bebeee 319 size += 2;
84778508
BS
320#ifdef DLINFO_ARCH_ITEMS
321 size += DLINFO_ARCH_ITEMS * 2;
322#endif
323 size += envc + argc + 2;
ffa03665 324 size += 1; /* argc itself */
84778508
BS
325 size *= n;
326 if (size & 15)
b4bebeee 327 sp -= 16 - (size & 15);
84778508
BS
328
329 /* This is correct because Linux defines
330 * elf_addr_t as Elf32_Off / Elf64_Off
331 */
332#define NEW_AUX_ENT(id, val) do { \
333 sp -= n; put_user_ual(val, sp); \
334 sp -= n; put_user_ual(id, sp); \
b4bebeee 335 } while (0)
84778508 336
b4bebeee 337 NEW_AUX_ENT(AT_NULL, 0);
84778508
BS
338
339 /* There must be exactly DLINFO_ITEMS entries here. */
340 NEW_AUX_ENT(AT_PHDR, (abi_ulong)(load_addr + exec->e_phoff));
b4bebeee 341 NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof(struct elf_phdr)));
84778508
BS
342 NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum));
343 NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(TARGET_PAGE_SIZE));
344 NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_load_addr));
345 NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0);
346 NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry);
347 NEW_AUX_ENT(AT_UID, (abi_ulong) getuid());
348 NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid());
349 NEW_AUX_ENT(AT_GID, (abi_ulong) getgid());
350 NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid());
351 NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);
352 NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
353 if (k_platform)
354 NEW_AUX_ENT(AT_PLATFORM, u_platform);
355#ifdef ARCH_DLINFO
356 /*
357 * ARCH_DLINFO must come last so platform specific code can enforce
358 * special alignment requirements on the AUXV if necessary (eg. PPC).
359 */
360 ARCH_DLINFO;
361#endif
362#undef NEW_AUX_ENT
363
ffa03665 364 sp = loader_build_argptr(envc, argc, sp, p);
84778508
BS
365 return sp;
366}
367
368
b4bebeee 369static abi_ulong load_elf_interp(struct elfhdr *interp_elf_ex,
84778508
BS
370 int interpreter_fd,
371 abi_ulong *interp_load_addr)
372{
b4bebeee
WL
373 struct elf_phdr *elf_phdata = NULL;
374 struct elf_phdr *eppnt;
375 abi_ulong load_addr = 0;
376 int load_addr_set = 0;
377 int retval;
378 abi_ulong last_bss, elf_bss;
379 abi_ulong error;
380 int i;
84778508 381
b4bebeee
WL
382 elf_bss = 0;
383 last_bss = 0;
384 error = 0;
84778508 385
b4bebeee 386 bswap_ehdr(interp_elf_ex);
b4bebeee
WL
387 /* First of all, some simple consistency checks */
388 if ((interp_elf_ex->e_type != ET_EXEC &&
389 interp_elf_ex->e_type != ET_DYN) ||
390 !elf_check_arch(interp_elf_ex->e_machine)) {
391 return ~((abi_ulong)0UL);
392 }
84778508
BS
393
394
b4bebeee 395 /* Now read in all of the header information */
84778508 396
b4bebeee
WL
397 if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
398 return ~(abi_ulong)0UL;
84778508 399
b4bebeee
WL
400 elf_phdata = (struct elf_phdr *)
401 malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
84778508 402
b4bebeee
WL
403 if (!elf_phdata)
404 return ~((abi_ulong)0UL);
84778508 405
b4bebeee
WL
406 /*
407 * If the size of this structure has changed, then punt, since
408 * we will be doing the wrong thing.
409 */
410 if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
411 free(elf_phdata);
412 return ~((abi_ulong)0UL);
413 }
84778508 414
b4bebeee
WL
415 retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
416 if (retval >= 0) {
417 retval = read(interpreter_fd,
418 (char *) elf_phdata,
419 sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
420 }
421 if (retval < 0) {
422 perror("load_elf_interp");
423 exit(-1);
ffa03665 424 free(elf_phdata);
b4bebeee
WL
425 return retval;
426 }
b62f790c 427 bswap_phdr(elf_phdata, interp_elf_ex->e_phnum);
84778508 428
b4bebeee
WL
429 if (interp_elf_ex->e_type == ET_DYN) {
430 /* in order to avoid hardcoding the interpreter load
431 address in qemu, we allocate a big enough memory zone */
432 error = target_mmap(0, INTERP_MAP_SIZE,
433 PROT_NONE, MAP_PRIVATE | MAP_ANON,
434 -1, 0);
435 if (error == -1) {
436 perror("mmap");
437 exit(-1);
84778508 438 }
b4bebeee
WL
439 load_addr = error;
440 load_addr_set = 1;
441 }
84778508 442
b4bebeee
WL
443 eppnt = elf_phdata;
444 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++)
445 if (eppnt->p_type == PT_LOAD) {
84778508
BS
446 int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
447 int elf_prot = 0;
448 abi_ulong vaddr = 0;
449 abi_ulong k;
450
451 if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
452 if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
453 if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
454 if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
455 elf_type |= MAP_FIXED;
456 vaddr = eppnt->p_vaddr;
457 }
b4bebeee
WL
458 error = target_mmap(load_addr + TARGET_ELF_PAGESTART(vaddr),
459 eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
460 elf_prot,
461 elf_type,
462 interpreter_fd,
463 eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
84778508
BS
464
465 if (error == -1) {
b4bebeee
WL
466 /* Real error */
467 close(interpreter_fd);
468 free(elf_phdata);
469 return ~((abi_ulong)0UL);
84778508
BS
470 }
471
472 if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
b4bebeee
WL
473 load_addr = error;
474 load_addr_set = 1;
84778508
BS
475 }
476
477 /*
478 * Find the end of the file mapping for this phdr, and keep
479 * track of the largest address we see for this.
480 */
481 k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
482 if (k > elf_bss) elf_bss = k;
483
484 /*
485 * Do the same thing for the memory mapping - between
486 * elf_bss and last_bss is the bss section.
487 */
488 k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
489 if (k > last_bss) last_bss = k;
b4bebeee 490 }
84778508 491
b4bebeee 492 /* Now use mmap to map the library into memory. */
84778508 493
b4bebeee 494 close(interpreter_fd);
84778508 495
b4bebeee
WL
496 /*
497 * Now fill out the bss section. First pad the last page up
498 * to the page boundary, and then perform a mmap to make sure
499 * that there are zeromapped pages up to and including the last
500 * bss page.
501 */
502 padzero(elf_bss, last_bss);
503 elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); /* What we have mapped so far */
504
505 /* Map the last of the bss segment */
506 if (last_bss > elf_bss) {
507 target_mmap(elf_bss, last_bss - elf_bss,
508 PROT_READ | PROT_WRITE | PROT_EXEC,
509 MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
510 }
511 free(elf_phdata);
84778508 512
b4bebeee
WL
513 *interp_load_addr = load_addr;
514 return ((abi_ulong) interp_elf_ex->e_entry) + load_addr;
84778508
BS
515}
516
517static int symfind(const void *s0, const void *s1)
518{
c7c530cd 519 target_ulong addr = *(target_ulong *)s0;
84778508
BS
520 struct elf_sym *sym = (struct elf_sym *)s1;
521 int result = 0;
c7c530cd 522 if (addr < sym->st_value) {
84778508 523 result = -1;
c7c530cd 524 } else if (addr >= sym->st_value + sym->st_size) {
84778508
BS
525 result = 1;
526 }
527 return result;
528}
529
530static const char *lookup_symbolxx(struct syminfo *s, target_ulong orig_addr)
531{
532#if ELF_CLASS == ELFCLASS32
533 struct elf_sym *syms = s->disas_symtab.elf32;
534#else
535 struct elf_sym *syms = s->disas_symtab.elf64;
536#endif
537
538 // binary search
84778508
BS
539 struct elf_sym *sym;
540
c7c530cd 541 sym = bsearch(&orig_addr, syms, s->disas_num_syms, sizeof(*syms), symfind);
7cba04f6 542 if (sym != NULL) {
84778508
BS
543 return s->disas_strtab + sym->st_name;
544 }
545
546 return "";
547}
548
549/* FIXME: This should use elf_ops.h */
550static int symcmp(const void *s0, const void *s1)
551{
552 struct elf_sym *sym0 = (struct elf_sym *)s0;
553 struct elf_sym *sym1 = (struct elf_sym *)s1;
554 return (sym0->st_value < sym1->st_value)
555 ? -1
556 : ((sym0->st_value > sym1->st_value) ? 1 : 0);
557}
558
559/* Best attempt to load symbols from this ELF object. */
560static void load_symbols(struct elfhdr *hdr, int fd)
561{
562 unsigned int i, nsyms;
563 struct elf_shdr sechdr, symtab, strtab;
564 char *strings;
565 struct syminfo *s;
29718712 566 struct elf_sym *syms, *new_syms;
84778508
BS
567
568 lseek(fd, hdr->e_shoff, SEEK_SET);
569 for (i = 0; i < hdr->e_shnum; i++) {
570 if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
571 return;
b62f790c 572 bswap_shdr(&sechdr, 1);
84778508
BS
573 if (sechdr.sh_type == SHT_SYMTAB) {
574 symtab = sechdr;
575 lseek(fd, hdr->e_shoff
576 + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
577 if (read(fd, &strtab, sizeof(strtab))
578 != sizeof(strtab))
579 return;
b62f790c 580 bswap_shdr(&strtab, 1);
84778508
BS
581 goto found;
582 }
583 }
584 return; /* Shouldn't happen... */
585
586 found:
587 /* Now know where the strtab and symtab are. Snarf them. */
588 s = malloc(sizeof(*s));
589 syms = malloc(symtab.sh_size);
29718712
SW
590 if (!syms) {
591 free(s);
84778508 592 return;
29718712 593 }
84778508 594 s->disas_strtab = strings = malloc(strtab.sh_size);
29718712
SW
595 if (!s->disas_strtab) {
596 free(s);
597 free(syms);
84778508 598 return;
29718712 599 }
84778508
BS
600
601 lseek(fd, symtab.sh_offset, SEEK_SET);
29718712
SW
602 if (read(fd, syms, symtab.sh_size) != symtab.sh_size) {
603 free(s);
604 free(syms);
605 free(strings);
84778508 606 return;
29718712 607 }
84778508
BS
608
609 nsyms = symtab.sh_size / sizeof(struct elf_sym);
610
611 i = 0;
612 while (i < nsyms) {
84778508 613 bswap_sym(syms + i);
84778508
BS
614 // Throw away entries which we do not need.
615 if (syms[i].st_shndx == SHN_UNDEF ||
616 syms[i].st_shndx >= SHN_LORESERVE ||
617 ELF_ST_TYPE(syms[i].st_info) != STT_FUNC) {
618 nsyms--;
619 if (i < nsyms) {
620 syms[i] = syms[nsyms];
621 }
622 continue;
623 }
84778508
BS
624 i++;
625 }
29718712
SW
626
627 /* Attempt to free the storage associated with the local symbols
628 that we threw away. Whether or not this has any effect on the
629 memory allocation depends on the malloc implementation and how
630 many symbols we managed to discard. */
631 new_syms = realloc(syms, nsyms * sizeof(*syms));
632 if (new_syms == NULL) {
633 free(s);
634 free(syms);
635 free(strings);
636 return;
637 }
638 syms = new_syms;
84778508
BS
639
640 qsort(syms, nsyms, sizeof(*syms), symcmp);
641
642 lseek(fd, strtab.sh_offset, SEEK_SET);
29718712
SW
643 if (read(fd, strings, strtab.sh_size) != strtab.sh_size) {
644 free(s);
645 free(syms);
646 free(strings);
84778508 647 return;
29718712 648 }
84778508
BS
649 s->disas_num_syms = nsyms;
650#if ELF_CLASS == ELFCLASS32
651 s->disas_symtab.elf32 = syms;
032e51d7 652 s->lookup_symbol = (lookup_symbol_t)lookup_symbolxx;
84778508
BS
653#else
654 s->disas_symtab.elf64 = syms;
032e51d7 655 s->lookup_symbol = (lookup_symbol_t)lookup_symbolxx;
84778508
BS
656#endif
657 s->next = syminfos;
658 syminfos = s;
659}
660
afcbcff8 661int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
b4bebeee 662 struct image_info *info)
84778508
BS
663{
664 struct elfhdr elf_ex;
665 struct elfhdr interp_elf_ex;
84778508
BS
666 int interpreter_fd = -1; /* avoid warning */
667 abi_ulong load_addr, load_bias;
668 int load_addr_set = 0;
84778508 669 int i;
84778508
BS
670 struct elf_phdr * elf_ppnt;
671 struct elf_phdr *elf_phdata;
672 abi_ulong elf_bss, k, elf_brk;
673 int retval;
674 char * elf_interpreter;
675 abi_ulong elf_entry, interp_load_addr = 0;
84778508
BS
676 abi_ulong start_code, end_code, start_data, end_data;
677 abi_ulong reloc_func_desc = 0;
71025956
PM
678#ifdef LOW_ELF_STACK
679 abi_ulong elf_stack = ~((abi_ulong)0UL);
680#endif
84778508 681
84778508
BS
682 load_addr = 0;
683 load_bias = 0;
684 elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */
84778508 685 bswap_ehdr(&elf_ex);
84778508
BS
686
687 /* First of all, some simple consistency checks */
688 if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
b4bebeee 689 (!elf_check_arch(elf_ex.e_machine))) {
84778508
BS
690 return -ENOEXEC;
691 }
692
693 bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p);
b4bebeee
WL
694 bprm->p = copy_elf_strings(bprm->envc, bprm->envp, bprm->page,bprm->p);
695 bprm->p = copy_elf_strings(bprm->argc, bprm->argv, bprm->page,bprm->p);
84778508
BS
696 if (!bprm->p) {
697 retval = -E2BIG;
698 }
699
700 /* Now read in all of the header information */
701 elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
702 if (elf_phdata == NULL) {
703 return -ENOMEM;
704 }
705
706 retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
b4bebeee
WL
707 if (retval > 0) {
708 retval = read(bprm->fd, (char *)elf_phdata,
84778508
BS
709 elf_ex.e_phentsize * elf_ex.e_phnum);
710 }
711
712 if (retval < 0) {
713 perror("load_elf_binary");
714 exit(-1);
b4bebeee 715 free(elf_phdata);
84778508
BS
716 return -errno;
717 }
718
b62f790c
WL
719 bswap_phdr(elf_phdata, elf_ex.e_phnum);
720
84778508
BS
721 elf_ppnt = elf_phdata;
722
723 elf_bss = 0;
724 elf_brk = 0;
725
726
84778508
BS
727 elf_interpreter = NULL;
728 start_code = ~((abi_ulong)0UL);
729 end_code = 0;
730 start_data = 0;
731 end_data = 0;
84778508 732
b4bebeee 733 for (i = 0;i < elf_ex.e_phnum; i++) {
84778508 734 if (elf_ppnt->p_type == PT_INTERP) {
b4bebeee 735 if (elf_interpreter != NULL)
84778508 736 {
b4bebeee 737 free(elf_phdata);
84778508
BS
738 free(elf_interpreter);
739 close(bprm->fd);
740 return -EINVAL;
741 }
742
743 /* This is the program interpreter used for
744 * shared libraries - for now assume that this
745 * is an a.out format binary
746 */
747
748 elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
749
750 if (elf_interpreter == NULL) {
b4bebeee 751 free(elf_phdata);
84778508
BS
752 close(bprm->fd);
753 return -ENOMEM;
754 }
755
756 retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
b4bebeee 757 if (retval >= 0) {
84778508
BS
758 retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
759 }
b4bebeee 760 if (retval < 0) {
84778508
BS
761 perror("load_elf_binary2");
762 exit(-1);
763 }
764
84778508
BS
765 if (retval >= 0) {
766 retval = open(path(elf_interpreter), O_RDONLY);
b4bebeee 767 if (retval >= 0) {
84778508
BS
768 interpreter_fd = retval;
769 }
770 else {
771 perror(elf_interpreter);
772 exit(-1);
773 /* retval = -errno; */
774 }
775 }
776
777 if (retval >= 0) {
778 retval = lseek(interpreter_fd, 0, SEEK_SET);
b4bebeee
WL
779 if (retval >= 0) {
780 retval = read(interpreter_fd, bprm->buf, 128);
84778508
BS
781 }
782 }
783 if (retval >= 0) {
6ece4df6 784 interp_elf_ex = *((struct elfhdr *) bprm->buf); /* elf exec-header */
84778508
BS
785 }
786 if (retval < 0) {
787 perror("load_elf_binary3");
788 exit(-1);
b4bebeee 789 free(elf_phdata);
84778508
BS
790 free(elf_interpreter);
791 close(bprm->fd);
792 return retval;
793 }
794 }
795 elf_ppnt++;
796 }
797
798 /* Some simple consistency checks for the interpreter */
b4bebeee 799 if (elf_interpreter) {
84778508 800 if (interp_elf_ex.e_ident[0] != 0x7f ||
ffa03665 801 strncmp((char *)&interp_elf_ex.e_ident[1], "ELF", 3) != 0) {
84778508
BS
802 free(elf_interpreter);
803 free(elf_phdata);
804 close(bprm->fd);
805 return -ELIBBAD;
806 }
807 }
808
809 /* OK, we are done with that, now set up the arg stuff,
810 and then start this sucker up */
811
ffa03665
WL
812 if (!bprm->p) {
813 free(elf_interpreter);
814 free(elf_phdata);
815 close(bprm->fd);
816 return -E2BIG;
84778508
BS
817 }
818
819 /* OK, This is the point of no return */
820 info->end_data = 0;
821 info->end_code = 0;
822 info->start_mmap = (abi_ulong)ELF_START_MMAP;
823 info->mmap = 0;
824 elf_entry = (abi_ulong) elf_ex.e_entry;
825
2fa5d9ba
BS
826 /*
827 * In case where user has not explicitly set the guest_base, we
828 * probe here that should we set it automatically.
829 */
830 if (!have_guest_base) {
831 /*
832 * Go through ELF program header table and find out whether
7d37435b 833 * any of the segments drop below our current mmap_min_addr and
2fa5d9ba
BS
834 * in that case set guest_base to corresponding address.
835 */
836 for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum;
837 i++, elf_ppnt++) {
838 if (elf_ppnt->p_type != PT_LOAD)
839 continue;
840 if (HOST_PAGE_ALIGN(elf_ppnt->p_vaddr) < mmap_min_addr) {
841 guest_base = HOST_PAGE_ALIGN(mmap_min_addr);
842 break;
843 }
844 }
845 }
2fa5d9ba 846
84778508
BS
847 /* Do this so that we can load the interpreter, if need be. We will
848 change some of these later */
849 info->rss = 0;
850 bprm->p = setup_arg_pages(bprm->p, bprm, info);
851 info->start_stack = bprm->p;
852
853 /* Now we do a little grungy work by mmaping the ELF image into
854 * the correct location in memory. At this point, we assume that
855 * the image should be loaded at fixed address, not at a variable
856 * address.
857 */
858
b4bebeee 859 for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
84778508
BS
860 int elf_prot = 0;
861 int elf_flags = 0;
862 abi_ulong error;
863
864 if (elf_ppnt->p_type != PT_LOAD)
865 continue;
866
867 if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
868 if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
869 if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
870 elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
871 if (elf_ex.e_type == ET_EXEC || load_addr_set) {
872 elf_flags |= MAP_FIXED;
873 } else if (elf_ex.e_type == ET_DYN) {
874 /* Try and get dynamic programs out of the way of the default mmap
875 base, as well as whatever program they might try to exec. This
876 is because the brk will follow the loader, and is not movable. */
877 /* NOTE: for qemu, we do a big mmap to get enough space
878 without hardcoding any address */
879 error = target_mmap(0, ET_DYN_MAP_SIZE,
880 PROT_NONE, MAP_PRIVATE | MAP_ANON,
881 -1, 0);
882 if (error == -1) {
883 perror("mmap");
884 exit(-1);
885 }
886 load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
887 }
888
889 error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
890 (elf_ppnt->p_filesz +
891 TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
892 elf_prot,
893 (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
894 bprm->fd,
895 (elf_ppnt->p_offset -
896 TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
897 if (error == -1) {
898 perror("mmap");
899 exit(-1);
900 }
901
902#ifdef LOW_ELF_STACK
903 if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
904 elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr);
905#endif
906
907 if (!load_addr_set) {
908 load_addr_set = 1;
909 load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
910 if (elf_ex.e_type == ET_DYN) {
911 load_bias += error -
912 TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
913 load_addr += load_bias;
914 reloc_func_desc = load_bias;
915 }
916 }
917 k = elf_ppnt->p_vaddr;
918 if (k < start_code)
919 start_code = k;
920 if (start_data < k)
921 start_data = k;
922 k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
923 if (k > elf_bss)
924 elf_bss = k;
925 if ((elf_ppnt->p_flags & PF_X) && end_code < k)
926 end_code = k;
927 if (end_data < k)
928 end_data = k;
929 k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
930 if (k > elf_brk) elf_brk = k;
931 }
932
933 elf_entry += load_bias;
934 elf_bss += load_bias;
935 elf_brk += load_bias;
936 start_code += load_bias;
937 end_code += load_bias;
938 start_data += load_bias;
939 end_data += load_bias;
940
941 if (elf_interpreter) {
ffa03665
WL
942 elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
943 &interp_load_addr);
84778508
BS
944 reloc_func_desc = interp_load_addr;
945
946 close(interpreter_fd);
947 free(elf_interpreter);
948
949 if (elf_entry == ~((abi_ulong)0UL)) {
950 printf("Unable to load interpreter\n");
951 free(elf_phdata);
952 exit(-1);
953 return 0;
954 }
955 }
956
957 free(elf_phdata);
958
93fcfe39 959 if (qemu_log_enabled())
84778508
BS
960 load_symbols(&elf_ex, bprm->fd);
961
ffa03665 962 close(bprm->fd);
84778508
BS
963
964#ifdef LOW_ELF_STACK
965 info->start_stack = bprm->p = elf_stack - 4;
966#endif
967 bprm->p = create_elf_tables(bprm->p,
ffa03665
WL
968 bprm->argc,
969 bprm->envc,
970 &elf_ex,
971 load_addr, load_bias,
972 interp_load_addr,
973 info);
84778508
BS
974 info->load_addr = reloc_func_desc;
975 info->start_brk = info->brk = elf_brk;
976 info->end_code = end_code;
977 info->start_code = start_code;
978 info->start_data = start_data;
979 info->end_data = end_data;
980 info->start_stack = bprm->p;
981
982 /* Calling set_brk effectively mmaps the pages that we need for the bss and break
983 sections */
984 set_brk(elf_bss, elf_brk);
985
986 padzero(elf_bss, elf_brk);
987
988#if 0
989 printf("(start_brk) %x\n" , info->start_brk);
990 printf("(end_code) %x\n" , info->end_code);
991 printf("(start_code) %x\n" , info->start_code);
992 printf("(end_data) %x\n" , info->end_data);
993 printf("(start_stack) %x\n" , info->start_stack);
994 printf("(brk) %x\n" , info->brk);
995#endif
996
84778508
BS
997 info->entry = elf_entry;
998
999 return 0;
1000}
1001
84778508
BS
1002void do_init_thread(struct target_pt_regs *regs, struct image_info *infop)
1003{
1004 init_thread(regs, infop);
1005}