blob: 042c65dc7aefdafe45cdd195d154127a47198ad7 [file] [log] [blame]
bellard31e31b82003-02-18 22:55:36 +00001/* 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>
bellard31e31b82003-02-18 22:55:36 +00006#include <errno.h>
7#include <unistd.h>
8#include <sys/mman.h>
9#include <stdlib.h>
10#include <string.h>
11
bellard3ef693a2003-03-23 20:17:16 +000012#include "qemu.h"
bellard689f9362003-04-29 20:40:07 +000013#include "disas.h"
bellard31e31b82003-02-18 22:55:36 +000014
bellard83fb7ad2004-07-05 21:25:26 +000015/* 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
bellard30ac07d2003-04-07 21:33:03 +000025#ifdef TARGET_I386
26
bellard15338fd2005-11-26 11:41:16 +000027#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
bellard30ac07d2003-04-07 21:33:03 +000047#define ELF_START_MMAP 0x80000000
48
bellard30ac07d2003-04-07 21:33:03 +000049/*
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
bellardb346ff42003-06-15 20:05:50 +000061static 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;
pbrooke5fe0c52006-06-11 13:32:59 +000065
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;
bellardb346ff42003-06-15 20:05:50 +000074}
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
bellardb346ff42003-06-15 20:05:50 +000095static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
96{
pbrook53a59602006-03-25 19:31:22 +000097 target_long stack = infop->start_stack;
bellardb346ff42003-06-15 20:05:50 +000098 memset(regs, 0, sizeof(*regs));
99 regs->ARM_cpsr = 0x10;
pbrook0240ded2006-02-04 19:30:51 +0000100 if (infop->entry & 1)
101 regs->ARM_cpsr |= CPSR_T;
102 regs->ARM_pc = infop->entry & 0xfffffffe;
bellardb346ff42003-06-15 20:05:50 +0000103 regs->ARM_sp = infop->start_stack;
pbrook53a59602006-03-25 19:31:22 +0000104 regs->ARM_r2 = tgetl(stack + 8); /* envp */
105 regs->ARM_r1 = tgetl(stack + 4); /* envp */
bellarda1516e92003-07-09 17:13:37 +0000106 /* XXX: it seems that r0 is zeroed after ! */
pbrooke5fe0c52006-06-11 13:32:59 +0000107 regs->ARM_r0 = 0;
108 /* For uClinux PIC binaries. */
109 regs->ARM_r10 = infop->start_data;
bellardb346ff42003-06-15 20:05:50 +0000110}
111
bellard30ac07d2003-04-07 21:33:03 +0000112#define USE_ELF_CORE_DUMP
113#define ELF_EXEC_PAGESIZE 4096
114
bellardafce2922005-10-30 20:58:30 +0000115enum
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
bellard15338fd2005-11-26 11:41:16 +0000127#define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF \
bellardafce2922005-10-30 20:58:30 +0000128 | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT \
129 | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP)
130
bellard30ac07d2003-04-07 21:33:03 +0000131#endif
132
bellard853d6f72003-09-30 20:58:32 +0000133#ifdef TARGET_SPARC
bellarda315a142005-01-30 22:59:18 +0000134#ifdef TARGET_SPARC64
bellard853d6f72003-09-30 20:58:32 +0000135
136#define ELF_START_MMAP 0x80000000
137
bellard5ef54112006-07-18 21:14:09 +0000138#define elf_check_arch(x) ( (x) == EM_SPARCV9 )
bellard853d6f72003-09-30 20:58:32 +0000139
bellarda315a142005-01-30 22:59:18 +0000140#define ELF_CLASS ELFCLASS64
141#define ELF_DATA ELFDATA2MSB
bellard5ef54112006-07-18 21:14:09 +0000142#define ELF_ARCH EM_SPARCV9
143
144#define STACK_BIAS 2047
bellarda315a142005-01-30 22:59:18 +0000145
bellarda315a142005-01-30 22:59:18 +0000146static 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;
bellard5ef54112006-07-18 21:14:09 +0000152 regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;
bellarda315a142005-01-30 22:59:18 +0000153}
154
155#else
156#define ELF_START_MMAP 0x80000000
157
158#define elf_check_arch(x) ( (x) == EM_SPARC )
159
bellard853d6f72003-09-30 20:58:32 +0000160#define ELF_CLASS ELFCLASS32
161#define ELF_DATA ELFDATA2MSB
162#define ELF_ARCH EM_SPARC
163
bellard853d6f72003-09-30 20:58:32 +0000164static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
165{
bellardf5155282004-01-04 15:46:50 +0000166 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;
bellard853d6f72003-09-30 20:58:32 +0000171}
172
173#endif
bellarda315a142005-01-30 22:59:18 +0000174#endif
bellard853d6f72003-09-30 20:58:32 +0000175
bellard67867302003-11-23 17:05:30 +0000176#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
bellardf5155282004-01-04 15:46:50 +0000190/*
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 */
bellard0bccf032005-08-21 10:12:28 +0000208#define DLINFO_ARCH_ITEMS 5
bellardf5155282004-01-04 15:46:50 +0000209#define ARCH_DLINFO \
210do { \
bellard0bccf032005-08-21 10:12:28 +0000211 NEW_AUX_ENT(AT_DCACHEBSIZE, 0x20); \
212 NEW_AUX_ENT(AT_ICACHEBSIZE, 0x20); \
213 NEW_AUX_ENT(AT_UCACHEBSIZE, 0); \
bellardf5155282004-01-04 15:46:50 +0000214 /* \
215 * Now handle glibc compatibility. \
216 */ \
bellard0bccf032005-08-21 10:12:28 +0000217 NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
218 NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
bellardf5155282004-01-04 15:46:50 +0000219 } while (0)
220
bellard67867302003-11-23 17:05:30 +0000221static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
222{
pbrooke5fe0c52006-06-11 13:32:59 +0000223 target_ulong pos = infop->start_stack;
224 target_ulong tmp;
225
bellard67867302003-11-23 17:05:30 +0000226 _regs->msr = 1 << MSR_PR; /* Set user mode */
227 _regs->gpr[1] = infop->start_stack;
228 _regs->nip = infop->entry;
pbrooke5fe0c52006-06-11 13:32:59 +0000229 /* 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;
bellard67867302003-11-23 17:05:30 +0000239}
240
241#define USE_ELF_CORE_DUMP
242#define ELF_EXEC_PAGESIZE 4096
243
244#endif
245
bellard048f6b42005-11-26 18:47:20 +0000246#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
bellard048f6b42005-11-26 18:47:20 +0000260static 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
bellardfdf9b3e2006-04-27 21:07:38 +0000269#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
bellardfdf9b3e2006-04-27 21:07:38 +0000279static 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
pbrooke6e59062006-10-22 00:18:54 +0000291#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
304static 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
bellard15338fd2005-11-26 11:41:16 +0000316#ifndef ELF_PLATFORM
317#define ELF_PLATFORM (NULL)
318#endif
319
320#ifndef ELF_HWCAP
321#define ELF_HWCAP 0
322#endif
323
bellard31e31b82003-02-18 22:55:36 +0000324#include "elf.h"
bellard09bfb052003-04-10 00:03:40 +0000325
bellard09bfb052003-04-10 00:03:40 +0000326struct exec
327{
328 unsigned int a_info; /* Use macros N_MAGIC, etc for access */
329 unsigned int a_text; /* length of text, in bytes */
330 unsigned int a_data; /* length of data, in bytes */
331 unsigned int a_bss; /* length of uninitialized data area, in bytes */
332 unsigned int a_syms; /* length of symbol table data in file, in bytes */
333 unsigned int a_entry; /* start address */
334 unsigned int a_trsize; /* length of relocation info for text, in bytes */
335 unsigned int a_drsize; /* length of relocation info for data, in bytes */
336};
337
338
339#define N_MAGIC(exec) ((exec).a_info & 0xffff)
340#define OMAGIC 0407
341#define NMAGIC 0410
342#define ZMAGIC 0413
343#define QMAGIC 0314
344
bellard09bfb052003-04-10 00:03:40 +0000345/* max code+data+bss space allocated to elf interpreter */
346#define INTERP_MAP_SIZE (32 * 1024 * 1024)
347
348/* max code+data+bss+brk space allocated to ET_DYN executables */
349#define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
350
351/* from personality.h */
352
353/* Flags for bug emulation. These occupy the top three bytes. */
354#define STICKY_TIMEOUTS 0x4000000
355#define WHOLE_SECONDS 0x2000000
356
357/* Personality types. These go in the low byte. Avoid using the top bit,
358 * it will conflict with error returns.
359 */
360#define PER_MASK (0x00ff)
361#define PER_LINUX (0x0000)
362#define PER_SVR4 (0x0001 | STICKY_TIMEOUTS)
363#define PER_SVR3 (0x0002 | STICKY_TIMEOUTS)
364#define PER_SCOSVR3 (0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS)
365#define PER_WYSEV386 (0x0004 | STICKY_TIMEOUTS)
366#define PER_ISCR4 (0x0005 | STICKY_TIMEOUTS)
367#define PER_BSD (0x0006)
368#define PER_XENIX (0x0007 | STICKY_TIMEOUTS)
bellard31e31b82003-02-18 22:55:36 +0000369
370/* Necessary parameters */
bellard54936002003-05-13 00:25:15 +0000371#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
372#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
373#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
bellard31e31b82003-02-18 22:55:36 +0000374
375#define INTERPRETER_NONE 0
376#define INTERPRETER_AOUT 1
377#define INTERPRETER_ELF 2
378
bellard15338fd2005-11-26 11:41:16 +0000379#define DLINFO_ITEMS 12
bellard31e31b82003-02-18 22:55:36 +0000380
bellard09bfb052003-04-10 00:03:40 +0000381static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
382{
383 memcpy(to, from, n);
384}
385
bellard31e31b82003-02-18 22:55:36 +0000386extern unsigned long x86_stack_size;
387
388static int load_aout_interp(void * exptr, int interp_fd);
389
390#ifdef BSWAP_NEEDED
bellard92a31b12005-02-10 22:00:52 +0000391static void bswap_ehdr(struct elfhdr *ehdr)
bellard31e31b82003-02-18 22:55:36 +0000392{
393 bswap16s(&ehdr->e_type); /* Object file type */
394 bswap16s(&ehdr->e_machine); /* Architecture */
395 bswap32s(&ehdr->e_version); /* Object file version */
bellard92a31b12005-02-10 22:00:52 +0000396 bswaptls(&ehdr->e_entry); /* Entry point virtual address */
397 bswaptls(&ehdr->e_phoff); /* Program header table file offset */
398 bswaptls(&ehdr->e_shoff); /* Section header table file offset */
bellard31e31b82003-02-18 22:55:36 +0000399 bswap32s(&ehdr->e_flags); /* Processor-specific flags */
400 bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
401 bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
402 bswap16s(&ehdr->e_phnum); /* Program header table entry count */
403 bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
404 bswap16s(&ehdr->e_shnum); /* Section header table entry count */
405 bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
406}
407
bellard92a31b12005-02-10 22:00:52 +0000408static void bswap_phdr(struct elf_phdr *phdr)
bellard31e31b82003-02-18 22:55:36 +0000409{
410 bswap32s(&phdr->p_type); /* Segment type */
bellard92a31b12005-02-10 22:00:52 +0000411 bswaptls(&phdr->p_offset); /* Segment file offset */
412 bswaptls(&phdr->p_vaddr); /* Segment virtual address */
413 bswaptls(&phdr->p_paddr); /* Segment physical address */
414 bswaptls(&phdr->p_filesz); /* Segment size in file */
415 bswaptls(&phdr->p_memsz); /* Segment size in memory */
bellard31e31b82003-02-18 22:55:36 +0000416 bswap32s(&phdr->p_flags); /* Segment flags */
bellard92a31b12005-02-10 22:00:52 +0000417 bswaptls(&phdr->p_align); /* Segment alignment */
bellard31e31b82003-02-18 22:55:36 +0000418}
bellard689f9362003-04-29 20:40:07 +0000419
bellard92a31b12005-02-10 22:00:52 +0000420static void bswap_shdr(struct elf_shdr *shdr)
bellard689f9362003-04-29 20:40:07 +0000421{
422 bswap32s(&shdr->sh_name);
423 bswap32s(&shdr->sh_type);
bellard92a31b12005-02-10 22:00:52 +0000424 bswaptls(&shdr->sh_flags);
425 bswaptls(&shdr->sh_addr);
426 bswaptls(&shdr->sh_offset);
427 bswaptls(&shdr->sh_size);
bellard689f9362003-04-29 20:40:07 +0000428 bswap32s(&shdr->sh_link);
429 bswap32s(&shdr->sh_info);
bellard92a31b12005-02-10 22:00:52 +0000430 bswaptls(&shdr->sh_addralign);
431 bswaptls(&shdr->sh_entsize);
bellard689f9362003-04-29 20:40:07 +0000432}
433
434static void bswap_sym(Elf32_Sym *sym)
435{
436 bswap32s(&sym->st_name);
437 bswap32s(&sym->st_value);
438 bswap32s(&sym->st_size);
439 bswap16s(&sym->st_shndx);
440}
bellard31e31b82003-02-18 22:55:36 +0000441#endif
442
bellard31e31b82003-02-18 22:55:36 +0000443/*
pbrooke5fe0c52006-06-11 13:32:59 +0000444 * 'copy_elf_strings()' copies argument/envelope strings from user
bellard31e31b82003-02-18 22:55:36 +0000445 * memory to free pages in kernel mem. These are in a format ready
446 * to be put directly into the top of new user memory.
447 *
448 */
pbrooke5fe0c52006-06-11 13:32:59 +0000449static unsigned long copy_elf_strings(int argc,char ** argv, void **page,
450 unsigned long p)
bellard31e31b82003-02-18 22:55:36 +0000451{
452 char *tmp, *tmp1, *pag = NULL;
453 int len, offset = 0;
454
455 if (!p) {
456 return 0; /* bullet-proofing */
457 }
458 while (argc-- > 0) {
bellardedf779f2004-02-22 13:40:13 +0000459 tmp = argv[argc];
460 if (!tmp) {
bellard31e31b82003-02-18 22:55:36 +0000461 fprintf(stderr, "VFS: argc is wrong");
462 exit(-1);
463 }
bellardedf779f2004-02-22 13:40:13 +0000464 tmp1 = tmp;
465 while (*tmp++);
bellard31e31b82003-02-18 22:55:36 +0000466 len = tmp - tmp1;
467 if (p < len) { /* this shouldn't happen - 128kB */
468 return 0;
469 }
470 while (len) {
471 --p; --tmp; --len;
472 if (--offset < 0) {
bellard54936002003-05-13 00:25:15 +0000473 offset = p % TARGET_PAGE_SIZE;
pbrook53a59602006-03-25 19:31:22 +0000474 pag = (char *)page[p/TARGET_PAGE_SIZE];
bellard44a91ca2004-01-18 22:05:44 +0000475 if (!pag) {
pbrook53a59602006-03-25 19:31:22 +0000476 pag = (char *)malloc(TARGET_PAGE_SIZE);
477 page[p/TARGET_PAGE_SIZE] = pag;
bellard44a91ca2004-01-18 22:05:44 +0000478 if (!pag)
479 return 0;
bellard31e31b82003-02-18 22:55:36 +0000480 }
481 }
482 if (len == 0 || offset == 0) {
bellardedf779f2004-02-22 13:40:13 +0000483 *(pag + offset) = *tmp;
bellard31e31b82003-02-18 22:55:36 +0000484 }
485 else {
486 int bytes_to_copy = (len > offset) ? offset : len;
487 tmp -= bytes_to_copy;
488 p -= bytes_to_copy;
489 offset -= bytes_to_copy;
490 len -= bytes_to_copy;
491 memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
492 }
493 }
494 }
495 return p;
496}
497
pbrook53a59602006-03-25 19:31:22 +0000498unsigned long setup_arg_pages(target_ulong p, struct linux_binprm * bprm,
499 struct image_info * info)
500{
501 target_ulong stack_base, size, error;
bellard31e31b82003-02-18 22:55:36 +0000502 int i;
bellard31e31b82003-02-18 22:55:36 +0000503
504 /* Create enough stack to hold everything. If we don't use
505 * it for args, we'll use it for something else...
506 */
bellard09bfb052003-04-10 00:03:40 +0000507 size = x86_stack_size;
bellard54936002003-05-13 00:25:15 +0000508 if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
509 size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
510 error = target_mmap(0,
bellard83fb7ad2004-07-05 21:25:26 +0000511 size + qemu_host_page_size,
bellard54936002003-05-13 00:25:15 +0000512 PROT_READ | PROT_WRITE,
513 MAP_PRIVATE | MAP_ANONYMOUS,
514 -1, 0);
bellard09bfb052003-04-10 00:03:40 +0000515 if (error == -1) {
516 perror("stk mmap");
517 exit(-1);
bellard31e31b82003-02-18 22:55:36 +0000518 }
bellard09bfb052003-04-10 00:03:40 +0000519 /* we reserve one extra page at the top of the stack as guard */
bellard83fb7ad2004-07-05 21:25:26 +0000520 target_mprotect(error + size, qemu_host_page_size, PROT_NONE);
bellard09bfb052003-04-10 00:03:40 +0000521
bellard54936002003-05-13 00:25:15 +0000522 stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE;
bellard09bfb052003-04-10 00:03:40 +0000523 p += stack_base;
524
bellard31e31b82003-02-18 22:55:36 +0000525 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
526 if (bprm->page[i]) {
527 info->rss++;
528
pbrook53a59602006-03-25 19:31:22 +0000529 memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);
530 free(bprm->page[i]);
bellard31e31b82003-02-18 22:55:36 +0000531 }
pbrook53a59602006-03-25 19:31:22 +0000532 stack_base += TARGET_PAGE_SIZE;
bellard31e31b82003-02-18 22:55:36 +0000533 }
534 return p;
535}
536
537static void set_brk(unsigned long start, unsigned long end)
538{
539 /* page-align the start and end addresses... */
bellard54936002003-05-13 00:25:15 +0000540 start = HOST_PAGE_ALIGN(start);
541 end = HOST_PAGE_ALIGN(end);
bellard31e31b82003-02-18 22:55:36 +0000542 if (end <= start)
543 return;
bellard54936002003-05-13 00:25:15 +0000544 if(target_mmap(start, end - start,
545 PROT_READ | PROT_WRITE | PROT_EXEC,
546 MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
bellard31e31b82003-02-18 22:55:36 +0000547 perror("cannot mmap brk");
548 exit(-1);
549 }
550}
551
552
bellard853d6f72003-09-30 20:58:32 +0000553/* We need to explicitly zero any fractional pages after the data
554 section (i.e. bss). This would contain the junk from the file that
555 should not be in memory. */
bellard31e31b82003-02-18 22:55:36 +0000556static void padzero(unsigned long elf_bss)
557{
558 unsigned long nbyte;
bellard31e31b82003-02-18 22:55:36 +0000559
bellard853d6f72003-09-30 20:58:32 +0000560 /* XXX: this is really a hack : if the real host page size is
561 smaller than the target page size, some pages after the end
562 of the file may not be mapped. A better fix would be to
563 patch target_mmap(), but it is more complicated as the file
564 size must be known */
bellard83fb7ad2004-07-05 21:25:26 +0000565 if (qemu_real_host_page_size < qemu_host_page_size) {
bellard853d6f72003-09-30 20:58:32 +0000566 unsigned long end_addr, end_addr1;
bellard83fb7ad2004-07-05 21:25:26 +0000567 end_addr1 = (elf_bss + qemu_real_host_page_size - 1) &
568 ~(qemu_real_host_page_size - 1);
bellard853d6f72003-09-30 20:58:32 +0000569 end_addr = HOST_PAGE_ALIGN(elf_bss);
570 if (end_addr1 < end_addr) {
571 mmap((void *)end_addr1, end_addr - end_addr1,
572 PROT_READ|PROT_WRITE|PROT_EXEC,
573 MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
574 }
575 }
576
bellard83fb7ad2004-07-05 21:25:26 +0000577 nbyte = elf_bss & (qemu_host_page_size-1);
bellard31e31b82003-02-18 22:55:36 +0000578 if (nbyte) {
bellard83fb7ad2004-07-05 21:25:26 +0000579 nbyte = qemu_host_page_size - nbyte;
bellard31e31b82003-02-18 22:55:36 +0000580 do {
pbrook53a59602006-03-25 19:31:22 +0000581 tput8(elf_bss, 0);
582 elf_bss++;
bellard31e31b82003-02-18 22:55:36 +0000583 } while (--nbyte);
584 }
585}
586
bellardedf779f2004-02-22 13:40:13 +0000587
pbrook53a59602006-03-25 19:31:22 +0000588static unsigned long create_elf_tables(target_ulong p, int argc, int envc,
589 struct elfhdr * exec,
590 unsigned long load_addr,
591 unsigned long load_bias,
592 unsigned long interp_load_addr, int ibcs,
593 struct image_info *info)
594{
pbrook53a59602006-03-25 19:31:22 +0000595 target_ulong sp;
596 int size;
597 target_ulong u_platform;
598 const char *k_platform;
599 const int n = sizeof(target_ulong);
600
601 sp = p;
602 u_platform = 0;
bellard15338fd2005-11-26 11:41:16 +0000603 k_platform = ELF_PLATFORM;
604 if (k_platform) {
605 size_t len = strlen(k_platform) + 1;
pbrook53a59602006-03-25 19:31:22 +0000606 sp -= (len + n - 1) & ~(n - 1);
607 u_platform = sp;
608 memcpy_to_target(sp, k_platform, len);
bellard15338fd2005-11-26 11:41:16 +0000609 }
pbrook53a59602006-03-25 19:31:22 +0000610 /*
611 * Force 16 byte _final_ alignment here for generality.
612 */
613 sp = sp &~ (target_ulong)15;
614 size = (DLINFO_ITEMS + 1) * 2;
bellard15338fd2005-11-26 11:41:16 +0000615 if (k_platform)
pbrook53a59602006-03-25 19:31:22 +0000616 size += 2;
bellardf5155282004-01-04 15:46:50 +0000617#ifdef DLINFO_ARCH_ITEMS
pbrook53a59602006-03-25 19:31:22 +0000618 size += DLINFO_ARCH_ITEMS * 2;
bellardf5155282004-01-04 15:46:50 +0000619#endif
pbrook53a59602006-03-25 19:31:22 +0000620 size += envc + argc + 2;
621 size += (!ibcs ? 3 : 1); /* argc itself */
622 size *= n;
623 if (size & 15)
624 sp -= 16 - (size & 15);
bellardf5155282004-01-04 15:46:50 +0000625
pbrook53a59602006-03-25 19:31:22 +0000626#define NEW_AUX_ENT(id, val) do { \
627 sp -= n; tputl(sp, val); \
628 sp -= n; tputl(sp, id); \
629 } while(0)
bellard0bccf032005-08-21 10:12:28 +0000630 NEW_AUX_ENT (AT_NULL, 0);
bellardf5155282004-01-04 15:46:50 +0000631
bellard0bccf032005-08-21 10:12:28 +0000632 /* There must be exactly DLINFO_ITEMS entries here. */
633 NEW_AUX_ENT(AT_PHDR, (target_ulong)(load_addr + exec->e_phoff));
634 NEW_AUX_ENT(AT_PHENT, (target_ulong)(sizeof (struct elf_phdr)));
635 NEW_AUX_ENT(AT_PHNUM, (target_ulong)(exec->e_phnum));
636 NEW_AUX_ENT(AT_PAGESZ, (target_ulong)(TARGET_PAGE_SIZE));
637 NEW_AUX_ENT(AT_BASE, (target_ulong)(interp_load_addr));
638 NEW_AUX_ENT(AT_FLAGS, (target_ulong)0);
639 NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry);
640 NEW_AUX_ENT(AT_UID, (target_ulong) getuid());
641 NEW_AUX_ENT(AT_EUID, (target_ulong) geteuid());
642 NEW_AUX_ENT(AT_GID, (target_ulong) getgid());
643 NEW_AUX_ENT(AT_EGID, (target_ulong) getegid());
bellard15338fd2005-11-26 11:41:16 +0000644 NEW_AUX_ENT(AT_HWCAP, (target_ulong) ELF_HWCAP);
645 if (k_platform)
pbrook53a59602006-03-25 19:31:22 +0000646 NEW_AUX_ENT(AT_PLATFORM, u_platform);
bellardf5155282004-01-04 15:46:50 +0000647#ifdef ARCH_DLINFO
648 /*
649 * ARCH_DLINFO must come last so platform specific code can enforce
650 * special alignment requirements on the AUXV if necessary (eg. PPC).
651 */
652 ARCH_DLINFO;
653#endif
654#undef NEW_AUX_ENT
655
pbrooke5fe0c52006-06-11 13:32:59 +0000656 sp = loader_build_argptr(envc, argc, sp, p, !ibcs);
bellard31e31b82003-02-18 22:55:36 +0000657 return sp;
658}
659
660
bellard31e31b82003-02-18 22:55:36 +0000661static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
662 int interpreter_fd,
663 unsigned long *interp_load_addr)
664{
665 struct elf_phdr *elf_phdata = NULL;
666 struct elf_phdr *eppnt;
bellard09bfb052003-04-10 00:03:40 +0000667 unsigned long load_addr = 0;
bellard31e31b82003-02-18 22:55:36 +0000668 int load_addr_set = 0;
669 int retval;
670 unsigned long last_bss, elf_bss;
671 unsigned long error;
672 int i;
673
674 elf_bss = 0;
675 last_bss = 0;
676 error = 0;
677
bellard644c4332003-03-24 23:00:36 +0000678#ifdef BSWAP_NEEDED
679 bswap_ehdr(interp_elf_ex);
680#endif
bellard31e31b82003-02-18 22:55:36 +0000681 /* First of all, some simple consistency checks */
682 if ((interp_elf_ex->e_type != ET_EXEC &&
bellard09bfb052003-04-10 00:03:40 +0000683 interp_elf_ex->e_type != ET_DYN) ||
bellard31e31b82003-02-18 22:55:36 +0000684 !elf_check_arch(interp_elf_ex->e_machine)) {
685 return ~0UL;
686 }
687
bellard644c4332003-03-24 23:00:36 +0000688
bellard31e31b82003-02-18 22:55:36 +0000689 /* Now read in all of the header information */
690
bellard54936002003-05-13 00:25:15 +0000691 if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
bellard31e31b82003-02-18 22:55:36 +0000692 return ~0UL;
693
694 elf_phdata = (struct elf_phdr *)
695 malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
696
697 if (!elf_phdata)
698 return ~0UL;
699
700 /*
701 * If the size of this structure has changed, then punt, since
702 * we will be doing the wrong thing.
703 */
bellard09bfb052003-04-10 00:03:40 +0000704 if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
bellard31e31b82003-02-18 22:55:36 +0000705 free(elf_phdata);
706 return ~0UL;
bellard09bfb052003-04-10 00:03:40 +0000707 }
bellard31e31b82003-02-18 22:55:36 +0000708
709 retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
710 if(retval >= 0) {
711 retval = read(interpreter_fd,
712 (char *) elf_phdata,
713 sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
714 }
bellard31e31b82003-02-18 22:55:36 +0000715 if (retval < 0) {
716 perror("load_elf_interp");
717 exit(-1);
718 free (elf_phdata);
719 return retval;
720 }
721#ifdef BSWAP_NEEDED
722 eppnt = elf_phdata;
723 for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
724 bswap_phdr(eppnt);
725 }
726#endif
bellard09bfb052003-04-10 00:03:40 +0000727
728 if (interp_elf_ex->e_type == ET_DYN) {
729 /* in order to avoid harcoding the interpreter load
730 address in qemu, we allocate a big enough memory zone */
bellard54936002003-05-13 00:25:15 +0000731 error = target_mmap(0, INTERP_MAP_SIZE,
732 PROT_NONE, MAP_PRIVATE | MAP_ANON,
733 -1, 0);
bellard09bfb052003-04-10 00:03:40 +0000734 if (error == -1) {
735 perror("mmap");
736 exit(-1);
737 }
738 load_addr = error;
739 load_addr_set = 1;
740 }
741
bellard31e31b82003-02-18 22:55:36 +0000742 eppnt = elf_phdata;
743 for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
744 if (eppnt->p_type == PT_LOAD) {
745 int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
746 int elf_prot = 0;
747 unsigned long vaddr = 0;
748 unsigned long k;
749
750 if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
751 if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
752 if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
753 if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
754 elf_type |= MAP_FIXED;
755 vaddr = eppnt->p_vaddr;
756 }
bellard54936002003-05-13 00:25:15 +0000757 error = target_mmap(load_addr+TARGET_ELF_PAGESTART(vaddr),
758 eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
bellard31e31b82003-02-18 22:55:36 +0000759 elf_prot,
760 elf_type,
761 interpreter_fd,
bellard54936002003-05-13 00:25:15 +0000762 eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
bellard31e31b82003-02-18 22:55:36 +0000763
pbrooke89f07d2006-02-04 20:46:24 +0000764 if (error == -1) {
bellard31e31b82003-02-18 22:55:36 +0000765 /* Real error */
766 close(interpreter_fd);
767 free(elf_phdata);
768 return ~0UL;
769 }
770
771 if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
772 load_addr = error;
773 load_addr_set = 1;
774 }
775
776 /*
777 * Find the end of the file mapping for this phdr, and keep
778 * track of the largest address we see for this.
779 */
780 k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
781 if (k > elf_bss) elf_bss = k;
782
783 /*
784 * Do the same thing for the memory mapping - between
785 * elf_bss and last_bss is the bss section.
786 */
787 k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
788 if (k > last_bss) last_bss = k;
789 }
790
791 /* Now use mmap to map the library into memory. */
792
793 close(interpreter_fd);
794
795 /*
796 * Now fill out the bss section. First pad the last page up
797 * to the page boundary, and then perform a mmap to make sure
798 * that there are zeromapped pages up to and including the last
799 * bss page.
800 */
801 padzero(elf_bss);
bellard83fb7ad2004-07-05 21:25:26 +0000802 elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); /* What we have mapped so far */
bellard31e31b82003-02-18 22:55:36 +0000803
804 /* Map the last of the bss segment */
805 if (last_bss > elf_bss) {
bellard54936002003-05-13 00:25:15 +0000806 target_mmap(elf_bss, last_bss-elf_bss,
807 PROT_READ|PROT_WRITE|PROT_EXEC,
808 MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
bellard31e31b82003-02-18 22:55:36 +0000809 }
810 free(elf_phdata);
811
812 *interp_load_addr = load_addr;
813 return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
814}
815
bellard689f9362003-04-29 20:40:07 +0000816/* Best attempt to load symbols from this ELF object. */
817static void load_symbols(struct elfhdr *hdr, int fd)
818{
819 unsigned int i;
820 struct elf_shdr sechdr, symtab, strtab;
821 char *strings;
bellarde80cfcf2004-12-19 23:18:01 +0000822 struct syminfo *s;
bellard31e31b82003-02-18 22:55:36 +0000823
bellard689f9362003-04-29 20:40:07 +0000824 lseek(fd, hdr->e_shoff, SEEK_SET);
825 for (i = 0; i < hdr->e_shnum; i++) {
826 if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
827 return;
828#ifdef BSWAP_NEEDED
829 bswap_shdr(&sechdr);
830#endif
831 if (sechdr.sh_type == SHT_SYMTAB) {
832 symtab = sechdr;
833 lseek(fd, hdr->e_shoff
834 + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
835 if (read(fd, &strtab, sizeof(strtab))
836 != sizeof(strtab))
837 return;
838#ifdef BSWAP_NEEDED
839 bswap_shdr(&strtab);
840#endif
841 goto found;
842 }
843 }
844 return; /* Shouldn't happen... */
845
846 found:
847 /* Now know where the strtab and symtab are. Snarf them. */
bellarde80cfcf2004-12-19 23:18:01 +0000848 s = malloc(sizeof(*s));
849 s->disas_symtab = malloc(symtab.sh_size);
850 s->disas_strtab = strings = malloc(strtab.sh_size);
851 if (!s->disas_symtab || !s->disas_strtab)
bellard689f9362003-04-29 20:40:07 +0000852 return;
853
854 lseek(fd, symtab.sh_offset, SEEK_SET);
bellarde80cfcf2004-12-19 23:18:01 +0000855 if (read(fd, s->disas_symtab, symtab.sh_size) != symtab.sh_size)
bellard689f9362003-04-29 20:40:07 +0000856 return;
857
858#ifdef BSWAP_NEEDED
859 for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++)
bellarde80cfcf2004-12-19 23:18:01 +0000860 bswap_sym(s->disas_symtab + sizeof(struct elf_sym)*i);
bellard689f9362003-04-29 20:40:07 +0000861#endif
862
863 lseek(fd, strtab.sh_offset, SEEK_SET);
864 if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
865 return;
bellarde80cfcf2004-12-19 23:18:01 +0000866 s->disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);
867 s->next = syminfos;
868 syminfos = s;
bellard689f9362003-04-29 20:40:07 +0000869}
bellard31e31b82003-02-18 22:55:36 +0000870
pbrooke5fe0c52006-06-11 13:32:59 +0000871int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
872 struct image_info * info)
bellard31e31b82003-02-18 22:55:36 +0000873{
874 struct elfhdr elf_ex;
875 struct elfhdr interp_elf_ex;
876 struct exec interp_ex;
877 int interpreter_fd = -1; /* avoid warning */
bellard09bfb052003-04-10 00:03:40 +0000878 unsigned long load_addr, load_bias;
bellard31e31b82003-02-18 22:55:36 +0000879 int load_addr_set = 0;
880 unsigned int interpreter_type = INTERPRETER_NONE;
881 unsigned char ibcs2_interpreter;
882 int i;
bellard54936002003-05-13 00:25:15 +0000883 unsigned long mapped_addr;
bellard31e31b82003-02-18 22:55:36 +0000884 struct elf_phdr * elf_ppnt;
885 struct elf_phdr *elf_phdata;
886 unsigned long elf_bss, k, elf_brk;
887 int retval;
888 char * elf_interpreter;
889 unsigned long elf_entry, interp_load_addr = 0;
890 int status;
891 unsigned long start_code, end_code, end_data;
892 unsigned long elf_stack;
893 char passed_fileno[6];
894
895 ibcs2_interpreter = 0;
896 status = 0;
897 load_addr = 0;
bellard09bfb052003-04-10 00:03:40 +0000898 load_bias = 0;
bellard31e31b82003-02-18 22:55:36 +0000899 elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */
900#ifdef BSWAP_NEEDED
901 bswap_ehdr(&elf_ex);
902#endif
903
bellard31e31b82003-02-18 22:55:36 +0000904 /* First of all, some simple consistency checks */
905 if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
906 (! elf_check_arch(elf_ex.e_machine))) {
907 return -ENOEXEC;
908 }
909
pbrooke5fe0c52006-06-11 13:32:59 +0000910 bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p);
911 bprm->p = copy_elf_strings(bprm->envc,bprm->envp,bprm->page,bprm->p);
912 bprm->p = copy_elf_strings(bprm->argc,bprm->argv,bprm->page,bprm->p);
913 if (!bprm->p) {
914 retval = -E2BIG;
915 }
916
bellard31e31b82003-02-18 22:55:36 +0000917 /* Now read in all of the header information */
bellard31e31b82003-02-18 22:55:36 +0000918 elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
919 if (elf_phdata == NULL) {
920 return -ENOMEM;
921 }
922
923 retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
924 if(retval > 0) {
925 retval = read(bprm->fd, (char *) elf_phdata,
926 elf_ex.e_phentsize * elf_ex.e_phnum);
927 }
928
929 if (retval < 0) {
930 perror("load_elf_binary");
931 exit(-1);
932 free (elf_phdata);
933 return -errno;
934 }
935
bellardb17780d2003-02-18 23:32:15 +0000936#ifdef BSWAP_NEEDED
937 elf_ppnt = elf_phdata;
938 for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
939 bswap_phdr(elf_ppnt);
940 }
941#endif
bellard31e31b82003-02-18 22:55:36 +0000942 elf_ppnt = elf_phdata;
943
944 elf_bss = 0;
945 elf_brk = 0;
946
947
948 elf_stack = ~0UL;
949 elf_interpreter = NULL;
950 start_code = ~0UL;
951 end_code = 0;
952 end_data = 0;
953
954 for(i=0;i < elf_ex.e_phnum; i++) {
955 if (elf_ppnt->p_type == PT_INTERP) {
956 if ( elf_interpreter != NULL )
957 {
958 free (elf_phdata);
959 free(elf_interpreter);
960 close(bprm->fd);
961 return -EINVAL;
962 }
963
964 /* This is the program interpreter used for
965 * shared libraries - for now assume that this
966 * is an a.out format binary
967 */
968
bellard32ce6332003-04-11 00:16:16 +0000969 elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
bellard31e31b82003-02-18 22:55:36 +0000970
971 if (elf_interpreter == NULL) {
972 free (elf_phdata);
973 close(bprm->fd);
974 return -ENOMEM;
975 }
976
bellard31e31b82003-02-18 22:55:36 +0000977 retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
978 if(retval >= 0) {
bellard32ce6332003-04-11 00:16:16 +0000979 retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
bellard31e31b82003-02-18 22:55:36 +0000980 }
981 if(retval < 0) {
982 perror("load_elf_binary2");
983 exit(-1);
984 }
985
986 /* If the program interpreter is one of these two,
987 then assume an iBCS2 image. Otherwise assume
988 a native linux image. */
989
990 /* JRP - Need to add X86 lib dir stuff here... */
991
992 if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
993 strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
994 ibcs2_interpreter = 1;
995 }
996
997#if 0
998 printf("Using ELF interpreter %s\n", elf_interpreter);
999#endif
1000 if (retval >= 0) {
bellard32ce6332003-04-11 00:16:16 +00001001 retval = open(path(elf_interpreter), O_RDONLY);
bellard31e31b82003-02-18 22:55:36 +00001002 if(retval >= 0) {
1003 interpreter_fd = retval;
1004 }
1005 else {
1006 perror(elf_interpreter);
1007 exit(-1);
1008 /* retval = -errno; */
1009 }
1010 }
1011
1012 if (retval >= 0) {
1013 retval = lseek(interpreter_fd, 0, SEEK_SET);
1014 if(retval >= 0) {
1015 retval = read(interpreter_fd,bprm->buf,128);
1016 }
1017 }
1018 if (retval >= 0) {
1019 interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */
1020 interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */
1021 }
1022 if (retval < 0) {
1023 perror("load_elf_binary3");
1024 exit(-1);
1025 free (elf_phdata);
1026 free(elf_interpreter);
1027 close(bprm->fd);
1028 return retval;
1029 }
1030 }
1031 elf_ppnt++;
1032 }
1033
1034 /* Some simple consistency checks for the interpreter */
1035 if (elf_interpreter){
1036 interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
1037
1038 /* Now figure out which format our binary is */
1039 if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
1040 (N_MAGIC(interp_ex) != QMAGIC)) {
1041 interpreter_type = INTERPRETER_ELF;
1042 }
1043
1044 if (interp_elf_ex.e_ident[0] != 0x7f ||
1045 strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
1046 interpreter_type &= ~INTERPRETER_ELF;
1047 }
1048
1049 if (!interpreter_type) {
1050 free(elf_interpreter);
1051 free(elf_phdata);
1052 close(bprm->fd);
1053 return -ELIBBAD;
1054 }
1055 }
1056
1057 /* OK, we are done with that, now set up the arg stuff,
1058 and then start this sucker up */
1059
pbrooke5fe0c52006-06-11 13:32:59 +00001060 {
bellard31e31b82003-02-18 22:55:36 +00001061 char * passed_p;
1062
1063 if (interpreter_type == INTERPRETER_AOUT) {
bellardeba2af62004-06-19 17:23:39 +00001064 snprintf(passed_fileno, sizeof(passed_fileno), "%d", bprm->fd);
bellard31e31b82003-02-18 22:55:36 +00001065 passed_p = passed_fileno;
1066
1067 if (elf_interpreter) {
pbrooke5fe0c52006-06-11 13:32:59 +00001068 bprm->p = copy_elf_strings(1,&passed_p,bprm->page,bprm->p);
bellard31e31b82003-02-18 22:55:36 +00001069 bprm->argc++;
1070 }
1071 }
1072 if (!bprm->p) {
1073 if (elf_interpreter) {
1074 free(elf_interpreter);
1075 }
1076 free (elf_phdata);
1077 close(bprm->fd);
1078 return -E2BIG;
1079 }
1080 }
1081
1082 /* OK, This is the point of no return */
1083 info->end_data = 0;
1084 info->end_code = 0;
1085 info->start_mmap = (unsigned long)ELF_START_MMAP;
1086 info->mmap = 0;
1087 elf_entry = (unsigned long) elf_ex.e_entry;
1088
1089 /* Do this so that we can load the interpreter, if need be. We will
1090 change some of these later */
1091 info->rss = 0;
1092 bprm->p = setup_arg_pages(bprm->p, bprm, info);
1093 info->start_stack = bprm->p;
1094
1095 /* Now we do a little grungy work by mmaping the ELF image into
1096 * the correct location in memory. At this point, we assume that
1097 * the image should be loaded at fixed address, not at a variable
1098 * address.
1099 */
1100
bellard31e31b82003-02-18 22:55:36 +00001101 for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
bellard09bfb052003-04-10 00:03:40 +00001102 int elf_prot = 0;
1103 int elf_flags = 0;
1104 unsigned long error;
1105
1106 if (elf_ppnt->p_type != PT_LOAD)
1107 continue;
1108
1109 if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
1110 if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
1111 if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
1112 elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
1113 if (elf_ex.e_type == ET_EXEC || load_addr_set) {
1114 elf_flags |= MAP_FIXED;
1115 } else if (elf_ex.e_type == ET_DYN) {
1116 /* Try and get dynamic programs out of the way of the default mmap
1117 base, as well as whatever program they might try to exec. This
1118 is because the brk will follow the loader, and is not movable. */
1119 /* NOTE: for qemu, we do a big mmap to get enough space
1120 without harcoding any address */
bellard54936002003-05-13 00:25:15 +00001121 error = target_mmap(0, ET_DYN_MAP_SIZE,
1122 PROT_NONE, MAP_PRIVATE | MAP_ANON,
1123 -1, 0);
bellard09bfb052003-04-10 00:03:40 +00001124 if (error == -1) {
1125 perror("mmap");
1126 exit(-1);
1127 }
bellard54936002003-05-13 00:25:15 +00001128 load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
bellard09bfb052003-04-10 00:03:40 +00001129 }
1130
bellard54936002003-05-13 00:25:15 +00001131 error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
1132 (elf_ppnt->p_filesz +
1133 TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
1134 elf_prot,
1135 (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
1136 bprm->fd,
1137 (elf_ppnt->p_offset -
1138 TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
bellard09bfb052003-04-10 00:03:40 +00001139 if (error == -1) {
1140 perror("mmap");
1141 exit(-1);
1142 }
bellard31e31b82003-02-18 22:55:36 +00001143
1144#ifdef LOW_ELF_STACK
bellard54936002003-05-13 00:25:15 +00001145 if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
1146 elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr);
bellard31e31b82003-02-18 22:55:36 +00001147#endif
bellard09bfb052003-04-10 00:03:40 +00001148
1149 if (!load_addr_set) {
1150 load_addr_set = 1;
1151 load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
1152 if (elf_ex.e_type == ET_DYN) {
1153 load_bias += error -
bellard54936002003-05-13 00:25:15 +00001154 TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
bellard09bfb052003-04-10 00:03:40 +00001155 load_addr += load_bias;
1156 }
1157 }
1158 k = elf_ppnt->p_vaddr;
1159 if (k < start_code)
1160 start_code = k;
1161 k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
1162 if (k > elf_bss)
1163 elf_bss = k;
1164 if ((elf_ppnt->p_flags & PF_X) && end_code < k)
1165 end_code = k;
1166 if (end_data < k)
1167 end_data = k;
1168 k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
1169 if (k > elf_brk) elf_brk = k;
bellard31e31b82003-02-18 22:55:36 +00001170 }
1171
bellard09bfb052003-04-10 00:03:40 +00001172 elf_entry += load_bias;
1173 elf_bss += load_bias;
1174 elf_brk += load_bias;
1175 start_code += load_bias;
1176 end_code += load_bias;
1177 // start_data += load_bias;
1178 end_data += load_bias;
1179
bellard31e31b82003-02-18 22:55:36 +00001180 if (elf_interpreter) {
1181 if (interpreter_type & 1) {
1182 elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
1183 }
1184 else if (interpreter_type & 2) {
1185 elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
1186 &interp_load_addr);
1187 }
1188
1189 close(interpreter_fd);
1190 free(elf_interpreter);
1191
1192 if (elf_entry == ~0UL) {
1193 printf("Unable to load interpreter\n");
1194 free(elf_phdata);
1195 exit(-1);
1196 return 0;
1197 }
1198 }
1199
1200 free(elf_phdata);
1201
bellard689f9362003-04-29 20:40:07 +00001202 if (loglevel)
1203 load_symbols(&elf_ex, bprm->fd);
1204
bellard31e31b82003-02-18 22:55:36 +00001205 if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
1206 info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
1207
1208#ifdef LOW_ELF_STACK
1209 info->start_stack = bprm->p = elf_stack - 4;
1210#endif
pbrook53a59602006-03-25 19:31:22 +00001211 bprm->p = create_elf_tables(bprm->p,
bellard31e31b82003-02-18 22:55:36 +00001212 bprm->argc,
1213 bprm->envc,
bellarda1516e92003-07-09 17:13:37 +00001214 &elf_ex,
bellard09bfb052003-04-10 00:03:40 +00001215 load_addr, load_bias,
bellard31e31b82003-02-18 22:55:36 +00001216 interp_load_addr,
1217 (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
1218 info);
bellard31e31b82003-02-18 22:55:36 +00001219 info->start_brk = info->brk = elf_brk;
1220 info->end_code = end_code;
1221 info->start_code = start_code;
pbrooke5fe0c52006-06-11 13:32:59 +00001222 info->start_data = end_code;
bellard31e31b82003-02-18 22:55:36 +00001223 info->end_data = end_data;
1224 info->start_stack = bprm->p;
1225
1226 /* Calling set_brk effectively mmaps the pages that we need for the bss and break
1227 sections */
1228 set_brk(elf_bss, elf_brk);
1229
1230 padzero(elf_bss);
1231
1232#if 0
1233 printf("(start_brk) %x\n" , info->start_brk);
1234 printf("(end_code) %x\n" , info->end_code);
1235 printf("(start_code) %x\n" , info->start_code);
1236 printf("(end_data) %x\n" , info->end_data);
1237 printf("(start_stack) %x\n" , info->start_stack);
1238 printf("(brk) %x\n" , info->brk);
1239#endif
1240
1241 if ( info->personality == PER_SVR4 )
1242 {
1243 /* Why this, you ask??? Well SVr4 maps page 0 as read-only,
1244 and some applications "depend" upon this behavior.
1245 Since we do not have the power to recompile these, we
1246 emulate the SVr4 behavior. Sigh. */
bellard83fb7ad2004-07-05 21:25:26 +00001247 mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC,
bellard54936002003-05-13 00:25:15 +00001248 MAP_FIXED | MAP_PRIVATE, -1, 0);
bellard31e31b82003-02-18 22:55:36 +00001249 }
1250
bellard31e31b82003-02-18 22:55:36 +00001251 info->entry = elf_entry;
1252
1253 return 0;
1254}
1255
bellard31e31b82003-02-18 22:55:36 +00001256static int load_aout_interp(void * exptr, int interp_fd)
1257{
1258 printf("a.out interpreter not yet supported\n");
1259 return(0);
1260}
1261
pbrooke5fe0c52006-06-11 13:32:59 +00001262void do_init_thread(struct target_pt_regs *regs, struct image_info *infop)
1263{
1264 init_thread(regs, infop);
1265}