1:
2:
3: #include <stdio.h>
4: #include <sys/types.h>
5: #include <fcntl.h>
6: #include <errno.h>
7: #include <unistd.h>
8: #include <sys/mman.h>
9: #include <stdlib.h>
10: #include <string.h>
11:
12: #include "qemu.h"
13: #include "disas.h"
14:
15:
16:
17:
18:
19:
20:
21:
22: enum {
23: ADDR_NO_RANDOMIZE = 0x0040000,
24: FDPIC_FUNCPTRS = 0x0080000,
25:
26:
27: MMAP_PAGE_ZERO = 0x0100000,
28: ADDR_COMPAT_LAYOUT = 0x0200000,
29: READ_IMPLIES_EXEC = 0x0400000,
30: ADDR_LIMIT_32BIT = 0x0800000,
31: SHORT_INODE = 0x1000000,
32: WHOLE_SECONDS = 0x2000000,
33: STICKY_TIMEOUTS = 0x4000000,
34: ADDR_LIMIT_3GB = 0x8000000,
35: };
36:
37:
38:
39:
40:
41:
42:
43: enum {
44: PER_LINUX = 0x0000,
45: PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT,
46: PER_LINUX_FDPIC = 0x0000 | FDPIC_FUNCPTRS,
47: PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
48: PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
49: PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS |
50: WHOLE_SECONDS | SHORT_INODE,
51: PER_OSR5 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
52: PER_WYSEV386 = 0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
53: PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS,
54: PER_BSD = 0x0006,
55: PER_SUNOS = 0x0006 | STICKY_TIMEOUTS,
56: PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
57: PER_LINUX32 = 0x0008,
58: PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB,
59: PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS,
60: PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS,
61: PER_IRIX64 = 0x000b | STICKY_TIMEOUTS,
62: PER_RISCOS = 0x000c,
63: PER_SOLARIS = 0x000d | STICKY_TIMEOUTS,
64: PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
65: PER_OSF4 = 0x000f,
66: PER_HPUX = 0x0010,
67: PER_MASK = 0x00ff,
68: };
69:
70:
71:
72:
73: #define personality(pers) (pers & PER_MASK)
74:
75:
76: #ifndef MAP_DENYWRITE
77: #define MAP_DENYWRITE 0
78: #endif
79:
80:
81: #ifndef ELIBBAD
82: #define ELIBBAD 80
83: #endif
84:
85: #ifdef TARGET_I386
86:
87: #define ELF_PLATFORM get_elf_platform()
88:
89: static const char *get_elf_platform(void)
90: {
91: static char elf_platform[] = "i386";
92: int family = (global_env->cpuid_version >> 8) & 0xff;
93: if (family > 6)
94: family = 6;
95: if (family >= 3)
96: elf_platform[1] = '0' + family;
97: return elf_platform;
98: }
99:
100: #define ELF_HWCAP get_elf_hwcap()
101:
102: static uint32_t get_elf_hwcap(void)
103: {
104: return global_env->cpuid_features;
105: }
106:
107: #ifdef TARGET_X86_64
108: #define ELF_START_MMAP 0x2aaaaab000ULL
109: #define elf_check_arch(x) ( ((x) == ELF_ARCH) )
110:
111: #define ELF_CLASS ELFCLASS64
112: #define ELF_DATA ELFDATA2LSB
113: #define ELF_ARCH EM_X86_64
114:
115: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
116: {
117: regs->rax = 0;
118: regs->rsp = infop->start_stack;
119: regs->rip = infop->entry;
120: }
121:
122: #else
123:
124: #define ELF_START_MMAP 0x80000000
125:
126:
127:
128:
129: #define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
130:
131:
132:
133:
134: #define ELF_CLASS ELFCLASS32
135: #define ELF_DATA ELFDATA2LSB
136: #define ELF_ARCH EM_386
137:
138: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
139: {
140: regs->esp = infop->start_stack;
141: regs->eip = infop->entry;
142:
143:
144:
145:
146:
147:
148:
149:
150: regs->edx = 0;
151: }
152: #endif
153:
154: #define USE_ELF_CORE_DUMP
155: #define ELF_EXEC_PAGESIZE 4096
156:
157: #endif
158:
159: #ifdef TARGET_ARM
160:
161: #define ELF_START_MMAP 0x80000000
162:
163: #define elf_check_arch(x) ( (x) == EM_ARM )
164:
165: #define ELF_CLASS ELFCLASS32
166: #ifdef TARGET_WORDS_BIGENDIAN
167: #define ELF_DATA ELFDATA2MSB
168: #else
169: #define ELF_DATA ELFDATA2LSB
170: #endif
171: #define ELF_ARCH EM_ARM
172:
173: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
174: {
175: abi_long stack = infop->start_stack;
176: memset(regs, 0, sizeof(*regs));
177: regs->ARM_cpsr = 0x10;
178: if (infop->entry & 1)
179: regs->ARM_cpsr |= CPSR_T;
180: regs->ARM_pc = infop->entry & 0xfffffffe;
181: regs->ARM_sp = infop->start_stack;
182:
183: get_user_ual(regs->ARM_r2, stack + 8);
184: get_user_ual(regs->ARM_r1, stack + 4);
185:
186: regs->ARM_r0 = 0;
187:
188:
189: regs->ARM_r10 = infop->start_data;
190: }
191:
192: #define USE_ELF_CORE_DUMP
193: #define ELF_EXEC_PAGESIZE 4096
194:
195: enum
196: {
197: ARM_HWCAP_ARM_SWP = 1 << 0,
198: ARM_HWCAP_ARM_HALF = 1 << 1,
199: ARM_HWCAP_ARM_THUMB = 1 << 2,
200: ARM_HWCAP_ARM_26BIT = 1 << 3,
201: ARM_HWCAP_ARM_FAST_MULT = 1 << 4,
202: ARM_HWCAP_ARM_FPA = 1 << 5,
203: ARM_HWCAP_ARM_VFP = 1 << 6,
204: ARM_HWCAP_ARM_EDSP = 1 << 7,
205: };
206:
207: #define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF \
208: | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT \
209: | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP)
210:
211: #endif
212:
213: #ifdef TARGET_SPARC
214: #ifdef TARGET_SPARC64
215:
216: #define ELF_START_MMAP 0x80000000
217:
218: #ifndef TARGET_ABI32
219: #define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS )
220: #else
221: #define elf_check_arch(x) ( (x) == EM_SPARC32PLUS || (x) == EM_SPARC )
222: #endif
223:
224: #define ELF_CLASS ELFCLASS64
225: #define ELF_DATA ELFDATA2MSB
226: #define ELF_ARCH EM_SPARCV9
227:
228: #define STACK_BIAS 2047
229:
230: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
231: {
232: #ifndef TARGET_ABI32
233: regs->tstate = 0;
234: #endif
235: regs->pc = infop->entry;
236: regs->npc = regs->pc + 4;
237: regs->y = 0;
238: #ifdef TARGET_ABI32
239: regs->u_regs[14] = infop->start_stack - 16 * 4;
240: #else
241: if (personality(infop->personality) == PER_LINUX32)
242: regs->u_regs[14] = infop->start_stack - 16 * 4;
243: else
244: regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;
245: #endif
246: }
247:
248: #else
249: #define ELF_START_MMAP 0x80000000
250:
251: #define elf_check_arch(x) ( (x) == EM_SPARC )
252:
253: #define ELF_CLASS ELFCLASS32
254: #define ELF_DATA ELFDATA2MSB
255: #define ELF_ARCH EM_SPARC
256:
257: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
258: {
259: regs->psr = 0;
260: regs->pc = infop->entry;
261: regs->npc = regs->pc + 4;
262: regs->y = 0;
263: regs->u_regs[14] = infop->start_stack - 16 * 4;
264: }
265:
266: #endif
267: #endif
268:
269: #ifdef TARGET_PPC
270:
271: #define ELF_START_MMAP 0x80000000
272:
273: #if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
274:
275: #define elf_check_arch(x) ( (x) == EM_PPC64 )
276:
277: #define ELF_CLASS ELFCLASS64
278:
279: #else
280:
281: #define elf_check_arch(x) ( (x) == EM_PPC )
282:
283: #define ELF_CLASS ELFCLASS32
284:
285: #endif
286:
287: #ifdef TARGET_WORDS_BIGENDIAN
288: #define ELF_DATA ELFDATA2MSB
289: #else
290: #define ELF_DATA ELFDATA2LSB
291: #endif
292: #define ELF_ARCH EM_PPC
293:
294:
295:
296:
297:
298: #define AT_DCACHEBSIZE 19
299: #define AT_ICACHEBSIZE 20
300: #define AT_UCACHEBSIZE 21
301:
302: #define AT_IGNOREPPC 22
303:
304:
305:
306:
307:
308:
309:
310:
311:
312: #define DLINFO_ARCH_ITEMS 5
313: #define ARCH_DLINFO \
314: do { \
315: NEW_AUX_ENT(AT_DCACHEBSIZE, 0x20); \
316: NEW_AUX_ENT(AT_ICACHEBSIZE, 0x20); \
317: NEW_AUX_ENT(AT_UCACHEBSIZE, 0); \
318:
319:
320: \
321: NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
322: NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
323: } while (0)
324:
325: static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
326: {
327: abi_ulong pos = infop->start_stack;
328: abi_ulong tmp;
329: #if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
330: abi_ulong entry, toc;
331: #endif
332:
333: _regs->gpr[1] = infop->start_stack;
334: #if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
335: entry = ldq_raw(infop->entry) + infop->load_addr;
336: toc = ldq_raw(infop->entry + 8) + infop->load_addr;
337: _regs->gpr[2] = toc;
338: infop->entry = entry;
339: #endif
340: _regs->nip = infop->entry;
341:
342:
343:
344:
345:
346: get_user_ual(_regs->gpr[3], pos);
347: pos += sizeof(abi_ulong);
348: _regs->gpr[4] = pos;
349: for (tmp = 1; tmp != 0; pos += sizeof(abi_ulong))
350: tmp = ldl(pos);
351: _regs->gpr[5] = pos;
352: }
353:
354: #define USE_ELF_CORE_DUMP
355: #define ELF_EXEC_PAGESIZE 4096
356:
357: #endif
358:
359: #ifdef TARGET_MIPS
360:
361: #define ELF_START_MMAP 0x80000000
362:
363: #define elf_check_arch(x) ( (x) == EM_MIPS )
364:
365: #ifdef TARGET_MIPS64
366: #define ELF_CLASS ELFCLASS64
367: #else
368: #define ELF_CLASS ELFCLASS32
369: #endif
370: #ifdef TARGET_WORDS_BIGENDIAN
371: #define ELF_DATA ELFDATA2MSB
372: #else
373: #define ELF_DATA ELFDATA2LSB
374: #endif
375: #define ELF_ARCH EM_MIPS
376:
377: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
378: {
379: regs->cp0_status = 2 << CP0St_KSU;
380: regs->cp0_epc = infop->entry;
381: regs->regs[29] = infop->start_stack;
382: }
383:
384: #define USE_ELF_CORE_DUMP
385: #define ELF_EXEC_PAGESIZE 4096
386:
387: #endif
388:
389: #ifdef TARGET_SH4
390:
391: #define ELF_START_MMAP 0x80000000
392:
393: #define elf_check_arch(x) ( (x) == EM_SH )
394:
395: #define ELF_CLASS ELFCLASS32
396: #define ELF_DATA ELFDATA2LSB
397: #define ELF_ARCH EM_SH
398:
399: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
400: {
401:
402: regs->pc = infop->entry;
403: regs->regs[15] = infop->start_stack;
404: }
405:
406: #define USE_ELF_CORE_DUMP
407: #define ELF_EXEC_PAGESIZE 4096
408:
409: #endif
410:
411: #ifdef TARGET_CRIS
412:
413: #define ELF_START_MMAP 0x80000000
414:
415: #define elf_check_arch(x) ( (x) == EM_CRIS )
416:
417: #define ELF_CLASS ELFCLASS32
418: #define ELF_DATA ELFDATA2LSB
419: #define ELF_ARCH EM_CRIS
420:
421: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
422: {
423: regs->erp = infop->entry;
424: }
425:
426: #define USE_ELF_CORE_DUMP
427: #define ELF_EXEC_PAGESIZE 8192
428:
429: #endif
430:
431: #ifdef TARGET_M68K
432:
433: #define ELF_START_MMAP 0x80000000
434:
435: #define elf_check_arch(x) ( (x) == EM_68K )
436:
437: #define ELF_CLASS ELFCLASS32
438: #define ELF_DATA ELFDATA2MSB
439: #define ELF_ARCH EM_68K
440:
441:
442:
443:
444: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
445: {
446: regs->usp = infop->start_stack;
447: regs->sr = 0;
448: regs->pc = infop->entry;
449: }
450:
451: #define USE_ELF_CORE_DUMP
452: #define ELF_EXEC_PAGESIZE 8192
453:
454: #endif
455:
456: #ifdef TARGET_ALPHA
457:
458: #define ELF_START_MMAP (0x30000000000ULL)
459:
460: #define elf_check_arch(x) ( (x) == ELF_ARCH )
461:
462: #define ELF_CLASS ELFCLASS64
463: #define ELF_DATA ELFDATA2MSB
464: #define ELF_ARCH EM_ALPHA
465:
466: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
467: {
468: regs->pc = infop->entry;
469: regs->ps = 8;
470: regs->usp = infop->start_stack;
471: regs->unique = infop->start_data;
472: printf("Set unique value to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n",
473: regs->unique, infop->start_data);
474: }
475:
476: #define USE_ELF_CORE_DUMP
477: #define ELF_EXEC_PAGESIZE 8192
478:
479: #endif
480:
481: #ifndef ELF_PLATFORM
482: #define ELF_PLATFORM (NULL)
483: #endif
484:
485: #ifndef ELF_HWCAP
486: #define ELF_HWCAP 0
487: #endif
488:
489: #ifdef TARGET_ABI32
490: #undef ELF_CLASS
491: #define ELF_CLASS ELFCLASS32
492: #undef bswaptls
493: #define bswaptls(ptr) bswap32s(ptr)
494: #endif
495:
496: #include "elf.h"
497:
498: struct exec
499: {
500: unsigned int a_info;
501: unsigned int a_text;
502: unsigned int a_data;
503: unsigned int a_bss;
504: unsigned int a_syms;
505: unsigned int a_entry;
506: unsigned int a_trsize;
507: unsigned int a_drsize;
508: };
509:
510:
511: #define N_MAGIC(exec) ((exec).a_info & 0xffff)
512: #define OMAGIC 0407
513: #define NMAGIC 0410
514: #define ZMAGIC 0413
515: #define QMAGIC 0314
516:
517:
518: #define INTERP_MAP_SIZE (32 * 1024 * 1024)
519:
520:
521: #define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
522:
523:
524: #define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE