Loading cpu-exec.c +172 −131 Original line number Diff line number Diff line Loading @@ -64,21 +64,31 @@ void cpu_loop_exit(void) /* exit the current TB from a signal handler. The host registers are restored in a state compatible with the CPU emulator */ #if defined(CONFIG_SOFTMMU) void cpu_resume_from_signal(CPUState *env1, void *puc) { env = env1; /* XXX: restore cpu registers saved in host registers */ env->exception_index = -1; longjmp(env->jmp_env, 1); } #else void cpu_resume_from_signal(CPUState *env1, void *puc) { #if !defined(CONFIG_SOFTMMU) #ifdef __linux__ struct ucontext *uc = puc; #elif defined(__OpenBSD__) struct sigcontext *uc = puc; #endif #endif env = env1; /* XXX: restore cpu registers saved in host registers */ #if !defined(CONFIG_SOFTMMU) if (puc) { /* XXX: use siglongjmp ? */ #ifdef __linux__ Loading @@ -91,10 +101,10 @@ void cpu_resume_from_signal(CPUState *env1, void *puc) sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL); #endif } #endif env->exception_index = -1; longjmp(env->jmp_env, 1); } #endif /* Execute the code without caching the generated code. An interpreter could be used if available. */ Loading Loading @@ -751,9 +761,11 @@ void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32) #if !defined(CONFIG_SOFTMMU) #if defined(TARGET_I386) #define EXCEPTION_ACTION raise_exception_err(env->exception_index, env->error_code) #define EXCEPTION_ACTION \ raise_exception_err(env->exception_index, env->error_code) #else #define EXCEPTION_ACTION cpu_loop_exit() #define EXCEPTION_ACTION \ cpu_loop_exit() #endif /* 'pc' is the host PC at which the exception was raised. 'address' is Loading @@ -767,8 +779,9 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, TranslationBlock *tb; int ret; if (cpu_single_env) if (cpu_single_env) { env = cpu_single_env; /* XXX: find a correct solution for multithread */ } #if defined(DEBUG_SIGNAL) qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", pc, address, is_write, *(unsigned long *)old_set); Loading @@ -780,10 +793,12 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, /* see if it is an MMU fault */ ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); if (ret < 0) if (ret < 0) { return 0; /* not an MMU fault */ if (ret == 0) } if (ret == 0) { return 1; /* the MMU fault was handled without causing real CPU fault */ } /* now we have a real cpu fault */ tb = tb_find_pc(pc); if (tb) { Loading Loading @@ -918,18 +933,28 @@ int cpu_signal_handler(int host_signum, void *pinfo, */ #ifdef linux /* All Registers access - only for local access */ # define REG_sig(reg_name, context) ((context)->uc_mcontext.regs->reg_name) #define REG_sig(reg_name, context) \ ((context)->uc_mcontext.regs->reg_name) /* Gpr Registers access */ #define GPR_sig(reg_num, context) REG_sig(gpr[reg_num], context) # define IAR_sig(context) REG_sig(nip, context) /* Program counter */ # define MSR_sig(context) REG_sig(msr, context) /* Machine State Register (Supervisor) */ # define CTR_sig(context) REG_sig(ctr, context) /* Count register */ # define XER_sig(context) REG_sig(xer, context) /* User's integer exception register */ # define LR_sig(context) REG_sig(link, context) /* Link register */ # define CR_sig(context) REG_sig(ccr, context) /* Condition register */ /* Program counter */ #define IAR_sig(context) REG_sig(nip, context) /* Machine State Register (Supervisor) */ #define MSR_sig(context) REG_sig(msr, context) /* Count register */ #define CTR_sig(context) REG_sig(ctr, context) /* User's integer exception register */ #define XER_sig(context) REG_sig(xer, context) /* Link register */ #define LR_sig(context) REG_sig(link, context) /* Condition register */ #define CR_sig(context) REG_sig(ccr, context) /* Float Registers access */ # define FLOAT_sig(reg_num, context) (((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num]) # define FPSCR_sig(context) (*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4))) #define FLOAT_sig(reg_num, context) \ (((double *)((char *)((context)->uc_mcontext.regs + 48 * 4)))[reg_num]) #define FPSCR_sig(context) \ (*(int *)((char *)((context)->uc_mcontext.regs + (48 + 32 * 2) * 4))) /* Exception Registers access */ #define DAR_sig(context) REG_sig(dar, context) #define DSISR_sig(context) REG_sig(dsisr, context) Loading @@ -954,25 +979,38 @@ int cpu_signal_handler(int host_signum, void *pinfo, #include <sys/ucontext.h> typedef struct ucontext SIGCONTEXT; /* All Registers access - only for local access */ # define REG_sig(reg_name, context) ((context)->uc_mcontext->ss.reg_name) # define FLOATREG_sig(reg_name, context) ((context)->uc_mcontext->fs.reg_name) # define EXCEPREG_sig(reg_name, context) ((context)->uc_mcontext->es.reg_name) # define VECREG_sig(reg_name, context) ((context)->uc_mcontext->vs.reg_name) #define REG_sig(reg_name, context) \ ((context)->uc_mcontext->ss.reg_name) #define FLOATREG_sig(reg_name, context) \ ((context)->uc_mcontext->fs.reg_name) #define EXCEPREG_sig(reg_name, context) \ ((context)->uc_mcontext->es.reg_name) #define VECREG_sig(reg_name, context) \ ((context)->uc_mcontext->vs.reg_name) /* Gpr Registers access */ #define GPR_sig(reg_num, context) REG_sig(r##reg_num, context) # define IAR_sig(context) REG_sig(srr0, context) /* Program counter */ # define MSR_sig(context) REG_sig(srr1, context) /* Machine State Register (Supervisor) */ /* Program counter */ #define IAR_sig(context) REG_sig(srr0, context) /* Machine State Register (Supervisor) */ #define MSR_sig(context) REG_sig(srr1, context) #define CTR_sig(context) REG_sig(ctr, context) # define XER_sig(context) REG_sig(xer, context) /* Link register */ # define LR_sig(context) REG_sig(lr, context) /* User's integer exception register */ # define CR_sig(context) REG_sig(cr, context) /* Condition register */ /* Link register */ #define XER_sig(context) REG_sig(xer, context) /* User's integer exception register */ #define LR_sig(context) REG_sig(lr, context) /* Condition register */ #define CR_sig(context) REG_sig(cr, context) /* Float Registers access */ # define FLOAT_sig(reg_num, context) FLOATREG_sig(fpregs[reg_num], context) # define FPSCR_sig(context) ((double)FLOATREG_sig(fpscr, context)) #define FLOAT_sig(reg_num, context) \ FLOATREG_sig(fpregs[reg_num], context) #define FPSCR_sig(context) \ ((double)FLOATREG_sig(fpscr, context)) /* Exception Registers access */ # define DAR_sig(context) EXCEPREG_sig(dar, context) /* Fault registers for coredump */ /* Fault registers for coredump */ #define DAR_sig(context) EXCEPREG_sig(dar, context) #define DSISR_sig(context) EXCEPREG_sig(dsisr, context) # define TRAP_sig(context) EXCEPREG_sig(exception, context) /* number of powerpc exception taken */ /* number of powerpc exception taken */ #define TRAP_sig(context) EXCEPREG_sig(exception, context) #endif /* __APPLE__ */ int cpu_signal_handler(int host_signum, void *pinfo, Loading @@ -991,11 +1029,13 @@ int cpu_signal_handler(int host_signum, void *pinfo, is_write = 0; #if 0 /* ppc 4xx case */ if (DSISR_sig(uc) & 0x00800000) if (DSISR_sig(uc) & 0x00800000) { is_write = 1; } #else if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000)) if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000)) { is_write = 1; } #endif return handle_cpu_signal(pc, (unsigned long)info->si_addr, is_write, &uc->uc_sigmask, puc); Loading @@ -1014,17 +1054,17 @@ int cpu_signal_handler(int host_signum, void *pinfo, /* XXX: need kernel patch to get write flag faster */ switch (insn >> 26) { case 0x0d: // stw case 0x0e: // stb case 0x0f: // stq_u case 0x24: // stf case 0x25: // stg case 0x26: // sts case 0x27: // stt case 0x2c: // stl case 0x2d: // stq case 0x2e: // stl_c case 0x2f: // stq_c case 0x0d: /* stw */ case 0x0e: /* stb */ case 0x0f: /* stq_u */ case 0x24: /* stf */ case 0x25: /* stg */ case 0x26: /* sts */ case 0x27: /* stt */ case 0x2c: /* stl */ case 0x2d: /* stq */ case 0x2e: /* stl_c */ case 0x2f: /* stq_c */ is_write = 1; } Loading Loading @@ -1061,25 +1101,25 @@ int cpu_signal_handler(int host_signum, void *pinfo, insn = *(uint32_t *)pc; if ((insn >> 30) == 3) { switch ((insn >> 19) & 0x3f) { case 0x05: // stb case 0x15: // stba case 0x06: // sth case 0x16: // stha case 0x04: // st case 0x14: // sta case 0x07: // std case 0x17: // stda case 0x0e: // stx case 0x1e: // stxa case 0x24: // stf case 0x34: // stfa case 0x27: // stdf case 0x37: // stdfa case 0x26: // stqf case 0x36: // stqfa case 0x25: // stfsr case 0x3c: // casa case 0x3e: // casxa case 0x05: /* stb */ case 0x15: /* stba */ case 0x06: /* sth */ case 0x16: /* stha */ case 0x04: /* st */ case 0x14: /* sta */ case 0x07: /* std */ case 0x17: /* stda */ case 0x0e: /* stx */ case 0x1e: /* stxa */ case 0x24: /* stf */ case 0x34: /* stfa */ case 0x27: /* stdf */ case 0x37: /* stdfa */ case 0x26: /* stqf */ case 0x36: /* stqfa */ case 0x25: /* stfsr */ case 0x3c: /* casa */ case 0x3e: /* casxa */ is_write = 1; break; } Loading Loading @@ -1149,9 +1189,10 @@ int cpu_signal_handler(int host_signum, void *pinfo, void *puc) case SIGSEGV: case SIGBUS: case SIGTRAP: if (info->si_code && (info->si_segvflags & __ISR_VALID)) if (info->si_code && (info->si_segvflags & __ISR_VALID)) { /* ISR.W (write-access) is bit 33: */ is_write = (info->si_isr >> 33) & 1; } break; default: Loading Loading
cpu-exec.c +172 −131 Original line number Diff line number Diff line Loading @@ -64,21 +64,31 @@ void cpu_loop_exit(void) /* exit the current TB from a signal handler. The host registers are restored in a state compatible with the CPU emulator */ #if defined(CONFIG_SOFTMMU) void cpu_resume_from_signal(CPUState *env1, void *puc) { env = env1; /* XXX: restore cpu registers saved in host registers */ env->exception_index = -1; longjmp(env->jmp_env, 1); } #else void cpu_resume_from_signal(CPUState *env1, void *puc) { #if !defined(CONFIG_SOFTMMU) #ifdef __linux__ struct ucontext *uc = puc; #elif defined(__OpenBSD__) struct sigcontext *uc = puc; #endif #endif env = env1; /* XXX: restore cpu registers saved in host registers */ #if !defined(CONFIG_SOFTMMU) if (puc) { /* XXX: use siglongjmp ? */ #ifdef __linux__ Loading @@ -91,10 +101,10 @@ void cpu_resume_from_signal(CPUState *env1, void *puc) sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL); #endif } #endif env->exception_index = -1; longjmp(env->jmp_env, 1); } #endif /* Execute the code without caching the generated code. An interpreter could be used if available. */ Loading Loading @@ -751,9 +761,11 @@ void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32) #if !defined(CONFIG_SOFTMMU) #if defined(TARGET_I386) #define EXCEPTION_ACTION raise_exception_err(env->exception_index, env->error_code) #define EXCEPTION_ACTION \ raise_exception_err(env->exception_index, env->error_code) #else #define EXCEPTION_ACTION cpu_loop_exit() #define EXCEPTION_ACTION \ cpu_loop_exit() #endif /* 'pc' is the host PC at which the exception was raised. 'address' is Loading @@ -767,8 +779,9 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, TranslationBlock *tb; int ret; if (cpu_single_env) if (cpu_single_env) { env = cpu_single_env; /* XXX: find a correct solution for multithread */ } #if defined(DEBUG_SIGNAL) qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", pc, address, is_write, *(unsigned long *)old_set); Loading @@ -780,10 +793,12 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, /* see if it is an MMU fault */ ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); if (ret < 0) if (ret < 0) { return 0; /* not an MMU fault */ if (ret == 0) } if (ret == 0) { return 1; /* the MMU fault was handled without causing real CPU fault */ } /* now we have a real cpu fault */ tb = tb_find_pc(pc); if (tb) { Loading Loading @@ -918,18 +933,28 @@ int cpu_signal_handler(int host_signum, void *pinfo, */ #ifdef linux /* All Registers access - only for local access */ # define REG_sig(reg_name, context) ((context)->uc_mcontext.regs->reg_name) #define REG_sig(reg_name, context) \ ((context)->uc_mcontext.regs->reg_name) /* Gpr Registers access */ #define GPR_sig(reg_num, context) REG_sig(gpr[reg_num], context) # define IAR_sig(context) REG_sig(nip, context) /* Program counter */ # define MSR_sig(context) REG_sig(msr, context) /* Machine State Register (Supervisor) */ # define CTR_sig(context) REG_sig(ctr, context) /* Count register */ # define XER_sig(context) REG_sig(xer, context) /* User's integer exception register */ # define LR_sig(context) REG_sig(link, context) /* Link register */ # define CR_sig(context) REG_sig(ccr, context) /* Condition register */ /* Program counter */ #define IAR_sig(context) REG_sig(nip, context) /* Machine State Register (Supervisor) */ #define MSR_sig(context) REG_sig(msr, context) /* Count register */ #define CTR_sig(context) REG_sig(ctr, context) /* User's integer exception register */ #define XER_sig(context) REG_sig(xer, context) /* Link register */ #define LR_sig(context) REG_sig(link, context) /* Condition register */ #define CR_sig(context) REG_sig(ccr, context) /* Float Registers access */ # define FLOAT_sig(reg_num, context) (((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num]) # define FPSCR_sig(context) (*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4))) #define FLOAT_sig(reg_num, context) \ (((double *)((char *)((context)->uc_mcontext.regs + 48 * 4)))[reg_num]) #define FPSCR_sig(context) \ (*(int *)((char *)((context)->uc_mcontext.regs + (48 + 32 * 2) * 4))) /* Exception Registers access */ #define DAR_sig(context) REG_sig(dar, context) #define DSISR_sig(context) REG_sig(dsisr, context) Loading @@ -954,25 +979,38 @@ int cpu_signal_handler(int host_signum, void *pinfo, #include <sys/ucontext.h> typedef struct ucontext SIGCONTEXT; /* All Registers access - only for local access */ # define REG_sig(reg_name, context) ((context)->uc_mcontext->ss.reg_name) # define FLOATREG_sig(reg_name, context) ((context)->uc_mcontext->fs.reg_name) # define EXCEPREG_sig(reg_name, context) ((context)->uc_mcontext->es.reg_name) # define VECREG_sig(reg_name, context) ((context)->uc_mcontext->vs.reg_name) #define REG_sig(reg_name, context) \ ((context)->uc_mcontext->ss.reg_name) #define FLOATREG_sig(reg_name, context) \ ((context)->uc_mcontext->fs.reg_name) #define EXCEPREG_sig(reg_name, context) \ ((context)->uc_mcontext->es.reg_name) #define VECREG_sig(reg_name, context) \ ((context)->uc_mcontext->vs.reg_name) /* Gpr Registers access */ #define GPR_sig(reg_num, context) REG_sig(r##reg_num, context) # define IAR_sig(context) REG_sig(srr0, context) /* Program counter */ # define MSR_sig(context) REG_sig(srr1, context) /* Machine State Register (Supervisor) */ /* Program counter */ #define IAR_sig(context) REG_sig(srr0, context) /* Machine State Register (Supervisor) */ #define MSR_sig(context) REG_sig(srr1, context) #define CTR_sig(context) REG_sig(ctr, context) # define XER_sig(context) REG_sig(xer, context) /* Link register */ # define LR_sig(context) REG_sig(lr, context) /* User's integer exception register */ # define CR_sig(context) REG_sig(cr, context) /* Condition register */ /* Link register */ #define XER_sig(context) REG_sig(xer, context) /* User's integer exception register */ #define LR_sig(context) REG_sig(lr, context) /* Condition register */ #define CR_sig(context) REG_sig(cr, context) /* Float Registers access */ # define FLOAT_sig(reg_num, context) FLOATREG_sig(fpregs[reg_num], context) # define FPSCR_sig(context) ((double)FLOATREG_sig(fpscr, context)) #define FLOAT_sig(reg_num, context) \ FLOATREG_sig(fpregs[reg_num], context) #define FPSCR_sig(context) \ ((double)FLOATREG_sig(fpscr, context)) /* Exception Registers access */ # define DAR_sig(context) EXCEPREG_sig(dar, context) /* Fault registers for coredump */ /* Fault registers for coredump */ #define DAR_sig(context) EXCEPREG_sig(dar, context) #define DSISR_sig(context) EXCEPREG_sig(dsisr, context) # define TRAP_sig(context) EXCEPREG_sig(exception, context) /* number of powerpc exception taken */ /* number of powerpc exception taken */ #define TRAP_sig(context) EXCEPREG_sig(exception, context) #endif /* __APPLE__ */ int cpu_signal_handler(int host_signum, void *pinfo, Loading @@ -991,11 +1029,13 @@ int cpu_signal_handler(int host_signum, void *pinfo, is_write = 0; #if 0 /* ppc 4xx case */ if (DSISR_sig(uc) & 0x00800000) if (DSISR_sig(uc) & 0x00800000) { is_write = 1; } #else if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000)) if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000)) { is_write = 1; } #endif return handle_cpu_signal(pc, (unsigned long)info->si_addr, is_write, &uc->uc_sigmask, puc); Loading @@ -1014,17 +1054,17 @@ int cpu_signal_handler(int host_signum, void *pinfo, /* XXX: need kernel patch to get write flag faster */ switch (insn >> 26) { case 0x0d: // stw case 0x0e: // stb case 0x0f: // stq_u case 0x24: // stf case 0x25: // stg case 0x26: // sts case 0x27: // stt case 0x2c: // stl case 0x2d: // stq case 0x2e: // stl_c case 0x2f: // stq_c case 0x0d: /* stw */ case 0x0e: /* stb */ case 0x0f: /* stq_u */ case 0x24: /* stf */ case 0x25: /* stg */ case 0x26: /* sts */ case 0x27: /* stt */ case 0x2c: /* stl */ case 0x2d: /* stq */ case 0x2e: /* stl_c */ case 0x2f: /* stq_c */ is_write = 1; } Loading Loading @@ -1061,25 +1101,25 @@ int cpu_signal_handler(int host_signum, void *pinfo, insn = *(uint32_t *)pc; if ((insn >> 30) == 3) { switch ((insn >> 19) & 0x3f) { case 0x05: // stb case 0x15: // stba case 0x06: // sth case 0x16: // stha case 0x04: // st case 0x14: // sta case 0x07: // std case 0x17: // stda case 0x0e: // stx case 0x1e: // stxa case 0x24: // stf case 0x34: // stfa case 0x27: // stdf case 0x37: // stdfa case 0x26: // stqf case 0x36: // stqfa case 0x25: // stfsr case 0x3c: // casa case 0x3e: // casxa case 0x05: /* stb */ case 0x15: /* stba */ case 0x06: /* sth */ case 0x16: /* stha */ case 0x04: /* st */ case 0x14: /* sta */ case 0x07: /* std */ case 0x17: /* stda */ case 0x0e: /* stx */ case 0x1e: /* stxa */ case 0x24: /* stf */ case 0x34: /* stfa */ case 0x27: /* stdf */ case 0x37: /* stdfa */ case 0x26: /* stqf */ case 0x36: /* stqfa */ case 0x25: /* stfsr */ case 0x3c: /* casa */ case 0x3e: /* casxa */ is_write = 1; break; } Loading Loading @@ -1149,9 +1189,10 @@ int cpu_signal_handler(int host_signum, void *pinfo, void *puc) case SIGSEGV: case SIGBUS: case SIGTRAP: if (info->si_code && (info->si_segvflags & __ISR_VALID)) if (info->si_code && (info->si_segvflags & __ISR_VALID)) { /* ISR.W (write-access) is bit 33: */ is_write = (info->si_isr >> 33) & 1; } break; default: Loading