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