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_log_needs_buffers(); 853 qemu_set_log_filename(log_file); 854 if (log_mask) { 855 int mask; 856 857 mask = qemu_str_to_log_mask(log_mask); 858 if (!mask) { 859 qemu_print_log_usage(stdout); 860 exit(1); 861 } 862 qemu_set_log(mask); 863 } 864 865 if (optind >= argc) { 866 usage(); 867 } 868 filename = argv[optind]; 869 870 /* Zero out regs */ 871 memset(regs, 0, sizeof(struct target_pt_regs)); 872 873 /* Zero out image_info */ 874 memset(info, 0, sizeof(struct image_info)); 875 876 /* Scan interp_prefix dir for replacement files. */ 877 init_paths(interp_prefix); 878 879 if (cpu_model == NULL) { 880 #if defined(TARGET_I386) 881 #ifdef TARGET_X86_64 882 cpu_model = "qemu64"; 883 #else 884 cpu_model = "qemu32"; 885 #endif 886 #elif defined(TARGET_SPARC) 887 #ifdef TARGET_SPARC64 888 cpu_model = "TI UltraSparc II"; 889 #else 890 cpu_model = "Fujitsu MB86904"; 891 #endif 892 #else 893 cpu_model = "any"; 894 #endif 895 } 896 tcg_exec_init(0); 897 /* NOTE: we need to init the CPU at this stage to get 898 qemu_host_page_size */ 899 cpu = cpu_init(cpu_model); 900 if (!cpu) { 901 fprintf(stderr, "Unable to find CPU definition\n"); 902 exit(1); 903 } 904 env = cpu->env_ptr; 905 #if defined(TARGET_SPARC) || defined(TARGET_PPC) 906 cpu_reset(cpu); 907 #endif 908 thread_cpu = cpu; 909 910 if (getenv("QEMU_STRACE")) { 911 do_strace = 1; 912 } 913 914 target_environ = envlist_to_environ(envlist, NULL); 915 envlist_free(envlist); 916 917 /* 918 * Now that page sizes are configured in cpu_init() we can do 919 * proper page alignment for guest_base. 920 */ 921 guest_base = HOST_PAGE_ALIGN(guest_base); 922 923 /* 924 * Read in mmap_min_addr kernel parameter. This value is used 925 * When loading the ELF image to determine whether guest_base 926 * is needed. 927 * 928 * When user has explicitly set the quest base, we skip this 929 * test. 930 */ 931 if (!have_guest_base) { 932 FILE *fp; 933 934 if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) { 935 unsigned long tmp; 936 if (fscanf(fp, "%lu", &tmp) == 1) { 937 mmap_min_addr = tmp; 938 qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n", mmap_min_addr); 939 } 940 fclose(fp); 941 } 942 } 943 944 if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) { 945 printf("Error loading %s\n", filename); 946 _exit(1); 947 } 948 949 for (wrk = target_environ; *wrk; wrk++) { 950 free(*wrk); 951 } 952 953 free(target_environ); 954 955 if (qemu_loglevel_mask(CPU_LOG_PAGE)) { 956 qemu_log("guest_base 0x%lx\n", guest_base); 957 log_page_dump(); 958 959 qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk); 960 qemu_log("end_code 0x" TARGET_ABI_FMT_lx "\n", info->end_code); 961 qemu_log("start_code 0x" TARGET_ABI_FMT_lx "\n", 962 info->start_code); 963 qemu_log("start_data 0x" TARGET_ABI_FMT_lx "\n", 964 info->start_data); 965 qemu_log("end_data 0x" TARGET_ABI_FMT_lx "\n", info->end_data); 966 qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n", 967 info->start_stack); 968 qemu_log("brk 0x" TARGET_ABI_FMT_lx "\n", info->brk); 969 qemu_log("entry 0x" TARGET_ABI_FMT_lx "\n", info->entry); 970 } 971 972 target_set_brk(info->brk); 973 syscall_init(); 974 signal_init(); 975 976 /* Now that we've loaded the binary, GUEST_BASE is fixed. Delay 977 generating the prologue until now so that the prologue can take 978 the real value of GUEST_BASE into account. */ 979 tcg_prologue_init(&tcg_ctx); 980 981 /* build Task State */ 982 memset(ts, 0, sizeof(TaskState)); 983 init_task_state(ts); 984 ts->info = info; 985 cpu->opaque = ts; 986 987 #if defined(TARGET_I386) 988 env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK; 989 env->hflags |= HF_PE_MASK | HF_CPL_MASK; 990 if (env->features[FEAT_1_EDX] & CPUID_SSE) { 991 env->cr[4] |= CR4_OSFXSR_MASK; 992 env->hflags |= HF_OSFXSR_MASK; 993 } 994 #ifndef TARGET_ABI32 995 /* enable 64 bit mode if possible */ 996 if (!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) { 997 fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n"); 998 exit(1); 999 } 1000 env->cr[4] |= CR4_PAE_MASK; 1001 env->efer |= MSR_EFER_LMA | MSR_EFER_LME; 1002 env->hflags |= HF_LMA_MASK; 1003 #endif 1004 1005 /* flags setup : we activate the IRQs by default as in user mode */ 1006 env->eflags |= IF_MASK; 1007 1008 /* linux register setup */ 1009 #ifndef TARGET_ABI32 1010 env->regs[R_EAX] = regs->rax; 1011 env->regs[R_EBX] = regs->rbx; 1012 env->regs[R_ECX] = regs->rcx; 1013 env->regs[R_EDX] = regs->rdx; 1014 env->regs[R_ESI] = regs->rsi; 1015 env->regs[R_EDI] = regs->rdi; 1016 env->regs[R_EBP] = regs->rbp; 1017 env->regs[R_ESP] = regs->rsp; 1018 env->eip = regs->rip; 1019 #else 1020 env->regs[R_EAX] = regs->eax; 1021 env->regs[R_EBX] = regs->ebx; 1022 env->regs[R_ECX] = regs->ecx; 1023 env->regs[R_EDX] = regs->edx; 1024 env->regs[R_ESI] = regs->esi; 1025 env->regs[R_EDI] = regs->edi; 1026 env->regs[R_EBP] = regs->ebp; 1027 env->regs[R_ESP] = regs->esp; 1028 env->eip = regs->eip; 1029 #endif 1030 1031 /* linux interrupt setup */ 1032 #ifndef TARGET_ABI32 1033 env->idt.limit = 511; 1034 #else 1035 env->idt.limit = 255; 1036 #endif 1037 env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1), 1038 PROT_READ|PROT_WRITE, 1039 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); 1040 idt_table = g2h(env->idt.base); 1041 set_idt(0, 0); 1042 set_idt(1, 0); 1043 set_idt(2, 0); 1044 set_idt(3, 3); 1045 set_idt(4, 3); 1046 set_idt(5, 0); 1047 set_idt(6, 0); 1048 set_idt(7, 0); 1049 set_idt(8, 0); 1050 set_idt(9, 0); 1051 set_idt(10, 0); 1052 set_idt(11, 0); 1053 set_idt(12, 0); 1054 set_idt(13, 0); 1055 set_idt(14, 0); 1056 set_idt(15, 0); 1057 set_idt(16, 0); 1058 set_idt(17, 0); 1059 set_idt(18, 0); 1060 set_idt(19, 0); 1061 set_idt(0x80, 3); 1062 1063 /* linux segment setup */ 1064 { 1065 uint64_t *gdt_table; 1066 env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES, 1067 PROT_READ|PROT_WRITE, 1068 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); 1069 env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1; 1070 gdt_table = g2h(env->gdt.base); 1071 #ifdef TARGET_ABI32 1072 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff, 1073 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | 1074 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT)); 1075 #else 1076 /* 64 bit code segment */ 1077 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff, 1078 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | 1079 DESC_L_MASK | 1080 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT)); 1081 #endif 1082 write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff, 1083 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | 1084 (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT)); 1085 } 1086 1087 cpu_x86_load_seg(env, R_CS, __USER_CS); 1088 cpu_x86_load_seg(env, R_SS, __USER_DS); 1089 #ifdef TARGET_ABI32 1090 cpu_x86_load_seg(env, R_DS, __USER_DS); 1091 cpu_x86_load_seg(env, R_ES, __USER_DS); 1092 cpu_x86_load_seg(env, R_FS, __USER_DS); 1093 cpu_x86_load_seg(env, R_GS, __USER_DS); 1094 /* This hack makes Wine work... */ 1095 env->segs[R_FS].selector = 0; 1096 #else 1097 cpu_x86_load_seg(env, R_DS, 0); 1098 cpu_x86_load_seg(env, R_ES, 0); 1099 cpu_x86_load_seg(env, R_FS, 0); 1100 cpu_x86_load_seg(env, R_GS, 0); 1101 #endif 1102 #elif defined(TARGET_SPARC) 1103 { 1104 int i; 1105 env->pc = regs->pc; 1106 env->npc = regs->npc; 1107 env->y = regs->y; 1108 for(i = 0; i < 8; i++) 1109 env->gregs[i] = regs->u_regs[i]; 1110 for(i = 0; i < 8; i++) 1111 env->regwptr[i] = regs->u_regs[i + 8]; 1112 } 1113 #else 1114 #error unsupported target CPU 1115 #endif 1116 1117 if (gdbstub_port) { 1118 gdbserver_start (gdbstub_port); 1119 gdb_handlesig(cpu, 0); 1120 } 1121 cpu_loop(env); 1122 /* never exits */ 1123 return 0; 1124 } 1125