void cpu_loop(CPUX86State *env) { CPUState *cs = CPU(x86_env_get_cpu(env)); int trapnr; abi_ulong pc; target_siginfo_t info; for(;;) { cpu_exec_start(cs); trapnr = cpu_x86_exec(cs); cpu_exec_end(cs); switch(trapnr) { case 0x80: /* linux syscall from int $0x80 */ env->regs[R_EAX] = do_syscall(env, env->regs[R_EAX], env->regs[R_EBX], env->regs[R_ECX], env->regs[R_EDX], env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP], 0, 0); break; #ifndef TARGET_ABI32 case EXCP_SYSCALL: /* linux syscall from syscall instruction */ env->regs[R_EAX] = do_syscall(env, env->regs[R_EAX], env->regs[R_EDI], env->regs[R_ESI], env->regs[R_EDX], env->regs[10], env->regs[8], env->regs[9], 0, 0); break; #endif case EXCP0B_NOSEG: case EXCP0C_STACK: info.si_signo = TARGET_SIGBUS; info.si_errno = 0; info.si_code = TARGET_SI_KERNEL; info._sifields._sigfault._addr = 0; queue_signal(env, info.si_signo, &info); break; case EXCP0D_GPF: /* XXX: potential problem if ABI32 */ #ifndef TARGET_X86_64 if (env->eflags & VM_MASK) { handle_vm86_fault(env); } else #endif { info.si_signo = TARGET_SIGSEGV; info.si_errno = 0; info.si_code = TARGET_SI_KERNEL; info._sifields._sigfault._addr = 0; queue_signal(env, info.si_signo, &info); } break; case EXCP0E_PAGE: info.si_signo = TARGET_SIGSEGV; info.si_errno = 0; if (!(env->error_code & 1)) info.si_code = TARGET_SEGV_MAPERR; else info.si_code = TARGET_SEGV_ACCERR; info._sifields._sigfault._addr = env->cr[2]; queue_signal(env, info.si_signo, &info); break; case EXCP00_DIVZ: #ifndef TARGET_X86_64 if (env->eflags & VM_MASK) { handle_vm86_trap(env, trapnr); } else #endif { /* division by zero */ info.si_signo = TARGET_SIGFPE; info.si_errno = 0; info.si_code = TARGET_FPE_INTDIV; info._sifields._sigfault._addr = env->eip; queue_signal(env, info.si_signo, &info); } break; case EXCP01_DB: case EXCP03_INT3: #ifndef TARGET_X86_64 if (env->eflags & VM_MASK) { handle_vm86_trap(env, trapnr); } else #endif { info.si_signo = TARGET_SIGTRAP; info.si_errno = 0; if (trapnr == EXCP01_DB) { info.si_code = TARGET_TRAP_BRKPT; info._sifields._sigfault._addr = env->eip; } else { info.si_code = TARGET_SI_KERNEL; info._sifields._sigfault._addr = 0; } queue_signal(env, info.si_signo, &info); } break; case EXCP04_INTO: case EXCP05_BOUND: #ifndef TARGET_X86_64 if (env->eflags & VM_MASK) { handle_vm86_trap(env, trapnr); } else #endif { info.si_signo = TARGET_SIGSEGV; info.si_errno = 0; info.si_code = TARGET_SI_KERNEL; info._sifields._sigfault._addr = 0; queue_signal(env, info.si_signo, &info); } break; case EXCP06_ILLOP: info.si_signo = TARGET_SIGILL; info.si_errno = 0; info.si_code = TARGET_ILL_ILLOPN; info._sifields._sigfault._addr = env->eip; queue_signal(env, info.si_signo, &info); break; case EXCP_INTERRUPT: /* just indicate that signals should be handled asap */ break; case EXCP_DEBUG: { int sig; sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; info.si_errno = 0; info.si_code = TARGET_TRAP_BRKPT; queue_signal(env, info.si_signo, &info); } } break; default: pc = env->segs[R_CS].base + env->eip; EXCP_DUMP(env, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n", (long)pc, trapnr); abort(); } process_pending_signals(env); } }
void cpu_loop(CPUX86State *env) { CPUState *cs = CPU(x86_env_get_cpu(env)); int trapnr; abi_ulong pc; target_siginfo_t info; for(;;) { cpu_exec_start(cs); trapnr = cpu_x86_exec(cs); cpu_exec_end(cs); switch(trapnr) { case 0x80:   env->regs[R_EAX] = do_syscall(env, env->regs[R_EAX], env->regs[R_EBX], env->regs[R_ECX], env->regs[R_EDX], env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP], 0, 0); break; #ifndef TARGET_ABI32 case EXCP_SYSCALL:   env->regs[R_EAX] = do_syscall(env, env->regs[R_EAX], env->regs[R_EDI], env->regs[R_ESI], env->regs[R_EDX], env->regs[10], env->regs[8], env->regs[9], 0, 0); break; #endif case EXCP0B_NOSEG: case EXCP0C_STACK: info.si_signo = TARGET_SIGBUS; info.si_errno = 0; info.si_code = TARGET_SI_KERNEL; info._sifields._sigfault._addr = 0; queue_signal(env, info.si_signo, &info); break; case EXCP0D_GPF:   #ifndef TARGET_X86_64 if (env->eflags & VM_MASK) { handle_vm86_fault(env); } else #endif { info.si_signo = TARGET_SIGSEGV; info.si_errno = 0; info.si_code = TARGET_SI_KERNEL; info._sifields._sigfault._addr = 0; queue_signal(env, info.si_signo, &info); } break; case EXCP0E_PAGE: info.si_signo = TARGET_SIGSEGV; info.si_errno = 0; if (!(env->error_code & 1)) info.si_code = TARGET_SEGV_MAPERR; else info.si_code = TARGET_SEGV_ACCERR; info._sifields._sigfault._addr = env->cr[2]; queue_signal(env, info.si_signo, &info); break; case EXCP00_DIVZ: #ifndef TARGET_X86_64 if (env->eflags & VM_MASK) { handle_vm86_trap(env, trapnr); } else #endif {   info.si_signo = TARGET_SIGFPE; info.si_errno = 0; info.si_code = TARGET_FPE_INTDIV; info._sifields._sigfault._addr = env->eip; queue_signal(env, info.si_signo, &info); } break; case EXCP01_DB: case EXCP03_INT3: #ifndef TARGET_X86_64 if (env->eflags & VM_MASK) { handle_vm86_trap(env, trapnr); } else #endif { info.si_signo = TARGET_SIGTRAP; info.si_errno = 0; if (trapnr == EXCP01_DB) { info.si_code = TARGET_TRAP_BRKPT; info._sifields._sigfault._addr = env->eip; } else { info.si_code = TARGET_SI_KERNEL; info._sifields._sigfault._addr = 0; } queue_signal(env, info.si_signo, &info); } break; case EXCP04_INTO: case EXCP05_BOUND: #ifndef TARGET_X86_64 if (env->eflags & VM_MASK) { handle_vm86_trap(env, trapnr); } else #endif { info.si_signo = TARGET_SIGSEGV; info.si_errno = 0; info.si_code = TARGET_SI_KERNEL; info._sifields._sigfault._addr = 0; queue_signal(env, info.si_signo, &info); } break; case EXCP06_ILLOP: info.si_signo = TARGET_SIGILL; info.si_errno = 0; info.si_code = TARGET_ILL_ILLOPN; info._sifields._sigfault._addr = env->eip; queue_signal(env, info.si_signo, &info); break; case EXCP_INTERRUPT:   break; case EXCP_DEBUG: { int sig; sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; info.si_errno = 0; info.si_code = TARGET_TRAP_BRKPT; queue_signal(env, info.si_signo, &info); } } break; default: pc = env->segs[R_CS].base + env->eip; EXCP_DUMP(env, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n", (long)pc, trapnr); abort(); } process_pending_signals(env); } }