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