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