Index: cpu-exec.c =================================================================== RCS file: /cvsroot/qemu/qemu/cpu-exec.c,v retrieving revision 1.46 diff -u -r1.46 cpu-exec.c --- cpu-exec.c 2 Feb 2005 20:42:01 -0000 1.46 +++ cpu-exec.c 3 Feb 2005 14:04:53 -0000 @@ -731,11 +731,35 @@ int is_write, sigset_t *old_set, void *puc) { + TranslationBlock *tb; + + 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); +#endif /* XXX: locking issue */ if (is_write && page_unprotect(address, pc, puc)) { return 1; } - return 0; + + /* XXX: see if it is an MMU fault */ + env->address=address; + tb = tb_find_pc(pc); + if (tb) { + /* the PC is inside the translated code. It means that we have + a virtual CPU fault */ + cpu_restore_state(tb, env, pc, puc); + } + + /* we restore the process signal mask as the sigreturn should + do it (XXX: use sigsetjmp) */ + sigprocmask(SIG_SETMASK, old_set, NULL); + raise_exception(EXCP_PAGE); + + /* never comes here */ + return 1; } #elif defined(TARGET_SPARC) static inline int handle_cpu_signal(unsigned long pc, unsigned long address, Index: linux-user/main.c =================================================================== RCS file: /cvsroot/qemu/qemu/linux-user/main.c,v retrieving revision 1.58 diff -u -r1.58 main.c --- linux-user/main.c 12 Jan 2005 22:34:47 -0000 1.58 +++ linux-user/main.c 3 Feb 2005 14:04:53 -0000 @@ -365,6 +365,16 @@ } } break; + case EXCP_PAGE: + { + info.si_signo = SIGSEGV; + info.si_errno = 0; + /* XXX: check env->error_code */ + info.si_code = TARGET_SEGV_MAPERR; + info._sifields._sigfault._addr = env->address; + queue_signal(info.si_signo, &info); + } + break; case EXCP_INTERRUPT: /* just indicate that signals should be handled asap */ break; Index: target-arm/cpu.h =================================================================== RCS file: /cvsroot/qemu/qemu/target-arm/cpu.h,v retrieving revision 1.5 diff -u -r1.5 cpu.h --- target-arm/cpu.h 31 Jan 2005 20:43:28 -0000 1.5 +++ target-arm/cpu.h 3 Feb 2005 14:04:53 -0000 @@ -26,6 +26,7 @@ #define EXCP_UDEF 1 /* undefined instruction */ #define EXCP_SWI 2 /* software interrupt */ +#define EXCP_PAGE 3 typedef struct CPUARMState { uint32_t regs[16]; @@ -45,6 +46,7 @@ int interrupt_request; struct TranslationBlock *current_tb; int user_mode_only; + uint32_t address; /* in order to avoid passing too many arguments to the memory write helpers, we store some rarely used information in the CPU Index: target-arm/exec.h =================================================================== RCS file: /cvsroot/qemu/qemu/target-arm/exec.h,v retrieving revision 1.3 diff -u -r1.3 exec.h --- target-arm/exec.h 31 Jan 2005 20:43:28 -0000 1.3 +++ target-arm/exec.h 3 Feb 2005 14:04:53 -0000 @@ -31,6 +31,8 @@ void cpu_unlock(void); void cpu_loop_exit(void); +void raise_exception(int tt); + /* Implemented CPSR bits. */ #define CACHED_CPSR_BITS 0xf8000000 static inline int compute_cpsr(void) Index: target-arm/op.c =================================================================== RCS file: /cvsroot/qemu/qemu/target-arm/op.c,v retrieving revision 1.7 diff -u -r1.7 op.c --- target-arm/op.c 2 Feb 2005 20:43:01 -0000 1.7 +++ target-arm/op.c 3 Feb 2005 14:04:53 -0000 @@ -840,6 +840,12 @@ /* exceptions */ +void raise_exception(int tt) +{ + env->exception_index = tt; + cpu_loop_exit(); +} + void OPPROTO op_swi(void) { env->exception_index = EXCP_SWI;