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