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