1
2#include <sys/time.h>
3#include <sys/param.h>
4
5#include <stdio.h>
6#include <sys/types.h>
7#include <fcntl.h>
8#include <errno.h>
9#include <unistd.h>
10#include <sys/mman.h>
11#include <sys/resource.h>
12#include <stdlib.h>
13#include <string.h>
14#include <time.h>
15
16#include "qemu.h"
17#include "disas.h"
18
19#ifdef _ARCH_PPC64
20#undef ARCH_DLINFO
21#undef ELF_PLATFORM
22#undef ELF_HWCAP
23#undef ELF_CLASS
24#undef ELF_DATA
25#undef ELF_ARCH
26#endif
27
28#define ELF_OSABI ELFOSABI_SYSV
29
30
31
32
33
34
35
36
37enum {
38 ADDR_NO_RANDOMIZE = 0x0040000,
39 FDPIC_FUNCPTRS = 0x0080000,
40
41
42 MMAP_PAGE_ZERO = 0x0100000,
43 ADDR_COMPAT_LAYOUT = 0x0200000,
44 READ_IMPLIES_EXEC = 0x0400000,
45 ADDR_LIMIT_32BIT = 0x0800000,
46 SHORT_INODE = 0x1000000,
47 WHOLE_SECONDS = 0x2000000,
48 STICKY_TIMEOUTS = 0x4000000,
49 ADDR_LIMIT_3GB = 0x8000000,
50};
51
52
53
54
55
56
57
58enum {
59 PER_LINUX = 0x0000,
60 PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT,
61 PER_LINUX_FDPIC = 0x0000 | FDPIC_FUNCPTRS,
62 PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
63 PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
64 PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS |
65 WHOLE_SECONDS | SHORT_INODE,
66 PER_OSR5 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
67 PER_WYSEV386 = 0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
68 PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS,
69 PER_BSD = 0x0006,
70 PER_SUNOS = 0x0006 | STICKY_TIMEOUTS,
71 PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
72 PER_LINUX32 = 0x0008,
73 PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB,
74 PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS,
75 PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS,
76 PER_IRIX64 = 0x000b | STICKY_TIMEOUTS,
77 PER_RISCOS = 0x000c,
78 PER_SOLARIS = 0x000d | STICKY_TIMEOUTS,
79 PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
80 PER_OSF4 = 0x000f,
81 PER_HPUX = 0x0010,
82 PER_MASK = 0x00ff,
83};
84
85
86
87
88#define personality(pers) (pers & PER_MASK)
89
90
91#ifndef MAP_DENYWRITE
92#define MAP_DENYWRITE 0
93#endif
94
95
96#ifndef ELIBBAD
97#define ELIBBAD 80
98#endif
99
100#ifdef TARGET_I386
101
102#define ELF_PLATFORM get_elf_platform()
103
104static const char *get_elf_platform(void)
105{
106 static char elf_platform[] = "i386";
107 int family = (thread_env->cpuid_version >> 8) & 0xff;
108 if (family > 6)
109 family = 6;
110 if (family >= 3)
111 elf_platform[1] = '0' + family;
112 return elf_platform;
113}
114
115#define ELF_HWCAP get_elf_hwcap()
116
117static uint32_t get_elf_hwcap(void)
118{
119 return thread_env->cpuid_features;
120}
121
122#ifdef TARGET_X86_64
123#define ELF_START_MMAP 0x2aaaaab000ULL
124#define elf_check_arch(x) ( ((x) == ELF_ARCH) )
125
126#define ELF_CLASS ELFCLASS64
127#define ELF_DATA ELFDATA2LSB
128#define ELF_ARCH EM_X86_64
129
130static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
131{
132 regs->rax = 0;
133 regs->rsp = infop->start_stack;
134 regs->rip = infop->entry;
135}
136
137typedef target_ulong elf_greg_t;
138typedef uint32_t target_uid_t;
139typedef uint32_t target_gid_t;
140typedef int32_t target_pid_t;
141
142#define ELF_NREG 27
143typedef elf_greg_t elf_gregset_t[ELF_NREG];
144
145
146
147
148
149
150
151
152static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env)
153{
154 (*regs)[0] = env->regs[15];
155 (*regs)[1] = env->regs[14];
156 (*regs)[2] = env->regs[13];
157 (*regs)[3] = env->regs[12];
158 (*regs)[4] = env->regs[R_EBP];
159 (*regs)[5] = env->regs[R_EBX];
160 (*regs)[6] = env->regs[11];
161 (*regs)[7] = env->regs[10];
162 (*regs)[8] = env->regs[9];
163 (*regs)[9] = env->regs[8];
164 (*regs)[10] = env->regs[R_EAX];
165 (*regs)[11] = env->regs[R_ECX];
166 (*regs)[12] = env->regs[R_EDX];
167 (*regs)[13] = env->regs[R_ESI];
168 (*regs)[14] = env->regs[R_EDI];
169 (*regs)[15] = env->regs[R_EAX];
170 (*regs)[16] = env->eip;
171 (*regs)[17] = env->segs[R_CS].selector & 0xffff;
172 (*regs)[18] = env->eflags;
173 (*regs)[19] = env->regs[R_ESP];
174 (*regs)[20] = env->segs[R_SS].selector & 0xffff;
175 (*regs)[21] = env->segs[R_FS].selector & 0xffff;
176 (*regs)[22] = env->segs[R_GS].selector & 0xffff;
177 (*regs)[23] = env->segs[R_DS].selector & 0xffff;
178 (*regs)[24] = env->segs[R_ES].selector & 0xffff;
179 (*regs)[25] = env->segs[R_FS].selector & 0xffff;
180 (*regs)[26] = env->segs[R_GS].selector & 0xffff;
181}
182
183#else
184
185#define ELF_START_MMAP 0x80000000
186
187
188
189
190#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
191
192
193
194
195#define ELF_CLASS ELFCLASS32
196#define ELF_DATA ELFDATA2LSB
197#define ELF_ARCH EM_386
198
199static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
200{
201 regs->esp = infop->start_stack;
202 regs->eip = infop->entry;
203
204
205
206
207
208
209
210
211 regs->edx = 0;
212}
213
214typedef target_ulong elf_greg_t;
215typedef uint16_t target_uid_t;
216typedef uint16_t target_gid_t;
217typedef int32_t target_pid_t;
218
219#define ELF_NREG 17
220typedef elf_greg_t elf_gregset_t[ELF_NREG];
221
222
223
224
225
226
227
228
229static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env)
230{
231 (*regs)[0] = env->regs[R_EBX];
232 (*regs)[1] = env->regs[R_ECX];
233 (*regs)[2] = env->regs[R_EDX];
234 (*regs)[3] = env->regs[R_ESI];
235 (*regs)[4] = env->regs[R_EDI];
236 (*regs)[5] = env->regs[R_EBP];
237 (*regs)[6] = env->regs[R_EAX];
238 (*regs)[7] = env->segs[R_DS].selector & 0xffff;
239 (*regs)[8] = env->segs[R_ES].selector & 0xffff;
240 (*regs)[9] = env->segs[R_FS].selector & 0xffff;
241 (*regs)[10] = env->segs[R_GS].selector & 0xffff;
242 (*regs)[11] = env->regs[R_EAX];
243 (*regs)[12] = env->eip;
244 (*regs)[13] = env->segs[R_CS].selector & 0xffff;
245 (*regs)[14] = env->eflags;
246 (*regs)[15] = env->regs[R_ESP];
247 (*regs)[16] = env->segs[R_SS].selector & 0xffff;
248}
249#endif
250
251#define USE_ELF_CORE_DUMP
252#define ELF_EXEC_PAGESIZE 4096
253
254#endif
255
256#ifdef TARGET_ARM
257
258#define ELF_START_MMAP 0x80000000
259
260#define elf_check_arch(x) ( (x) == EM_ARM )
261
262#define ELF_CLASS ELFCLASS32
263#ifdef TARGET_WORDS_BIGENDIAN
264#define ELF_DATA ELFDATA2MSB
265#else
266#define ELF_DATA ELFDATA2LSB
267#endif
268#define ELF_ARCH EM_ARM
269
270static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
271{
272 abi_long stack = infop->start_stack;
273 memset(regs, 0, sizeof(*regs));
274 regs->ARM_cpsr = 0x10;
275 if (infop->entry & 1)
276 regs->ARM_cpsr |= CPSR_T;
277 regs->ARM_pc = infop->entry & 0xfffffffe;
278 regs->ARM_sp = infop->start_stack;
279
280 get_user_ual(regs->ARM_r2, stack + 8);
281 get_user_ual(regs->ARM_r1, stack + 4);
282
283 regs->ARM_r0 = 0;
284
285
286 regs->ARM_r10 = infop->start_data;
287}
288
289typedef uint32_t elf_greg_t;
290typedef uint16_t target_uid_t;
291typedef uint16_t target_gid_t;
292typedef int32_t target_pid_t;
293
294#define ELF_NREG 18
295typedef elf_greg_t elf_gregset_t[ELF_NREG];
296
297static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env)
298{
299 (*regs)[0] = env->regs[0];
300 (*regs)[1] = env->regs[1];
301 (*regs)[2] = env->regs[2];
302 (*regs)[3] = env->regs[3];
303 (*regs)[4] = env->regs[4];
304 (*regs)[5] = env->regs[5];
305 (*regs)[6] = env->regs[6];
306 (*regs)[7] = env->regs[7];
307 (*regs)[8] = env->regs[8];
308 (*regs)[9] = env->regs[9];
309 (*regs)[10] = env->regs[10];
310 (*regs)[11] = env->regs[11];
311 (*regs)[12] = env->regs[12];
312 (*regs)[13] = env->regs[13];
313 (*regs)[14] = env->regs[14];
314 (*regs)[15] = env->regs[15];
315
316 (*regs)[16] = cpsr_read((CPUState *)env);
317 (*regs)[17] = env->regs[0];
318}
319
320#define USE_ELF_CORE_DUMP
321#define ELF_EXEC_PAGESIZE 4096
322
323enum
324{
325 ARM_HWCAP_ARM_SWP = 1 << 0,
326 ARM_HWCAP_ARM_HALF = 1 << 1,
327 ARM_HWCAP_ARM_THUMB = 1 << 2,
328 ARM_HWCAP_ARM_26BIT = 1 << 3,
329 ARM_HWCAP_ARM_FAST_MULT = 1 << 4,
330 ARM_HWCAP_ARM_FPA = 1 << 5,
331 ARM_HWCAP_ARM_VFP = 1 << 6,
332 ARM_HWCAP_ARM_EDSP = 1 << 7,
333};
334
335#define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF \
336 | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT \
337 | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP)
338
339#endif
340
341#ifdef TARGET_SPARC
342#ifdef TARGET_SPARC64
343
344#define ELF_START_MMAP 0x80000000
345
346#ifndef TARGET_ABI32
347#define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS )
348#else
349#define elf_check_arch(x) ( (x) == EM_SPARC32PLUS || (x) == EM_SPARC )
350#endif
351
352#define ELF_CLASS ELFCLASS64
353#define ELF_DATA ELFDATA2MSB
354#define ELF_ARCH EM_SPARCV9
355
356#define STACK_BIAS 2047
357
358static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
359{
360#ifndef TARGET_ABI32
361 regs->tstate = 0;
362#endif
363 regs->pc = infop->entry;
364 regs->npc = regs->pc + 4;
365 regs->y = 0;
366#ifdef TARGET_ABI32
367 regs->u_regs[14] = infop->start_stack - 16 * 4;
368#else
369 if (personality(infop->personality) == PER_LINUX32)
370 regs->u_regs[14] = infop->start_stack - 16 * 4;
371 else
372 regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;
373#endif
374}
375
376#else
377#define ELF_START_MMAP 0x80000000
378
379#define elf_check_arch(x) ( (x) == EM_SPARC )
380
381#define ELF_CLASS ELFCLASS32
382#define ELF_DATA ELFDATA2MSB
383#define ELF_ARCH EM_SPARC
384
385static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
386{
387 regs->psr = 0;
388 regs->pc = infop->entry;
389 regs->npc = regs->pc + 4;
390 regs->y = 0;
391 regs->u_regs[14] = infop->start_stack - 16 * 4;
392}
393
394#endif
395#endif
396
397#ifdef TARGET_PPC
398
399#define ELF_START_MMAP 0x80000000
400
401#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
402
403#define elf_check_arch(x) ( (x) == EM_PPC64 )
404
405#define ELF_CLASS ELFCLASS64
406
407#else
408
409#define elf_check_arch(x) ( (x) == EM_PPC )
410
411#define ELF_CLASS ELFCLASS32
412
413#endif
414
415#ifdef TARGET_WORDS_BIGENDIAN
416#define ELF_DATA ELFDATA2MSB
417#else
418#define ELF_DATA ELFDATA2LSB
419#endif
420#define ELF_ARCH EM_PPC
421
422
423
424enum {
425 PPC_FEATURE_32 = 0x80000000,
426 PPC_FEATURE_64 = 0x40000000,
427 PPC_FEATURE_601_INSTR = 0x20000000,
428 PPC_FEATURE_HAS_ALTIVEC = 0x10000000,
429 PPC_FEATURE_HAS_FPU = 0x08000000,
430 PPC_FEATURE_HAS_MMU = 0x04000000,
431 PPC_FEATURE_HAS_4xxMAC = 0x02000000,
432 PPC_FEATURE_UNIFIED_CACHE = 0x01000000,
433 PPC_FEATURE_HAS_SPE = 0x00800000,
434 PPC_FEATURE_HAS_EFP_SINGLE = 0x00400000,
435 PPC_FEATURE_HAS_EFP_DOUBLE = 0x00200000,
436 PPC_FEATURE_NO_TB = 0x00100000,
437 PPC_FEATURE_POWER4 = 0x00080000,
438 PPC_FEATURE_POWER5 = 0x00040000,
439 PPC_FEATURE_POWER5_PLUS = 0x00020000,
440 PPC_FEATURE_CELL = 0x00010000,
441 PPC_FEATURE_BOOKE = 0x00008000,
442 PPC_FEATURE_SMT = 0x00004000,
443 PPC_FEATURE_ICACHE_SNOOP = 0x00002000,
444 PPC_FEATURE_ARCH_2_05 = 0x00001000,
445 PPC_FEATURE_PA6T = 0x00000800,
446 PPC_FEATURE_HAS_DFP = 0x00000400,
447 PPC_FEATURE_POWER6_EXT = 0x00000200,
448 PPC_FEATURE_ARCH_2_06 = 0x00000100,
449 PPC_FEATURE_HAS_VSX = 0x00000080,
450 PPC_FEATURE_PSERIES_PERFMON_COMPAT = 0x00000040,
451
452 PPC_FEATURE_TRUE_LE = 0x00000002,
453 PPC_FEATURE_PPC_LE = 0x00000001,
454};
455
456#define ELF_HWCAP get_elf_hwcap()
457
458static uint32_t get_elf_hwcap(void)
459{
460 CPUState *e = thread_env;
461 uint32_t features = 0;
462
463
464
465#define GET_FEATURE(flag, feature) \
466 do {if (e->insns_flags & flag) features |= feature; } while(0)
467 GET_FEATURE(PPC_64B, PPC_FEATURE_64);
468 GET_FEATURE(PPC_FLOAT, PPC_FEATURE_HAS_FPU);
469 GET_FEATURE(PPC_ALTIVEC, PPC_FEATURE_HAS_ALTIVEC);
470 GET_FEATURE(PPC_SPE, PPC_FEATURE_HAS_SPE);
471 GET_FEATURE(PPC_SPE_SINGLE, PPC_FEATURE_HAS_EFP_SINGLE);
472 GET_FEATURE(PPC_SPE_DOUBLE, PPC_FEATURE_HAS_EFP_DOUBLE);
473 GET_FEATURE(PPC_BOOKE, PPC_FEATURE_BOOKE);
474 GET_FEATURE(PPC_405_MAC, PPC_FEATURE_HAS_4xxMAC);
475#undef GET_FEATURE
476
477 return features;
478}
479
480
481
482
483
484#define AT_DCACHEBSIZE 19
485#define AT_ICACHEBSIZE 20
486#define AT_UCACHEBSIZE 21
487
488#define AT_IGNOREPPC 22
489
490
491
492
493
494
495
496
497
498#define DLINFO_ARCH_ITEMS 5
499#define ARCH_DLINFO \
500do { \
501 NEW_AUX_ENT(AT_DCACHEBSIZE, 0x20); \
502 NEW_AUX_ENT(AT_ICACHEBSIZE, 0x20); \
503 NEW_AUX_ENT(AT_UCACHEBSIZE, 0); \
504
505
506 \
507 NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
508 NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
509 } while (0)
510
511static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
512{
513 abi_ulong pos = infop->start_stack;
514 abi_ulong tmp;
515#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
516 abi_ulong entry, toc;
517#endif
518
519 _regs->gpr[1] = infop->start_stack;
520#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
521 entry = ldq_raw(infop->entry) + infop->load_addr;
522 toc = ldq_raw(infop->entry + 8) + infop->load_addr;
523 _regs->gpr[2] = toc;
524 infop->entry = entry;
525#endif
526 _regs->nip = infop->entry;
527
528
529
530
531
532 get_user_ual(_regs->gpr[3], pos);
533 pos += sizeof(abi_ulong);
534 _regs->gpr[4] = pos;
535 for (tmp = 1; tmp != 0; pos += sizeof(abi_ulong))
536 tmp = ldl(pos);
537 _regs->gpr[5] = pos;
538}
539
540#define ELF_EXEC_PAGESIZE 4096
541
542#endif
543
544#ifdef TARGET_MIPS
545
546#define ELF_START_MMAP 0x80000000
547
548#define elf_check_arch(x) ( (x) == EM_MIPS )
549
550#ifdef TARGET_MIPS64
551#define ELF_CLASS ELFCLASS64
552#else
553#define ELF_CLASS ELFCLASS32
554#endif
555#ifdef TARGET_WORDS_BIGENDIAN
556#define ELF_DATA ELFDATA2MSB
557#else
558#define ELF_DATA ELFDATA2LSB
559#endif
560#define ELF_ARCH EM_MIPS
561
562static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
563{
564 regs->cp0_status = 2 << CP0St_KSU;
565 regs->cp0_epc = infop->entry;
566 regs->regs[29] = infop->start_stack;
567}
568
569#define ELF_EXEC_PAGESIZE 4096
570
571#endif
572
573#ifdef TARGET_MICROBLAZE
574
575#define ELF_START_MMAP 0x80000000
576
577#define elf_check_arch(x) ( (x) == EM_XILINX_MICROBLAZE )
578
579#define ELF_CLASS ELFCLASS32
580#define ELF_DATA ELFDATA2MSB
581#define ELF_ARCH EM_MIPS
582
583static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
584{
585 regs->pc = infop->entry;
586 regs->r1 = infop->start_stack;
587
588}
589
590#define ELF_EXEC_PAGESIZE 4096
591
592#endif
593
594#ifdef TARGET_SH4
595
596#define ELF_START_MMAP 0x80000000
597
598#define elf_check_arch(x) ( (x) == EM_SH )
599
600#define ELF_CLASS ELFCLASS32
601#define ELF_DATA ELFDATA2LSB
602#define ELF_ARCH EM_SH
603
604static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
605{
606
607 regs->pc = infop->entry;
608 regs->regs[15] = infop->start_stack;
609}
610
611#define ELF_EXEC_PAGESIZE 4096
612
613#endif
614
615#ifdef TARGET_CRIS
616
617#define ELF_START_MMAP 0x80000000
618
619#define elf_check_arch(x) ( (x) == EM_CRIS )
620
621#define ELF_CLASS ELFCLASS32
622#define ELF_DATA ELFDATA2LSB
623#define ELF_ARCH EM_CRIS
624
625static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
626{
627 regs->erp = infop->entry;
628}
629
630#define ELF_EXEC_PAGESIZE 8192
631
632#endif
633
634#ifdef TARGET_M68K
635
636#define ELF_START_MMAP 0x80000000
637
638#define elf_check_arch(x) ( (x) == EM_68K )
639
640#define ELF_CLASS ELFCLASS32
641#define ELF_DATA ELFDATA2MSB
642#define ELF_ARCH EM_68K
643
644
645
646
647static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
648{
649 regs->usp = infop->start_stack;
650 regs->sr = 0;
651 regs->pc = infop->entry;
652}
653
654#define ELF_EXEC_PAGESIZE 8192
655
656#endif
657
658#ifdef TARGET_ALPHA
659
660#define ELF_START_MMAP (0x30000000000ULL)
661
662#define elf_check_arch(x) ( (x) == ELF_ARCH )
663
664#define ELF_CLASS ELFCLASS64
665#define ELF_DATA ELFDATA2MSB
666#define ELF_ARCH EM_ALPHA
667
668static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
669{
670 regs->pc = infop->entry;
671 regs->ps = 8;
672 regs->usp = infop->start_stack;
673 regs->unique = infop->start_data;
674 printf("Set unique value to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n",
675 regs->unique, infop->start_data);
676}
677
678#define ELF_EXEC_PAGESIZE 8192
679
680#endif
681
682#ifndef ELF_PLATFORM
683#define ELF_PLATFORM (NULL)
684#endif
685
686#ifndef ELF_HWCAP
687#define ELF_HWCAP 0
688#endif
689
690#ifdef TARGET_ABI32
691#undef ELF_CLASS
692#define ELF_CLASS ELFCLASS32
693#undef bswaptls
694#define bswaptls(ptr) bswap32s(ptr)
695#endif
696
697#include "elf.h"
698
699struct exec
700{
701 unsigned int a_info;
702 unsigned int a_text;
703 unsigned int a_data;
704 unsigned int a_bss;
705 unsigned int a_syms;
706 unsigned int a_entry;
707 unsigned int a_trsize;
708 unsigned int a_drsize;
709};
710
711
712#define N_MAGIC(exec) ((exec).a_info & 0xffff)
713#define OMAGIC 0407
714#define NMAGIC 0410
715#define ZMAGIC 0413
716#define QMAGIC 0314
717
718
719#define INTERP_MAP_SIZE (32 * 1024 * 1024)
720
721
722#define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
723
724
725#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
726#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
727#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
728
729#define INTERPRETER_NONE 0
730#define INTERPRETER_AOUT 1
731#define INTERPRETER_ELF 2
732
733#define DLINFO_ITEMS 12
734
735static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
736{
737 memcpy(to, from, n);
738}
739
740static int load_aout_interp(void * exptr, int interp_fd);
741
742#ifdef BSWAP_NEEDED
743static void bswap_ehdr(struct elfhdr *ehdr)
744{
745 bswap16s(&ehdr->e_type);
746 bswap16s(&ehdr->e_machine);
747 bswap32s(&ehdr->e_version);
748 bswaptls(&ehdr->e_entry);
749 bswaptls(&ehdr->e_phoff);
750 bswaptls(&ehdr->e_shoff);
751 bswap32s(&ehdr->e_flags);
752 bswap16s(&ehdr->e_ehsize);
753 bswap16s(&ehdr->e_phentsize);
754 bswap16s(&ehdr->e_phnum);
755 bswap16s(&ehdr->e_shentsize);
756 bswap16s(&ehdr->e_shnum);
757 bswap16s(&ehdr->e_shstrndx);
758}
759
760static void bswap_phdr(struct elf_phdr *phdr)
761{
762 bswap32s(&phdr->p_type);
763 bswaptls(&phdr->p_offset);
764 bswaptls(&phdr->p_vaddr);
765 bswaptls(&phdr->p_paddr);
766 bswaptls(&phdr->p_filesz);
767 bswaptls(&phdr->p_memsz);
768 bswap32s(&phdr->p_flags);
769 bswaptls(&phdr->p_align);
770}
771
772static void bswap_shdr(struct elf_shdr *shdr)
773{
774 bswap32s(&shdr->sh_name);
775 bswap32s(&shdr->sh_type);
776 bswaptls(&shdr->sh_flags);
777 bswaptls(&shdr->sh_addr);
778 bswaptls(&shdr->sh_offset);
779 bswaptls(&shdr->sh_size);
780 bswap32s(&shdr->sh_link);
781 bswap32s(&shdr->sh_info);
782 bswaptls(&shdr->sh_addralign);
783 bswaptls(&shdr->sh_entsize);
784}
785
786static void bswap_sym(struct elf_sym *sym)
787{
788 bswap32s(&sym->st_name);
789 bswaptls(&sym->st_value);
790 bswaptls(&sym->st_size);
791 bswap16s(&sym->st_shndx);
792}
793#endif
794
795#ifdef USE_ELF_CORE_DUMP
796static int elf_core_dump(int, const CPUState *);
797
798#ifdef BSWAP_NEEDED
799static void bswap_note(struct elf_note *en)
800{
801 bswaptls(&en->n_namesz);
802 bswaptls(&en->n_descsz);
803 bswaptls(&en->n_type);
804}
805#endif
806
807#endif
808
809
810
811
812
813
814
815static abi_ulong copy_elf_strings(int argc,char ** argv, void **page,
816 abi_ulong p)
817{
818 char *tmp, *tmp1, *pag = NULL;
819 int len, offset = 0;
820
821 if (!p) {
822 return 0;
823 }
824 while (argc-- > 0) {
825 tmp = argv[argc];
826 if (!tmp) {
827 fprintf(stderr, "VFS: argc is wrong");
828 exit(-1);
829 }
830 tmp1 = tmp;
831 while (*tmp++);
832 len = tmp - tmp1;
833 if (p < len) {
834 return 0;
835 }
836 while (len) {
837 --p; --tmp; --len;
838 if (--offset < 0) {
839 offset = p % TARGET_PAGE_SIZE;
840 pag = (char *)page[p/TARGET_PAGE_SIZE];
841 if (!pag) {
842 pag = (char *)malloc(TARGET_PAGE_SIZE);
843 memset(pag, 0, TARGET_PAGE_SIZE);
844 page[p/TARGET_PAGE_SIZE] = pag;
845 if (!pag)
846 return 0;
847 }
848 }
849 if (len == 0 || offset == 0) {
850 *(pag + offset) = *tmp;
851 }
852 else {
853 int bytes_to_copy = (len > offset) ? offset : len;
854 tmp -= bytes_to_copy;
855 p -= bytes_to_copy;
856 offset -= bytes_to_copy;
857 len -= bytes_to_copy;
858 memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
859 }
860 }
861 }
862 return p;
863}
864
865static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,
866 struct image_info *info)
867{
868 abi_ulong stack_base, size, error;
869 int i;
870
871
872
873
874 size = x86_stack_size;
875 if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
876 size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
877 error = target_mmap(0,
878 size + qemu_host_page_size,
879 PROT_READ | PROT_WRITE,
880 MAP_PRIVATE | MAP_ANONYMOUS,
881 -1, 0);
882 if (error == -1) {
883 perror("stk mmap");
884 exit(-1);
885 }
886
887 target_mprotect(error + size, qemu_host_page_size, PROT_NONE);
888
889 stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE;
890 p += stack_base;
891
892 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
893 if (bprm->page[i]) {
894 info->rss++;
895
896 memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);
897 free(bprm->page[i]);
898 }
899 stack_base += TARGET_PAGE_SIZE;
900 }
901 return p;
902}
903
904static void set_brk(abi_ulong start, abi_ulong end)
905{
906
907 start = HOST_PAGE_ALIGN(start);
908 end = HOST_PAGE_ALIGN(end);
909 if (end <= start)
910 return;
911 if(target_mmap(start, end - start,
912 PROT_READ | PROT_WRITE | PROT_EXEC,
913 MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
914 perror("cannot mmap brk");
915 exit(-1);
916 }
917}
918
919
920
921
922
923static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
924{
925 abi_ulong nbyte;
926
927 if (elf_bss >= last_bss)
928 return;
929
930
931
932
933
934
935 if (qemu_real_host_page_size < qemu_host_page_size) {
936 abi_ulong end_addr, end_addr1;
937 end_addr1 = (elf_bss + qemu_real_host_page_size - 1) &
938 ~(qemu_real_host_page_size - 1);
939 end_addr = HOST_PAGE_ALIGN(elf_bss);
940 if (end_addr1 < end_addr) {
941 mmap((void *)g2h(end_addr1), end_addr - end_addr1,
942 PROT_READ|PROT_WRITE|PROT_EXEC,
943 MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
944 }
945 }
946
947 nbyte = elf_bss & (qemu_host_page_size-1);
948 if (nbyte) {
949 nbyte = qemu_host_page_size - nbyte;
950 do {
951
952 put_user_u8(0, elf_bss);
953 elf_bss++;
954 } while (--nbyte);
955 }
956}
957
958
959static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
960 struct elfhdr * exec,
961 abi_ulong load_addr,
962 abi_ulong load_bias,
963 abi_ulong interp_load_addr, int ibcs,
964 struct image_info *info)
965{
966 abi_ulong sp;
967 int size;
968 abi_ulong u_platform;
969 const char *k_platform;
970 const int n = sizeof(elf_addr_t);
971
972 sp = p;
973 u_platform = 0;
974 k_platform = ELF_PLATFORM;
975 if (k_platform) {
976 size_t len = strlen(k_platform) + 1;
977 sp -= (len + n - 1) & ~(n - 1);
978 u_platform = sp;
979
980 memcpy_to_target(sp, k_platform, len);
981 }
982
983
984
985 sp = sp &~ (abi_ulong)15;
986 size = (DLINFO_ITEMS + 1) * 2;
987 if (k_platform)
988 size += 2;
989#ifdef DLINFO_ARCH_ITEMS
990 size += DLINFO_ARCH_ITEMS * 2;
991#endif
992 size += envc + argc + 2;
993 size += (!ibcs ? 3 : 1);
994 size *= n;
995 if (size & 15)
996 sp -= 16 - (size & 15);
997
998
999
1000
1001#define NEW_AUX_ENT(id, val) do { \
1002 sp -= n; put_user_ual(val, sp); \
1003 sp -= n; put_user_ual(id, sp); \
1004 } while(0)
1005
1006 NEW_AUX_ENT (AT_NULL, 0);
1007
1008
1009 NEW_AUX_ENT(AT_PHDR, (abi_ulong)(load_addr + exec->e_phoff));
1010 NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr)));
1011 NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum));
1012 NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(TARGET_PAGE_SIZE));
1013 NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_load_addr));
1014 NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0);
1015 NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry);
1016 NEW_AUX_ENT(AT_UID, (abi_ulong) getuid());
1017 NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid());
1018 NEW_AUX_ENT(AT_GID, (abi_ulong) getgid());
1019 NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid());
1020 NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);
1021 NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
1022 if (k_platform)
1023 NEW_AUX_ENT(AT_PLATFORM, u_platform);
1024#ifdef ARCH_DLINFO
1025
1026
1027
1028
1029 ARCH_DLINFO;
1030#endif
1031#undef NEW_AUX_ENT
1032
1033 info->saved_auxv = sp;
1034
1035 sp = loader_build_argptr(envc, argc, sp, p, !ibcs);
1036 return sp;
1037}
1038
1039
1040static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex,
1041 int interpreter_fd,
1042 abi_ulong *interp_load_addr)
1043{
1044 struct elf_phdr *elf_phdata = NULL;
1045 struct elf_phdr *eppnt;
1046 abi_ulong load_addr = 0;
1047 int load_addr_set = 0;
1048 int retval;
1049 abi_ulong last_bss, elf_bss;
1050 abi_ulong error;
1051 int i;
1052
1053 elf_bss = 0;
1054 last_bss = 0;
1055 error = 0;
1056
1057#ifdef BSWAP_NEEDED
1058 bswap_ehdr(interp_elf_ex);
1059#endif
1060
1061 if ((interp_elf_ex->e_type != ET_EXEC &&
1062 interp_elf_ex->e_type != ET_DYN) ||
1063 !elf_check_arch(interp_elf_ex->e_machine)) {
1064 return ~((abi_ulong)0UL);
1065 }
1066
1067
1068
1069
1070 if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
1071 return ~(abi_ulong)0UL;
1072
1073 elf_phdata = (struct elf_phdr *)
1074 malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
1075
1076 if (!elf_phdata)
1077 return ~((abi_ulong)0UL);
1078
1079
1080
1081
1082
1083 if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
1084 free(elf_phdata);
1085 return ~((abi_ulong)0UL);
1086 }
1087
1088 retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
1089 if(retval >= 0) {
1090 retval = read(interpreter_fd,
1091 (char *) elf_phdata,
1092 sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
1093 }
1094 if (retval < 0) {
1095 perror("load_elf_interp");
1096 exit(-1);
1097 free (elf_phdata);
1098 return retval;
1099 }
1100#ifdef BSWAP_NEEDED
1101 eppnt = elf_phdata;
1102 for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
1103 bswap_phdr(eppnt);
1104 }
1105#endif
1106
1107 if (interp_elf_ex->e_type == ET_DYN) {
1108
1109
1110 error = target_mmap(0, INTERP_MAP_SIZE,
1111 PROT_NONE, MAP_PRIVATE | MAP_ANON,
1112 -1, 0);
1113 if (error == -1) {
1114 perror("mmap");
1115 exit(-1);
1116 }
1117 load_addr = error;
1118 load_addr_set = 1;
1119 }
1120
1121 eppnt = elf_phdata;
1122 for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
1123 if (eppnt->p_type == PT_LOAD) {
1124 int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
1125 int elf_prot = 0;
1126 abi_ulong vaddr = 0;
1127 abi_ulong k;
1128
1129 if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
1130 if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
1131 if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
1132 if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
1133 elf_type |= MAP_FIXED;
1134 vaddr = eppnt->p_vaddr;
1135 }
1136 error = target_mmap(load_addr+TARGET_ELF_PAGESTART(vaddr),
1137 eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
1138 elf_prot,
1139 elf_type,
1140 interpreter_fd,
1141 eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
1142
1143 if (error == -1) {
1144
1145 close(interpreter_fd);
1146 free(elf_phdata);
1147 return ~((abi_ulong)0UL);
1148 }
1149
1150 if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
1151 load_addr = error;
1152 load_addr_set = 1;
1153 }
1154
1155
1156
1157
1158
1159 k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
1160 if (k > elf_bss) elf_bss = k;
1161
1162
1163
1164
1165
1166 k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
1167 if (k > last_bss) last_bss = k;
1168 }
1169
1170
1171
1172 close(interpreter_fd);
1173
1174
1175
1176
1177
1178
1179
1180 padzero(elf_bss, last_bss);
1181 elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1);
1182
1183
1184 if (last_bss > elf_bss) {
1185 target_mmap(elf_bss, last_bss-elf_bss,
1186 PROT_READ|PROT_WRITE|PROT_EXEC,
1187 MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
1188 }
1189 free(elf_phdata);
1190
1191 *interp_load_addr = load_addr;
1192 return ((abi_ulong) interp_elf_ex->e_entry) + load_addr;
1193}
1194
1195static int symfind(const void *s0, const void *s1)
1196{
1197 struct elf_sym *key = (struct elf_sym *)s0;
1198 struct elf_sym *sym = (struct elf_sym *)s1;
1199 int result = 0;
1200 if (key->st_value < sym->st_value) {
1201 result = -1;
1202 } else if (key->st_value >= sym->st_value + sym->st_size) {
1203 result = 1;
1204 }
1205 return result;
1206}
1207
1208static const char *lookup_symbolxx(struct syminfo *s, target_ulong orig_addr)
1209{
1210#if ELF_CLASS == ELFCLASS32
1211 struct elf_sym *syms = s->disas_symtab.elf32;
1212#else
1213 struct elf_sym *syms = s->disas_symtab.elf64;
1214#endif
1215
1216
1217 struct elf_sym key;
1218 struct elf_sym *sym;
1219
1220 key.st_value = orig_addr;
1221
1222 sym = bsearch(&key, syms, s->disas_num_syms, sizeof(*syms), symfind);
1223 if (sym != NULL) {
1224 return s->disas_strtab + sym->st_name;
1225 }
1226
1227 return "";
1228}
1229
1230
1231static int symcmp(const void *s0, const void *s1)
1232{
1233 struct elf_sym *sym0 = (struct elf_sym *)s0;
1234 struct elf_sym *sym1 = (struct elf_sym *)s1;
1235 return (sym0->st_value < sym1->st_value)
1236 ? -1
1237 : ((sym0->st_value > sym1->st_value) ? 1 : 0);
1238}
1239
1240
1241static void load_symbols(struct elfhdr *hdr, int fd)
1242{
1243 unsigned int i, nsyms;
1244 struct elf_shdr sechdr, symtab, strtab;
1245 char *strings;
1246 struct syminfo *s;
1247 struct elf_sym *syms;
1248
1249 lseek(fd, hdr->e_shoff, SEEK_SET);
1250 for (i = 0; i < hdr->e_shnum; i++) {
1251 if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
1252 return;
1253#ifdef BSWAP_NEEDED
1254 bswap_shdr(&sechdr);
1255#endif
1256 if (sechdr.sh_type == SHT_SYMTAB) {
1257 symtab = sechdr;
1258 lseek(fd, hdr->e_shoff
1259 + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
1260 if (read(fd, &strtab, sizeof(strtab))
1261 != sizeof(strtab))
1262 return;
1263#ifdef BSWAP_NEEDED
1264 bswap_shdr(&strtab);
1265#endif
1266 goto found;
1267 }
1268 }
1269 return;
1270
1271 found:
1272
1273 s = malloc(sizeof(*s));
1274 syms = malloc(symtab.sh_size);
1275 if (!syms)
1276 return;
1277 s->disas_strtab = strings = malloc(strtab.sh_size);
1278 if (!s->disas_strtab)
1279 return;
1280
1281 lseek(fd, symtab.sh_offset, SEEK_SET);
1282 if (read(fd, syms, symtab.sh_size) != symtab.sh_size)
1283 return;
1284
1285 nsyms = symtab.sh_size / sizeof(struct elf_sym);
1286
1287 i = 0;
1288 while (i < nsyms) {
1289#ifdef BSWAP_NEEDED
1290 bswap_sym(syms + i);
1291#endif
1292
1293 if (syms[i].st_shndx == SHN_UNDEF ||
1294 syms[i].st_shndx >= SHN_LORESERVE ||
1295 ELF_ST_TYPE(syms[i].st_info) != STT_FUNC) {
1296 nsyms--;
1297 if (i < nsyms) {
1298 syms[i] = syms[nsyms];
1299 }
1300 continue;
1301 }
1302#if defined(TARGET_ARM) || defined (TARGET_MIPS)
1303
1304 syms[i].st_value &= ~(target_ulong)1;
1305#endif
1306 i++;
1307 }
1308 syms = realloc(syms, nsyms * sizeof(*syms));
1309
1310 qsort(syms, nsyms, sizeof(*syms), symcmp);
1311
1312 lseek(fd, strtab.sh_offset, SEEK_SET);
1313 if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
1314 return;
1315 s->disas_num_syms = nsyms;
1316#if ELF_CLASS == ELFCLASS32
1317 s->disas_symtab.elf32 = syms;
1318 s->lookup_symbol = lookup_symbolxx;
1319#else
1320 s->disas_symtab.elf64 = syms;
1321 s->lookup_symbol = lookup_symbolxx;
1322#endif
1323 s->next = syminfos;
1324 syminfos = s;
1325}
1326
1327int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
1328 struct image_info * info)
1329{
1330 struct elfhdr elf_ex;
1331 struct elfhdr interp_elf_ex;
1332 struct exec interp_ex;
1333 int interpreter_fd = -1;
1334 abi_ulong load_addr, load_bias;
1335 int load_addr_set = 0;
1336 unsigned int interpreter_type = INTERPRETER_NONE;
1337 unsigned char ibcs2_interpreter;
1338 int i;
1339 abi_ulong mapped_addr;
1340 struct elf_phdr * elf_ppnt;
1341 struct elf_phdr *elf_phdata;
1342 abi_ulong elf_bss, k, elf_brk;
1343 int retval;
1344 char * elf_interpreter;
1345 abi_ulong elf_entry, interp_load_addr = 0;
1346 int status;
1347 abi_ulong start_code, end_code, start_data, end_data;
1348 abi_ulong reloc_func_desc = 0;
1349 abi_ulong elf_stack;
1350 char passed_fileno[6];
1351
1352 ibcs2_interpreter = 0;
1353 status = 0;
1354 load_addr = 0;
1355 load_bias = 0;
1356 elf_ex = *((struct elfhdr *) bprm->buf);
1357#ifdef BSWAP_NEEDED
1358 bswap_ehdr(&elf_ex);
1359#endif
1360
1361
1362 if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
1363 (! elf_check_arch(elf_ex.e_machine))) {
1364 return -ENOEXEC;
1365 }
1366
1367 bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p);
1368 bprm->p = copy_elf_strings(bprm->envc,bprm->envp,bprm->page,bprm->p);
1369 bprm->p = copy_elf_strings(bprm->argc,bprm->argv,bprm->page,bprm->p);
1370 if (!bprm->p) {
1371 retval = -E2BIG;
1372 }
1373
1374
1375 elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
1376 if (elf_phdata == NULL) {
1377 return -ENOMEM;
1378 }
1379
1380 retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
1381 if(retval > 0) {
1382 retval = read(bprm->fd, (char *) elf_phdata,
1383 elf_ex.e_phentsize * elf_ex.e_phnum);
1384 }
1385
1386 if (retval < 0) {
1387 perror("load_elf_binary");
1388 exit(-1);
1389 free (elf_phdata);
1390 return -errno;
1391 }
1392
1393#ifdef BSWAP_NEEDED
1394 elf_ppnt = elf_phdata;
1395 for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
1396 bswap_phdr(elf_ppnt);
1397 }
1398#endif
1399 elf_ppnt = elf_phdata;
1400
1401 elf_bss = 0;
1402 elf_brk = 0;
1403
1404
1405 elf_stack = ~((abi_ulong)0UL);
1406 elf_interpreter = NULL;
1407 start_code = ~((abi_ulong)0UL);
1408 end_code = 0;
1409 start_data = 0;
1410 end_data = 0;
1411 interp_ex.a_info = 0;
1412
1413 for(i=0;i < elf_ex.e_phnum; i++) {
1414 if (elf_ppnt->p_type == PT_INTERP) {
1415 if ( elf_interpreter != NULL )
1416 {
1417 free (elf_phdata);
1418 free(elf_interpreter);
1419 close(bprm->fd);
1420 return -EINVAL;
1421 }
1422
1423
1424
1425
1426
1427
1428 elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
1429
1430 if (elf_interpreter == NULL) {
1431 free (elf_phdata);
1432 close(bprm->fd);
1433 return -ENOMEM;
1434 }
1435
1436 retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
1437 if(retval >= 0) {
1438 retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
1439 }
1440 if(retval < 0) {
1441 perror("load_elf_binary2");
1442 exit(-1);
1443 }
1444
1445
1446
1447
1448
1449
1450
1451 if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
1452 strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
1453 ibcs2_interpreter = 1;
1454 }
1455
1456#if 0
1457 printf("Using ELF interpreter %s\n", elf_interpreter);
1458#endif
1459 if (retval >= 0) {
1460 retval = open(path(elf_interpreter), O_RDONLY);
1461 if(retval >= 0) {
1462 interpreter_fd = retval;
1463 }
1464 else {
1465 perror(elf_interpreter);
1466 exit(-1);
1467
1468 }
1469 }
1470
1471 if (retval >= 0) {
1472 retval = lseek(interpreter_fd, 0, SEEK_SET);
1473 if(retval >= 0) {
1474 retval = read(interpreter_fd,bprm->buf,128);
1475 }
1476 }
1477 if (retval >= 0) {
1478 interp_ex = *((struct exec *) bprm->buf);
1479 interp_elf_ex=*((struct elfhdr *) bprm->buf);
1480 }
1481 if (retval < 0) {
1482 perror("load_elf_binary3");
1483 exit(-1);
1484 free (elf_phdata);
1485 free(elf_interpreter);
1486 close(bprm->fd);
1487 return retval;
1488 }
1489 }
1490 elf_ppnt++;
1491 }
1492
1493
1494 if (elf_interpreter){
1495 interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
1496
1497
1498 if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
1499 (N_MAGIC(interp_ex) != QMAGIC)) {
1500 interpreter_type = INTERPRETER_ELF;
1501 }
1502
1503 if (interp_elf_ex.e_ident[0] != 0x7f ||
1504 strncmp((char *)&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
1505 interpreter_type &= ~INTERPRETER_ELF;
1506 }
1507
1508 if (!interpreter_type) {
1509 free(elf_interpreter);
1510 free(elf_phdata);
1511 close(bprm->fd);
1512 return -ELIBBAD;
1513 }
1514 }
1515
1516
1517
1518
1519 {
1520 char * passed_p;
1521
1522 if (interpreter_type == INTERPRETER_AOUT) {
1523 snprintf(passed_fileno, sizeof(passed_fileno), "%d", bprm->fd);
1524 passed_p = passed_fileno;
1525
1526 if (elf_interpreter) {
1527 bprm->p = copy_elf_strings(1,&passed_p,bprm->page,bprm->p);
1528 bprm->argc++;
1529 }
1530 }
1531 if (!bprm->p) {
1532 if (elf_interpreter) {
1533 free(elf_interpreter);
1534 }
1535 free (elf_phdata);
1536 close(bprm->fd);
1537 return -E2BIG;
1538 }
1539 }
1540
1541
1542 info->end_data = 0;
1543 info->end_code = 0;
1544 info->start_mmap = (abi_ulong)ELF_START_MMAP;
1545 info->mmap = 0;
1546 elf_entry = (abi_ulong) elf_ex.e_entry;
1547
1548
1549
1550 info->rss = 0;
1551 bprm->p = setup_arg_pages(bprm->p, bprm, info);
1552 info->start_stack = bprm->p;
1553
1554
1555
1556
1557
1558
1559
1560 for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
1561 int elf_prot = 0;
1562 int elf_flags = 0;
1563 abi_ulong error;
1564
1565 if (elf_ppnt->p_type != PT_LOAD)
1566 continue;
1567
1568 if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
1569 if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
1570 if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
1571 elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
1572 if (elf_ex.e_type == ET_EXEC || load_addr_set) {
1573 elf_flags |= MAP_FIXED;
1574 } else if (elf_ex.e_type == ET_DYN) {
1575
1576
1577
1578
1579
1580 error = target_mmap(0, ET_DYN_MAP_SIZE,
1581 PROT_NONE, MAP_PRIVATE | MAP_ANON,
1582 -1, 0);
1583 if (error == -1) {
1584 perror("mmap");
1585 exit(-1);
1586 }
1587 load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
1588 }
1589
1590 error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
1591 (elf_ppnt->p_filesz +
1592 TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
1593 elf_prot,
1594 (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
1595 bprm->fd,
1596 (elf_ppnt->p_offset -
1597 TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
1598 if (error == -1) {
1599 perror("mmap");
1600 exit(-1);
1601 }
1602
1603#ifdef LOW_ELF_STACK
1604 if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
1605 elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr);
1606#endif
1607
1608 if (!load_addr_set) {
1609 load_addr_set = 1;
1610 load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
1611 if (elf_ex.e_type == ET_DYN) {
1612 load_bias += error -
1613 TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
1614 load_addr += load_bias;
1615 reloc_func_desc = load_bias;
1616 }
1617 }
1618 k = elf_ppnt->p_vaddr;
1619 if (k < start_code)
1620 start_code = k;
1621 if (start_data < k)
1622 start_data = k;
1623 k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
1624 if (k > elf_bss)
1625 elf_bss = k;
1626 if ((elf_ppnt->p_flags & PF_X) && end_code < k)
1627 end_code = k;
1628 if (end_data < k)
1629 end_data = k;
1630 k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
1631 if (k > elf_brk) elf_brk = k;
1632 }
1633
1634 elf_entry += load_bias;
1635 elf_bss += load_bias;
1636 elf_brk += load_bias;
1637 start_code += load_bias;
1638 end_code += load_bias;
1639 start_data += load_bias;
1640 end_data += load_bias;
1641
1642 if (elf_interpreter) {
1643 if (interpreter_type & 1) {
1644 elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
1645 }
1646 else if (interpreter_type & 2) {
1647 elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
1648 &interp_load_addr);
1649 }
1650 reloc_func_desc = interp_load_addr;
1651
1652 close(interpreter_fd);
1653 free(elf_interpreter);
1654
1655 if (elf_entry == ~((abi_ulong)0UL)) {
1656 printf("Unable to load interpreter\n");
1657 free(elf_phdata);
1658 exit(-1);
1659 return 0;
1660 }
1661 }
1662
1663 free(elf_phdata);
1664
1665 if (qemu_log_enabled())
1666 load_symbols(&elf_ex, bprm->fd);
1667
1668 if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
1669 info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
1670
1671#ifdef LOW_ELF_STACK
1672 info->start_stack = bprm->p = elf_stack - 4;
1673#endif
1674 bprm->p = create_elf_tables(bprm->p,
1675 bprm->argc,
1676 bprm->envc,
1677 &elf_ex,
1678 load_addr, load_bias,
1679 interp_load_addr,
1680 (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
1681 info);
1682 info->load_addr = reloc_func_desc;
1683 info->start_brk = info->brk = elf_brk;
1684 info->end_code = end_code;
1685 info->start_code = start_code;
1686 info->start_data = start_data;
1687 info->end_data = end_data;
1688 info->start_stack = bprm->p;
1689
1690
1691
1692 set_brk(elf_bss, elf_brk);
1693
1694 padzero(elf_bss, elf_brk);
1695
1696#if 0
1697 printf("(start_brk) %x\n" , info->start_brk);
1698 printf("(end_code) %x\n" , info->end_code);
1699 printf("(start_code) %x\n" , info->start_code);
1700 printf("(end_data) %x\n" , info->end_data);
1701 printf("(start_stack) %x\n" , info->start_stack);
1702 printf("(brk) %x\n" , info->brk);
1703#endif
1704
1705 if ( info->personality == PER_SVR4 )
1706 {
1707
1708
1709
1710
1711 mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC,
1712 MAP_FIXED | MAP_PRIVATE, -1, 0);
1713 }
1714
1715 info->entry = elf_entry;
1716
1717#ifdef USE_ELF_CORE_DUMP
1718 bprm->core_dump = &elf_core_dump;
1719#endif
1720
1721 return 0;
1722}
1723
1724#ifdef USE_ELF_CORE_DUMP
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772struct memelfnote {
1773 const char *name;
1774 size_t namesz;
1775 size_t namesz_rounded;
1776 int type;
1777 size_t datasz;
1778 void *data;
1779 size_t notesz;
1780};
1781
1782struct elf_siginfo {
1783 int si_signo;
1784 int si_code;
1785 int si_errno;
1786};
1787
1788struct elf_prstatus {
1789 struct elf_siginfo pr_info;
1790 short pr_cursig;
1791 target_ulong pr_sigpend;
1792 target_ulong pr_sighold;
1793 target_pid_t pr_pid;
1794 target_pid_t pr_ppid;
1795 target_pid_t pr_pgrp;
1796 target_pid_t pr_sid;
1797 struct target_timeval pr_utime;
1798 struct target_timeval pr_stime;
1799 struct target_timeval pr_cutime;
1800 struct target_timeval pr_cstime;
1801 elf_gregset_t pr_reg;
1802 int pr_fpvalid;
1803};
1804
1805#define ELF_PRARGSZ (80)
1806
1807struct elf_prpsinfo {
1808 char pr_state;
1809 char pr_sname;
1810 char pr_zomb;
1811 char pr_nice;
1812 target_ulong pr_flag;
1813 target_uid_t pr_uid;
1814 target_gid_t pr_gid;
1815 target_pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
1816
1817 char pr_fname[16];
1818 char pr_psargs[ELF_PRARGSZ];
1819};
1820
1821
1822struct elf_thread_status {
1823 TAILQ_ENTRY(elf_thread_status) ets_link;
1824 struct elf_prstatus prstatus;
1825#if 0
1826 elf_fpregset_t fpu;
1827 struct task_struct *thread;
1828 elf_fpxregset_t xfpu;
1829#endif
1830 struct memelfnote notes[1];
1831 int num_notes;
1832};
1833
1834struct elf_note_info {
1835 struct memelfnote *notes;
1836 struct elf_prstatus *prstatus;
1837 struct elf_prpsinfo *psinfo;
1838
1839 TAILQ_HEAD(thread_list_head, elf_thread_status) thread_list;
1840#if 0
1841
1842
1843
1844
1845 elf_fpregset_t *fpu;
1846 elf_fpxregset_t *xfpu;
1847 int thread_status_size;
1848#endif
1849 int notes_size;
1850 int numnote;
1851};
1852
1853struct vm_area_struct {
1854 abi_ulong vma_start;
1855 abi_ulong vma_end;
1856 abi_ulong vma_flags;
1857 TAILQ_ENTRY(vm_area_struct) vma_link;
1858};
1859
1860struct mm_struct {
1861 TAILQ_HEAD(, vm_area_struct) mm_mmap;
1862 int mm_count;
1863};
1864
1865static struct mm_struct *vma_init(void);
1866static void vma_delete(struct mm_struct *);
1867static int vma_add_mapping(struct mm_struct *, abi_ulong,
1868 abi_ulong, abi_ulong);
1869static int vma_get_mapping_count(const struct mm_struct *);
1870static struct vm_area_struct *vma_first(const struct mm_struct *);
1871static struct vm_area_struct *vma_next(struct vm_area_struct *);
1872static abi_ulong vma_dump_size(const struct vm_area_struct *);
1873static int vma_walker(void *priv, unsigned long start, unsigned long end,
1874 unsigned long flags);
1875
1876static void fill_elf_header(struct elfhdr *, int, uint16_t, uint32_t);
1877static void fill_note(struct memelfnote *, const char *, int,
1878 unsigned int, void *);
1879static void fill_prstatus(struct elf_prstatus *, const TaskState *, int);
1880static int fill_psinfo(struct elf_prpsinfo *, const TaskState *);
1881static void fill_auxv_note(struct memelfnote *, const TaskState *);
1882static void fill_elf_note_phdr(struct elf_phdr *, int, off_t);
1883static size_t note_size(const struct memelfnote *);
1884static void free_note_info(struct elf_note_info *);
1885static int fill_note_info(struct elf_note_info *, long, const CPUState *);
1886static void fill_thread_info(struct elf_note_info *, const CPUState *);
1887static int core_dump_filename(const TaskState *, char *, size_t);
1888
1889static int dump_write(int, const void *, size_t);
1890static int write_note(struct memelfnote *, int);
1891static int write_note_info(struct elf_note_info *, int);
1892
1893#ifdef BSWAP_NEEDED
1894static void bswap_prstatus(struct elf_prstatus *);
1895static void bswap_psinfo(struct elf_prpsinfo *);
1896
1897static void bswap_prstatus(struct elf_prstatus *prstatus)
1898{
1899 prstatus->pr_info.si_signo = tswapl(prstatus->pr_info.si_signo);
1900 prstatus->pr_info.si_code = tswapl(prstatus->pr_info.si_code);
1901 prstatus->pr_info.si_errno = tswapl(prstatus->pr_info.si_errno);
1902 prstatus->pr_cursig = tswap16(prstatus->pr_cursig);
1903 prstatus->pr_sigpend = tswapl(prstatus->pr_sigpend);
1904 prstatus->pr_sighold = tswapl(prstatus->pr_sighold);
1905 prstatus->pr_pid = tswap32(prstatus->pr_pid);
1906 prstatus->pr_ppid = tswap32(prstatus->pr_ppid);
1907 prstatus->pr_pgrp = tswap32(prstatus->pr_pgrp);
1908 prstatus->pr_sid = tswap32(prstatus->pr_sid);
1909
1910
1911 prstatus->pr_fpvalid = tswap32(prstatus->pr_fpvalid);
1912}
1913
1914static void bswap_psinfo(struct elf_prpsinfo *psinfo)
1915{
1916 psinfo->pr_flag = tswapl(psinfo->pr_flag);
1917 psinfo->pr_uid = tswap16(psinfo->pr_uid);
1918 psinfo->pr_gid = tswap16(psinfo->pr_gid);
1919 psinfo->pr_pid = tswap32(psinfo->pr_pid);
1920 psinfo->pr_ppid = tswap32(psinfo->pr_ppid);
1921 psinfo->pr_pgrp = tswap32(psinfo->pr_pgrp);
1922 psinfo->pr_sid = tswap32(psinfo->pr_sid);
1923}
1924#endif
1925
1926
1927
1928
1929
1930
1931
1932
1933static struct mm_struct *vma_init(void)
1934{
1935 struct mm_struct *mm;
1936
1937 if ((mm = qemu_malloc(sizeof (*mm))) == NULL)
1938 return (NULL);
1939
1940 mm->mm_count = 0;
1941 TAILQ_INIT(&mm->mm_mmap);
1942
1943 return (mm);
1944}
1945
1946static void vma_delete(struct mm_struct *mm)
1947{
1948 struct vm_area_struct *vma;
1949
1950 while ((vma = vma_first(mm)) != NULL) {
1951 TAILQ_REMOVE(&mm->mm_mmap, vma, vma_link);
1952 qemu_free(vma);
1953 }
1954 qemu_free(mm);
1955}
1956
1957static int vma_add_mapping(struct mm_struct *mm, abi_ulong start,
1958 abi_ulong end, abi_ulong flags)
1959{
1960 struct vm_area_struct *vma;
1961
1962 if ((vma = qemu_mallocz(sizeof (*vma))) == NULL)
1963 return (-1);
1964
1965 vma->vma_start = start;
1966 vma->vma_end = end;
1967 vma->vma_flags = flags;
1968
1969 TAILQ_INSERT_TAIL(&mm->mm_mmap, vma, vma_link);
1970 mm->mm_count++;
1971
1972 return (0);
1973}
1974
1975static struct vm_area_struct *vma_first(const struct mm_struct *mm)
1976{
1977 return (TAILQ_FIRST(&mm->mm_mmap));
1978}
1979
1980static struct vm_area_struct *vma_next(struct vm_area_struct *vma)
1981{
1982 return (TAILQ_NEXT(vma, vma_link));
1983}
1984
1985static int vma_get_mapping_count(const struct mm_struct *mm)
1986{
1987 return (mm->mm_count);
1988}
1989
1990
1991
1992
1993static abi_ulong vma_dump_size(const struct vm_area_struct *vma)
1994{
1995
1996 if (!access_ok(VERIFY_READ, vma->vma_start, TARGET_PAGE_SIZE))
1997 return (0);
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007 if (vma->vma_flags & PROT_EXEC) {
2008 char page[TARGET_PAGE_SIZE];
2009
2010 copy_from_user(page, vma->vma_start, sizeof (page));
2011 if ((page[EI_MAG0] == ELFMAG0) &&
2012 (page[EI_MAG1] == ELFMAG1) &&
2013 (page[EI_MAG2] == ELFMAG2) &&
2014 (page[EI_MAG3] == ELFMAG3)) {
2015
2016
2017
2018
2019 return (0);
2020 }
2021 }
2022
2023 return (vma->vma_end - vma->vma_start);
2024}
2025
2026static int vma_walker(void *priv, unsigned long start, unsigned long end,
2027 unsigned long flags)
2028{
2029 struct mm_struct *mm = (struct mm_struct *)priv;
2030
2031
2032
2033
2034 if (flags & PAGE_RESERVED)
2035 return (0);
2036
2037 vma_add_mapping(mm, start, end, flags);
2038 return (0);
2039}
2040
2041static void fill_note(struct memelfnote *note, const char *name, int type,
2042 unsigned int sz, void *data)
2043{
2044 unsigned int namesz;
2045
2046 namesz = strlen(name) + 1;
2047 note->name = name;
2048 note->namesz = namesz;
2049 note->namesz_rounded = roundup(namesz, sizeof (int32_t));
2050 note->type = type;
2051 note->datasz = roundup(sz, sizeof (int32_t));;
2052 note->data = data;
2053
2054
2055
2056
2057
2058 note->notesz = sizeof (struct elf_note) +
2059 note->namesz_rounded + note->datasz;
2060}
2061
2062static void fill_elf_header(struct elfhdr *elf, int segs, uint16_t machine,
2063 uint32_t flags)
2064{
2065 (void) memset(elf, 0, sizeof(*elf));
2066
2067 (void) memcpy(elf->e_ident, ELFMAG, SELFMAG);
2068 elf->e_ident[EI_CLASS] = ELF_CLASS;
2069 elf->e_ident[EI_DATA] = ELF_DATA;
2070 elf->e_ident[EI_VERSION] = EV_CURRENT;
2071 elf->e_ident[EI_OSABI] = ELF_OSABI;
2072
2073 elf->e_type = ET_CORE;
2074 elf->e_machine = machine;
2075 elf->e_version = EV_CURRENT;
2076 elf->e_phoff = sizeof(struct elfhdr);
2077 elf->e_flags = flags;
2078 elf->e_ehsize = sizeof(struct elfhdr);
2079 elf->e_phentsize = sizeof(struct elf_phdr);
2080 elf->e_phnum = segs;
2081
2082#ifdef BSWAP_NEEDED
2083 bswap_ehdr(elf);
2084#endif
2085}
2086
2087static void fill_elf_note_phdr(struct elf_phdr *phdr, int sz, off_t offset)
2088{
2089 phdr->p_type = PT_NOTE;
2090 phdr->p_offset = offset;
2091 phdr->p_vaddr = 0;
2092 phdr->p_paddr = 0;
2093 phdr->p_filesz = sz;
2094 phdr->p_memsz = 0;
2095 phdr->p_flags = 0;
2096 phdr->p_align = 0;
2097
2098#ifdef BSWAP_NEEDED
2099 bswap_phdr(phdr);
2100#endif
2101}
2102
2103static size_t note_size(const struct memelfnote *note)
2104{
2105 return (note->notesz);
2106}
2107
2108static void fill_prstatus(struct elf_prstatus *prstatus,
2109 const TaskState *ts, int signr)
2110{
2111 (void) memset(prstatus, 0, sizeof (*prstatus));
2112 prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
2113 prstatus->pr_pid = ts->ts_tid;
2114 prstatus->pr_ppid = getppid();
2115 prstatus->pr_pgrp = getpgrp();
2116 prstatus->pr_sid = getsid(0);
2117
2118#ifdef BSWAP_NEEDED
2119 bswap_prstatus(prstatus);
2120#endif
2121}
2122
2123static int fill_psinfo(struct elf_prpsinfo *psinfo, const TaskState *ts)
2124{
2125 char *filename, *base_filename;
2126 unsigned int i, len;
2127
2128 (void) memset(psinfo, 0, sizeof (*psinfo));
2129
2130 len = ts->info->arg_end - ts->info->arg_start;
2131 if (len >= ELF_PRARGSZ)
2132 len = ELF_PRARGSZ - 1;
2133 if (copy_from_user(&psinfo->pr_psargs, ts->info->arg_start, len))
2134 return -EFAULT;
2135 for (i = 0; i < len; i++)
2136 if (psinfo->pr_psargs[i] == 0)
2137 psinfo->pr_psargs[i] = ' ';
2138 psinfo->pr_psargs[len] = 0;
2139
2140 psinfo->pr_pid = getpid();
2141 psinfo->pr_ppid = getppid();
2142 psinfo->pr_pgrp = getpgrp();
2143 psinfo->pr_sid = getsid(0);
2144 psinfo->pr_uid = getuid();
2145 psinfo->pr_gid = getgid();
2146
2147 filename = strdup(ts->bprm->filename);
2148 base_filename = strdup(basename(filename));
2149 (void) strncpy(psinfo->pr_fname, base_filename,
2150 sizeof(psinfo->pr_fname));
2151 free(base_filename);
2152 free(filename);
2153
2154#ifdef BSWAP_NEEDED
2155 bswap_psinfo(psinfo);
2156#endif
2157 return (0);
2158}
2159
2160static void fill_auxv_note(struct memelfnote *note, const TaskState *ts)
2161{
2162 elf_addr_t auxv = (elf_addr_t)ts->info->saved_auxv;
2163 elf_addr_t orig_auxv = auxv;
2164 abi_ulong val;
2165 void *ptr;
2166 int i, len;
2167
2168
2169
2170
2171
2172
2173
2174
2175 i = len = 0;
2176 do {
2177 get_user_ual(val, auxv);
2178 i += 2;
2179 auxv += 2 * sizeof (elf_addr_t);
2180 } while (val != AT_NULL);
2181 len = i * sizeof (elf_addr_t);
2182
2183
2184 ptr = lock_user(VERIFY_READ, orig_auxv, len, 0);
2185 if (ptr != NULL) {
2186 fill_note(note, "CORE", NT_AUXV, len, ptr);
2187 unlock_user(ptr, auxv, len);
2188 }
2189}
2190
2191
2192
2193
2194
2195
2196
2197
2198static int core_dump_filename(const TaskState *ts, char *buf,
2199 size_t bufsize)
2200{
2201 char timestamp[64];
2202 char *filename = NULL;
2203 char *base_filename = NULL;
2204 struct timeval tv;
2205 struct tm tm;
2206
2207 assert(bufsize >= PATH_MAX);
2208
2209 if (gettimeofday(&tv, NULL) < 0) {
2210 (void) fprintf(stderr, "unable to get current timestamp: %s",
2211 strerror(errno));
2212 return (-1);
2213 }
2214
2215 filename = strdup(ts->bprm->filename);
2216 base_filename = strdup(basename(filename));
2217 (void) strftime(timestamp, sizeof (timestamp), "%Y%m%d-%H%M%S",
2218 localtime_r(&tv.tv_sec, &tm));
2219 (void) snprintf(buf, bufsize, "qemu_%s_%s_%d.core",
2220 base_filename, timestamp, (int)getpid());
2221 free(base_filename);
2222 free(filename);
2223
2224 return (0);
2225}
2226
2227static int dump_write(int fd, const void *ptr, size_t size)
2228{
2229 const char *bufp = (const char *)ptr;
2230 ssize_t bytes_written, bytes_left;
2231 struct rlimit dumpsize;
2232 off_t pos;
2233
2234 bytes_written = 0;
2235 getrlimit(RLIMIT_CORE, &dumpsize);
2236 if ((pos = lseek(fd, 0, SEEK_CUR))==-1) {
2237 if (errno == ESPIPE) {
2238 bytes_left = size;
2239 } else {
2240 return pos;
2241 }
2242 } else {
2243 if (dumpsize.rlim_cur <= pos) {
2244 return -1;
2245 } else if (dumpsize.rlim_cur == RLIM_INFINITY) {
2246 bytes_left = size;
2247 } else {
2248 size_t limit_left=dumpsize.rlim_cur - pos;
2249 bytes_left = limit_left >= size ? size : limit_left ;
2250 }
2251 }
2252
2253
2254
2255
2256
2257 do {
2258 bytes_written = write(fd, bufp, bytes_left);
2259 if (bytes_written < 0) {
2260 if (errno == EINTR)
2261 continue;
2262 return (-1);
2263 } else if (bytes_written == 0) {
2264 return (-1);
2265 }
2266 bufp += bytes_written;
2267 bytes_left -= bytes_written;
2268 } while (bytes_left > 0);
2269
2270 return (0);
2271}
2272
2273static int write_note(struct memelfnote *men, int fd)
2274{
2275 struct elf_note en;
2276
2277 en.n_namesz = men->namesz;
2278 en.n_type = men->type;
2279 en.n_descsz = men->datasz;
2280
2281#ifdef BSWAP_NEEDED
2282 bswap_note(&en);
2283#endif
2284
2285 if (dump_write(fd, &en, sizeof(en)) != 0)
2286 return (-1);
2287 if (dump_write(fd, men->name, men->namesz_rounded) != 0)
2288 return (-1);
2289 if (dump_write(fd, men->data, men->datasz) != 0)
2290 return (-1);
2291
2292 return (0);
2293}
2294
2295static void fill_thread_info(struct elf_note_info *info, const CPUState *env)
2296{
2297 TaskState *ts = (TaskState *)env->opaque;
2298 struct elf_thread_status *ets;
2299
2300 ets = qemu_mallocz(sizeof (*ets));
2301 ets->num_notes = 1;
2302 fill_prstatus(&ets->prstatus, ts, 0);
2303 elf_core_copy_regs(&ets->prstatus.pr_reg, env);
2304 fill_note(&ets->notes[0], "CORE", NT_PRSTATUS, sizeof (ets->prstatus),
2305 &ets->prstatus);
2306
2307 TAILQ_INSERT_TAIL(&info->thread_list, ets, ets_link);
2308
2309 info->notes_size += note_size(&ets->notes[0]);
2310}
2311
2312static int fill_note_info(struct elf_note_info *info,
2313 long signr, const CPUState *env)
2314{
2315#define NUMNOTES 3
2316 CPUState *cpu = NULL;
2317 TaskState *ts = (TaskState *)env->opaque;
2318 int i;
2319
2320 (void) memset(info, 0, sizeof (*info));
2321
2322 TAILQ_INIT(&info->thread_list);
2323
2324 info->notes = qemu_mallocz(NUMNOTES * sizeof (struct memelfnote));
2325 if (info->notes == NULL)
2326 return (-ENOMEM);
2327 info->prstatus = qemu_mallocz(sizeof (*info->prstatus));
2328 if (info->prstatus == NULL)
2329 return (-ENOMEM);
2330 info->psinfo = qemu_mallocz(sizeof (*info->psinfo));
2331 if (info->prstatus == NULL)
2332 return (-ENOMEM);
2333
2334
2335
2336
2337
2338 fill_prstatus(info->prstatus, ts, signr);
2339 elf_core_copy_regs(&info->prstatus->pr_reg, env);
2340 fill_note(&info->notes[0], "CORE", NT_PRSTATUS,
2341 sizeof (*info->prstatus), info->prstatus);
2342 fill_psinfo(info->psinfo, ts);
2343 fill_note(&info->notes[1], "CORE", NT_PRPSINFO,
2344 sizeof (*info->psinfo), info->psinfo);
2345 fill_auxv_note(&info->notes[2], ts);
2346 info->numnote = 3;
2347
2348 info->notes_size = 0;
2349 for (i = 0; i < info->numnote; i++)
2350 info->notes_size += note_size(&info->notes[i]);
2351
2352
2353 cpu_list_lock();
2354 for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
2355 if (cpu == thread_env)
2356 continue;
2357 fill_thread_info(info, cpu);
2358 }
2359 cpu_list_unlock();
2360
2361 return (0);
2362}
2363
2364static void free_note_info(struct elf_note_info *info)
2365{
2366 struct elf_thread_status *ets;
2367
2368 while (!TAILQ_EMPTY(&info->thread_list)) {
2369 ets = TAILQ_FIRST(&info->thread_list);
2370 TAILQ_REMOVE(&info->thread_list, ets, ets_link);
2371 qemu_free(ets);
2372 }
2373
2374 qemu_free(info->prstatus);
2375 qemu_free(info->psinfo);
2376 qemu_free(info->notes);
2377}
2378
2379static int write_note_info(struct elf_note_info *info, int fd)
2380{
2381 struct elf_thread_status *ets;
2382 int i, error = 0;
2383
2384
2385 for (i = 0; i < info->numnote; i++)
2386 if ((error = write_note(&info->notes[i], fd)) != 0)
2387 return (error);
2388
2389
2390 for (ets = info->thread_list.tqh_first; ets != NULL;
2391 ets = ets->ets_link.tqe_next) {
2392 if ((error = write_note(&ets->notes[0], fd)) != 0)
2393 return (error);
2394 }
2395
2396 return (0);
2397}
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442static int elf_core_dump(int signr, const CPUState *env)
2443{
2444 const TaskState *ts = (const TaskState *)env->opaque;
2445 struct vm_area_struct *vma = NULL;
2446 char corefile[PATH_MAX];
2447 struct elf_note_info info;
2448 struct elfhdr elf;
2449 struct elf_phdr phdr;
2450 struct rlimit dumpsize;
2451 struct mm_struct *mm = NULL;
2452 off_t offset = 0, data_offset = 0;
2453 int segs = 0;
2454 int fd = -1;
2455
2456 errno = 0;
2457 getrlimit(RLIMIT_CORE, &dumpsize);
2458 if (dumpsize.rlim_cur == 0)
2459 return 0;
2460
2461 if (core_dump_filename(ts, corefile, sizeof (corefile)) < 0)
2462 return (-errno);
2463
2464 if ((fd = open(corefile, O_WRONLY | O_CREAT,
2465 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0)
2466 return (-errno);
2467
2468
2469
2470
2471
2472
2473 if ((mm = vma_init()) == NULL)
2474 goto out;
2475
2476 walk_memory_regions(mm, vma_walker);
2477 segs = vma_get_mapping_count(mm);
2478
2479
2480
2481
2482
2483 fill_elf_header(&elf, segs + 1, ELF_MACHINE, 0);
2484 if (dump_write(fd, &elf, sizeof (elf)) != 0)
2485 goto out;
2486
2487
2488 if (fill_note_info(&info, signr, env) < 0)
2489 goto out;
2490
2491 offset += sizeof (elf);
2492 offset += (segs + 1) * sizeof (struct elf_phdr);
2493
2494
2495 fill_elf_note_phdr(&phdr, info.notes_size, offset);
2496
2497 offset += info.notes_size;
2498 if (dump_write(fd, &phdr, sizeof (phdr)) != 0)
2499 goto out;
2500
2501
2502
2503
2504
2505 offset = roundup(offset, ELF_EXEC_PAGESIZE);
2506
2507
2508
2509
2510
2511 for (vma = vma_first(mm); vma != NULL; vma = vma_next(vma)) {
2512 (void) memset(&phdr, 0, sizeof (phdr));
2513
2514 phdr.p_type = PT_LOAD;
2515 phdr.p_offset = offset;
2516 phdr.p_vaddr = vma->vma_start;
2517 phdr.p_paddr = 0;
2518 phdr.p_filesz = vma_dump_size(vma);
2519 offset += phdr.p_filesz;
2520 phdr.p_memsz = vma->vma_end - vma->vma_start;
2521 phdr.p_flags = vma->vma_flags & PROT_READ ? PF_R : 0;
2522 if (vma->vma_flags & PROT_WRITE)
2523 phdr.p_flags |= PF_W;
2524 if (vma->vma_flags & PROT_EXEC)
2525 phdr.p_flags |= PF_X;
2526 phdr.p_align = ELF_EXEC_PAGESIZE;
2527
2528 dump_write(fd, &phdr, sizeof (phdr));
2529 }
2530
2531
2532
2533
2534
2535 if (write_note_info(&info, fd) < 0)
2536 goto out;
2537
2538
2539 data_offset = lseek(fd, 0, SEEK_CUR);
2540 data_offset = TARGET_PAGE_ALIGN(data_offset);
2541 if (lseek(fd, data_offset, SEEK_SET) != data_offset)
2542 goto out;
2543
2544
2545
2546
2547 for (vma = vma_first(mm); vma != NULL; vma = vma_next(vma)) {
2548 abi_ulong addr;
2549 abi_ulong end;
2550
2551 end = vma->vma_start + vma_dump_size(vma);
2552
2553 for (addr = vma->vma_start; addr < end;
2554 addr += TARGET_PAGE_SIZE) {
2555 char page[TARGET_PAGE_SIZE];
2556 int error;
2557
2558
2559
2560
2561
2562 error = copy_from_user(page, addr, sizeof (page));
2563 if (error != 0) {
2564 (void) fprintf(stderr, "unable to dump " TARGET_FMT_lx "\n",
2565 addr);
2566 errno = -error;
2567 goto out;
2568 }
2569 if (dump_write(fd, page, TARGET_PAGE_SIZE) < 0)
2570 goto out;
2571 }
2572 }
2573
2574out:
2575 free_note_info(&info);
2576 if (mm != NULL)
2577 vma_delete(mm);
2578 (void) close(fd);
2579
2580 if (errno != 0)
2581 return (-errno);
2582 return (0);
2583}
2584
2585#endif
2586
2587static int load_aout_interp(void * exptr, int interp_fd)
2588{
2589 printf("a.out interpreter not yet supported\n");
2590 return(0);
2591}
2592
2593void do_init_thread(struct target_pt_regs *regs, struct image_info *infop)
2594{
2595 init_thread(regs, infop);
2596}
2597