|
|
1.1 root 1: /*
2: * qemu user main
3: *
4: * Copyright (c) 2003-2008 Fabrice Bellard
5: *
6: * This program is free software; you can redistribute it and/or modify
7: * it under the terms of the GNU General Public License as published by
8: * the Free Software Foundation; either version 2 of the License, or
9: * (at your option) any later version.
10: *
11: * This program is distributed in the hope that it will be useful,
12: * but WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: * GNU General Public License for more details.
15: *
16: * You should have received a copy of the GNU General Public License
1.1.1.2 root 17: * along with this program; if not, see <http://www.gnu.org/licenses/>.
1.1 root 18: */
19: #include <stdlib.h>
20: #include <stdio.h>
21: #include <stdarg.h>
22: #include <string.h>
23: #include <errno.h>
24: #include <unistd.h>
25: #include <machine/trap.h>
1.1.1.2 root 26: #include <sys/types.h>
27: #include <sys/mman.h>
1.1 root 28:
29: #include "qemu.h"
30: #include "qemu-common.h"
31: /* For tb_lock */
1.1.1.6 ! root 32: #include "cpu.h"
1.1.1.4 root 33: #include "tcg.h"
34: #include "qemu-timer.h"
1.1.1.3 root 35: #include "envlist.h"
36:
1.1 root 37: #define DEBUG_LOGFILE "/tmp/qemu.log"
38:
1.1.1.2 root 39: int singlestep;
1.1.1.3 root 40: #if defined(CONFIG_USE_GUEST_BASE)
41: unsigned long mmap_min_addr;
42: unsigned long guest_base;
43: int have_guest_base;
44: #endif
1.1.1.2 root 45:
1.1.1.4 root 46: static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
1.1 root 47: const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
48: extern char **environ;
1.1.1.3 root 49: enum BSDType bsd_type;
1.1 root 50:
51: /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
52: we allocate a bigger stack. Need a better solution, for example
53: by remapping the process stack directly at the right place */
54: unsigned long x86_stack_size = 512 * 1024;
55:
56: void gemu_log(const char *fmt, ...)
57: {
58: va_list ap;
59:
60: va_start(ap, fmt);
61: vfprintf(stderr, fmt, ap);
62: va_end(ap);
63: }
1.1.1.2 root 64:
65: #if defined(TARGET_I386)
66: int cpu_get_pic_interrupt(CPUState *env)
67: {
68: return -1;
69: }
70: #endif
71:
72: /* These are no-ops because we are not threadsafe. */
73: static inline void cpu_exec_start(CPUState *env)
74: {
75: }
76:
77: static inline void cpu_exec_end(CPUState *env)
78: {
79: }
80:
81: static inline void start_exclusive(void)
82: {
83: }
84:
85: static inline void end_exclusive(void)
86: {
87: }
88:
89: void fork_start(void)
90: {
91: }
92:
93: void fork_end(int child)
94: {
95: if (child) {
96: gdbserver_fork(thread_env);
97: }
98: }
99:
100: void cpu_list_lock(void)
101: {
102: }
103:
104: void cpu_list_unlock(void)
105: {
106: }
107:
108: #ifdef TARGET_I386
109: /***********************************************************/
110: /* CPUX86 core interface */
111:
112: void cpu_smm_update(CPUState *env)
113: {
114: }
115:
116: uint64_t cpu_get_tsc(CPUX86State *env)
117: {
118: return cpu_get_real_ticks();
119: }
120:
121: static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
122: int flags)
123: {
124: unsigned int e1, e2;
125: uint32_t *p;
126: e1 = (addr << 16) | (limit & 0xffff);
127: e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
128: e2 |= flags;
129: p = ptr;
130: p[0] = tswap32(e1);
131: p[1] = tswap32(e2);
132: }
133:
134: static uint64_t *idt_table;
135: #ifdef TARGET_X86_64
136: static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
137: uint64_t addr, unsigned int sel)
138: {
139: uint32_t *p, e1, e2;
140: e1 = (addr & 0xffff) | (sel << 16);
141: e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
142: p = ptr;
143: p[0] = tswap32(e1);
144: p[1] = tswap32(e2);
145: p[2] = tswap32(addr >> 32);
146: p[3] = 0;
147: }
148: /* only dpl matters as we do only user space emulation */
149: static void set_idt(int n, unsigned int dpl)
150: {
151: set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
152: }
153: #else
154: static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
155: uint32_t addr, unsigned int sel)
156: {
157: uint32_t *p, e1, e2;
158: e1 = (addr & 0xffff) | (sel << 16);
159: e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
160: p = ptr;
161: p[0] = tswap32(e1);
162: p[1] = tswap32(e2);
163: }
164:
165: /* only dpl matters as we do only user space emulation */
166: static void set_idt(int n, unsigned int dpl)
167: {
168: set_gate(idt_table + n, 0, dpl, 0, 0);
169: }
170: #endif
171:
1.1.1.3 root 172: void cpu_loop(CPUX86State *env)
1.1.1.2 root 173: {
174: int trapnr;
175: abi_ulong pc;
176: //target_siginfo_t info;
177:
178: for(;;) {
179: trapnr = cpu_x86_exec(env);
180: switch(trapnr) {
181: case 0x80:
182: /* syscall from int $0x80 */
1.1.1.3 root 183: if (bsd_type == target_freebsd) {
184: abi_ulong params = (abi_ulong) env->regs[R_ESP] +
185: sizeof(int32_t);
186: int32_t syscall_nr = env->regs[R_EAX];
187: int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8;
188:
189: if (syscall_nr == TARGET_FREEBSD_NR_syscall) {
190: get_user_s32(syscall_nr, params);
191: params += sizeof(int32_t);
192: } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) {
193: get_user_s32(syscall_nr, params);
194: params += sizeof(int64_t);
195: }
196: get_user_s32(arg1, params);
197: params += sizeof(int32_t);
198: get_user_s32(arg2, params);
199: params += sizeof(int32_t);
200: get_user_s32(arg3, params);
201: params += sizeof(int32_t);
202: get_user_s32(arg4, params);
203: params += sizeof(int32_t);
204: get_user_s32(arg5, params);
205: params += sizeof(int32_t);
206: get_user_s32(arg6, params);
207: params += sizeof(int32_t);
208: get_user_s32(arg7, params);
209: params += sizeof(int32_t);
210: get_user_s32(arg8, params);
211: env->regs[R_EAX] = do_freebsd_syscall(env,
212: syscall_nr,
213: arg1,
214: arg2,
215: arg3,
216: arg4,
217: arg5,
218: arg6,
219: arg7,
220: arg8);
221: } else { //if (bsd_type == target_openbsd)
222: env->regs[R_EAX] = do_openbsd_syscall(env,
223: env->regs[R_EAX],
224: env->regs[R_EBX],
225: env->regs[R_ECX],
226: env->regs[R_EDX],
227: env->regs[R_ESI],
228: env->regs[R_EDI],
229: env->regs[R_EBP]);
230: }
231: if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) {
232: env->regs[R_EAX] = -env->regs[R_EAX];
233: env->eflags |= CC_C;
234: } else {
235: env->eflags &= ~CC_C;
236: }
1.1.1.2 root 237: break;
238: #ifndef TARGET_ABI32
239: case EXCP_SYSCALL:
1.1.1.6 ! root 240: /* syscall from syscall instruction */
1.1.1.3 root 241: if (bsd_type == target_freebsd)
242: env->regs[R_EAX] = do_freebsd_syscall(env,
243: env->regs[R_EAX],
244: env->regs[R_EDI],
245: env->regs[R_ESI],
246: env->regs[R_EDX],
247: env->regs[R_ECX],
248: env->regs[8],
249: env->regs[9], 0, 0);
250: else { //if (bsd_type == target_openbsd)
251: env->regs[R_EAX] = do_openbsd_syscall(env,
252: env->regs[R_EAX],
253: env->regs[R_EDI],
254: env->regs[R_ESI],
255: env->regs[R_EDX],
256: env->regs[10],
257: env->regs[8],
258: env->regs[9]);
259: }
1.1.1.2 root 260: env->eip = env->exception_next_eip;
1.1.1.3 root 261: if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) {
262: env->regs[R_EAX] = -env->regs[R_EAX];
263: env->eflags |= CC_C;
264: } else {
265: env->eflags &= ~CC_C;
266: }
1.1.1.2 root 267: break;
268: #endif
269: #if 0
270: case EXCP0B_NOSEG:
271: case EXCP0C_STACK:
272: info.si_signo = SIGBUS;
273: info.si_errno = 0;
274: info.si_code = TARGET_SI_KERNEL;
275: info._sifields._sigfault._addr = 0;
276: queue_signal(env, info.si_signo, &info);
277: break;
278: case EXCP0D_GPF:
279: /* XXX: potential problem if ABI32 */
280: #ifndef TARGET_X86_64
281: if (env->eflags & VM_MASK) {
282: handle_vm86_fault(env);
283: } else
284: #endif
285: {
286: info.si_signo = SIGSEGV;
287: info.si_errno = 0;
288: info.si_code = TARGET_SI_KERNEL;
289: info._sifields._sigfault._addr = 0;
290: queue_signal(env, info.si_signo, &info);
291: }
292: break;
293: case EXCP0E_PAGE:
294: info.si_signo = SIGSEGV;
295: info.si_errno = 0;
296: if (!(env->error_code & 1))
297: info.si_code = TARGET_SEGV_MAPERR;
298: else
299: info.si_code = TARGET_SEGV_ACCERR;
300: info._sifields._sigfault._addr = env->cr[2];
301: queue_signal(env, info.si_signo, &info);
302: break;
303: case EXCP00_DIVZ:
304: #ifndef TARGET_X86_64
305: if (env->eflags & VM_MASK) {
306: handle_vm86_trap(env, trapnr);
307: } else
308: #endif
309: {
310: /* division by zero */
311: info.si_signo = SIGFPE;
312: info.si_errno = 0;
313: info.si_code = TARGET_FPE_INTDIV;
314: info._sifields._sigfault._addr = env->eip;
315: queue_signal(env, info.si_signo, &info);
316: }
317: break;
318: case EXCP01_DB:
319: case EXCP03_INT3:
320: #ifndef TARGET_X86_64
321: if (env->eflags & VM_MASK) {
322: handle_vm86_trap(env, trapnr);
323: } else
324: #endif
325: {
326: info.si_signo = SIGTRAP;
327: info.si_errno = 0;
328: if (trapnr == EXCP01_DB) {
329: info.si_code = TARGET_TRAP_BRKPT;
330: info._sifields._sigfault._addr = env->eip;
331: } else {
332: info.si_code = TARGET_SI_KERNEL;
333: info._sifields._sigfault._addr = 0;
334: }
335: queue_signal(env, info.si_signo, &info);
336: }
337: break;
338: case EXCP04_INTO:
339: case EXCP05_BOUND:
340: #ifndef TARGET_X86_64
341: if (env->eflags & VM_MASK) {
342: handle_vm86_trap(env, trapnr);
343: } else
344: #endif
345: {
346: info.si_signo = SIGSEGV;
347: info.si_errno = 0;
348: info.si_code = TARGET_SI_KERNEL;
349: info._sifields._sigfault._addr = 0;
350: queue_signal(env, info.si_signo, &info);
351: }
352: break;
353: case EXCP06_ILLOP:
354: info.si_signo = SIGILL;
355: info.si_errno = 0;
356: info.si_code = TARGET_ILL_ILLOPN;
357: info._sifields._sigfault._addr = env->eip;
358: queue_signal(env, info.si_signo, &info);
359: break;
360: #endif
361: case EXCP_INTERRUPT:
362: /* just indicate that signals should be handled asap */
363: break;
364: #if 0
365: case EXCP_DEBUG:
366: {
367: int sig;
368:
369: sig = gdb_handlesig (env, TARGET_SIGTRAP);
370: if (sig)
371: {
372: info.si_signo = sig;
373: info.si_errno = 0;
374: info.si_code = TARGET_TRAP_BRKPT;
375: queue_signal(env, info.si_signo, &info);
376: }
377: }
378: break;
379: #endif
380: default:
381: pc = env->segs[R_CS].base + env->eip;
382: fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
383: (long)pc, trapnr);
384: abort();
385: }
386: process_pending_signals(env);
387: }
388: }
389: #endif
390:
1.1 root 391: #ifdef TARGET_SPARC
392: #define SPARC64_STACK_BIAS 2047
393:
394: //#define DEBUG_WIN
395: /* WARNING: dealing with register windows _is_ complicated. More info
396: can be found at http://www.sics.se/~psm/sparcstack.html */
397: static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
398: {
399: index = (index + cwp * 16) % (16 * env->nwindows);
400: /* wrap handling : if cwp is on the last window, then we use the
401: registers 'after' the end */
402: if (index < 8 && env->cwp == env->nwindows - 1)
403: index += 16 * env->nwindows;
404: return index;
405: }
406:
407: /* save the register window 'cwp1' */
408: static inline void save_window_offset(CPUSPARCState *env, int cwp1)
409: {
410: unsigned int i;
411: abi_ulong sp_ptr;
412:
413: sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
414: #ifdef TARGET_SPARC64
415: if (sp_ptr & 3)
416: sp_ptr += SPARC64_STACK_BIAS;
417: #endif
418: #if defined(DEBUG_WIN)
419: printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
420: sp_ptr, cwp1);
421: #endif
422: for(i = 0; i < 16; i++) {
423: /* FIXME - what to do if put_user() fails? */
424: put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
425: sp_ptr += sizeof(abi_ulong);
426: }
427: }
428:
429: static void save_window(CPUSPARCState *env)
430: {
431: #ifndef TARGET_SPARC64
432: unsigned int new_wim;
433: new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
434: ((1LL << env->nwindows) - 1);
435: save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
436: env->wim = new_wim;
437: #else
438: save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
439: env->cansave++;
440: env->canrestore--;
441: #endif
442: }
443:
444: static void restore_window(CPUSPARCState *env)
445: {
446: #ifndef TARGET_SPARC64
447: unsigned int new_wim;
448: #endif
449: unsigned int i, cwp1;
450: abi_ulong sp_ptr;
451:
452: #ifndef TARGET_SPARC64
453: new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
454: ((1LL << env->nwindows) - 1);
455: #endif
456:
457: /* restore the invalid window */
458: cwp1 = cpu_cwp_inc(env, env->cwp + 1);
459: sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
460: #ifdef TARGET_SPARC64
461: if (sp_ptr & 3)
462: sp_ptr += SPARC64_STACK_BIAS;
463: #endif
464: #if defined(DEBUG_WIN)
465: printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
466: sp_ptr, cwp1);
467: #endif
468: for(i = 0; i < 16; i++) {
469: /* FIXME - what to do if get_user() fails? */
470: get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
471: sp_ptr += sizeof(abi_ulong);
472: }
473: #ifdef TARGET_SPARC64
474: env->canrestore++;
475: if (env->cleanwin < env->nwindows - 1)
476: env->cleanwin++;
477: env->cansave--;
478: #else
479: env->wim = new_wim;
480: #endif
481: }
482:
483: static void flush_windows(CPUSPARCState *env)
484: {
485: int offset, cwp1;
486:
487: offset = 1;
488: for(;;) {
489: /* if restore would invoke restore_window(), then we can stop */
490: cwp1 = cpu_cwp_inc(env, env->cwp + offset);
491: #ifndef TARGET_SPARC64
492: if (env->wim & (1 << cwp1))
493: break;
494: #else
495: if (env->canrestore == 0)
496: break;
497: env->cansave++;
498: env->canrestore--;
499: #endif
500: save_window_offset(env, cwp1);
501: offset++;
502: }
503: cwp1 = cpu_cwp_inc(env, env->cwp + 1);
504: #ifndef TARGET_SPARC64
505: /* set wim so that restore will reload the registers */
506: env->wim = 1 << cwp1;
507: #endif
508: #if defined(DEBUG_WIN)
509: printf("flush_windows: nb=%d\n", offset - 1);
510: #endif
511: }
512:
1.1.1.3 root 513: void cpu_loop(CPUSPARCState *env)
1.1 root 514: {
515: int trapnr, ret, syscall_nr;
516: //target_siginfo_t info;
517:
518: while (1) {
519: trapnr = cpu_sparc_exec (env);
520:
521: switch (trapnr) {
522: #ifndef TARGET_SPARC64
523: case 0x80:
524: #else
1.1.1.3 root 525: /* FreeBSD uses 0x141 for syscalls too */
526: case 0x141:
527: if (bsd_type != target_freebsd)
528: goto badtrap;
1.1 root 529: case 0x100:
530: #endif
531: syscall_nr = env->gregs[1];
532: if (bsd_type == target_freebsd)
533: ret = do_freebsd_syscall(env, syscall_nr,
534: env->regwptr[0], env->regwptr[1],
535: env->regwptr[2], env->regwptr[3],
1.1.1.3 root 536: env->regwptr[4], env->regwptr[5], 0, 0);
1.1 root 537: else if (bsd_type == target_netbsd)
538: ret = do_netbsd_syscall(env, syscall_nr,
539: env->regwptr[0], env->regwptr[1],
540: env->regwptr[2], env->regwptr[3],
541: env->regwptr[4], env->regwptr[5]);
542: else { //if (bsd_type == target_openbsd)
543: #if defined(TARGET_SPARC64)
544: syscall_nr &= ~(TARGET_OPENBSD_SYSCALL_G7RFLAG |
545: TARGET_OPENBSD_SYSCALL_G2RFLAG);
546: #endif
547: ret = do_openbsd_syscall(env, syscall_nr,
548: env->regwptr[0], env->regwptr[1],
549: env->regwptr[2], env->regwptr[3],
550: env->regwptr[4], env->regwptr[5]);
551: }
552: if ((unsigned int)ret >= (unsigned int)(-515)) {
1.1.1.3 root 553: ret = -ret;
1.1 root 554: #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
555: env->xcc |= PSR_CARRY;
556: #else
557: env->psr |= PSR_CARRY;
558: #endif
559: } else {
560: #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
561: env->xcc &= ~PSR_CARRY;
562: #else
563: env->psr &= ~PSR_CARRY;
564: #endif
565: }
566: env->regwptr[0] = ret;
567: /* next instruction */
568: #if defined(TARGET_SPARC64)
569: if (bsd_type == target_openbsd &&
570: env->gregs[1] & TARGET_OPENBSD_SYSCALL_G2RFLAG) {
571: env->pc = env->gregs[2];
572: env->npc = env->pc + 4;
573: } else if (bsd_type == target_openbsd &&
574: env->gregs[1] & TARGET_OPENBSD_SYSCALL_G7RFLAG) {
575: env->pc = env->gregs[7];
576: env->npc = env->pc + 4;
577: } else {
578: env->pc = env->npc;
579: env->npc = env->npc + 4;
580: }
581: #else
582: env->pc = env->npc;
583: env->npc = env->npc + 4;
584: #endif
585: break;
586: case 0x83: /* flush windows */
587: #ifdef TARGET_ABI32
588: case 0x103:
589: #endif
590: flush_windows(env);
591: /* next instruction */
592: env->pc = env->npc;
593: env->npc = env->npc + 4;
594: break;
595: #ifndef TARGET_SPARC64
596: case TT_WIN_OVF: /* window overflow */
597: save_window(env);
598: break;
599: case TT_WIN_UNF: /* window underflow */
600: restore_window(env);
601: break;
602: case TT_TFAULT:
603: case TT_DFAULT:
604: #if 0
605: {
606: info.si_signo = SIGSEGV;
607: info.si_errno = 0;
608: /* XXX: check env->error_code */
609: info.si_code = TARGET_SEGV_MAPERR;
610: info._sifields._sigfault._addr = env->mmuregs[4];
611: queue_signal(env, info.si_signo, &info);
612: }
613: #endif
614: break;
615: #else
616: case TT_SPILL: /* window overflow */
617: save_window(env);
618: break;
619: case TT_FILL: /* window underflow */
620: restore_window(env);
621: break;
622: case TT_TFAULT:
623: case TT_DFAULT:
624: #if 0
625: {
626: info.si_signo = SIGSEGV;
627: info.si_errno = 0;
628: /* XXX: check env->error_code */
629: info.si_code = TARGET_SEGV_MAPERR;
630: if (trapnr == TT_DFAULT)
631: info._sifields._sigfault._addr = env->dmmuregs[4];
632: else
633: info._sifields._sigfault._addr = env->tsptr->tpc;
634: //queue_signal(env, info.si_signo, &info);
635: }
636: #endif
637: break;
638: #endif
639: case EXCP_INTERRUPT:
640: /* just indicate that signals should be handled asap */
641: break;
642: case EXCP_DEBUG:
643: {
644: int sig;
645:
646: sig = gdb_handlesig (env, TARGET_SIGTRAP);
647: #if 0
648: if (sig)
649: {
650: info.si_signo = sig;
651: info.si_errno = 0;
652: info.si_code = TARGET_TRAP_BRKPT;
653: //queue_signal(env, info.si_signo, &info);
654: }
655: #endif
656: }
657: break;
658: default:
1.1.1.3 root 659: #ifdef TARGET_SPARC64
660: badtrap:
661: #endif
1.1 root 662: printf ("Unhandled trap: 0x%x\n", trapnr);
663: cpu_dump_state(env, stderr, fprintf, 0);
664: exit (1);
665: }
666: process_pending_signals (env);
667: }
668: }
669:
670: #endif
671:
672: static void usage(void)
673: {
674: printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
675: "usage: qemu-" TARGET_ARCH " [options] program [arguments...]\n"
676: "BSD CPU emulator (compiled for %s emulation)\n"
677: "\n"
678: "Standard options:\n"
679: "-h print this help\n"
680: "-g port wait gdb connection to port\n"
681: "-L path set the elf interpreter prefix (default=%s)\n"
682: "-s size set the stack size in bytes (default=%ld)\n"
683: "-cpu model select CPU (-cpu ? for list)\n"
684: "-drop-ld-preload drop LD_PRELOAD for target process\n"
1.1.1.3 root 685: "-E var=value sets/modifies targets environment variable(s)\n"
686: "-U var unsets targets environment variable(s)\n"
687: #if defined(CONFIG_USE_GUEST_BASE)
688: "-B address set guest_base address to address\n"
689: #endif
1.1 root 690: "-bsd type select emulated BSD type FreeBSD/NetBSD/OpenBSD (default)\n"
691: "\n"
692: "Debug options:\n"
1.1.1.6 ! root 693: "-d options activate log (default logfile=%s)\n"
! 694: "-D logfile override default logfile location\n"
1.1 root 695: "-p pagesize set the host page size to 'pagesize'\n"
1.1.1.2 root 696: "-singlestep always run in singlestep mode\n"
1.1 root 697: "-strace log system calls\n"
698: "\n"
699: "Environment variables:\n"
700: "QEMU_STRACE Print system calls and arguments similar to the\n"
701: " 'strace' program. Enable by setting to any value.\n"
1.1.1.3 root 702: "You can use -E and -U options to set/unset environment variables\n"
703: "for target process. It is possible to provide several variables\n"
704: "by repeating the option. For example:\n"
705: " -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
706: "Note that if you provide several changes to single variable\n"
707: "last change will stay in effect.\n"
1.1 root 708: ,
709: TARGET_ARCH,
710: interp_prefix,
711: x86_stack_size,
712: DEBUG_LOGFILE);
713: exit(1);
714: }
715:
716: THREAD CPUState *thread_env;
717:
718: /* Assumes contents are already zeroed. */
719: void init_task_state(TaskState *ts)
720: {
721: int i;
722:
723: ts->used = 1;
724: ts->first_free = ts->sigqueue_table;
725: for (i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) {
726: ts->sigqueue_table[i].next = &ts->sigqueue_table[i + 1];
727: }
728: ts->sigqueue_table[i].next = NULL;
729: }
730:
731: int main(int argc, char **argv)
732: {
733: const char *filename;
734: const char *cpu_model;
1.1.1.6 ! root 735: const char *log_file = DEBUG_LOGFILE;
! 736: const char *log_mask = NULL;
1.1 root 737: struct target_pt_regs regs1, *regs = ®s1;
738: struct image_info info1, *info = &info1;
739: TaskState ts1, *ts = &ts1;
740: CPUState *env;
741: int optind;
742: const char *r;
743: int gdbstub_port = 0;
1.1.1.3 root 744: char **target_environ, **wrk;
745: envlist_t *envlist = NULL;
746: bsd_type = target_openbsd;
1.1 root 747:
748: if (argc <= 1)
749: usage();
750:
1.1.1.3 root 751: if ((envlist = envlist_create()) == NULL) {
752: (void) fprintf(stderr, "Unable to allocate envlist\n");
753: exit(1);
754: }
755:
756: /* add current environment into the list */
757: for (wrk = environ; *wrk != NULL; wrk++) {
758: (void) envlist_setenv(envlist, *wrk);
759: }
760:
1.1 root 761: cpu_model = NULL;
1.1.1.4 root 762: #if defined(cpudef_setup)
763: cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
764: #endif
765:
1.1 root 766: optind = 1;
767: for(;;) {
768: if (optind >= argc)
769: break;
770: r = argv[optind];
771: if (r[0] != '-')
772: break;
773: optind++;
774: r++;
775: if (!strcmp(r, "-")) {
776: break;
777: } else if (!strcmp(r, "d")) {
1.1.1.6 ! root 778: if (optind >= argc) {
! 779: break;
! 780: }
! 781: log_mask = argv[optind++];
! 782: } else if (!strcmp(r, "D")) {
! 783: if (optind >= argc) {
1.1 root 784: break;
785: }
1.1.1.6 ! root 786: log_file = argv[optind++];
1.1.1.3 root 787: } else if (!strcmp(r, "E")) {
788: r = argv[optind++];
789: if (envlist_setenv(envlist, r) != 0)
790: usage();
1.1.1.5 root 791: } else if (!strcmp(r, "ignore-environment")) {
792: envlist_free(envlist);
793: if ((envlist = envlist_create()) == NULL) {
794: (void) fprintf(stderr, "Unable to allocate envlist\n");
795: exit(1);
796: }
1.1.1.3 root 797: } else if (!strcmp(r, "U")) {
798: r = argv[optind++];
799: if (envlist_unsetenv(envlist, r) != 0)
800: usage();
1.1 root 801: } else if (!strcmp(r, "s")) {
802: r = argv[optind++];
803: x86_stack_size = strtol(r, (char **)&r, 0);
804: if (x86_stack_size <= 0)
805: usage();
806: if (*r == 'M')
807: x86_stack_size *= 1024 * 1024;
808: else if (*r == 'k' || *r == 'K')
809: x86_stack_size *= 1024;
810: } else if (!strcmp(r, "L")) {
811: interp_prefix = argv[optind++];
812: } else if (!strcmp(r, "p")) {
813: qemu_host_page_size = atoi(argv[optind++]);
814: if (qemu_host_page_size == 0 ||
815: (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
816: fprintf(stderr, "page size must be a power of two\n");
817: exit(1);
818: }
819: } else if (!strcmp(r, "g")) {
820: gdbstub_port = atoi(argv[optind++]);
821: } else if (!strcmp(r, "r")) {
822: qemu_uname_release = argv[optind++];
823: } else if (!strcmp(r, "cpu")) {
824: cpu_model = argv[optind++];
825: if (strcmp(cpu_model, "?") == 0) {
826: /* XXX: implement xxx_cpu_list for targets that still miss it */
827: #if defined(cpu_list)
828: cpu_list(stdout, &fprintf);
829: #endif
830: exit(1);
831: }
1.1.1.3 root 832: #if defined(CONFIG_USE_GUEST_BASE)
833: } else if (!strcmp(r, "B")) {
834: guest_base = strtol(argv[optind++], NULL, 0);
835: have_guest_base = 1;
836: #endif
1.1 root 837: } else if (!strcmp(r, "drop-ld-preload")) {
1.1.1.3 root 838: (void) envlist_unsetenv(envlist, "LD_PRELOAD");
1.1 root 839: } else if (!strcmp(r, "bsd")) {
840: if (!strcasecmp(argv[optind], "freebsd")) {
841: bsd_type = target_freebsd;
842: } else if (!strcasecmp(argv[optind], "netbsd")) {
843: bsd_type = target_netbsd;
844: } else if (!strcasecmp(argv[optind], "openbsd")) {
845: bsd_type = target_openbsd;
846: } else {
847: usage();
848: }
849: optind++;
1.1.1.2 root 850: } else if (!strcmp(r, "singlestep")) {
851: singlestep = 1;
1.1 root 852: } else if (!strcmp(r, "strace")) {
853: do_strace = 1;
854: } else
855: {
856: usage();
857: }
858: }
1.1.1.6 ! root 859:
! 860: /* init debug */
! 861: cpu_set_log_filename(log_file);
! 862: if (log_mask) {
! 863: int mask;
! 864: const CPULogItem *item;
! 865:
! 866: mask = cpu_str_to_log_mask(log_mask);
! 867: if (!mask) {
! 868: printf("Log items (comma separated):\n");
! 869: for (item = cpu_log_items; item->mask != 0; item++) {
! 870: printf("%-10s %s\n", item->name, item->help);
! 871: }
! 872: exit(1);
! 873: }
! 874: cpu_set_log(mask);
! 875: }
! 876:
! 877: if (optind >= argc) {
1.1 root 878: usage();
1.1.1.6 ! root 879: }
1.1 root 880: filename = argv[optind];
881:
882: /* Zero out regs */
883: memset(regs, 0, sizeof(struct target_pt_regs));
884:
885: /* Zero out image_info */
886: memset(info, 0, sizeof(struct image_info));
887:
888: /* Scan interp_prefix dir for replacement files. */
889: init_paths(interp_prefix);
890:
891: if (cpu_model == NULL) {
1.1.1.2 root 892: #if defined(TARGET_I386)
893: #ifdef TARGET_X86_64
894: cpu_model = "qemu64";
895: #else
896: cpu_model = "qemu32";
897: #endif
898: #elif defined(TARGET_SPARC)
1.1 root 899: #ifdef TARGET_SPARC64
900: cpu_model = "TI UltraSparc II";
901: #else
902: cpu_model = "Fujitsu MB86904";
903: #endif
904: #else
905: cpu_model = "any";
906: #endif
907: }
908: cpu_exec_init_all(0);
909: /* NOTE: we need to init the CPU at this stage to get
910: qemu_host_page_size */
911: env = cpu_init(cpu_model);
912: if (!env) {
913: fprintf(stderr, "Unable to find CPU definition\n");
914: exit(1);
915: }
1.1.1.3 root 916: #if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
917: cpu_reset(env);
918: #endif
1.1 root 919: thread_env = env;
920:
921: if (getenv("QEMU_STRACE")) {
922: do_strace = 1;
923: }
924:
1.1.1.3 root 925: target_environ = envlist_to_environ(envlist, NULL);
926: envlist_free(envlist);
927:
928: #if defined(CONFIG_USE_GUEST_BASE)
929: /*
930: * Now that page sizes are configured in cpu_init() we can do
931: * proper page alignment for guest_base.
932: */
933: guest_base = HOST_PAGE_ALIGN(guest_base);
934:
935: /*
936: * Read in mmap_min_addr kernel parameter. This value is used
937: * When loading the ELF image to determine whether guest_base
938: * is needed.
939: *
940: * When user has explicitly set the quest base, we skip this
941: * test.
942: */
943: if (!have_guest_base) {
944: FILE *fp;
945:
946: if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
947: unsigned long tmp;
948: if (fscanf(fp, "%lu", &tmp) == 1) {
949: mmap_min_addr = tmp;
950: qemu_log("host mmap_min_addr=0x%lx\n", mmap_min_addr);
951: }
952: fclose(fp);
953: }
1.1 root 954: }
1.1.1.3 root 955: #endif /* CONFIG_USE_GUEST_BASE */
1.1 root 956:
957: if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) {
958: printf("Error loading %s\n", filename);
959: _exit(1);
960: }
961:
962: for (wrk = target_environ; *wrk; wrk++) {
963: free(*wrk);
964: }
965:
966: free(target_environ);
967:
968: if (qemu_log_enabled()) {
1.1.1.3 root 969: #if defined(CONFIG_USE_GUEST_BASE)
970: qemu_log("guest_base 0x%lx\n", guest_base);
971: #endif
1.1 root 972: log_page_dump();
973:
974: qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
975: qemu_log("end_code 0x" TARGET_ABI_FMT_lx "\n", info->end_code);
976: qemu_log("start_code 0x" TARGET_ABI_FMT_lx "\n",
977: info->start_code);
978: qemu_log("start_data 0x" TARGET_ABI_FMT_lx "\n",
979: info->start_data);
980: qemu_log("end_data 0x" TARGET_ABI_FMT_lx "\n", info->end_data);
981: qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n",
982: info->start_stack);
983: qemu_log("brk 0x" TARGET_ABI_FMT_lx "\n", info->brk);
984: qemu_log("entry 0x" TARGET_ABI_FMT_lx "\n", info->entry);
985: }
986:
987: target_set_brk(info->brk);
988: syscall_init();
989: signal_init();
990:
1.1.1.4 root 991: #if defined(CONFIG_USE_GUEST_BASE)
992: /* Now that we've loaded the binary, GUEST_BASE is fixed. Delay
993: generating the prologue until now so that the prologue can take
994: the real value of GUEST_BASE into account. */
995: tcg_prologue_init(&tcg_ctx);
996: #endif
997:
1.1 root 998: /* build Task State */
999: memset(ts, 0, sizeof(TaskState));
1000: init_task_state(ts);
1001: ts->info = info;
1002: env->opaque = ts;
1003:
1.1.1.2 root 1004: #if defined(TARGET_I386)
1005: cpu_x86_set_cpl(env, 3);
1006:
1007: env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
1008: env->hflags |= HF_PE_MASK;
1009: if (env->cpuid_features & CPUID_SSE) {
1010: env->cr[4] |= CR4_OSFXSR_MASK;
1011: env->hflags |= HF_OSFXSR_MASK;
1012: }
1013: #ifndef TARGET_ABI32
1014: /* enable 64 bit mode if possible */
1015: if (!(env->cpuid_ext2_features & CPUID_EXT2_LM)) {
1016: fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n");
1017: exit(1);
1018: }
1019: env->cr[4] |= CR4_PAE_MASK;
1020: env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
1021: env->hflags |= HF_LMA_MASK;
1022: #endif
1023:
1024: /* flags setup : we activate the IRQs by default as in user mode */
1025: env->eflags |= IF_MASK;
1026:
1027: /* linux register setup */
1028: #ifndef TARGET_ABI32
1029: env->regs[R_EAX] = regs->rax;
1030: env->regs[R_EBX] = regs->rbx;
1031: env->regs[R_ECX] = regs->rcx;
1032: env->regs[R_EDX] = regs->rdx;
1033: env->regs[R_ESI] = regs->rsi;
1034: env->regs[R_EDI] = regs->rdi;
1035: env->regs[R_EBP] = regs->rbp;
1036: env->regs[R_ESP] = regs->rsp;
1037: env->eip = regs->rip;
1038: #else
1039: env->regs[R_EAX] = regs->eax;
1040: env->regs[R_EBX] = regs->ebx;
1041: env->regs[R_ECX] = regs->ecx;
1042: env->regs[R_EDX] = regs->edx;
1043: env->regs[R_ESI] = regs->esi;
1044: env->regs[R_EDI] = regs->edi;
1045: env->regs[R_EBP] = regs->ebp;
1046: env->regs[R_ESP] = regs->esp;
1047: env->eip = regs->eip;
1048: #endif
1049:
1050: /* linux interrupt setup */
1051: #ifndef TARGET_ABI32
1052: env->idt.limit = 511;
1053: #else
1054: env->idt.limit = 255;
1055: #endif
1056: env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
1057: PROT_READ|PROT_WRITE,
1058: MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
1059: idt_table = g2h(env->idt.base);
1060: set_idt(0, 0);
1061: set_idt(1, 0);
1062: set_idt(2, 0);
1063: set_idt(3, 3);
1064: set_idt(4, 3);
1065: set_idt(5, 0);
1066: set_idt(6, 0);
1067: set_idt(7, 0);
1068: set_idt(8, 0);
1069: set_idt(9, 0);
1070: set_idt(10, 0);
1071: set_idt(11, 0);
1072: set_idt(12, 0);
1073: set_idt(13, 0);
1074: set_idt(14, 0);
1075: set_idt(15, 0);
1076: set_idt(16, 0);
1077: set_idt(17, 0);
1078: set_idt(18, 0);
1079: set_idt(19, 0);
1080: set_idt(0x80, 3);
1081:
1082: /* linux segment setup */
1083: {
1084: uint64_t *gdt_table;
1085: env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
1086: PROT_READ|PROT_WRITE,
1087: MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
1088: env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
1089: gdt_table = g2h(env->gdt.base);
1090: #ifdef TARGET_ABI32
1091: write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
1092: DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
1093: (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
1094: #else
1095: /* 64 bit code segment */
1096: write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
1097: DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
1098: DESC_L_MASK |
1099: (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
1100: #endif
1101: write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
1102: DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
1103: (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
1104: }
1105:
1106: cpu_x86_load_seg(env, R_CS, __USER_CS);
1107: cpu_x86_load_seg(env, R_SS, __USER_DS);
1108: #ifdef TARGET_ABI32
1109: cpu_x86_load_seg(env, R_DS, __USER_DS);
1110: cpu_x86_load_seg(env, R_ES, __USER_DS);
1111: cpu_x86_load_seg(env, R_FS, __USER_DS);
1112: cpu_x86_load_seg(env, R_GS, __USER_DS);
1113: /* This hack makes Wine work... */
1114: env->segs[R_FS].selector = 0;
1115: #else
1116: cpu_x86_load_seg(env, R_DS, 0);
1117: cpu_x86_load_seg(env, R_ES, 0);
1118: cpu_x86_load_seg(env, R_FS, 0);
1119: cpu_x86_load_seg(env, R_GS, 0);
1120: #endif
1121: #elif defined(TARGET_SPARC)
1.1 root 1122: {
1123: int i;
1124: env->pc = regs->pc;
1125: env->npc = regs->npc;
1126: env->y = regs->y;
1127: for(i = 0; i < 8; i++)
1128: env->gregs[i] = regs->u_regs[i];
1129: for(i = 0; i < 8; i++)
1130: env->regwptr[i] = regs->u_regs[i + 8];
1131: }
1132: #else
1133: #error unsupported target CPU
1134: #endif
1135:
1136: if (gdbstub_port) {
1137: gdbserver_start (gdbstub_port);
1138: gdb_handlesig(env, 0);
1139: }
1.1.1.3 root 1140: cpu_loop(env);
1.1 root 1141: /* never exits */
1142: return 0;
1143: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.