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