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