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