1 /* 2 * qemu user main 3 * 4 * Copyright (c) 2003 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, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20 #include <stdlib.h> 21 #include <stdio.h> 22 #include <stdarg.h> 23 #include <string.h> 24 #include <errno.h> 25 #include <unistd.h> 26 27 #include "qemu.h" 28 29 #define DEBUG_LOGFILE "/tmp/qemu.log" 30 31 #ifdef __APPLE__ 32 #include <crt_externs.h> 33 # define environ (*_NSGetEnviron()) 34 #endif 35 36 static const char *interp_prefix = CONFIG_QEMU_PREFIX; 37 38 #if defined(__i386__) && !defined(CONFIG_STATIC) 39 /* Force usage of an ELF interpreter even if it is an ELF shared 40 object ! */ 41 const char interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2"; 42 #endif 43 44 /* for recent libc, we add these dummy symbols which are not declared 45 when generating a linked object (bug in ld ?) */ 46 #if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined(CONFIG_STATIC) 47 long __preinit_array_start[0]; 48 long __preinit_array_end[0]; 49 long __init_array_start[0]; 50 long __init_array_end[0]; 51 long __fini_array_start[0]; 52 long __fini_array_end[0]; 53 #endif 54 55 /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so 56 we allocate a bigger stack. Need a better solution, for example 57 by remapping the process stack directly at the right place */ 58 unsigned long x86_stack_size = 512 * 1024; 59 60 void gemu_log(const char *fmt, ...) 61 { 62 va_list ap; 63 64 va_start(ap, fmt); 65 vfprintf(stderr, fmt, ap); 66 va_end(ap); 67 } 68 69 void cpu_outb(CPUState *env, int addr, int val) 70 { 71 fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val); 72 } 73 74 void cpu_outw(CPUState *env, int addr, int val) 75 { 76 fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val); 77 } 78 79 void cpu_outl(CPUState *env, int addr, int val) 80 { 81 fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val); 82 } 83 84 int cpu_inb(CPUState *env, int addr) 85 { 86 fprintf(stderr, "inb: port=0x%04x\n", addr); 87 return 0; 88 } 89 90 int cpu_inw(CPUState *env, int addr) 91 { 92 fprintf(stderr, "inw: port=0x%04x\n", addr); 93 return 0; 94 } 95 96 int cpu_inl(CPUState *env, int addr) 97 { 98 fprintf(stderr, "inl: port=0x%04x\n", addr); 99 return 0; 100 } 101 102 int cpu_get_pic_interrupt(CPUState *env) 103 { 104 return -1; 105 } 106 107 /* timers for rdtsc */ 108 109 #if defined(__i386__) 110 111 int64_t cpu_get_real_ticks(void) 112 { 113 int64_t val; 114 asm volatile ("rdtsc" : "=A" (val)); 115 return val; 116 } 117 118 #elif defined(__x86_64__) 119 120 int64_t cpu_get_real_ticks(void) 121 { 122 uint32_t low,high; 123 int64_t val; 124 asm volatile("rdtsc" : "=a" (low), "=d" (high)); 125 val = high; 126 val <<= 32; 127 val |= low; 128 return val; 129 } 130 131 #else 132 133 static uint64_t emu_time; 134 135 int64_t cpu_get_real_ticks(void) 136 { 137 return emu_time++; 138 } 139 140 #endif 141 142 #ifdef TARGET_I386 143 /***********************************************************/ 144 /* CPUX86 core interface */ 145 146 uint64_t cpu_get_tsc(CPUX86State *env) 147 { 148 return cpu_get_real_ticks(); 149 } 150 151 static void write_dt(void *ptr, unsigned long addr, unsigned long limit, 152 int flags) 153 { 154 unsigned int e1, e2; 155 e1 = (addr << 16) | (limit & 0xffff); 156 e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000); 157 e2 |= flags; 158 stl((uint8_t *)ptr, e1); 159 stl((uint8_t *)ptr + 4, e2); 160 } 161 162 static void set_gate(void *ptr, unsigned int type, unsigned int dpl, 163 unsigned long addr, unsigned int sel) 164 { 165 unsigned int e1, e2; 166 e1 = (addr & 0xffff) | (sel << 16); 167 e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8); 168 stl((uint8_t *)ptr, e1); 169 stl((uint8_t *)ptr + 4, e2); 170 } 171 172 uint64_t gdt_table[6]; 173 uint64_t idt_table[256]; 174 175 /* only dpl matters as we do only user space emulation */ 176 static void set_idt(int n, unsigned int dpl) 177 { 178 set_gate(idt_table + n, 0, dpl, 0, 0); 179 } 180 181 void cpu_loop(CPUX86State *env) 182 { 183 int trapnr; 184 uint8_t *pc; 185 target_siginfo_t info; 186 187 for(;;) { 188 trapnr = cpu_x86_exec(env); 189 switch(trapnr) { 190 case 0x80: 191 /* linux syscall */ 192 env->regs[R_EAX] = do_syscall(env, 193 env->regs[R_EAX], 194 env->regs[R_EBX], 195 env->regs[R_ECX], 196 env->regs[R_EDX], 197 env->regs[R_ESI], 198 env->regs[R_EDI], 199 env->regs[R_EBP]); 200 break; 201 case EXCP0B_NOSEG: 202 case EXCP0C_STACK: 203 info.si_signo = SIGBUS; 204 info.si_errno = 0; 205 info.si_code = TARGET_SI_KERNEL; 206 info._sifields._sigfault._addr = 0; 207 queue_signal(info.si_signo, &info); 208 break; 209 case EXCP0D_GPF: 210 if (env->eflags & VM_MASK) { 211 handle_vm86_fault(env); 212 } else { 213 info.si_signo = SIGSEGV; 214 info.si_errno = 0; 215 info.si_code = TARGET_SI_KERNEL; 216 info._sifields._sigfault._addr = 0; 217 queue_signal(info.si_signo, &info); 218 } 219 break; 220 case EXCP0E_PAGE: 221 info.si_signo = SIGSEGV; 222 info.si_errno = 0; 223 if (!(env->error_code & 1)) 224 info.si_code = TARGET_SEGV_MAPERR; 225 else 226 info.si_code = TARGET_SEGV_ACCERR; 227 info._sifields._sigfault._addr = env->cr[2]; 228 queue_signal(info.si_signo, &info); 229 break; 230 case EXCP00_DIVZ: 231 if (env->eflags & VM_MASK) { 232 handle_vm86_trap(env, trapnr); 233 } else { 234 /* division by zero */ 235 info.si_signo = SIGFPE; 236 info.si_errno = 0; 237 info.si_code = TARGET_FPE_INTDIV; 238 info._sifields._sigfault._addr = env->eip; 239 queue_signal(info.si_signo, &info); 240 } 241 break; 242 case EXCP01_SSTP: 243 case EXCP03_INT3: 244 if (env->eflags & VM_MASK) { 245 handle_vm86_trap(env, trapnr); 246 } else { 247 info.si_signo = SIGTRAP; 248 info.si_errno = 0; 249 if (trapnr == EXCP01_SSTP) { 250 info.si_code = TARGET_TRAP_BRKPT; 251 info._sifields._sigfault._addr = env->eip; 252 } else { 253 info.si_code = TARGET_SI_KERNEL; 254 info._sifields._sigfault._addr = 0; 255 } 256 queue_signal(info.si_signo, &info); 257 } 258 break; 259 case EXCP04_INTO: 260 case EXCP05_BOUND: 261 if (env->eflags & VM_MASK) { 262 handle_vm86_trap(env, trapnr); 263 } else { 264 info.si_signo = SIGSEGV; 265 info.si_errno = 0; 266 info.si_code = TARGET_SI_KERNEL; 267 info._sifields._sigfault._addr = 0; 268 queue_signal(info.si_signo, &info); 269 } 270 break; 271 case EXCP06_ILLOP: 272 info.si_signo = SIGILL; 273 info.si_errno = 0; 274 info.si_code = TARGET_ILL_ILLOPN; 275 info._sifields._sigfault._addr = env->eip; 276 queue_signal(info.si_signo, &info); 277 break; 278 case EXCP_INTERRUPT: 279 /* just indicate that signals should be handled asap */ 280 break; 281 default: 282 pc = env->segs[R_CS].base + env->eip; 283 fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n", 284 (long)pc, trapnr); 285 abort(); 286 } 287 process_pending_signals(env); 288 } 289 } 290 #endif 291 292 #ifdef TARGET_ARM 293 294 /* XXX: find a better solution */ 295 extern void tb_invalidate_page_range(target_ulong start, target_ulong end); 296 297 static void arm_cache_flush(target_ulong start, target_ulong last) 298 { 299 target_ulong addr, last1; 300 301 if (last < start) 302 return; 303 addr = start; 304 for(;;) { 305 last1 = ((addr + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK) - 1; 306 if (last1 > last) 307 last1 = last; 308 tb_invalidate_page_range(addr, last1 + 1); 309 if (last1 == last) 310 break; 311 addr = last1 + 1; 312 } 313 } 314 315 void cpu_loop(CPUARMState *env) 316 { 317 int trapnr; 318 unsigned int n, insn; 319 target_siginfo_t info; 320 321 for(;;) { 322 trapnr = cpu_arm_exec(env); 323 switch(trapnr) { 324 case EXCP_UDEF: 325 { 326 TaskState *ts = env->opaque; 327 uint32_t opcode; 328 329 /* we handle the FPU emulation here, as Linux */ 330 /* we get the opcode */ 331 opcode = ldl_raw((uint8_t *)env->regs[15]); 332 333 if (EmulateAll(opcode, &ts->fpa, env->regs) == 0) { 334 info.si_signo = SIGILL; 335 info.si_errno = 0; 336 info.si_code = TARGET_ILL_ILLOPN; 337 info._sifields._sigfault._addr = env->regs[15]; 338 queue_signal(info.si_signo, &info); 339 } else { 340 /* increment PC */ 341 env->regs[15] += 4; 342 } 343 } 344 break; 345 case EXCP_SWI: 346 { 347 /* system call */ 348 insn = ldl((void *)(env->regs[15] - 4)); 349 n = insn & 0xffffff; 350 if (n == ARM_NR_cacheflush) { 351 arm_cache_flush(env->regs[0], env->regs[1]); 352 } else if (n >= ARM_SYSCALL_BASE) { 353 /* linux syscall */ 354 n -= ARM_SYSCALL_BASE; 355 env->regs[0] = do_syscall(env, 356 n, 357 env->regs[0], 358 env->regs[1], 359 env->regs[2], 360 env->regs[3], 361 env->regs[4], 362 0); 363 } else { 364 goto error; 365 } 366 } 367 break; 368 case EXCP_INTERRUPT: 369 /* just indicate that signals should be handled asap */ 370 break; 371 default: 372 error: 373 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", 374 trapnr); 375 cpu_arm_dump_state(env, stderr, 0); 376 abort(); 377 } 378 process_pending_signals(env); 379 } 380 } 381 382 #endif 383 384 #ifdef TARGET_SPARC 385 386 //#define DEBUG_WIN 387 388 /* WARNING: dealing with register windows _is_ complicated */ 389 static inline int get_reg_index(CPUSPARCState *env, int cwp, int index) 390 { 391 index = (index + cwp * 16) & (16 * NWINDOWS - 1); 392 /* wrap handling : if cwp is on the last window, then we use the 393 registers 'after' the end */ 394 if (index < 8 && env->cwp == (NWINDOWS - 1)) 395 index += (16 * NWINDOWS); 396 return index; 397 } 398 399 static inline void save_window_offset(CPUSPARCState *env, int offset) 400 { 401 unsigned int new_wim, i, cwp1; 402 uint32_t *sp_ptr; 403 404 new_wim = ((env->wim >> 1) | (env->wim << (NWINDOWS - 1))) & 405 ((1LL << NWINDOWS) - 1); 406 /* save the window */ 407 cwp1 = (env->cwp + offset) & (NWINDOWS - 1); 408 sp_ptr = (uint32_t *)(env->regbase[get_reg_index(env, cwp1, 6)]); 409 #if defined(DEBUG_WIN) 410 printf("win_overflow: sp_ptr=0x%x save_cwp=%d\n", 411 (int)sp_ptr, cwp1); 412 #endif 413 for(i = 0; i < 16; i++) 414 stl_raw(sp_ptr + i, env->regbase[get_reg_index(env, cwp1, 8 + i)]); 415 env->wim = new_wim; 416 } 417 418 static void save_window(CPUSPARCState *env) 419 { 420 save_window_offset(env, 2); 421 } 422 423 static void restore_window(CPUSPARCState *env) 424 { 425 unsigned int new_wim, i, cwp1; 426 uint32_t *sp_ptr; 427 428 new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) & 429 ((1LL << NWINDOWS) - 1); 430 431 /* restore the invalid window */ 432 cwp1 = (env->cwp + 1) & (NWINDOWS - 1); 433 sp_ptr = (uint32_t *)(env->regbase[get_reg_index(env, cwp1, 6)]); 434 #if defined(DEBUG_WIN) 435 printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n", 436 (int)sp_ptr, cwp1); 437 #endif 438 for(i = 0; i < 16; i++) 439 env->regbase[get_reg_index(env, cwp1, 8 + i)] = ldl_raw(sp_ptr + i); 440 env->wim = new_wim; 441 } 442 443 static void flush_windows(CPUSPARCState *env) 444 { 445 int offset, cwp1; 446 #if defined(DEBUG_WIN) 447 printf("flush_windows:\n"); 448 #endif 449 offset = 2; 450 for(;;) { 451 /* if restore would invoke restore_window(), then we can stop */ 452 cwp1 = (env->cwp + 1) & (NWINDOWS - 1); 453 if (env->wim & (1 << cwp1)) 454 break; 455 #if defined(DEBUG_WIN) 456 printf("offset=%d: ", offset); 457 #endif 458 save_window_offset(env, offset); 459 offset++; 460 } 461 } 462 463 void cpu_loop (CPUSPARCState *env) 464 { 465 int trapnr, ret; 466 467 while (1) { 468 trapnr = cpu_sparc_exec (env); 469 470 switch (trapnr) { 471 case 0x88: 472 case 0x90: 473 ret = do_syscall (env, env->gregs[1], 474 env->regwptr[0], env->regwptr[1], 475 env->regwptr[2], env->regwptr[3], 476 env->regwptr[4], env->regwptr[5]); 477 if ((unsigned int)ret >= (unsigned int)(-515)) { 478 env->psr |= PSR_CARRY; 479 ret = -ret; 480 } else { 481 env->psr &= ~PSR_CARRY; 482 } 483 env->regwptr[0] = ret; 484 /* next instruction */ 485 env->pc = env->npc; 486 env->npc = env->npc + 4; 487 break; 488 case 0x83: /* flush windows */ 489 // flush_windows(env); 490 /* next instruction */ 491 env->pc = env->npc; 492 env->npc = env->npc + 4; 493 break; 494 case TT_WIN_OVF: /* window overflow */ 495 save_window(env); 496 break; 497 case TT_WIN_UNF: /* window underflow */ 498 restore_window(env); 499 break; 500 default: 501 printf ("Unhandled trap: 0x%x\n", trapnr); 502 cpu_sparc_dump_state(env, stderr, 0); 503 exit (1); 504 } 505 process_pending_signals (env); 506 } 507 } 508 509 #endif 510 511 #ifdef TARGET_PPC 512 513 static inline uint64_t cpu_ppc_get_tb (CPUState *env) 514 { 515 /* TO FIX */ 516 return 0; 517 } 518 519 uint32_t cpu_ppc_load_tbl (CPUState *env) 520 { 521 return cpu_ppc_get_tb(env) & 0xFFFFFFFF; 522 } 523 524 uint32_t cpu_ppc_load_tbu (CPUState *env) 525 { 526 return cpu_ppc_get_tb(env) >> 32; 527 } 528 529 static void cpu_ppc_store_tb (CPUState *env, uint64_t value) 530 { 531 /* TO FIX */ 532 } 533 534 void cpu_ppc_store_tbu (CPUState *env, uint32_t value) 535 { 536 cpu_ppc_store_tb(env, ((uint64_t)value << 32) | cpu_ppc_load_tbl(env)); 537 } 538 539 void cpu_ppc_store_tbl (CPUState *env, uint32_t value) 540 { 541 cpu_ppc_store_tb(env, ((uint64_t)cpu_ppc_load_tbl(env) << 32) | value); 542 } 543 544 uint32_t cpu_ppc_load_decr (CPUState *env) 545 { 546 /* TO FIX */ 547 return -1; 548 } 549 550 void cpu_ppc_store_decr (CPUState *env, uint32_t value) 551 { 552 /* TO FIX */ 553 } 554 555 void cpu_loop(CPUPPCState *env) 556 { 557 target_siginfo_t info; 558 int trapnr; 559 uint32_t ret; 560 561 for(;;) { 562 trapnr = cpu_ppc_exec(env); 563 if (trapnr != EXCP_SYSCALL_USER && trapnr != EXCP_BRANCH && 564 trapnr != EXCP_TRACE) { 565 if (loglevel > 0) { 566 cpu_ppc_dump_state(env, logfile, 0); 567 } 568 } 569 switch(trapnr) { 570 case EXCP_NONE: 571 break; 572 case EXCP_SYSCALL_USER: 573 /* system call */ 574 /* WARNING: 575 * PPC ABI uses overflow flag in cr0 to signal an error 576 * in syscalls. 577 */ 578 #if 0 579 printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", env->gpr[0], 580 env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6]); 581 #endif 582 env->crf[0] &= ~0x1; 583 ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4], 584 env->gpr[5], env->gpr[6], env->gpr[7], 585 env->gpr[8]); 586 if (ret > (uint32_t)(-515)) { 587 env->crf[0] |= 0x1; 588 ret = -ret; 589 } 590 env->gpr[3] = ret; 591 #if 0 592 printf("syscall returned 0x%08x (%d)\n", ret, ret); 593 #endif 594 break; 595 case EXCP_RESET: 596 /* Should not happen ! */ 597 fprintf(stderr, "RESET asked... Stop emulation\n"); 598 if (loglevel) 599 fprintf(logfile, "RESET asked... Stop emulation\n"); 600 abort(); 601 case EXCP_MACHINE_CHECK: 602 fprintf(stderr, "Machine check exeption... Stop emulation\n"); 603 if (loglevel) 604 fprintf(logfile, "RESET asked... Stop emulation\n"); 605 info.si_signo = TARGET_SIGBUS; 606 info.si_errno = 0; 607 info.si_code = TARGET_BUS_OBJERR; 608 info._sifields._sigfault._addr = env->nip - 4; 609 queue_signal(info.si_signo, &info); 610 case EXCP_DSI: 611 fprintf(stderr, "Invalid data memory access: 0x%08x\n", env->spr[DAR]); 612 if (loglevel) { 613 fprintf(logfile, "Invalid data memory access: 0x%08x\n", 614 env->spr[DAR]); 615 } 616 switch (env->error_code & 0xF) { 617 case EXCP_DSI_TRANSLATE: 618 info.si_signo = TARGET_SIGSEGV; 619 info.si_errno = 0; 620 info.si_code = TARGET_SEGV_MAPERR; 621 break; 622 case EXCP_DSI_NOTSUP: 623 case EXCP_DSI_EXTERNAL: 624 info.si_signo = TARGET_SIGILL; 625 info.si_errno = 0; 626 info.si_code = TARGET_ILL_ILLADR; 627 break; 628 case EXCP_DSI_PROT: 629 info.si_signo = TARGET_SIGSEGV; 630 info.si_errno = 0; 631 info.si_code = TARGET_SEGV_ACCERR; 632 break; 633 case EXCP_DSI_DABR: 634 info.si_signo = TARGET_SIGTRAP; 635 info.si_errno = 0; 636 info.si_code = TARGET_TRAP_BRKPT; 637 break; 638 default: 639 /* Let's send a regular segfault... */ 640 fprintf(stderr, "Invalid segfault errno (%02x)\n", 641 env->error_code); 642 if (loglevel) { 643 fprintf(logfile, "Invalid segfault errno (%02x)\n", 644 env->error_code); 645 } 646 info.si_signo = TARGET_SIGSEGV; 647 info.si_errno = 0; 648 info.si_code = TARGET_SEGV_MAPERR; 649 break; 650 } 651 info._sifields._sigfault._addr = env->nip; 652 queue_signal(info.si_signo, &info); 653 break; 654 case EXCP_ISI: 655 fprintf(stderr, "Invalid instruction fetch\n"); 656 if (loglevel) 657 fprintf(logfile, "Invalid instruction fetch\n"); 658 switch (env->error_code) { 659 case EXCP_ISI_TRANSLATE: 660 info.si_signo = TARGET_SIGSEGV; 661 info.si_errno = 0; 662 info.si_code = TARGET_SEGV_MAPERR; 663 break; 664 case EXCP_ISI_GUARD: 665 info.si_signo = TARGET_SIGILL; 666 info.si_errno = 0; 667 info.si_code = TARGET_ILL_ILLADR; 668 break; 669 case EXCP_ISI_NOEXEC: 670 case EXCP_ISI_PROT: 671 info.si_signo = TARGET_SIGSEGV; 672 info.si_errno = 0; 673 info.si_code = TARGET_SEGV_ACCERR; 674 break; 675 default: 676 /* Let's send a regular segfault... */ 677 fprintf(stderr, "Invalid segfault errno (%02x)\n", 678 env->error_code); 679 if (loglevel) { 680 fprintf(logfile, "Invalid segfault errno (%02x)\n", 681 env->error_code); 682 } 683 info.si_signo = TARGET_SIGSEGV; 684 info.si_errno = 0; 685 info.si_code = TARGET_SEGV_MAPERR; 686 break; 687 } 688 info._sifields._sigfault._addr = env->nip - 4; 689 queue_signal(info.si_signo, &info); 690 break; 691 case EXCP_EXTERNAL: 692 /* Should not happen ! */ 693 fprintf(stderr, "External interruption... Stop emulation\n"); 694 if (loglevel) 695 fprintf(logfile, "External interruption... Stop emulation\n"); 696 abort(); 697 case EXCP_ALIGN: 698 fprintf(stderr, "Invalid unaligned memory access\n"); 699 if (loglevel) 700 fprintf(logfile, "Invalid unaligned memory access\n"); 701 info.si_signo = TARGET_SIGBUS; 702 info.si_errno = 0; 703 info.si_code = TARGET_BUS_ADRALN; 704 info._sifields._sigfault._addr = env->nip - 4; 705 queue_signal(info.si_signo, &info); 706 break; 707 case EXCP_PROGRAM: 708 switch (env->error_code & ~0xF) { 709 case EXCP_FP: 710 fprintf(stderr, "Program exception\n"); 711 if (loglevel) 712 fprintf(logfile, "Program exception\n"); 713 /* Set FX */ 714 env->fpscr[7] |= 0x8; 715 /* Finally, update FEX */ 716 if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) & 717 ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3))) 718 env->fpscr[7] |= 0x4; 719 info.si_signo = TARGET_SIGFPE; 720 info.si_errno = 0; 721 switch (env->error_code & 0xF) { 722 case EXCP_FP_OX: 723 info.si_code = TARGET_FPE_FLTOVF; 724 break; 725 case EXCP_FP_UX: 726 info.si_code = TARGET_FPE_FLTUND; 727 break; 728 case EXCP_FP_ZX: 729 case EXCP_FP_VXZDZ: 730 info.si_code = TARGET_FPE_FLTDIV; 731 break; 732 case EXCP_FP_XX: 733 info.si_code = TARGET_FPE_FLTRES; 734 break; 735 case EXCP_FP_VXSOFT: 736 info.si_code = TARGET_FPE_FLTINV; 737 break; 738 case EXCP_FP_VXNAN: 739 case EXCP_FP_VXISI: 740 case EXCP_FP_VXIDI: 741 case EXCP_FP_VXIMZ: 742 case EXCP_FP_VXVC: 743 case EXCP_FP_VXSQRT: 744 case EXCP_FP_VXCVI: 745 info.si_code = TARGET_FPE_FLTSUB; 746 break; 747 default: 748 fprintf(stderr, "Unknown floating point exception " 749 "(%02x)\n", env->error_code); 750 if (loglevel) { 751 fprintf(logfile, "Unknown floating point exception " 752 "(%02x)\n", env->error_code & 0xF); 753 } 754 } 755 break; 756 case EXCP_INVAL: 757 fprintf(stderr, "Invalid instruction\n"); 758 if (loglevel) 759 fprintf(logfile, "Invalid instruction\n"); 760 info.si_signo = TARGET_SIGILL; 761 info.si_errno = 0; 762 switch (env->error_code & 0xF) { 763 case EXCP_INVAL_INVAL: 764 info.si_code = TARGET_ILL_ILLOPC; 765 break; 766 case EXCP_INVAL_LSWX: 767 info.si_code = TARGET_ILL_ILLOPN; 768 break; 769 case EXCP_INVAL_SPR: 770 info.si_code = TARGET_ILL_PRVREG; 771 break; 772 case EXCP_INVAL_FP: 773 info.si_code = TARGET_ILL_COPROC; 774 break; 775 default: 776 fprintf(stderr, "Unknown invalid operation (%02x)\n", 777 env->error_code & 0xF); 778 if (loglevel) { 779 fprintf(logfile, "Unknown invalid operation (%02x)\n", 780 env->error_code & 0xF); 781 } 782 info.si_code = TARGET_ILL_ILLADR; 783 break; 784 } 785 break; 786 case EXCP_PRIV: 787 fprintf(stderr, "Privilege violation\n"); 788 if (loglevel) 789 fprintf(logfile, "Privilege violation\n"); 790 info.si_signo = TARGET_SIGILL; 791 info.si_errno = 0; 792 switch (env->error_code & 0xF) { 793 case EXCP_PRIV_OPC: 794 info.si_code = TARGET_ILL_PRVOPC; 795 break; 796 case EXCP_PRIV_REG: 797 info.si_code = TARGET_ILL_PRVREG; 798 break; 799 default: 800 fprintf(stderr, "Unknown privilege violation (%02x)\n", 801 env->error_code & 0xF); 802 info.si_code = TARGET_ILL_PRVOPC; 803 break; 804 } 805 break; 806 case EXCP_TRAP: 807 fprintf(stderr, "Tried to call a TRAP\n"); 808 if (loglevel) 809 fprintf(logfile, "Tried to call a TRAP\n"); 810 abort(); 811 default: 812 /* Should not happen ! */ 813 fprintf(stderr, "Unknown program exception (%02x)\n", 814 env->error_code); 815 if (loglevel) { 816 fprintf(logfile, "Unknwon program exception (%02x)\n", 817 env->error_code); 818 } 819 abort(); 820 } 821 info._sifields._sigfault._addr = env->nip - 4; 822 queue_signal(info.si_signo, &info); 823 break; 824 case EXCP_NO_FP: 825 fprintf(stderr, "No floating point allowed\n"); 826 if (loglevel) 827 fprintf(logfile, "No floating point allowed\n"); 828 info.si_signo = TARGET_SIGILL; 829 info.si_errno = 0; 830 info.si_code = TARGET_ILL_COPROC; 831 info._sifields._sigfault._addr = env->nip - 4; 832 queue_signal(info.si_signo, &info); 833 break; 834 case EXCP_DECR: 835 /* Should not happen ! */ 836 fprintf(stderr, "Decrementer exception\n"); 837 if (loglevel) 838 fprintf(logfile, "Decrementer exception\n"); 839 abort(); 840 case EXCP_RESA: /* Implementation specific */ 841 /* Should not happen ! */ 842 fprintf(stderr, "RESA exception should never happen !\n"); 843 if (loglevel) 844 fprintf(logfile, "RESA exception should never happen !\n"); 845 abort(); 846 case EXCP_RESB: /* Implementation specific */ 847 /* Should not happen ! */ 848 fprintf(stderr, "RESB exception should never happen !\n"); 849 if (loglevel) 850 fprintf(logfile, "RESB exception should never happen !\n"); 851 abort(); 852 case EXCP_TRACE: 853 /* Do nothing: we use this to trace execution */ 854 break; 855 case EXCP_FP_ASSIST: 856 /* Should not happen ! */ 857 fprintf(stderr, "Floating point assist exception\n"); 858 if (loglevel) 859 fprintf(logfile, "Floating point assist exception\n"); 860 abort(); 861 case EXCP_MTMSR: 862 /* We reloaded the msr, just go on */ 863 if (msr_pr == 0) { 864 fprintf(stderr, "Tried to go into supervisor mode !\n"); 865 if (loglevel) 866 fprintf(logfile, "Tried to go into supervisor mode !\n"); 867 abort(); 868 } 869 break; 870 case EXCP_BRANCH: 871 /* We stopped because of a jump... */ 872 break; 873 case EXCP_RFI: 874 /* Should not occur: we always are in user mode */ 875 fprintf(stderr, "Return from interrupt ?\n"); 876 if (loglevel) 877 fprintf(logfile, "Return from interrupt ?\n"); 878 abort(); 879 case EXCP_INTERRUPT: 880 /* Don't know why this should ever happen... */ 881 break; 882 case EXCP_DEBUG: 883 break; 884 default: 885 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", 886 trapnr); 887 if (loglevel) { 888 fprintf(logfile, "qemu: unhandled CPU exception 0x%02x - " 889 "0x%02x - aborting\n", trapnr, env->error_code); 890 } 891 abort(); 892 } 893 process_pending_signals(env); 894 } 895 } 896 #endif 897 898 void usage(void) 899 { 900 printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2004 Fabrice Bellard\n" 901 "usage: qemu-" TARGET_ARCH " [-h] [-d opts] [-L path] [-s size] program [arguments...]\n" 902 "Linux CPU emulator (compiled for %s emulation)\n" 903 "\n" 904 "-h print this help\n" 905 "-L path set the elf interpreter prefix (default=%s)\n" 906 "-s size set the stack size in bytes (default=%ld)\n" 907 "\n" 908 "debug options:\n" 909 #ifdef USE_CODE_COPY 910 "-no-code-copy disable code copy acceleration\n" 911 #endif 912 "-d options activate log (logfile=%s)\n" 913 "-p pagesize set the host page size to 'pagesize'\n", 914 TARGET_ARCH, 915 interp_prefix, 916 x86_stack_size, 917 DEBUG_LOGFILE); 918 _exit(1); 919 } 920 921 /* XXX: currently only used for async signals (see signal.c) */ 922 CPUState *global_env; 923 /* used only if single thread */ 924 CPUState *cpu_single_env = NULL; 925 926 /* used to free thread contexts */ 927 TaskState *first_task_state; 928 929 int main(int argc, char **argv) 930 { 931 const char *filename; 932 struct target_pt_regs regs1, *regs = ®s1; 933 struct image_info info1, *info = &info1; 934 TaskState ts1, *ts = &ts1; 935 CPUState *env; 936 int optind; 937 const char *r; 938 939 if (argc <= 1) 940 usage(); 941 942 /* init debug */ 943 cpu_set_log_filename(DEBUG_LOGFILE); 944 945 optind = 1; 946 for(;;) { 947 if (optind >= argc) 948 break; 949 r = argv[optind]; 950 if (r[0] != '-') 951 break; 952 optind++; 953 r++; 954 if (!strcmp(r, "-")) { 955 break; 956 } else if (!strcmp(r, "d")) { 957 int mask; 958 CPULogItem *item; 959 960 if (optind >= argc) 961 break; 962 963 r = argv[optind++]; 964 mask = cpu_str_to_log_mask(r); 965 if (!mask) { 966 printf("Log items (comma separated):\n"); 967 for(item = cpu_log_items; item->mask != 0; item++) { 968 printf("%-10s %s\n", item->name, item->help); 969 } 970 exit(1); 971 } 972 cpu_set_log(mask); 973 } else if (!strcmp(r, "s")) { 974 r = argv[optind++]; 975 x86_stack_size = strtol(r, (char **)&r, 0); 976 if (x86_stack_size <= 0) 977 usage(); 978 if (*r == 'M') 979 x86_stack_size *= 1024 * 1024; 980 else if (*r == 'k' || *r == 'K') 981 x86_stack_size *= 1024; 982 } else if (!strcmp(r, "L")) { 983 interp_prefix = argv[optind++]; 984 } else if (!strcmp(r, "p")) { 985 qemu_host_page_size = atoi(argv[optind++]); 986 if (qemu_host_page_size == 0 || 987 (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) { 988 fprintf(stderr, "page size must be a power of two\n"); 989 exit(1); 990 } 991 } else 992 #ifdef USE_CODE_COPY 993 if (!strcmp(r, "no-code-copy")) { 994 code_copy_enabled = 0; 995 } else 996 #endif 997 { 998 usage(); 999 } 1000 } 1001 if (optind >= argc) 1002 usage(); 1003 filename = argv[optind]; 1004 1005 /* Zero out regs */ 1006 memset(regs, 0, sizeof(struct target_pt_regs)); 1007 1008 /* Zero out image_info */ 1009 memset(info, 0, sizeof(struct image_info)); 1010 1011 /* Scan interp_prefix dir for replacement files. */ 1012 init_paths(interp_prefix); 1013 1014 /* NOTE: we need to init the CPU at this stage to get 1015 qemu_host_page_size */ 1016 env = cpu_init(); 1017 1018 if (elf_exec(filename, argv+optind, environ, regs, info) != 0) { 1019 printf("Error loading %s\n", filename); 1020 _exit(1); 1021 } 1022 1023 if (loglevel) { 1024 page_dump(logfile); 1025 1026 fprintf(logfile, "start_brk 0x%08lx\n" , info->start_brk); 1027 fprintf(logfile, "end_code 0x%08lx\n" , info->end_code); 1028 fprintf(logfile, "start_code 0x%08lx\n" , info->start_code); 1029 fprintf(logfile, "end_data 0x%08lx\n" , info->end_data); 1030 fprintf(logfile, "start_stack 0x%08lx\n" , info->start_stack); 1031 fprintf(logfile, "brk 0x%08lx\n" , info->brk); 1032 fprintf(logfile, "entry 0x%08lx\n" , info->entry); 1033 } 1034 1035 target_set_brk((char *)info->brk); 1036 syscall_init(); 1037 signal_init(); 1038 1039 global_env = env; 1040 1041 /* build Task State */ 1042 memset(ts, 0, sizeof(TaskState)); 1043 env->opaque = ts; 1044 ts->used = 1; 1045 env->user_mode_only = 1; 1046 1047 #if defined(TARGET_I386) 1048 cpu_x86_set_cpl(env, 3); 1049 1050 env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK; 1051 env->hflags |= HF_PE_MASK; 1052 1053 /* flags setup : we activate the IRQs by default as in user mode */ 1054 env->eflags |= IF_MASK; 1055 1056 /* linux register setup */ 1057 env->regs[R_EAX] = regs->eax; 1058 env->regs[R_EBX] = regs->ebx; 1059 env->regs[R_ECX] = regs->ecx; 1060 env->regs[R_EDX] = regs->edx; 1061 env->regs[R_ESI] = regs->esi; 1062 env->regs[R_EDI] = regs->edi; 1063 env->regs[R_EBP] = regs->ebp; 1064 env->regs[R_ESP] = regs->esp; 1065 env->eip = regs->eip; 1066 1067 /* linux interrupt setup */ 1068 env->idt.base = (void *)idt_table; 1069 env->idt.limit = sizeof(idt_table) - 1; 1070 set_idt(0, 0); 1071 set_idt(1, 0); 1072 set_idt(2, 0); 1073 set_idt(3, 3); 1074 set_idt(4, 3); 1075 set_idt(5, 3); 1076 set_idt(6, 0); 1077 set_idt(7, 0); 1078 set_idt(8, 0); 1079 set_idt(9, 0); 1080 set_idt(10, 0); 1081 set_idt(11, 0); 1082 set_idt(12, 0); 1083 set_idt(13, 0); 1084 set_idt(14, 0); 1085 set_idt(15, 0); 1086 set_idt(16, 0); 1087 set_idt(17, 0); 1088 set_idt(18, 0); 1089 set_idt(19, 0); 1090 set_idt(0x80, 3); 1091 1092 /* linux segment setup */ 1093 env->gdt.base = (void *)gdt_table; 1094 env->gdt.limit = sizeof(gdt_table) - 1; 1095 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff, 1096 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | 1097 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT)); 1098 write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff, 1099 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | 1100 (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT)); 1101 cpu_x86_load_seg(env, R_CS, __USER_CS); 1102 cpu_x86_load_seg(env, R_DS, __USER_DS); 1103 cpu_x86_load_seg(env, R_ES, __USER_DS); 1104 cpu_x86_load_seg(env, R_SS, __USER_DS); 1105 cpu_x86_load_seg(env, R_FS, __USER_DS); 1106 cpu_x86_load_seg(env, R_GS, __USER_DS); 1107 1108 #elif defined(TARGET_ARM) 1109 { 1110 int i; 1111 for(i = 0; i < 16; i++) { 1112 env->regs[i] = regs->uregs[i]; 1113 } 1114 env->cpsr = regs->uregs[16]; 1115 } 1116 #elif defined(TARGET_SPARC) 1117 { 1118 int i; 1119 env->pc = regs->pc; 1120 env->npc = regs->npc; 1121 env->y = regs->y; 1122 for(i = 0; i < 8; i++) 1123 env->gregs[i] = regs->u_regs[i]; 1124 for(i = 0; i < 8; i++) 1125 env->regwptr[i] = regs->u_regs[i + 8]; 1126 } 1127 #elif defined(TARGET_PPC) 1128 { 1129 int i; 1130 for (i = 0; i < 32; i++) { 1131 if (i != 12 && i != 6) 1132 env->msr[i] = (regs->msr >> i) & 1; 1133 } 1134 env->nip = regs->nip; 1135 for(i = 0; i < 32; i++) { 1136 env->gpr[i] = regs->gpr[i]; 1137 } 1138 } 1139 #else 1140 #error unsupported target CPU 1141 #endif 1142 1143 cpu_loop(env); 1144 /* never exits */ 1145 return 0; 1146 } 1147