1 /* 2 * i386 emulator main execution loop 3 * 4 * Copyright (c) 2003-2005 Fabrice Bellard 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library 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 GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 #include "config.h" 20 #include "exec.h" 21 #include "disas.h" 22 #include "tcg.h" 23 #include "kvm.h" 24 25 #if !defined(CONFIG_SOFTMMU) 26 #undef EAX 27 #undef ECX 28 #undef EDX 29 #undef EBX 30 #undef ESP 31 #undef EBP 32 #undef ESI 33 #undef EDI 34 #undef EIP 35 #include <signal.h> 36 #ifdef __linux__ 37 #include <sys/ucontext.h> 38 #endif 39 #endif 40 41 #if defined(__sparc__) && !defined(CONFIG_SOLARIS) 42 // Work around ugly bugs in glibc that mangle global register contents 43 #undef env 44 #define env cpu_single_env 45 #endif 46 47 int tb_invalidated_flag; 48 49 //#define CONFIG_DEBUG_EXEC 50 //#define DEBUG_SIGNAL 51 52 int qemu_cpu_has_work(CPUState *env) 53 { 54 return cpu_has_work(env); 55 } 56 57 void cpu_loop_exit(void) 58 { 59 /* NOTE: the register at this point must be saved by hand because 60 longjmp restore them */ 61 regs_to_env(); 62 longjmp(env->jmp_env, 1); 63 } 64 65 /* exit the current TB from a signal handler. The host registers are 66 restored in a state compatible with the CPU emulator 67 */ 68 void cpu_resume_from_signal(CPUState *env1, void *puc) 69 { 70 #if !defined(CONFIG_SOFTMMU) 71 #ifdef __linux__ 72 struct ucontext *uc = puc; 73 #elif defined(__OpenBSD__) 74 struct sigcontext *uc = puc; 75 #endif 76 #endif 77 78 env = env1; 79 80 /* XXX: restore cpu registers saved in host registers */ 81 82 #if !defined(CONFIG_SOFTMMU) 83 if (puc) { 84 /* XXX: use siglongjmp ? */ 85 #ifdef __linux__ 86 sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL); 87 #elif defined(__OpenBSD__) 88 sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL); 89 #endif 90 } 91 #endif 92 env->exception_index = -1; 93 longjmp(env->jmp_env, 1); 94 } 95 96 /* Execute the code without caching the generated code. An interpreter 97 could be used if available. */ 98 static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb) 99 { 100 unsigned long next_tb; 101 TranslationBlock *tb; 102 103 /* Should never happen. 104 We only end up here when an existing TB is too long. */ 105 if (max_cycles > CF_COUNT_MASK) 106 max_cycles = CF_COUNT_MASK; 107 108 tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags, 109 max_cycles); 110 env->current_tb = tb; 111 /* execute the generated code */ 112 next_tb = tcg_qemu_tb_exec(tb->tc_ptr); 113 114 if ((next_tb & 3) == 2) { 115 /* Restore PC. This may happen if async event occurs before 116 the TB starts executing. */ 117 cpu_pc_from_tb(env, tb); 118 } 119 tb_phys_invalidate(tb, -1); 120 tb_free(tb); 121 } 122 123 static TranslationBlock *tb_find_slow(target_ulong pc, 124 target_ulong cs_base, 125 uint64_t flags) 126 { 127 TranslationBlock *tb, **ptb1; 128 unsigned int h; 129 target_ulong phys_pc, phys_page1, phys_page2, virt_page2; 130 131 tb_invalidated_flag = 0; 132 133 regs_to_env(); /* XXX: do it just before cpu_gen_code() */ 134 135 /* find translated block using physical mappings */ 136 phys_pc = get_phys_addr_code(env, pc); 137 phys_page1 = phys_pc & TARGET_PAGE_MASK; 138 phys_page2 = -1; 139 h = tb_phys_hash_func(phys_pc); 140 ptb1 = &tb_phys_hash[h]; 141 for(;;) { 142 tb = *ptb1; 143 if (!tb) 144 goto not_found; 145 if (tb->pc == pc && 146 tb->page_addr[0] == phys_page1 && 147 tb->cs_base == cs_base && 148 tb->flags == flags) { 149 /* check next page if needed */ 150 if (tb->page_addr[1] != -1) { 151 virt_page2 = (pc & TARGET_PAGE_MASK) + 152 TARGET_PAGE_SIZE; 153 phys_page2 = get_phys_addr_code(env, virt_page2); 154 if (tb->page_addr[1] == phys_page2) 155 goto found; 156 } else { 157 goto found; 158 } 159 } 160 ptb1 = &tb->phys_hash_next; 161 } 162 not_found: 163 /* if no translated code available, then translate it now */ 164 tb = tb_gen_code(env, pc, cs_base, flags, 0); 165 166 found: 167 /* we add the TB in the virtual pc hash table */ 168 env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb; 169 return tb; 170 } 171 172 static inline TranslationBlock *tb_find_fast(void) 173 { 174 TranslationBlock *tb; 175 target_ulong cs_base, pc; 176 int flags; 177 178 /* we record a subset of the CPU state. It will 179 always be the same before a given translated block 180 is executed. */ 181 cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags); 182 tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]; 183 if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base || 184 tb->flags != flags)) { 185 tb = tb_find_slow(pc, cs_base, flags); 186 } 187 return tb; 188 } 189 190 static CPUDebugExcpHandler *debug_excp_handler; 191 192 CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler) 193 { 194 CPUDebugExcpHandler *old_handler = debug_excp_handler; 195 196 debug_excp_handler = handler; 197 return old_handler; 198 } 199 200 static void cpu_handle_debug_exception(CPUState *env) 201 { 202 CPUWatchpoint *wp; 203 204 if (!env->watchpoint_hit) 205 QTAILQ_FOREACH(wp, &env->watchpoints, entry) 206 wp->flags &= ~BP_WATCHPOINT_HIT; 207 208 if (debug_excp_handler) 209 debug_excp_handler(env); 210 } 211 212 /* main execution loop */ 213 214 int cpu_exec(CPUState *env1) 215 { 216 #define DECLARE_HOST_REGS 1 217 #include "hostregs_helper.h" 218 int ret, interrupt_request; 219 TranslationBlock *tb; 220 uint8_t *tc_ptr; 221 unsigned long next_tb; 222 223 if (cpu_halted(env1) == EXCP_HALTED) 224 return EXCP_HALTED; 225 226 cpu_single_env = env1; 227 228 /* first we save global registers */ 229 #define SAVE_HOST_REGS 1 230 #include "hostregs_helper.h" 231 env = env1; 232 233 env_to_regs(); 234 #if defined(TARGET_I386) 235 /* put eflags in CPU temporary format */ 236 CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); 237 DF = 1 - (2 * ((env->eflags >> 10) & 1)); 238 CC_OP = CC_OP_EFLAGS; 239 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); 240 #elif defined(TARGET_SPARC) 241 #elif defined(TARGET_M68K) 242 env->cc_op = CC_OP_FLAGS; 243 env->cc_dest = env->sr & 0xf; 244 env->cc_x = (env->sr >> 4) & 1; 245 #elif defined(TARGET_ALPHA) 246 #elif defined(TARGET_ARM) 247 #elif defined(TARGET_PPC) 248 #elif defined(TARGET_MICROBLAZE) 249 #elif defined(TARGET_MIPS) 250 #elif defined(TARGET_SH4) 251 #elif defined(TARGET_CRIS) 252 #elif defined(TARGET_S390X) 253 /* XXXXX */ 254 #else 255 #error unsupported target CPU 256 #endif 257 env->exception_index = -1; 258 259 /* prepare setjmp context for exception handling */ 260 for(;;) { 261 if (setjmp(env->jmp_env) == 0) { 262 #if defined(__sparc__) && !defined(CONFIG_SOLARIS) 263 #undef env 264 env = cpu_single_env; 265 #define env cpu_single_env 266 #endif 267 env->current_tb = NULL; 268 /* if an exception is pending, we execute it here */ 269 if (env->exception_index >= 0) { 270 if (env->exception_index >= EXCP_INTERRUPT) { 271 /* exit request from the cpu execution loop */ 272 ret = env->exception_index; 273 if (ret == EXCP_DEBUG) 274 cpu_handle_debug_exception(env); 275 break; 276 } else { 277 #if defined(CONFIG_USER_ONLY) 278 /* if user mode only, we simulate a fake exception 279 which will be handled outside the cpu execution 280 loop */ 281 #if defined(TARGET_I386) 282 do_interrupt_user(env->exception_index, 283 env->exception_is_int, 284 env->error_code, 285 env->exception_next_eip); 286 /* successfully delivered */ 287 env->old_exception = -1; 288 #endif 289 ret = env->exception_index; 290 break; 291 #else 292 #if defined(TARGET_I386) 293 /* simulate a real cpu exception. On i386, it can 294 trigger new exceptions, but we do not handle 295 double or triple faults yet. */ 296 do_interrupt(env->exception_index, 297 env->exception_is_int, 298 env->error_code, 299 env->exception_next_eip, 0); 300 /* successfully delivered */ 301 env->old_exception = -1; 302 #elif defined(TARGET_PPC) 303 do_interrupt(env); 304 #elif defined(TARGET_MICROBLAZE) 305 do_interrupt(env); 306 #elif defined(TARGET_MIPS) 307 do_interrupt(env); 308 #elif defined(TARGET_SPARC) 309 do_interrupt(env); 310 #elif defined(TARGET_ARM) 311 do_interrupt(env); 312 #elif defined(TARGET_SH4) 313 do_interrupt(env); 314 #elif defined(TARGET_ALPHA) 315 do_interrupt(env); 316 #elif defined(TARGET_CRIS) 317 do_interrupt(env); 318 #elif defined(TARGET_M68K) 319 do_interrupt(0); 320 #endif 321 env->exception_index = -1; 322 #endif 323 } 324 } 325 326 if (kvm_enabled()) { 327 kvm_cpu_exec(env); 328 longjmp(env->jmp_env, 1); 329 } 330 331 next_tb = 0; /* force lookup of first TB */ 332 for(;;) { 333 interrupt_request = env->interrupt_request; 334 if (unlikely(interrupt_request)) { 335 if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) { 336 /* Mask out external interrupts for this step. */ 337 interrupt_request &= ~(CPU_INTERRUPT_HARD | 338 CPU_INTERRUPT_FIQ | 339 CPU_INTERRUPT_SMI | 340 CPU_INTERRUPT_NMI); 341 } 342 if (interrupt_request & CPU_INTERRUPT_DEBUG) { 343 env->interrupt_request &= ~CPU_INTERRUPT_DEBUG; 344 env->exception_index = EXCP_DEBUG; 345 cpu_loop_exit(); 346 } 347 #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \ 348 defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \ 349 defined(TARGET_MICROBLAZE) 350 if (interrupt_request & CPU_INTERRUPT_HALT) { 351 env->interrupt_request &= ~CPU_INTERRUPT_HALT; 352 env->halted = 1; 353 env->exception_index = EXCP_HLT; 354 cpu_loop_exit(); 355 } 356 #endif 357 #if defined(TARGET_I386) 358 if (interrupt_request & CPU_INTERRUPT_INIT) { 359 svm_check_intercept(SVM_EXIT_INIT); 360 do_cpu_init(env); 361 env->exception_index = EXCP_HALTED; 362 cpu_loop_exit(); 363 } else if (interrupt_request & CPU_INTERRUPT_SIPI) { 364 do_cpu_sipi(env); 365 } else if (env->hflags2 & HF2_GIF_MASK) { 366 if ((interrupt_request & CPU_INTERRUPT_SMI) && 367 !(env->hflags & HF_SMM_MASK)) { 368 svm_check_intercept(SVM_EXIT_SMI); 369 env->interrupt_request &= ~CPU_INTERRUPT_SMI; 370 do_smm_enter(); 371 next_tb = 0; 372 } else if ((interrupt_request & CPU_INTERRUPT_NMI) && 373 !(env->hflags2 & HF2_NMI_MASK)) { 374 env->interrupt_request &= ~CPU_INTERRUPT_NMI; 375 env->hflags2 |= HF2_NMI_MASK; 376 do_interrupt(EXCP02_NMI, 0, 0, 0, 1); 377 next_tb = 0; 378 } else if (interrupt_request & CPU_INTERRUPT_MCE) { 379 env->interrupt_request &= ~CPU_INTERRUPT_MCE; 380 do_interrupt(EXCP12_MCHK, 0, 0, 0, 0); 381 next_tb = 0; 382 } else if ((interrupt_request & CPU_INTERRUPT_HARD) && 383 (((env->hflags2 & HF2_VINTR_MASK) && 384 (env->hflags2 & HF2_HIF_MASK)) || 385 (!(env->hflags2 & HF2_VINTR_MASK) && 386 (env->eflags & IF_MASK && 387 !(env->hflags & HF_INHIBIT_IRQ_MASK))))) { 388 int intno; 389 svm_check_intercept(SVM_EXIT_INTR); 390 env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ); 391 intno = cpu_get_pic_interrupt(env); 392 qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno); 393 #if defined(__sparc__) && !defined(CONFIG_SOLARIS) 394 #undef env 395 env = cpu_single_env; 396 #define env cpu_single_env 397 #endif 398 do_interrupt(intno, 0, 0, 0, 1); 399 /* ensure that no TB jump will be modified as 400 the program flow was changed */ 401 next_tb = 0; 402 #if !defined(CONFIG_USER_ONLY) 403 } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && 404 (env->eflags & IF_MASK) && 405 !(env->hflags & HF_INHIBIT_IRQ_MASK)) { 406 int intno; 407 /* FIXME: this should respect TPR */ 408 svm_check_intercept(SVM_EXIT_VINTR); 409 intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector)); 410 qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno); 411 do_interrupt(intno, 0, 0, 0, 1); 412 env->interrupt_request &= ~CPU_INTERRUPT_VIRQ; 413 next_tb = 0; 414 #endif 415 } 416 } 417 #elif defined(TARGET_PPC) 418 #if 0 419 if ((interrupt_request & CPU_INTERRUPT_RESET)) { 420 cpu_reset(env); 421 } 422 #endif 423 if (interrupt_request & CPU_INTERRUPT_HARD) { 424 ppc_hw_interrupt(env); 425 if (env->pending_interrupts == 0) 426 env->interrupt_request &= ~CPU_INTERRUPT_HARD; 427 next_tb = 0; 428 } 429 #elif defined(TARGET_MICROBLAZE) 430 if ((interrupt_request & CPU_INTERRUPT_HARD) 431 && (env->sregs[SR_MSR] & MSR_IE) 432 && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP)) 433 && !(env->iflags & (D_FLAG | IMM_FLAG))) { 434 env->exception_index = EXCP_IRQ; 435 do_interrupt(env); 436 next_tb = 0; 437 } 438 #elif defined(TARGET_MIPS) 439 if ((interrupt_request & CPU_INTERRUPT_HARD) && 440 (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) && 441 (env->CP0_Status & (1 << CP0St_IE)) && 442 !(env->CP0_Status & (1 << CP0St_EXL)) && 443 !(env->CP0_Status & (1 << CP0St_ERL)) && 444 !(env->hflags & MIPS_HFLAG_DM)) { 445 /* Raise it */ 446 env->exception_index = EXCP_EXT_INTERRUPT; 447 env->error_code = 0; 448 do_interrupt(env); 449 next_tb = 0; 450 } 451 #elif defined(TARGET_SPARC) 452 if ((interrupt_request & CPU_INTERRUPT_HARD) && 453 (env->psret != 0)) { 454 int pil = env->interrupt_index & 15; 455 int type = env->interrupt_index & 0xf0; 456 457 if (((type == TT_EXTINT) && 458 (pil == 15 || pil > env->psrpil)) || 459 type != TT_EXTINT) { 460 env->interrupt_request &= ~CPU_INTERRUPT_HARD; 461 env->exception_index = env->interrupt_index; 462 do_interrupt(env); 463 env->interrupt_index = 0; 464 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) 465 cpu_check_irqs(env); 466 #endif 467 next_tb = 0; 468 } 469 } else if (interrupt_request & CPU_INTERRUPT_TIMER) { 470 //do_interrupt(0, 0, 0, 0, 0); 471 env->interrupt_request &= ~CPU_INTERRUPT_TIMER; 472 } 473 #elif defined(TARGET_ARM) 474 if (interrupt_request & CPU_INTERRUPT_FIQ 475 && !(env->uncached_cpsr & CPSR_F)) { 476 env->exception_index = EXCP_FIQ; 477 do_interrupt(env); 478 next_tb = 0; 479 } 480 /* ARMv7-M interrupt return works by loading a magic value 481 into the PC. On real hardware the load causes the 482 return to occur. The qemu implementation performs the 483 jump normally, then does the exception return when the 484 CPU tries to execute code at the magic address. 485 This will cause the magic PC value to be pushed to 486 the stack if an interrupt occured at the wrong time. 487 We avoid this by disabling interrupts when 488 pc contains a magic address. */ 489 if (interrupt_request & CPU_INTERRUPT_HARD 490 && ((IS_M(env) && env->regs[15] < 0xfffffff0) 491 || !(env->uncached_cpsr & CPSR_I))) { 492 env->exception_index = EXCP_IRQ; 493 do_interrupt(env); 494 next_tb = 0; 495 } 496 #elif defined(TARGET_SH4) 497 if (interrupt_request & CPU_INTERRUPT_HARD) { 498 do_interrupt(env); 499 next_tb = 0; 500 } 501 #elif defined(TARGET_ALPHA) 502 if (interrupt_request & CPU_INTERRUPT_HARD) { 503 do_interrupt(env); 504 next_tb = 0; 505 } 506 #elif defined(TARGET_CRIS) 507 if (interrupt_request & CPU_INTERRUPT_HARD 508 && (env->pregs[PR_CCS] & I_FLAG)) { 509 env->exception_index = EXCP_IRQ; 510 do_interrupt(env); 511 next_tb = 0; 512 } 513 if (interrupt_request & CPU_INTERRUPT_NMI 514 && (env->pregs[PR_CCS] & M_FLAG)) { 515 env->exception_index = EXCP_NMI; 516 do_interrupt(env); 517 next_tb = 0; 518 } 519 #elif defined(TARGET_M68K) 520 if (interrupt_request & CPU_INTERRUPT_HARD 521 && ((env->sr & SR_I) >> SR_I_SHIFT) 522 < env->pending_level) { 523 /* Real hardware gets the interrupt vector via an 524 IACK cycle at this point. Current emulated 525 hardware doesn't rely on this, so we 526 provide/save the vector when the interrupt is 527 first signalled. */ 528 env->exception_index = env->pending_vector; 529 do_interrupt(1); 530 next_tb = 0; 531 } 532 #endif 533 /* Don't use the cached interupt_request value, 534 do_interrupt may have updated the EXITTB flag. */ 535 if (env->interrupt_request & CPU_INTERRUPT_EXITTB) { 536 env->interrupt_request &= ~CPU_INTERRUPT_EXITTB; 537 /* ensure that no TB jump will be modified as 538 the program flow was changed */ 539 next_tb = 0; 540 } 541 } 542 if (unlikely(env->exit_request)) { 543 env->exit_request = 0; 544 env->exception_index = EXCP_INTERRUPT; 545 cpu_loop_exit(); 546 } 547 #ifdef DEBUG_EXEC 548 if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) { 549 /* restore flags in standard format */ 550 regs_to_env(); 551 #if defined(TARGET_I386) 552 env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK); 553 log_cpu_state(env, X86_DUMP_CCOP); 554 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); 555 #elif defined(TARGET_ARM) 556 log_cpu_state(env, 0); 557 #elif defined(TARGET_SPARC) 558 log_cpu_state(env, 0); 559 #elif defined(TARGET_PPC) 560 log_cpu_state(env, 0); 561 #elif defined(TARGET_M68K) 562 cpu_m68k_flush_flags(env, env->cc_op); 563 env->cc_op = CC_OP_FLAGS; 564 env->sr = (env->sr & 0xffe0) 565 | env->cc_dest | (env->cc_x << 4); 566 log_cpu_state(env, 0); 567 #elif defined(TARGET_MICROBLAZE) 568 log_cpu_state(env, 0); 569 #elif defined(TARGET_MIPS) 570 log_cpu_state(env, 0); 571 #elif defined(TARGET_SH4) 572 log_cpu_state(env, 0); 573 #elif defined(TARGET_ALPHA) 574 log_cpu_state(env, 0); 575 #elif defined(TARGET_CRIS) 576 log_cpu_state(env, 0); 577 #else 578 #error unsupported target CPU 579 #endif 580 } 581 #endif 582 spin_lock(&tb_lock); 583 tb = tb_find_fast(); 584 /* Note: we do it here to avoid a gcc bug on Mac OS X when 585 doing it in tb_find_slow */ 586 if (tb_invalidated_flag) { 587 /* as some TB could have been invalidated because 588 of memory exceptions while generating the code, we 589 must recompute the hash index here */ 590 next_tb = 0; 591 tb_invalidated_flag = 0; 592 } 593 #ifdef DEBUG_EXEC 594 qemu_log_mask(CPU_LOG_EXEC, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n", 595 (long)tb->tc_ptr, tb->pc, 596 lookup_symbol(tb->pc)); 597 #endif 598 /* see if we can patch the calling TB. When the TB 599 spans two pages, we cannot safely do a direct 600 jump. */ 601 { 602 if (next_tb != 0 && 603 #ifdef CONFIG_KQEMU 604 (env->kqemu_enabled != 2) && 605 #endif 606 tb->page_addr[1] == -1) { 607 tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb); 608 } 609 } 610 spin_unlock(&tb_lock); 611 env->current_tb = tb; 612 613 /* cpu_interrupt might be called while translating the 614 TB, but before it is linked into a potentially 615 infinite loop and becomes env->current_tb. Avoid 616 starting execution if there is a pending interrupt. */ 617 if (unlikely (env->exit_request)) 618 env->current_tb = NULL; 619 620 while (env->current_tb) { 621 tc_ptr = tb->tc_ptr; 622 /* execute the generated code */ 623 #if defined(__sparc__) && !defined(CONFIG_SOLARIS) 624 #undef env 625 env = cpu_single_env; 626 #define env cpu_single_env 627 #endif 628 next_tb = tcg_qemu_tb_exec(tc_ptr); 629 env->current_tb = NULL; 630 if ((next_tb & 3) == 2) { 631 /* Instruction counter expired. */ 632 int insns_left; 633 tb = (TranslationBlock *)(long)(next_tb & ~3); 634 /* Restore PC. */ 635 cpu_pc_from_tb(env, tb); 636 insns_left = env->icount_decr.u32; 637 if (env->icount_extra && insns_left >= 0) { 638 /* Refill decrementer and continue execution. */ 639 env->icount_extra += insns_left; 640 if (env->icount_extra > 0xffff) { 641 insns_left = 0xffff; 642 } else { 643 insns_left = env->icount_extra; 644 } 645 env->icount_extra -= insns_left; 646 env->icount_decr.u16.low = insns_left; 647 } else { 648 if (insns_left > 0) { 649 /* Execute remaining instructions. */ 650 cpu_exec_nocache(insns_left, tb); 651 } 652 env->exception_index = EXCP_INTERRUPT; 653 next_tb = 0; 654 cpu_loop_exit(); 655 } 656 } 657 } 658 /* reset soft MMU for next block (it can currently 659 only be set by a memory fault) */ 660 #if defined(CONFIG_KQEMU) 661 #define MIN_CYCLE_BEFORE_SWITCH (100 * 1000) 662 if (kqemu_is_ok(env) && 663 (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) { 664 cpu_loop_exit(); 665 } 666 #endif 667 } /* for(;;) */ 668 } else { 669 env_to_regs(); 670 } 671 } /* for(;;) */ 672 673 674 #if defined(TARGET_I386) 675 /* restore flags in standard format */ 676 env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK); 677 #elif defined(TARGET_ARM) 678 /* XXX: Save/restore host fpu exception state?. */ 679 #elif defined(TARGET_SPARC) 680 #elif defined(TARGET_PPC) 681 #elif defined(TARGET_M68K) 682 cpu_m68k_flush_flags(env, env->cc_op); 683 env->cc_op = CC_OP_FLAGS; 684 env->sr = (env->sr & 0xffe0) 685 | env->cc_dest | (env->cc_x << 4); 686 #elif defined(TARGET_MICROBLAZE) 687 #elif defined(TARGET_MIPS) 688 #elif defined(TARGET_SH4) 689 #elif defined(TARGET_ALPHA) 690 #elif defined(TARGET_CRIS) 691 /* XXXXX */ 692 #else 693 #error unsupported target CPU 694 #endif 695 696 /* restore global registers */ 697 #include "hostregs_helper.h" 698 699 /* fail safe : never use cpu_single_env outside cpu_exec() */ 700 cpu_single_env = NULL; 701 return ret; 702 } 703 704 /* must only be called from the generated code as an exception can be 705 generated */ 706 void tb_invalidate_page_range(target_ulong start, target_ulong end) 707 { 708 /* XXX: cannot enable it yet because it yields to MMU exception 709 where NIP != read address on PowerPC */ 710 #if 0 711 target_ulong phys_addr; 712 phys_addr = get_phys_addr_code(env, start); 713 tb_invalidate_phys_page_range(phys_addr, phys_addr + end - start, 0); 714 #endif 715 } 716 717 #if defined(TARGET_I386) && defined(CONFIG_USER_ONLY) 718 719 void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector) 720 { 721 CPUX86State *saved_env; 722 723 saved_env = env; 724 env = s; 725 if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) { 726 selector &= 0xffff; 727 cpu_x86_load_seg_cache(env, seg_reg, selector, 728 (selector << 4), 0xffff, 0); 729 } else { 730 helper_load_seg(seg_reg, selector); 731 } 732 env = saved_env; 733 } 734 735 void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32) 736 { 737 CPUX86State *saved_env; 738 739 saved_env = env; 740 env = s; 741 742 helper_fsave(ptr, data32); 743 744 env = saved_env; 745 } 746 747 void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32) 748 { 749 CPUX86State *saved_env; 750 751 saved_env = env; 752 env = s; 753 754 helper_frstor(ptr, data32); 755 756 env = saved_env; 757 } 758 759 #endif /* TARGET_I386 */ 760 761 #if !defined(CONFIG_SOFTMMU) 762 763 #if defined(TARGET_I386) 764 765 /* 'pc' is the host PC at which the exception was raised. 'address' is 766 the effective address of the memory exception. 'is_write' is 1 if a 767 write caused the exception and otherwise 0'. 'old_set' is the 768 signal set which should be restored */ 769 static inline int handle_cpu_signal(unsigned long pc, unsigned long address, 770 int is_write, sigset_t *old_set, 771 void *puc) 772 { 773 TranslationBlock *tb; 774 int ret; 775 776 if (cpu_single_env) 777 env = cpu_single_env; /* XXX: find a correct solution for multithread */ 778 #if defined(DEBUG_SIGNAL) 779 qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 780 pc, address, is_write, *(unsigned long *)old_set); 781 #endif 782 /* XXX: locking issue */ 783 if (is_write && page_unprotect(h2g(address), pc, puc)) { 784 return 1; 785 } 786 787 /* see if it is an MMU fault */ 788 ret = cpu_x86_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); 789 if (ret < 0) 790 return 0; /* not an MMU fault */ 791 if (ret == 0) 792 return 1; /* the MMU fault was handled without causing real CPU fault */ 793 /* now we have a real cpu fault */ 794 tb = tb_find_pc(pc); 795 if (tb) { 796 /* the PC is inside the translated code. It means that we have 797 a virtual CPU fault */ 798 cpu_restore_state(tb, env, pc, puc); 799 } 800 if (ret == 1) { 801 #if 0 802 printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n", 803 env->eip, env->cr[2], env->error_code); 804 #endif 805 /* we restore the process signal mask as the sigreturn should 806 do it (XXX: use sigsetjmp) */ 807 sigprocmask(SIG_SETMASK, old_set, NULL); 808 raise_exception_err(env->exception_index, env->error_code); 809 } else { 810 /* activate soft MMU for this block */ 811 env->hflags |= HF_SOFTMMU_MASK; 812 cpu_resume_from_signal(env, puc); 813 } 814 /* never comes here */ 815 return 1; 816 } 817 818 #elif defined(TARGET_ARM) 819 static inline int handle_cpu_signal(unsigned long pc, unsigned long address, 820 int is_write, sigset_t *old_set, 821 void *puc) 822 { 823 TranslationBlock *tb; 824 int ret; 825 826 if (cpu_single_env) 827 env = cpu_single_env; /* XXX: find a correct solution for multithread */ 828 #if defined(DEBUG_SIGNAL) 829 printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 830 pc, address, is_write, *(unsigned long *)old_set); 831 #endif 832 /* XXX: locking issue */ 833 if (is_write && page_unprotect(h2g(address), pc, puc)) { 834 return 1; 835 } 836 /* see if it is an MMU fault */ 837 ret = cpu_arm_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); 838 if (ret < 0) 839 return 0; /* not an MMU fault */ 840 if (ret == 0) 841 return 1; /* the MMU fault was handled without causing real CPU fault */ 842 /* now we have a real cpu fault */ 843 tb = tb_find_pc(pc); 844 if (tb) { 845 /* the PC is inside the translated code. It means that we have 846 a virtual CPU fault */ 847 cpu_restore_state(tb, env, pc, puc); 848 } 849 /* we restore the process signal mask as the sigreturn should 850 do it (XXX: use sigsetjmp) */ 851 sigprocmask(SIG_SETMASK, old_set, NULL); 852 cpu_loop_exit(); 853 /* never comes here */ 854 return 1; 855 } 856 #elif defined(TARGET_SPARC) 857 static inline int handle_cpu_signal(unsigned long pc, unsigned long address, 858 int is_write, sigset_t *old_set, 859 void *puc) 860 { 861 TranslationBlock *tb; 862 int ret; 863 864 if (cpu_single_env) 865 env = cpu_single_env; /* XXX: find a correct solution for multithread */ 866 #if defined(DEBUG_SIGNAL) 867 printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 868 pc, address, is_write, *(unsigned long *)old_set); 869 #endif 870 /* XXX: locking issue */ 871 if (is_write && page_unprotect(h2g(address), pc, puc)) { 872 return 1; 873 } 874 /* see if it is an MMU fault */ 875 ret = cpu_sparc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); 876 if (ret < 0) 877 return 0; /* not an MMU fault */ 878 if (ret == 0) 879 return 1; /* the MMU fault was handled without causing real CPU fault */ 880 /* now we have a real cpu fault */ 881 tb = tb_find_pc(pc); 882 if (tb) { 883 /* the PC is inside the translated code. It means that we have 884 a virtual CPU fault */ 885 cpu_restore_state(tb, env, pc, puc); 886 } 887 /* we restore the process signal mask as the sigreturn should 888 do it (XXX: use sigsetjmp) */ 889 sigprocmask(SIG_SETMASK, old_set, NULL); 890 cpu_loop_exit(); 891 /* never comes here */ 892 return 1; 893 } 894 #elif defined (TARGET_PPC) 895 static inline int handle_cpu_signal(unsigned long pc, unsigned long address, 896 int is_write, sigset_t *old_set, 897 void *puc) 898 { 899 TranslationBlock *tb; 900 int ret; 901 902 if (cpu_single_env) 903 env = cpu_single_env; /* XXX: find a correct solution for multithread */ 904 #if defined(DEBUG_SIGNAL) 905 printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 906 pc, address, is_write, *(unsigned long *)old_set); 907 #endif 908 /* XXX: locking issue */ 909 if (is_write && page_unprotect(h2g(address), pc, puc)) { 910 return 1; 911 } 912 913 /* see if it is an MMU fault */ 914 ret = cpu_ppc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); 915 if (ret < 0) 916 return 0; /* not an MMU fault */ 917 if (ret == 0) 918 return 1; /* the MMU fault was handled without causing real CPU fault */ 919 920 /* now we have a real cpu fault */ 921 tb = tb_find_pc(pc); 922 if (tb) { 923 /* the PC is inside the translated code. It means that we have 924 a virtual CPU fault */ 925 cpu_restore_state(tb, env, pc, puc); 926 } 927 if (ret == 1) { 928 #if 0 929 printf("PF exception: NIP=0x%08x error=0x%x %p\n", 930 env->nip, env->error_code, tb); 931 #endif 932 /* we restore the process signal mask as the sigreturn should 933 do it (XXX: use sigsetjmp) */ 934 sigprocmask(SIG_SETMASK, old_set, NULL); 935 cpu_loop_exit(); 936 } else { 937 /* activate soft MMU for this block */ 938 cpu_resume_from_signal(env, puc); 939 } 940 /* never comes here */ 941 return 1; 942 } 943 944 #elif defined(TARGET_M68K) 945 static inline int handle_cpu_signal(unsigned long pc, unsigned long address, 946 int is_write, sigset_t *old_set, 947 void *puc) 948 { 949 TranslationBlock *tb; 950 int ret; 951 952 if (cpu_single_env) 953 env = cpu_single_env; /* XXX: find a correct solution for multithread */ 954 #if defined(DEBUG_SIGNAL) 955 printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 956 pc, address, is_write, *(unsigned long *)old_set); 957 #endif 958 /* XXX: locking issue */ 959 if (is_write && page_unprotect(address, pc, puc)) { 960 return 1; 961 } 962 /* see if it is an MMU fault */ 963 ret = cpu_m68k_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); 964 if (ret < 0) 965 return 0; /* not an MMU fault */ 966 if (ret == 0) 967 return 1; /* the MMU fault was handled without causing real CPU fault */ 968 /* now we have a real cpu fault */ 969 tb = tb_find_pc(pc); 970 if (tb) { 971 /* the PC is inside the translated code. It means that we have 972 a virtual CPU fault */ 973 cpu_restore_state(tb, env, pc, puc); 974 } 975 /* we restore the process signal mask as the sigreturn should 976 do it (XXX: use sigsetjmp) */ 977 sigprocmask(SIG_SETMASK, old_set, NULL); 978 cpu_loop_exit(); 979 /* never comes here */ 980 return 1; 981 } 982 983 #elif defined (TARGET_MIPS) 984 static inline int handle_cpu_signal(unsigned long pc, unsigned long address, 985 int is_write, sigset_t *old_set, 986 void *puc) 987 { 988 TranslationBlock *tb; 989 int ret; 990 991 if (cpu_single_env) 992 env = cpu_single_env; /* XXX: find a correct solution for multithread */ 993 #if defined(DEBUG_SIGNAL) 994 printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 995 pc, address, is_write, *(unsigned long *)old_set); 996 #endif 997 /* XXX: locking issue */ 998 if (is_write && page_unprotect(h2g(address), pc, puc)) { 999 return 1; 1000 } 1001 1002 /* see if it is an MMU fault */ 1003 ret = cpu_mips_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); 1004 if (ret < 0) 1005 return 0; /* not an MMU fault */ 1006 if (ret == 0) 1007 return 1; /* the MMU fault was handled without causing real CPU fault */ 1008 1009 /* now we have a real cpu fault */ 1010 tb = tb_find_pc(pc); 1011 if (tb) { 1012 /* the PC is inside the translated code. It means that we have 1013 a virtual CPU fault */ 1014 cpu_restore_state(tb, env, pc, puc); 1015 } 1016 if (ret == 1) { 1017 #if 0 1018 printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n", 1019 env->PC, env->error_code, tb); 1020 #endif 1021 /* we restore the process signal mask as the sigreturn should 1022 do it (XXX: use sigsetjmp) */ 1023 sigprocmask(SIG_SETMASK, old_set, NULL); 1024 cpu_loop_exit(); 1025 } else { 1026 /* activate soft MMU for this block */ 1027 cpu_resume_from_signal(env, puc); 1028 } 1029 /* never comes here */ 1030 return 1; 1031 } 1032 1033 #elif defined (TARGET_MICROBLAZE) 1034 static inline int handle_cpu_signal(unsigned long pc, unsigned long address, 1035 int is_write, sigset_t *old_set, 1036 void *puc) 1037 { 1038 TranslationBlock *tb; 1039 int ret; 1040 1041 if (cpu_single_env) 1042 env = cpu_single_env; /* XXX: find a correct solution for multithread */ 1043 #if defined(DEBUG_SIGNAL) 1044 printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 1045 pc, address, is_write, *(unsigned long *)old_set); 1046 #endif 1047 /* XXX: locking issue */ 1048 if (is_write && page_unprotect(h2g(address), pc, puc)) { 1049 return 1; 1050 } 1051 1052 /* see if it is an MMU fault */ 1053 ret = cpu_mb_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); 1054 if (ret < 0) 1055 return 0; /* not an MMU fault */ 1056 if (ret == 0) 1057 return 1; /* the MMU fault was handled without causing real CPU fault */ 1058 1059 /* now we have a real cpu fault */ 1060 tb = tb_find_pc(pc); 1061 if (tb) { 1062 /* the PC is inside the translated code. It means that we have 1063 a virtual CPU fault */ 1064 cpu_restore_state(tb, env, pc, puc); 1065 } 1066 if (ret == 1) { 1067 #if 0 1068 printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n", 1069 env->PC, env->error_code, tb); 1070 #endif 1071 /* we restore the process signal mask as the sigreturn should 1072 do it (XXX: use sigsetjmp) */ 1073 sigprocmask(SIG_SETMASK, old_set, NULL); 1074 cpu_loop_exit(); 1075 } else { 1076 /* activate soft MMU for this block */ 1077 cpu_resume_from_signal(env, puc); 1078 } 1079 /* never comes here */ 1080 return 1; 1081 } 1082 1083 #elif defined (TARGET_SH4) 1084 static inline int handle_cpu_signal(unsigned long pc, unsigned long address, 1085 int is_write, sigset_t *old_set, 1086 void *puc) 1087 { 1088 TranslationBlock *tb; 1089 int ret; 1090 1091 if (cpu_single_env) 1092 env = cpu_single_env; /* XXX: find a correct solution for multithread */ 1093 #if defined(DEBUG_SIGNAL) 1094 printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 1095 pc, address, is_write, *(unsigned long *)old_set); 1096 #endif 1097 /* XXX: locking issue */ 1098 if (is_write && page_unprotect(h2g(address), pc, puc)) { 1099 return 1; 1100 } 1101 1102 /* see if it is an MMU fault */ 1103 ret = cpu_sh4_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); 1104 if (ret < 0) 1105 return 0; /* not an MMU fault */ 1106 if (ret == 0) 1107 return 1; /* the MMU fault was handled without causing real CPU fault */ 1108 1109 /* now we have a real cpu fault */ 1110 tb = tb_find_pc(pc); 1111 if (tb) { 1112 /* the PC is inside the translated code. It means that we have 1113 a virtual CPU fault */ 1114 cpu_restore_state(tb, env, pc, puc); 1115 } 1116 #if 0 1117 printf("PF exception: NIP=0x%08x error=0x%x %p\n", 1118 env->nip, env->error_code, tb); 1119 #endif 1120 /* we restore the process signal mask as the sigreturn should 1121 do it (XXX: use sigsetjmp) */ 1122 sigprocmask(SIG_SETMASK, old_set, NULL); 1123 cpu_loop_exit(); 1124 /* never comes here */ 1125 return 1; 1126 } 1127 1128 #elif defined (TARGET_ALPHA) 1129 static inline int handle_cpu_signal(unsigned long pc, unsigned long address, 1130 int is_write, sigset_t *old_set, 1131 void *puc) 1132 { 1133 TranslationBlock *tb; 1134 int ret; 1135 1136 if (cpu_single_env) 1137 env = cpu_single_env; /* XXX: find a correct solution for multithread */ 1138 #if defined(DEBUG_SIGNAL) 1139 printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 1140 pc, address, is_write, *(unsigned long *)old_set); 1141 #endif 1142 /* XXX: locking issue */ 1143 if (is_write && page_unprotect(h2g(address), pc, puc)) { 1144 return 1; 1145 } 1146 1147 /* see if it is an MMU fault */ 1148 ret = cpu_alpha_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); 1149 if (ret < 0) 1150 return 0; /* not an MMU fault */ 1151 if (ret == 0) 1152 return 1; /* the MMU fault was handled without causing real CPU fault */ 1153 1154 /* now we have a real cpu fault */ 1155 tb = tb_find_pc(pc); 1156 if (tb) { 1157 /* the PC is inside the translated code. It means that we have 1158 a virtual CPU fault */ 1159 cpu_restore_state(tb, env, pc, puc); 1160 } 1161 #if 0 1162 printf("PF exception: NIP=0x%08x error=0x%x %p\n", 1163 env->nip, env->error_code, tb); 1164 #endif 1165 /* we restore the process signal mask as the sigreturn should 1166 do it (XXX: use sigsetjmp) */ 1167 sigprocmask(SIG_SETMASK, old_set, NULL); 1168 cpu_loop_exit(); 1169 /* never comes here */ 1170 return 1; 1171 } 1172 #elif defined (TARGET_CRIS) 1173 static inline int handle_cpu_signal(unsigned long pc, unsigned long address, 1174 int is_write, sigset_t *old_set, 1175 void *puc) 1176 { 1177 TranslationBlock *tb; 1178 int ret; 1179 1180 if (cpu_single_env) 1181 env = cpu_single_env; /* XXX: find a correct solution for multithread */ 1182 #if defined(DEBUG_SIGNAL) 1183 printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 1184 pc, address, is_write, *(unsigned long *)old_set); 1185 #endif 1186 /* XXX: locking issue */ 1187 if (is_write && page_unprotect(h2g(address), pc, puc)) { 1188 return 1; 1189 } 1190 1191 /* see if it is an MMU fault */ 1192 ret = cpu_cris_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); 1193 if (ret < 0) 1194 return 0; /* not an MMU fault */ 1195 if (ret == 0) 1196 return 1; /* the MMU fault was handled without causing real CPU fault */ 1197 1198 /* now we have a real cpu fault */ 1199 tb = tb_find_pc(pc); 1200 if (tb) { 1201 /* the PC is inside the translated code. It means that we have 1202 a virtual CPU fault */ 1203 cpu_restore_state(tb, env, pc, puc); 1204 } 1205 /* we restore the process signal mask as the sigreturn should 1206 do it (XXX: use sigsetjmp) */ 1207 sigprocmask(SIG_SETMASK, old_set, NULL); 1208 cpu_loop_exit(); 1209 /* never comes here */ 1210 return 1; 1211 } 1212 1213 #else 1214 #error unsupported target CPU 1215 #endif 1216 1217 #if defined(__i386__) 1218 1219 #if defined(__APPLE__) 1220 # include <sys/ucontext.h> 1221 1222 # define EIP_sig(context) (*((unsigned long*)&(context)->uc_mcontext->ss.eip)) 1223 # define TRAP_sig(context) ((context)->uc_mcontext->es.trapno) 1224 # define ERROR_sig(context) ((context)->uc_mcontext->es.err) 1225 # define MASK_sig(context) ((context)->uc_sigmask) 1226 #elif defined(__OpenBSD__) 1227 # define EIP_sig(context) ((context)->sc_eip) 1228 # define TRAP_sig(context) ((context)->sc_trapno) 1229 # define ERROR_sig(context) ((context)->sc_err) 1230 # define MASK_sig(context) ((context)->sc_mask) 1231 #else 1232 # define EIP_sig(context) ((context)->uc_mcontext.gregs[REG_EIP]) 1233 # define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO]) 1234 # define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR]) 1235 # define MASK_sig(context) ((context)->uc_sigmask) 1236 #endif 1237 1238 int cpu_signal_handler(int host_signum, void *pinfo, 1239 void *puc) 1240 { 1241 siginfo_t *info = pinfo; 1242 #if defined(__OpenBSD__) 1243 struct sigcontext *uc = puc; 1244 #else 1245 struct ucontext *uc = puc; 1246 #endif 1247 unsigned long pc; 1248 int trapno; 1249 1250 #ifndef REG_EIP 1251 /* for glibc 2.1 */ 1252 #define REG_EIP EIP 1253 #define REG_ERR ERR 1254 #define REG_TRAPNO TRAPNO 1255 #endif 1256 pc = EIP_sig(uc); 1257 trapno = TRAP_sig(uc); 1258 return handle_cpu_signal(pc, (unsigned long)info->si_addr, 1259 trapno == 0xe ? 1260 (ERROR_sig(uc) >> 1) & 1 : 0, 1261 &MASK_sig(uc), puc); 1262 } 1263 1264 #elif defined(__x86_64__) 1265 1266 #ifdef __NetBSD__ 1267 #define PC_sig(context) _UC_MACHINE_PC(context) 1268 #define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO]) 1269 #define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR]) 1270 #define MASK_sig(context) ((context)->uc_sigmask) 1271 #elif defined(__OpenBSD__) 1272 #define PC_sig(context) ((context)->sc_rip) 1273 #define TRAP_sig(context) ((context)->sc_trapno) 1274 #define ERROR_sig(context) ((context)->sc_err) 1275 #define MASK_sig(context) ((context)->sc_mask) 1276 #else 1277 #define PC_sig(context) ((context)->uc_mcontext.gregs[REG_RIP]) 1278 #define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO]) 1279 #define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR]) 1280 #define MASK_sig(context) ((context)->uc_sigmask) 1281 #endif 1282 1283 int cpu_signal_handler(int host_signum, void *pinfo, 1284 void *puc) 1285 { 1286 siginfo_t *info = pinfo; 1287 unsigned long pc; 1288 #ifdef __NetBSD__ 1289 ucontext_t *uc = puc; 1290 #elif defined(__OpenBSD__) 1291 struct sigcontext *uc = puc; 1292 #else 1293 struct ucontext *uc = puc; 1294 #endif 1295 1296 pc = PC_sig(uc); 1297 return handle_cpu_signal(pc, (unsigned long)info->si_addr, 1298 TRAP_sig(uc) == 0xe ? 1299 (ERROR_sig(uc) >> 1) & 1 : 0, 1300 &MASK_sig(uc), puc); 1301 } 1302 1303 #elif defined(_ARCH_PPC) 1304 1305 /*********************************************************************** 1306 * signal context platform-specific definitions 1307 * From Wine 1308 */ 1309 #ifdef linux 1310 /* All Registers access - only for local access */ 1311 # define REG_sig(reg_name, context) ((context)->uc_mcontext.regs->reg_name) 1312 /* Gpr Registers access */ 1313 # define GPR_sig(reg_num, context) REG_sig(gpr[reg_num], context) 1314 # define IAR_sig(context) REG_sig(nip, context) /* Program counter */ 1315 # define MSR_sig(context) REG_sig(msr, context) /* Machine State Register (Supervisor) */ 1316 # define CTR_sig(context) REG_sig(ctr, context) /* Count register */ 1317 # define XER_sig(context) REG_sig(xer, context) /* User's integer exception register */ 1318 # define LR_sig(context) REG_sig(link, context) /* Link register */ 1319 # define CR_sig(context) REG_sig(ccr, context) /* Condition register */ 1320 /* Float Registers access */ 1321 # define FLOAT_sig(reg_num, context) (((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num]) 1322 # define FPSCR_sig(context) (*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4))) 1323 /* Exception Registers access */ 1324 # define DAR_sig(context) REG_sig(dar, context) 1325 # define DSISR_sig(context) REG_sig(dsisr, context) 1326 # define TRAP_sig(context) REG_sig(trap, context) 1327 #endif /* linux */ 1328 1329 #ifdef __APPLE__ 1330 # include <sys/ucontext.h> 1331 typedef struct ucontext SIGCONTEXT; 1332 /* All Registers access - only for local access */ 1333 # define REG_sig(reg_name, context) ((context)->uc_mcontext->ss.reg_name) 1334 # define FLOATREG_sig(reg_name, context) ((context)->uc_mcontext->fs.reg_name) 1335 # define EXCEPREG_sig(reg_name, context) ((context)->uc_mcontext->es.reg_name) 1336 # define VECREG_sig(reg_name, context) ((context)->uc_mcontext->vs.reg_name) 1337 /* Gpr Registers access */ 1338 # define GPR_sig(reg_num, context) REG_sig(r##reg_num, context) 1339 # define IAR_sig(context) REG_sig(srr0, context) /* Program counter */ 1340 # define MSR_sig(context) REG_sig(srr1, context) /* Machine State Register (Supervisor) */ 1341 # define CTR_sig(context) REG_sig(ctr, context) 1342 # define XER_sig(context) REG_sig(xer, context) /* Link register */ 1343 # define LR_sig(context) REG_sig(lr, context) /* User's integer exception register */ 1344 # define CR_sig(context) REG_sig(cr, context) /* Condition register */ 1345 /* Float Registers access */ 1346 # define FLOAT_sig(reg_num, context) FLOATREG_sig(fpregs[reg_num], context) 1347 # define FPSCR_sig(context) ((double)FLOATREG_sig(fpscr, context)) 1348 /* Exception Registers access */ 1349 # define DAR_sig(context) EXCEPREG_sig(dar, context) /* Fault registers for coredump */ 1350 # define DSISR_sig(context) EXCEPREG_sig(dsisr, context) 1351 # define TRAP_sig(context) EXCEPREG_sig(exception, context) /* number of powerpc exception taken */ 1352 #endif /* __APPLE__ */ 1353 1354 int cpu_signal_handler(int host_signum, void *pinfo, 1355 void *puc) 1356 { 1357 siginfo_t *info = pinfo; 1358 struct ucontext *uc = puc; 1359 unsigned long pc; 1360 int is_write; 1361 1362 pc = IAR_sig(uc); 1363 is_write = 0; 1364 #if 0 1365 /* ppc 4xx case */ 1366 if (DSISR_sig(uc) & 0x00800000) 1367 is_write = 1; 1368 #else 1369 if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000)) 1370 is_write = 1; 1371 #endif 1372 return handle_cpu_signal(pc, (unsigned long)info->si_addr, 1373 is_write, &uc->uc_sigmask, puc); 1374 } 1375 1376 #elif defined(__alpha__) 1377 1378 int cpu_signal_handler(int host_signum, void *pinfo, 1379 void *puc) 1380 { 1381 siginfo_t *info = pinfo; 1382 struct ucontext *uc = puc; 1383 uint32_t *pc = uc->uc_mcontext.sc_pc; 1384 uint32_t insn = *pc; 1385 int is_write = 0; 1386 1387 /* XXX: need kernel patch to get write flag faster */ 1388 switch (insn >> 26) { 1389 case 0x0d: // stw 1390 case 0x0e: // stb 1391 case 0x0f: // stq_u 1392 case 0x24: // stf 1393 case 0x25: // stg 1394 case 0x26: // sts 1395 case 0x27: // stt 1396 case 0x2c: // stl 1397 case 0x2d: // stq 1398 case 0x2e: // stl_c 1399 case 0x2f: // stq_c 1400 is_write = 1; 1401 } 1402 1403 return handle_cpu_signal(pc, (unsigned long)info->si_addr, 1404 is_write, &uc->uc_sigmask, puc); 1405 } 1406 #elif defined(__sparc__) 1407 1408 int cpu_signal_handler(int host_signum, void *pinfo, 1409 void *puc) 1410 { 1411 siginfo_t *info = pinfo; 1412 int is_write; 1413 uint32_t insn; 1414 #if !defined(__arch64__) || defined(CONFIG_SOLARIS) 1415 uint32_t *regs = (uint32_t *)(info + 1); 1416 void *sigmask = (regs + 20); 1417 /* XXX: is there a standard glibc define ? */ 1418 unsigned long pc = regs[1]; 1419 #else 1420 #ifdef __linux__ 1421 struct sigcontext *sc = puc; 1422 unsigned long pc = sc->sigc_regs.tpc; 1423 void *sigmask = (void *)sc->sigc_mask; 1424 #elif defined(__OpenBSD__) 1425 struct sigcontext *uc = puc; 1426 unsigned long pc = uc->sc_pc; 1427 void *sigmask = (void *)(long)uc->sc_mask; 1428 #endif 1429 #endif 1430 1431 /* XXX: need kernel patch to get write flag faster */ 1432 is_write = 0; 1433 insn = *(uint32_t *)pc; 1434 if ((insn >> 30) == 3) { 1435 switch((insn >> 19) & 0x3f) { 1436 case 0x05: // stb 1437 case 0x15: // stba 1438 case 0x06: // sth 1439 case 0x16: // stha 1440 case 0x04: // st 1441 case 0x14: // sta 1442 case 0x07: // std 1443 case 0x17: // stda 1444 case 0x0e: // stx 1445 case 0x1e: // stxa 1446 case 0x24: // stf 1447 case 0x34: // stfa 1448 case 0x27: // stdf 1449 case 0x37: // stdfa 1450 case 0x26: // stqf 1451 case 0x36: // stqfa 1452 case 0x25: // stfsr 1453 case 0x3c: // casa 1454 case 0x3e: // casxa 1455 is_write = 1; 1456 break; 1457 } 1458 } 1459 return handle_cpu_signal(pc, (unsigned long)info->si_addr, 1460 is_write, sigmask, NULL); 1461 } 1462 1463 #elif defined(__arm__) 1464 1465 int cpu_signal_handler(int host_signum, void *pinfo, 1466 void *puc) 1467 { 1468 siginfo_t *info = pinfo; 1469 struct ucontext *uc = puc; 1470 unsigned long pc; 1471 int is_write; 1472 1473 #if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3)) 1474 pc = uc->uc_mcontext.gregs[R15]; 1475 #else 1476 pc = uc->uc_mcontext.arm_pc; 1477 #endif 1478 /* XXX: compute is_write */ 1479 is_write = 0; 1480 return handle_cpu_signal(pc, (unsigned long)info->si_addr, 1481 is_write, 1482 &uc->uc_sigmask, puc); 1483 } 1484 1485 #elif defined(__mc68000) 1486 1487 int cpu_signal_handler(int host_signum, void *pinfo, 1488 void *puc) 1489 { 1490 siginfo_t *info = pinfo; 1491 struct ucontext *uc = puc; 1492 unsigned long pc; 1493 int is_write; 1494 1495 pc = uc->uc_mcontext.gregs[16]; 1496 /* XXX: compute is_write */ 1497 is_write = 0; 1498 return handle_cpu_signal(pc, (unsigned long)info->si_addr, 1499 is_write, 1500 &uc->uc_sigmask, puc); 1501 } 1502 1503 #elif defined(__ia64) 1504 1505 #ifndef __ISR_VALID 1506 /* This ought to be in <bits/siginfo.h>... */ 1507 # define __ISR_VALID 1 1508 #endif 1509 1510 int cpu_signal_handler(int host_signum, void *pinfo, void *puc) 1511 { 1512 siginfo_t *info = pinfo; 1513 struct ucontext *uc = puc; 1514 unsigned long ip; 1515 int is_write = 0; 1516 1517 ip = uc->uc_mcontext.sc_ip; 1518 switch (host_signum) { 1519 case SIGILL: 1520 case SIGFPE: 1521 case SIGSEGV: 1522 case SIGBUS: 1523 case SIGTRAP: 1524 if (info->si_code && (info->si_segvflags & __ISR_VALID)) 1525 /* ISR.W (write-access) is bit 33: */ 1526 is_write = (info->si_isr >> 33) & 1; 1527 break; 1528 1529 default: 1530 break; 1531 } 1532 return handle_cpu_signal(ip, (unsigned long)info->si_addr, 1533 is_write, 1534 &uc->uc_sigmask, puc); 1535 } 1536 1537 #elif defined(__s390__) 1538 1539 int cpu_signal_handler(int host_signum, void *pinfo, 1540 void *puc) 1541 { 1542 siginfo_t *info = pinfo; 1543 struct ucontext *uc = puc; 1544 unsigned long pc; 1545 int is_write; 1546 1547 pc = uc->uc_mcontext.psw.addr; 1548 /* XXX: compute is_write */ 1549 is_write = 0; 1550 return handle_cpu_signal(pc, (unsigned long)info->si_addr, 1551 is_write, &uc->uc_sigmask, puc); 1552 } 1553 1554 #elif defined(__mips__) 1555 1556 int cpu_signal_handler(int host_signum, void *pinfo, 1557 void *puc) 1558 { 1559 siginfo_t *info = pinfo; 1560 struct ucontext *uc = puc; 1561 greg_t pc = uc->uc_mcontext.pc; 1562 int is_write; 1563 1564 /* XXX: compute is_write */ 1565 is_write = 0; 1566 return handle_cpu_signal(pc, (unsigned long)info->si_addr, 1567 is_write, &uc->uc_sigmask, puc); 1568 } 1569 1570 #elif defined(__hppa__) 1571 1572 int cpu_signal_handler(int host_signum, void *pinfo, 1573 void *puc) 1574 { 1575 struct siginfo *info = pinfo; 1576 struct ucontext *uc = puc; 1577 unsigned long pc; 1578 int is_write; 1579 1580 pc = uc->uc_mcontext.sc_iaoq[0]; 1581 /* FIXME: compute is_write */ 1582 is_write = 0; 1583 return handle_cpu_signal(pc, (unsigned long)info->si_addr, 1584 is_write, 1585 &uc->uc_sigmask, puc); 1586 } 1587 1588 #else 1589 1590 #error host CPU specific signal handler needed 1591 1592 #endif 1593 1594 #endif /* !defined(CONFIG_SOFTMMU) */ 1595