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