]> git.proxmox.com Git - mirror_qemu.git/blame - linux-user/elfload.c
fixed sparc cpu load/save
[mirror_qemu.git] / linux-user / elfload.c
CommitLineData
31e31b8a
FB
1/* This is the Linux kernel elf-loading code, ported into user space */
2
3#include <stdio.h>
4#include <sys/types.h>
5#include <fcntl.h>
6#include <sys/stat.h>
7#include <errno.h>
8#include <unistd.h>
9#include <sys/mman.h>
10#include <stdlib.h>
11#include <string.h>
12
3ef693a0 13#include "qemu.h"
689f936f 14#include "disas.h"
31e31b8a 15
83fb7adf
FB
16/* this flag is uneffective under linux too, should be deleted */
17#ifndef MAP_DENYWRITE
18#define MAP_DENYWRITE 0
19#endif
20
21/* should probably go in elf.h */
22#ifndef ELIBBAD
23#define ELIBBAD 80
24#endif
25
30ac07d4
FB
26#ifdef TARGET_I386
27
28#define ELF_START_MMAP 0x80000000
29
30ac07d4
FB
30/*
31 * This is used to ensure we don't load something for the wrong architecture.
32 */
33#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
34
35/*
36 * These are used to set parameters in the core dumps.
37 */
38#define ELF_CLASS ELFCLASS32
39#define ELF_DATA ELFDATA2LSB
40#define ELF_ARCH EM_386
41
42 /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
43 starts %edx contains a pointer to a function which might be
44 registered using `atexit'. This provides a mean for the
45 dynamic linker to call DT_FINI functions for shared libraries
46 that have been loaded before the code runs.
47
48 A value of 0 tells we have no such handler. */
49#define ELF_PLAT_INIT(_r) _r->edx = 0
50
b346ff46
FB
51static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
52{
53 regs->esp = infop->start_stack;
54 regs->eip = infop->entry;
55}
56
57#define USE_ELF_CORE_DUMP
58#define ELF_EXEC_PAGESIZE 4096
59
60#endif
61
62#ifdef TARGET_ARM
63
64#define ELF_START_MMAP 0x80000000
65
66#define elf_check_arch(x) ( (x) == EM_ARM )
67
68#define ELF_CLASS ELFCLASS32
69#ifdef TARGET_WORDS_BIGENDIAN
70#define ELF_DATA ELFDATA2MSB
71#else
72#define ELF_DATA ELFDATA2LSB
73#endif
74#define ELF_ARCH EM_ARM
75
76#define ELF_PLAT_INIT(_r) _r->ARM_r0 = 0
77
78static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
79{
80 target_long *stack = (void *)infop->start_stack;
81 memset(regs, 0, sizeof(*regs));
82 regs->ARM_cpsr = 0x10;
83 regs->ARM_pc = infop->entry;
84 regs->ARM_sp = infop->start_stack;
85 regs->ARM_r2 = tswapl(stack[2]); /* envp */
86 regs->ARM_r1 = tswapl(stack[1]); /* argv */
a1516e92
FB
87 /* XXX: it seems that r0 is zeroed after ! */
88 // regs->ARM_r0 = tswapl(stack[0]); /* argc */
b346ff46
FB
89}
90
30ac07d4
FB
91#define USE_ELF_CORE_DUMP
92#define ELF_EXEC_PAGESIZE 4096
93
94#endif
95
853d6f7a
FB
96#ifdef TARGET_SPARC
97
98#define ELF_START_MMAP 0x80000000
99
100#define elf_check_arch(x) ( (x) == EM_SPARC )
101
102#define ELF_CLASS ELFCLASS32
103#define ELF_DATA ELFDATA2MSB
104#define ELF_ARCH EM_SPARC
105
106/*XXX*/
107#define ELF_PLAT_INIT(_r)
108
109static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
110{
f5155289
FB
111 regs->psr = 0;
112 regs->pc = infop->entry;
113 regs->npc = regs->pc + 4;
114 regs->y = 0;
115 regs->u_regs[14] = infop->start_stack - 16 * 4;
853d6f7a
FB
116}
117
118#endif
119
67867308
FB
120#ifdef TARGET_PPC
121
122#define ELF_START_MMAP 0x80000000
123
124#define elf_check_arch(x) ( (x) == EM_PPC )
125
126#define ELF_CLASS ELFCLASS32
127#ifdef TARGET_WORDS_BIGENDIAN
128#define ELF_DATA ELFDATA2MSB
129#else
130#define ELF_DATA ELFDATA2LSB
131#endif
132#define ELF_ARCH EM_PPC
133
134/* Note that isn't exactly what regular kernel does
135 * but this is what the ABI wants and is needed to allow
136 * execution of PPC BSD programs.
137 */
138#define ELF_PLAT_INIT(_r) \
139do { \
274da6b2 140 target_ulong *pos = (target_ulong *)bprm->p, tmp = 1; \
67867308
FB
141 _r->gpr[3] = bprm->argc; \
142 _r->gpr[4] = (unsigned long)++pos; \
143 for (; tmp != 0; pos++) \
144 tmp = *pos; \
f5155289 145 _r->gpr[5] = (unsigned long)pos; \
67867308
FB
146} while (0)
147
f5155289
FB
148/*
149 * We need to put in some extra aux table entries to tell glibc what
150 * the cache block size is, so it can use the dcbz instruction safely.
151 */
152#define AT_DCACHEBSIZE 19
153#define AT_ICACHEBSIZE 20
154#define AT_UCACHEBSIZE 21
155/* A special ignored type value for PPC, for glibc compatibility. */
156#define AT_IGNOREPPC 22
157/*
158 * The requirements here are:
159 * - keep the final alignment of sp (sp & 0xf)
160 * - make sure the 32-bit value at the first 16 byte aligned position of
161 * AUXV is greater than 16 for glibc compatibility.
162 * AT_IGNOREPPC is used for that.
163 * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
164 * even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
165 */
166#define DLINFO_ARCH_ITEMS 3
167#define ARCH_DLINFO \
168do { \
169 sp -= DLINFO_ARCH_ITEMS * 2; \
170 NEW_AUX_ENT(0, AT_DCACHEBSIZE, 0x20); \
171 NEW_AUX_ENT(1, AT_ICACHEBSIZE, 0x20); \
172 NEW_AUX_ENT(2, AT_UCACHEBSIZE, 0); \
173 /* \
174 * Now handle glibc compatibility. \
175 */ \
176 sp -= 2*2; \
177 NEW_AUX_ENT(0, AT_IGNOREPPC, AT_IGNOREPPC); \
178 NEW_AUX_ENT(1, AT_IGNOREPPC, AT_IGNOREPPC); \
179 } while (0)
180
67867308
FB
181static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
182{
183 _regs->msr = 1 << MSR_PR; /* Set user mode */
184 _regs->gpr[1] = infop->start_stack;
185 _regs->nip = infop->entry;
186}
187
188#define USE_ELF_CORE_DUMP
189#define ELF_EXEC_PAGESIZE 4096
190
191#endif
192
31e31b8a 193#include "elf.h"
09bfb054
FB
194
195/*
196 * MAX_ARG_PAGES defines the number of pages allocated for arguments
197 * and envelope for the new program. 32 should suffice, this gives
198 * a maximum env+arg of 128kB w/4KB pages!
199 */
200#define MAX_ARG_PAGES 32
201
202/*
203 * This structure is used to hold the arguments that are
204 * used when loading binaries.
205 */
206struct linux_binprm {
207 char buf[128];
208 unsigned long page[MAX_ARG_PAGES];
209 unsigned long p;
210 int sh_bang;
211 int fd;
212 int e_uid, e_gid;
213 int argc, envc;
09bfb054
FB
214 char * filename; /* Name of binary */
215 unsigned long loader, exec;
216 int dont_iput; /* binfmt handler has put inode */
217};
218
219struct exec
220{
221 unsigned int a_info; /* Use macros N_MAGIC, etc for access */
222 unsigned int a_text; /* length of text, in bytes */
223 unsigned int a_data; /* length of data, in bytes */
224 unsigned int a_bss; /* length of uninitialized data area, in bytes */
225 unsigned int a_syms; /* length of symbol table data in file, in bytes */
226 unsigned int a_entry; /* start address */
227 unsigned int a_trsize; /* length of relocation info for text, in bytes */
228 unsigned int a_drsize; /* length of relocation info for data, in bytes */
229};
230
231
232#define N_MAGIC(exec) ((exec).a_info & 0xffff)
233#define OMAGIC 0407
234#define NMAGIC 0410
235#define ZMAGIC 0413
236#define QMAGIC 0314
237
09bfb054
FB
238/* max code+data+bss space allocated to elf interpreter */
239#define INTERP_MAP_SIZE (32 * 1024 * 1024)
240
241/* max code+data+bss+brk space allocated to ET_DYN executables */
242#define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
243
244/* from personality.h */
245
246/* Flags for bug emulation. These occupy the top three bytes. */
247#define STICKY_TIMEOUTS 0x4000000
248#define WHOLE_SECONDS 0x2000000
249
250/* Personality types. These go in the low byte. Avoid using the top bit,
251 * it will conflict with error returns.
252 */
253#define PER_MASK (0x00ff)
254#define PER_LINUX (0x0000)
255#define PER_SVR4 (0x0001 | STICKY_TIMEOUTS)
256#define PER_SVR3 (0x0002 | STICKY_TIMEOUTS)
257#define PER_SCOSVR3 (0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS)
258#define PER_WYSEV386 (0x0004 | STICKY_TIMEOUTS)
259#define PER_ISCR4 (0x0005 | STICKY_TIMEOUTS)
260#define PER_BSD (0x0006)
261#define PER_XENIX (0x0007 | STICKY_TIMEOUTS)
31e31b8a
FB
262
263/* Necessary parameters */
31e31b8a
FB
264#define NGROUPS 32
265
54936004
FB
266#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
267#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
268#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
31e31b8a
FB
269
270#define INTERPRETER_NONE 0
271#define INTERPRETER_AOUT 1
272#define INTERPRETER_ELF 2
273
f5155289 274#define DLINFO_ITEMS 11
31e31b8a 275
09bfb054
FB
276static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
277{
278 memcpy(to, from, n);
279}
d691f669 280
31e31b8a
FB
281extern unsigned long x86_stack_size;
282
283static int load_aout_interp(void * exptr, int interp_fd);
284
285#ifdef BSWAP_NEEDED
286static void bswap_ehdr(Elf32_Ehdr *ehdr)
287{
288 bswap16s(&ehdr->e_type); /* Object file type */
289 bswap16s(&ehdr->e_machine); /* Architecture */
290 bswap32s(&ehdr->e_version); /* Object file version */
291 bswap32s(&ehdr->e_entry); /* Entry point virtual address */
292 bswap32s(&ehdr->e_phoff); /* Program header table file offset */
293 bswap32s(&ehdr->e_shoff); /* Section header table file offset */
294 bswap32s(&ehdr->e_flags); /* Processor-specific flags */
295 bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
296 bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
297 bswap16s(&ehdr->e_phnum); /* Program header table entry count */
298 bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
299 bswap16s(&ehdr->e_shnum); /* Section header table entry count */
300 bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
301}
302
303static void bswap_phdr(Elf32_Phdr *phdr)
304{
305 bswap32s(&phdr->p_type); /* Segment type */
306 bswap32s(&phdr->p_offset); /* Segment file offset */
307 bswap32s(&phdr->p_vaddr); /* Segment virtual address */
308 bswap32s(&phdr->p_paddr); /* Segment physical address */
309 bswap32s(&phdr->p_filesz); /* Segment size in file */
310 bswap32s(&phdr->p_memsz); /* Segment size in memory */
311 bswap32s(&phdr->p_flags); /* Segment flags */
312 bswap32s(&phdr->p_align); /* Segment alignment */
313}
689f936f
FB
314
315static void bswap_shdr(Elf32_Shdr *shdr)
316{
317 bswap32s(&shdr->sh_name);
318 bswap32s(&shdr->sh_type);
319 bswap32s(&shdr->sh_flags);
320 bswap32s(&shdr->sh_addr);
321 bswap32s(&shdr->sh_offset);
322 bswap32s(&shdr->sh_size);
323 bswap32s(&shdr->sh_link);
324 bswap32s(&shdr->sh_info);
325 bswap32s(&shdr->sh_addralign);
326 bswap32s(&shdr->sh_entsize);
327}
328
329static void bswap_sym(Elf32_Sym *sym)
330{
331 bswap32s(&sym->st_name);
332 bswap32s(&sym->st_value);
333 bswap32s(&sym->st_size);
334 bswap16s(&sym->st_shndx);
335}
31e31b8a
FB
336#endif
337
338static void * get_free_page(void)
339{
340 void * retval;
341
342 /* User-space version of kernel get_free_page. Returns a page-aligned
343 * page-sized chunk of memory.
344 */
83fb7adf 345 retval = (void *)target_mmap(0, qemu_host_page_size, PROT_READ|PROT_WRITE,
54936004 346 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
31e31b8a
FB
347
348 if((long)retval == -1) {
349 perror("get_free_page");
350 exit(-1);
351 }
352 else {
353 return(retval);
354 }
355}
356
357static void free_page(void * pageaddr)
358{
83fb7adf 359 target_munmap((unsigned long)pageaddr, qemu_host_page_size);
31e31b8a
FB
360}
361
362/*
363 * 'copy_string()' copies argument/envelope strings from user
364 * memory to free pages in kernel mem. These are in a format ready
365 * to be put directly into the top of new user memory.
366 *
367 */
368static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
369 unsigned long p)
370{
371 char *tmp, *tmp1, *pag = NULL;
372 int len, offset = 0;
373
374 if (!p) {
375 return 0; /* bullet-proofing */
376 }
377 while (argc-- > 0) {
edf779ff
FB
378 tmp = argv[argc];
379 if (!tmp) {
31e31b8a
FB
380 fprintf(stderr, "VFS: argc is wrong");
381 exit(-1);
382 }
edf779ff
FB
383 tmp1 = tmp;
384 while (*tmp++);
31e31b8a
FB
385 len = tmp - tmp1;
386 if (p < len) { /* this shouldn't happen - 128kB */
387 return 0;
388 }
389 while (len) {
390 --p; --tmp; --len;
391 if (--offset < 0) {
54936004 392 offset = p % TARGET_PAGE_SIZE;
44a91cae
FB
393 pag = (char *) page[p/TARGET_PAGE_SIZE];
394 if (!pag) {
395 pag = (char *)get_free_page();
396 page[p/TARGET_PAGE_SIZE] = (unsigned long)pag;
397 if (!pag)
398 return 0;
31e31b8a
FB
399 }
400 }
401 if (len == 0 || offset == 0) {
edf779ff 402 *(pag + offset) = *tmp;
31e31b8a
FB
403 }
404 else {
405 int bytes_to_copy = (len > offset) ? offset : len;
406 tmp -= bytes_to_copy;
407 p -= bytes_to_copy;
408 offset -= bytes_to_copy;
409 len -= bytes_to_copy;
410 memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
411 }
412 }
413 }
414 return p;
415}
416
417static int in_group_p(gid_t g)
418{
419 /* return TRUE if we're in the specified group, FALSE otherwise */
420 int ngroup;
421 int i;
422 gid_t grouplist[NGROUPS];
423
424 ngroup = getgroups(NGROUPS, grouplist);
425 for(i = 0; i < ngroup; i++) {
426 if(grouplist[i] == g) {
427 return 1;
428 }
429 }
430 return 0;
431}
432
433static int count(char ** vec)
434{
435 int i;
436
437 for(i = 0; *vec; i++) {
438 vec++;
439 }
440
441 return(i);
442}
443
444static int prepare_binprm(struct linux_binprm *bprm)
445{
446 struct stat st;
447 int mode;
448 int retval, id_change;
449
450 if(fstat(bprm->fd, &st) < 0) {
451 return(-errno);
452 }
453
454 mode = st.st_mode;
455 if(!S_ISREG(mode)) { /* Must be regular file */
456 return(-EACCES);
457 }
458 if(!(mode & 0111)) { /* Must have at least one execute bit set */
459 return(-EACCES);
460 }
461
462 bprm->e_uid = geteuid();
463 bprm->e_gid = getegid();
464 id_change = 0;
465
466 /* Set-uid? */
467 if(mode & S_ISUID) {
468 bprm->e_uid = st.st_uid;
469 if(bprm->e_uid != geteuid()) {
470 id_change = 1;
471 }
472 }
473
474 /* Set-gid? */
475 /*
476 * If setgid is set but no group execute bit then this
477 * is a candidate for mandatory locking, not a setgid
478 * executable.
479 */
480 if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
481 bprm->e_gid = st.st_gid;
482 if (!in_group_p(bprm->e_gid)) {
483 id_change = 1;
484 }
485 }
486
487 memset(bprm->buf, 0, sizeof(bprm->buf));
488 retval = lseek(bprm->fd, 0L, SEEK_SET);
489 if(retval >= 0) {
490 retval = read(bprm->fd, bprm->buf, 128);
491 }
492 if(retval < 0) {
493 perror("prepare_binprm");
494 exit(-1);
495 /* return(-errno); */
496 }
497 else {
498 return(retval);
499 }
500}
501
502unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm,
503 struct image_info * info)
504{
09bfb054 505 unsigned long stack_base, size, error;
31e31b8a 506 int i;
31e31b8a 507
09bfb054
FB
508 /* Create enough stack to hold everything. If we don't use
509 * it for args, we'll use it for something else...
510 */
511 size = x86_stack_size;
54936004
FB
512 if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
513 size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
514 error = target_mmap(0,
83fb7adf 515 size + qemu_host_page_size,
54936004
FB
516 PROT_READ | PROT_WRITE,
517 MAP_PRIVATE | MAP_ANONYMOUS,
518 -1, 0);
09bfb054
FB
519 if (error == -1) {
520 perror("stk mmap");
521 exit(-1);
522 }
523 /* we reserve one extra page at the top of the stack as guard */
83fb7adf 524 target_mprotect(error + size, qemu_host_page_size, PROT_NONE);
31e31b8a 525
54936004 526 stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE;
31e31b8a 527 p += stack_base;
09bfb054 528
31e31b8a
FB
529 if (bprm->loader) {
530 bprm->loader += stack_base;
531 }
532 bprm->exec += stack_base;
533
31e31b8a
FB
534 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
535 if (bprm->page[i]) {
536 info->rss++;
537
54936004 538 memcpy((void *)stack_base, (void *)bprm->page[i], TARGET_PAGE_SIZE);
31e31b8a
FB
539 free_page((void *)bprm->page[i]);
540 }
54936004 541 stack_base += TARGET_PAGE_SIZE;
31e31b8a
FB
542 }
543 return p;
544}
545
546static void set_brk(unsigned long start, unsigned long end)
547{
548 /* page-align the start and end addresses... */
54936004
FB
549 start = HOST_PAGE_ALIGN(start);
550 end = HOST_PAGE_ALIGN(end);
31e31b8a
FB
551 if (end <= start)
552 return;
54936004
FB
553 if(target_mmap(start, end - start,
554 PROT_READ | PROT_WRITE | PROT_EXEC,
555 MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
31e31b8a
FB
556 perror("cannot mmap brk");
557 exit(-1);
558 }
559}
560
561
853d6f7a
FB
562/* We need to explicitly zero any fractional pages after the data
563 section (i.e. bss). This would contain the junk from the file that
564 should not be in memory. */
31e31b8a
FB
565static void padzero(unsigned long elf_bss)
566{
567 unsigned long nbyte;
568 char * fpnt;
569
853d6f7a
FB
570 /* XXX: this is really a hack : if the real host page size is
571 smaller than the target page size, some pages after the end
572 of the file may not be mapped. A better fix would be to
573 patch target_mmap(), but it is more complicated as the file
574 size must be known */
83fb7adf 575 if (qemu_real_host_page_size < qemu_host_page_size) {
853d6f7a 576 unsigned long end_addr, end_addr1;
83fb7adf
FB
577 end_addr1 = (elf_bss + qemu_real_host_page_size - 1) &
578 ~(qemu_real_host_page_size - 1);
853d6f7a
FB
579 end_addr = HOST_PAGE_ALIGN(elf_bss);
580 if (end_addr1 < end_addr) {
581 mmap((void *)end_addr1, end_addr - end_addr1,
582 PROT_READ|PROT_WRITE|PROT_EXEC,
583 MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
584 }
585 }
586
83fb7adf 587 nbyte = elf_bss & (qemu_host_page_size-1);
31e31b8a 588 if (nbyte) {
83fb7adf 589 nbyte = qemu_host_page_size - nbyte;
31e31b8a
FB
590 fpnt = (char *) elf_bss;
591 do {
592 *fpnt++ = 0;
593 } while (--nbyte);
594 }
595}
596
597static unsigned int * create_elf_tables(char *p, int argc, int envc,
09bfb054
FB
598 struct elfhdr * exec,
599 unsigned long load_addr,
600 unsigned long load_bias,
601 unsigned long interp_load_addr, int ibcs,
602 struct image_info *info)
31e31b8a 603{
f5155289
FB
604 target_ulong *argv, *envp;
605 target_ulong *sp, *csp;
edf779ff
FB
606 int v;
607
f5155289
FB
608 /*
609 * Force 16 byte _final_ alignment here for generality.
610 */
31e31b8a 611 sp = (unsigned int *) (~15UL & (unsigned long) p);
f5155289
FB
612 csp = sp;
613 csp -= (DLINFO_ITEMS + 1) * 2;
614#ifdef DLINFO_ARCH_ITEMS
615 csp -= DLINFO_ARCH_ITEMS*2;
616#endif
617 csp -= envc+1;
618 csp -= argc+1;
619 csp -= (!ibcs ? 3 : 1); /* argc itself */
620 if ((unsigned long)csp & 15UL)
621 sp -= ((unsigned long)csp & 15UL) / sizeof(*sp);
622
623#define NEW_AUX_ENT(nr, id, val) \
edf779ff
FB
624 put_user (id, sp + (nr * 2)); \
625 put_user (val, sp + (nr * 2 + 1))
f5155289
FB
626 sp -= 2;
627 NEW_AUX_ENT (0, AT_NULL, 0);
628
629 sp -= DLINFO_ITEMS*2;
630 NEW_AUX_ENT( 0, AT_PHDR, (target_ulong)(load_addr + exec->e_phoff));
631 NEW_AUX_ENT( 1, AT_PHENT, (target_ulong)(sizeof (struct elf_phdr)));
632 NEW_AUX_ENT( 2, AT_PHNUM, (target_ulong)(exec->e_phnum));
633 NEW_AUX_ENT( 3, AT_PAGESZ, (target_ulong)(TARGET_PAGE_SIZE));
634 NEW_AUX_ENT( 4, AT_BASE, (target_ulong)(interp_load_addr));
635 NEW_AUX_ENT( 5, AT_FLAGS, (target_ulong)0);
636 NEW_AUX_ENT( 6, AT_ENTRY, load_bias + exec->e_entry);
637 NEW_AUX_ENT( 7, AT_UID, (target_ulong) getuid());
638 NEW_AUX_ENT( 8, AT_EUID, (target_ulong) geteuid());
639 NEW_AUX_ENT( 9, AT_GID, (target_ulong) getgid());
640 NEW_AUX_ENT(11, AT_EGID, (target_ulong) getegid());
641#ifdef ARCH_DLINFO
642 /*
643 * ARCH_DLINFO must come last so platform specific code can enforce
644 * special alignment requirements on the AUXV if necessary (eg. PPC).
645 */
646 ARCH_DLINFO;
647#endif
648#undef NEW_AUX_ENT
649
31e31b8a
FB
650 sp -= envc+1;
651 envp = sp;
652 sp -= argc+1;
653 argv = sp;
654 if (!ibcs) {
edf779ff
FB
655 put_user((target_ulong)envp,--sp);
656 put_user((target_ulong)argv,--sp);
31e31b8a 657 }
edf779ff 658 put_user(argc,--sp);
31e31b8a
FB
659 info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff);
660 while (argc-->0) {
edf779ff
FB
661 put_user((target_ulong)p,argv++);
662 do {
663 get_user(v, p);
664 p++;
665 } while (v != 0);
31e31b8a
FB
666 }
667 put_user(0,argv);
668 info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff);
31e31b8a 669 while (envc-->0) {
edf779ff
FB
670 put_user((target_ulong)p,envp++);
671 do {
672 get_user(v, p);
673 p++;
674 } while (v != 0);
31e31b8a
FB
675 }
676 put_user(0,envp);
31e31b8a
FB
677 info->env_end = (unsigned int)((unsigned long)p & 0xffffffff);
678 return sp;
679}
680
681
682
683static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
684 int interpreter_fd,
685 unsigned long *interp_load_addr)
686{
687 struct elf_phdr *elf_phdata = NULL;
688 struct elf_phdr *eppnt;
09bfb054 689 unsigned long load_addr = 0;
31e31b8a
FB
690 int load_addr_set = 0;
691 int retval;
692 unsigned long last_bss, elf_bss;
693 unsigned long error;
694 int i;
695
696 elf_bss = 0;
697 last_bss = 0;
698 error = 0;
699
644c433c
FB
700#ifdef BSWAP_NEEDED
701 bswap_ehdr(interp_elf_ex);
702#endif
31e31b8a
FB
703 /* First of all, some simple consistency checks */
704 if ((interp_elf_ex->e_type != ET_EXEC &&
09bfb054 705 interp_elf_ex->e_type != ET_DYN) ||
31e31b8a
FB
706 !elf_check_arch(interp_elf_ex->e_machine)) {
707 return ~0UL;
708 }
709
644c433c 710
31e31b8a
FB
711 /* Now read in all of the header information */
712
54936004 713 if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
31e31b8a
FB
714 return ~0UL;
715
716 elf_phdata = (struct elf_phdr *)
717 malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
718
719 if (!elf_phdata)
720 return ~0UL;
721
722 /*
723 * If the size of this structure has changed, then punt, since
724 * we will be doing the wrong thing.
725 */
09bfb054 726 if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
31e31b8a
FB
727 free(elf_phdata);
728 return ~0UL;
09bfb054 729 }
31e31b8a
FB
730
731 retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
732 if(retval >= 0) {
733 retval = read(interpreter_fd,
734 (char *) elf_phdata,
735 sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
736 }
31e31b8a
FB
737 if (retval < 0) {
738 perror("load_elf_interp");
739 exit(-1);
740 free (elf_phdata);
741 return retval;
742 }
743#ifdef BSWAP_NEEDED
744 eppnt = elf_phdata;
745 for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
746 bswap_phdr(eppnt);
747 }
748#endif
09bfb054
FB
749
750 if (interp_elf_ex->e_type == ET_DYN) {
751 /* in order to avoid harcoding the interpreter load
752 address in qemu, we allocate a big enough memory zone */
54936004
FB
753 error = target_mmap(0, INTERP_MAP_SIZE,
754 PROT_NONE, MAP_PRIVATE | MAP_ANON,
755 -1, 0);
09bfb054
FB
756 if (error == -1) {
757 perror("mmap");
758 exit(-1);
759 }
760 load_addr = error;
761 load_addr_set = 1;
762 }
763
31e31b8a
FB
764 eppnt = elf_phdata;
765 for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
766 if (eppnt->p_type == PT_LOAD) {
767 int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
768 int elf_prot = 0;
769 unsigned long vaddr = 0;
770 unsigned long k;
771
772 if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
773 if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
774 if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
775 if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
776 elf_type |= MAP_FIXED;
777 vaddr = eppnt->p_vaddr;
778 }
54936004
FB
779 error = target_mmap(load_addr+TARGET_ELF_PAGESTART(vaddr),
780 eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
31e31b8a
FB
781 elf_prot,
782 elf_type,
783 interpreter_fd,
54936004 784 eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
31e31b8a
FB
785
786 if (error > -1024UL) {
787 /* Real error */
788 close(interpreter_fd);
789 free(elf_phdata);
790 return ~0UL;
791 }
792
793 if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
794 load_addr = error;
795 load_addr_set = 1;
796 }
797
798 /*
799 * Find the end of the file mapping for this phdr, and keep
800 * track of the largest address we see for this.
801 */
802 k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
803 if (k > elf_bss) elf_bss = k;
804
805 /*
806 * Do the same thing for the memory mapping - between
807 * elf_bss and last_bss is the bss section.
808 */
809 k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
810 if (k > last_bss) last_bss = k;
811 }
812
813 /* Now use mmap to map the library into memory. */
814
815 close(interpreter_fd);
816
817 /*
818 * Now fill out the bss section. First pad the last page up
819 * to the page boundary, and then perform a mmap to make sure
820 * that there are zeromapped pages up to and including the last
821 * bss page.
822 */
823 padzero(elf_bss);
83fb7adf 824 elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); /* What we have mapped so far */
31e31b8a
FB
825
826 /* Map the last of the bss segment */
827 if (last_bss > elf_bss) {
54936004
FB
828 target_mmap(elf_bss, last_bss-elf_bss,
829 PROT_READ|PROT_WRITE|PROT_EXEC,
830 MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
31e31b8a
FB
831 }
832 free(elf_phdata);
833
834 *interp_load_addr = load_addr;
835 return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
836}
837
689f936f
FB
838/* Best attempt to load symbols from this ELF object. */
839static void load_symbols(struct elfhdr *hdr, int fd)
840{
841 unsigned int i;
842 struct elf_shdr sechdr, symtab, strtab;
843 char *strings;
e80cfcfc 844 struct syminfo *s;
689f936f
FB
845
846 lseek(fd, hdr->e_shoff, SEEK_SET);
847 for (i = 0; i < hdr->e_shnum; i++) {
848 if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
849 return;
850#ifdef BSWAP_NEEDED
851 bswap_shdr(&sechdr);
852#endif
853 if (sechdr.sh_type == SHT_SYMTAB) {
854 symtab = sechdr;
855 lseek(fd, hdr->e_shoff
856 + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
857 if (read(fd, &strtab, sizeof(strtab))
858 != sizeof(strtab))
859 return;
860#ifdef BSWAP_NEEDED
861 bswap_shdr(&strtab);
862#endif
863 goto found;
864 }
865 }
866 return; /* Shouldn't happen... */
867
868 found:
869 /* Now know where the strtab and symtab are. Snarf them. */
e80cfcfc
FB
870 s = malloc(sizeof(*s));
871 s->disas_symtab = malloc(symtab.sh_size);
872 s->disas_strtab = strings = malloc(strtab.sh_size);
873 if (!s->disas_symtab || !s->disas_strtab)
689f936f
FB
874 return;
875
876 lseek(fd, symtab.sh_offset, SEEK_SET);
e80cfcfc 877 if (read(fd, s->disas_symtab, symtab.sh_size) != symtab.sh_size)
689f936f 878 return;
31e31b8a 879
689f936f
FB
880#ifdef BSWAP_NEEDED
881 for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++)
e80cfcfc 882 bswap_sym(s->disas_symtab + sizeof(struct elf_sym)*i);
689f936f
FB
883#endif
884
885 lseek(fd, strtab.sh_offset, SEEK_SET);
886 if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
887 return;
e80cfcfc
FB
888 s->disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);
889 s->next = syminfos;
890 syminfos = s;
689f936f 891}
31e31b8a 892
b17780d5
FB
893static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
894 struct image_info * info)
31e31b8a
FB
895{
896 struct elfhdr elf_ex;
897 struct elfhdr interp_elf_ex;
898 struct exec interp_ex;
899 int interpreter_fd = -1; /* avoid warning */
09bfb054 900 unsigned long load_addr, load_bias;
31e31b8a
FB
901 int load_addr_set = 0;
902 unsigned int interpreter_type = INTERPRETER_NONE;
903 unsigned char ibcs2_interpreter;
904 int i;
54936004 905 unsigned long mapped_addr;
31e31b8a
FB
906 struct elf_phdr * elf_ppnt;
907 struct elf_phdr *elf_phdata;
908 unsigned long elf_bss, k, elf_brk;
909 int retval;
910 char * elf_interpreter;
911 unsigned long elf_entry, interp_load_addr = 0;
912 int status;
913 unsigned long start_code, end_code, end_data;
914 unsigned long elf_stack;
915 char passed_fileno[6];
916
917 ibcs2_interpreter = 0;
918 status = 0;
919 load_addr = 0;
09bfb054 920 load_bias = 0;
31e31b8a
FB
921 elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */
922#ifdef BSWAP_NEEDED
923 bswap_ehdr(&elf_ex);
924#endif
925
926 if (elf_ex.e_ident[0] != 0x7f ||
927 strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
928 return -ENOEXEC;
929 }
930
31e31b8a
FB
931 /* First of all, some simple consistency checks */
932 if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
933 (! elf_check_arch(elf_ex.e_machine))) {
934 return -ENOEXEC;
935 }
936
937 /* Now read in all of the header information */
31e31b8a
FB
938 elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
939 if (elf_phdata == NULL) {
940 return -ENOMEM;
941 }
942
943 retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
944 if(retval > 0) {
945 retval = read(bprm->fd, (char *) elf_phdata,
946 elf_ex.e_phentsize * elf_ex.e_phnum);
947 }
948
949 if (retval < 0) {
950 perror("load_elf_binary");
951 exit(-1);
952 free (elf_phdata);
953 return -errno;
954 }
955
b17780d5
FB
956#ifdef BSWAP_NEEDED
957 elf_ppnt = elf_phdata;
958 for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
959 bswap_phdr(elf_ppnt);
960 }
961#endif
31e31b8a
FB
962 elf_ppnt = elf_phdata;
963
964 elf_bss = 0;
965 elf_brk = 0;
966
967
968 elf_stack = ~0UL;
969 elf_interpreter = NULL;
970 start_code = ~0UL;
971 end_code = 0;
972 end_data = 0;
973
974 for(i=0;i < elf_ex.e_phnum; i++) {
975 if (elf_ppnt->p_type == PT_INTERP) {
976 if ( elf_interpreter != NULL )
977 {
978 free (elf_phdata);
979 free(elf_interpreter);
980 close(bprm->fd);
981 return -EINVAL;
982 }
983
984 /* This is the program interpreter used for
985 * shared libraries - for now assume that this
986 * is an a.out format binary
987 */
988
32ce6337 989 elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
31e31b8a
FB
990
991 if (elf_interpreter == NULL) {
992 free (elf_phdata);
993 close(bprm->fd);
994 return -ENOMEM;
995 }
996
31e31b8a
FB
997 retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
998 if(retval >= 0) {
32ce6337 999 retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
31e31b8a
FB
1000 }
1001 if(retval < 0) {
1002 perror("load_elf_binary2");
1003 exit(-1);
1004 }
1005
1006 /* If the program interpreter is one of these two,
1007 then assume an iBCS2 image. Otherwise assume
1008 a native linux image. */
1009
1010 /* JRP - Need to add X86 lib dir stuff here... */
1011
1012 if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
1013 strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
1014 ibcs2_interpreter = 1;
1015 }
1016
1017#if 0
1018 printf("Using ELF interpreter %s\n", elf_interpreter);
1019#endif
1020 if (retval >= 0) {
32ce6337 1021 retval = open(path(elf_interpreter), O_RDONLY);
31e31b8a
FB
1022 if(retval >= 0) {
1023 interpreter_fd = retval;
1024 }
1025 else {
1026 perror(elf_interpreter);
1027 exit(-1);
1028 /* retval = -errno; */
1029 }
1030 }
1031
1032 if (retval >= 0) {
1033 retval = lseek(interpreter_fd, 0, SEEK_SET);
1034 if(retval >= 0) {
1035 retval = read(interpreter_fd,bprm->buf,128);
1036 }
1037 }
1038 if (retval >= 0) {
1039 interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */
1040 interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */
1041 }
1042 if (retval < 0) {
1043 perror("load_elf_binary3");
1044 exit(-1);
1045 free (elf_phdata);
1046 free(elf_interpreter);
1047 close(bprm->fd);
1048 return retval;
1049 }
1050 }
1051 elf_ppnt++;
1052 }
1053
1054 /* Some simple consistency checks for the interpreter */
1055 if (elf_interpreter){
1056 interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
1057
1058 /* Now figure out which format our binary is */
1059 if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
1060 (N_MAGIC(interp_ex) != QMAGIC)) {
1061 interpreter_type = INTERPRETER_ELF;
1062 }
1063
1064 if (interp_elf_ex.e_ident[0] != 0x7f ||
1065 strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
1066 interpreter_type &= ~INTERPRETER_ELF;
1067 }
1068
1069 if (!interpreter_type) {
1070 free(elf_interpreter);
1071 free(elf_phdata);
1072 close(bprm->fd);
1073 return -ELIBBAD;
1074 }
1075 }
1076
1077 /* OK, we are done with that, now set up the arg stuff,
1078 and then start this sucker up */
1079
1080 if (!bprm->sh_bang) {
1081 char * passed_p;
1082
1083 if (interpreter_type == INTERPRETER_AOUT) {
eba2af63 1084 snprintf(passed_fileno, sizeof(passed_fileno), "%d", bprm->fd);
31e31b8a
FB
1085 passed_p = passed_fileno;
1086
1087 if (elf_interpreter) {
1088 bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p);
1089 bprm->argc++;
1090 }
1091 }
1092 if (!bprm->p) {
1093 if (elf_interpreter) {
1094 free(elf_interpreter);
1095 }
1096 free (elf_phdata);
1097 close(bprm->fd);
1098 return -E2BIG;
1099 }
1100 }
1101
1102 /* OK, This is the point of no return */
1103 info->end_data = 0;
1104 info->end_code = 0;
1105 info->start_mmap = (unsigned long)ELF_START_MMAP;
1106 info->mmap = 0;
1107 elf_entry = (unsigned long) elf_ex.e_entry;
1108
1109 /* Do this so that we can load the interpreter, if need be. We will
1110 change some of these later */
1111 info->rss = 0;
1112 bprm->p = setup_arg_pages(bprm->p, bprm, info);
1113 info->start_stack = bprm->p;
1114
1115 /* Now we do a little grungy work by mmaping the ELF image into
1116 * the correct location in memory. At this point, we assume that
1117 * the image should be loaded at fixed address, not at a variable
1118 * address.
1119 */
1120
31e31b8a 1121 for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
09bfb054
FB
1122 int elf_prot = 0;
1123 int elf_flags = 0;
1124 unsigned long error;
1125
1126 if (elf_ppnt->p_type != PT_LOAD)
1127 continue;
1128
1129 if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
1130 if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
1131 if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
1132 elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
1133 if (elf_ex.e_type == ET_EXEC || load_addr_set) {
1134 elf_flags |= MAP_FIXED;
1135 } else if (elf_ex.e_type == ET_DYN) {
1136 /* Try and get dynamic programs out of the way of the default mmap
1137 base, as well as whatever program they might try to exec. This
1138 is because the brk will follow the loader, and is not movable. */
1139 /* NOTE: for qemu, we do a big mmap to get enough space
1140 without harcoding any address */
54936004
FB
1141 error = target_mmap(0, ET_DYN_MAP_SIZE,
1142 PROT_NONE, MAP_PRIVATE | MAP_ANON,
1143 -1, 0);
09bfb054
FB
1144 if (error == -1) {
1145 perror("mmap");
1146 exit(-1);
1147 }
54936004 1148 load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
09bfb054
FB
1149 }
1150
54936004
FB
1151 error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
1152 (elf_ppnt->p_filesz +
1153 TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
1154 elf_prot,
1155 (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
1156 bprm->fd,
1157 (elf_ppnt->p_offset -
1158 TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
09bfb054
FB
1159 if (error == -1) {
1160 perror("mmap");
1161 exit(-1);
1162 }
31e31b8a
FB
1163
1164#ifdef LOW_ELF_STACK
54936004
FB
1165 if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
1166 elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr);
31e31b8a 1167#endif
09bfb054
FB
1168
1169 if (!load_addr_set) {
1170 load_addr_set = 1;
1171 load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
1172 if (elf_ex.e_type == ET_DYN) {
1173 load_bias += error -
54936004 1174 TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
09bfb054
FB
1175 load_addr += load_bias;
1176 }
1177 }
1178 k = elf_ppnt->p_vaddr;
1179 if (k < start_code)
1180 start_code = k;
1181 k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
1182 if (k > elf_bss)
1183 elf_bss = k;
1184 if ((elf_ppnt->p_flags & PF_X) && end_code < k)
1185 end_code = k;
1186 if (end_data < k)
1187 end_data = k;
1188 k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
1189 if (k > elf_brk) elf_brk = k;
31e31b8a
FB
1190 }
1191
09bfb054
FB
1192 elf_entry += load_bias;
1193 elf_bss += load_bias;
1194 elf_brk += load_bias;
1195 start_code += load_bias;
1196 end_code += load_bias;
1197 // start_data += load_bias;
1198 end_data += load_bias;
1199
31e31b8a
FB
1200 if (elf_interpreter) {
1201 if (interpreter_type & 1) {
1202 elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
1203 }
1204 else if (interpreter_type & 2) {
1205 elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
1206 &interp_load_addr);
1207 }
1208
1209 close(interpreter_fd);
1210 free(elf_interpreter);
1211
1212 if (elf_entry == ~0UL) {
1213 printf("Unable to load interpreter\n");
1214 free(elf_phdata);
1215 exit(-1);
1216 return 0;
1217 }
1218 }
1219
1220 free(elf_phdata);
1221
689f936f
FB
1222 if (loglevel)
1223 load_symbols(&elf_ex, bprm->fd);
1224
31e31b8a
FB
1225 if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
1226 info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
1227
1228#ifdef LOW_ELF_STACK
1229 info->start_stack = bprm->p = elf_stack - 4;
1230#endif
1231 bprm->p = (unsigned long)
1232 create_elf_tables((char *)bprm->p,
1233 bprm->argc,
1234 bprm->envc,
a1516e92 1235 &elf_ex,
09bfb054 1236 load_addr, load_bias,
31e31b8a
FB
1237 interp_load_addr,
1238 (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
1239 info);
1240 if (interpreter_type == INTERPRETER_AOUT)
1241 info->arg_start += strlen(passed_fileno) + 1;
1242 info->start_brk = info->brk = elf_brk;
1243 info->end_code = end_code;
1244 info->start_code = start_code;
1245 info->end_data = end_data;
1246 info->start_stack = bprm->p;
1247
1248 /* Calling set_brk effectively mmaps the pages that we need for the bss and break
1249 sections */
1250 set_brk(elf_bss, elf_brk);
1251
1252 padzero(elf_bss);
1253
1254#if 0
1255 printf("(start_brk) %x\n" , info->start_brk);
1256 printf("(end_code) %x\n" , info->end_code);
1257 printf("(start_code) %x\n" , info->start_code);
1258 printf("(end_data) %x\n" , info->end_data);
1259 printf("(start_stack) %x\n" , info->start_stack);
1260 printf("(brk) %x\n" , info->brk);
1261#endif
1262
1263 if ( info->personality == PER_SVR4 )
1264 {
1265 /* Why this, you ask??? Well SVr4 maps page 0 as read-only,
1266 and some applications "depend" upon this behavior.
1267 Since we do not have the power to recompile these, we
1268 emulate the SVr4 behavior. Sigh. */
83fb7adf 1269 mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC,
54936004 1270 MAP_FIXED | MAP_PRIVATE, -1, 0);
31e31b8a
FB
1271 }
1272
1273#ifdef ELF_PLAT_INIT
1274 /*
1275 * The ABI may specify that certain registers be set up in special
1276 * ways (on i386 %edx is the address of a DT_FINI function, for
1277 * example. This macro performs whatever initialization to
1278 * the regs structure is required.
1279 */
1280 ELF_PLAT_INIT(regs);
1281#endif
1282
1283
1284 info->entry = elf_entry;
1285
1286 return 0;
1287}
1288
1289
1290
32ce6337 1291int elf_exec(const char * filename, char ** argv, char ** envp,
b17780d5 1292 struct target_pt_regs * regs, struct image_info *infop)
31e31b8a
FB
1293{
1294 struct linux_binprm bprm;
1295 int retval;
1296 int i;
1297
54936004 1298 bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
31e31b8a
FB
1299 for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */
1300 bprm.page[i] = 0;
1301 retval = open(filename, O_RDONLY);
c2735790
FB
1302 if (retval < 0)
1303 return retval;
1304 bprm.fd = retval;
31e31b8a
FB
1305 bprm.filename = (char *)filename;
1306 bprm.sh_bang = 0;
1307 bprm.loader = 0;
1308 bprm.exec = 0;
1309 bprm.dont_iput = 0;
1310 bprm.argc = count(argv);
1311 bprm.envc = count(envp);
1312
1313 retval = prepare_binprm(&bprm);
1314
1315 if(retval>=0) {
1316 bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p);
1317 bprm.exec = bprm.p;
1318 bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p);
1319 bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p);
1320 if (!bprm.p) {
1321 retval = -E2BIG;
1322 }
1323 }
1324
1325 if(retval>=0) {
1326 retval = load_elf_binary(&bprm,regs,infop);
1327 }
1328 if(retval>=0) {
1329 /* success. Initialize important registers */
b346ff46 1330 init_thread(regs, infop);
31e31b8a
FB
1331 return retval;
1332 }
1333
1334 /* Something went wrong, return the inode and free the argument pages*/
1335 for (i=0 ; i<MAX_ARG_PAGES ; i++) {
1336 free_page((void *)bprm.page[i]);
1337 }
1338 return(retval);
1339}
1340
1341
1342static int load_aout_interp(void * exptr, int interp_fd)
1343{
1344 printf("a.out interpreter not yet supported\n");
1345 return(0);
1346}
1347