summary refs log tree commit diff stats
path: root/linux-user
diff options
context:
space:
mode:
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/main.c10
-rw-r--r--linux-user/signal.c10
2 files changed, 15 insertions, 5 deletions
diff --git a/linux-user/main.c b/linux-user/main.c
index 1ae4656d3a..1b747d8738 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -331,6 +331,7 @@ void cpu_loop(CPUARMState *env)
     int trapnr;
     unsigned int n, insn;
     target_siginfo_t info;
+    uint32_t addr;
     
     for(;;) {
         trapnr = cpu_arm_exec(env);
@@ -397,13 +398,18 @@ void cpu_loop(CPUARMState *env)
             /* just indicate that signals should be handled asap */
             break;
         case EXCP_PREFETCH_ABORT:
+            addr = env->cp15.c6_data;
+            goto do_segv;
         case EXCP_DATA_ABORT:
+            addr = env->cp15.c6_insn;
+            goto do_segv;
+        do_segv:
             {
                 info.si_signo = SIGSEGV;
                 info.si_errno = 0;
                 /* XXX: check env->error_code */
                 info.si_code = TARGET_SEGV_MAPERR;
-                info._sifields._sigfault._addr = env->cp15_6;
+                info._sifields._sigfault._addr = addr;
                 queue_signal(info.si_signo, &info);
             }
             break;
@@ -1190,10 +1196,10 @@ int main(int argc, char **argv)
 #elif defined(TARGET_ARM)
     {
         int i;
+        cpsr_write(env, regs->uregs[16], 0xffffffff);
         for(i = 0; i < 16; i++) {
             env->regs[i] = regs->uregs[i];
         }
-        env->cpsr = regs->uregs[16];
         ts->stack_base = info->start_stack;
         ts->heap_base = info->brk;
         /* This will be filled in on the first SYS_HEAPINFO call.  */
diff --git a/linux-user/signal.c b/linux-user/signal.c
index a7c06c9fb8..29933bda43 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -1003,7 +1003,7 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
 	__put_user_error(env->regs[14], &sc->arm_lr, err);
 	__put_user_error(env->regs[15], &sc->arm_pc, err);
 #ifdef TARGET_CONFIG_CPU_32
-	__put_user_error(env->cpsr, &sc->arm_cpsr, err);
+	__put_user_error(cpsr_read(env), &sc->arm_cpsr, err);
 #endif
 
 	__put_user_error(/* current->thread.trap_no */ 0, &sc->trap_no, err);
@@ -1040,9 +1040,9 @@ setup_return(CPUState *env, struct emulated_sigaction *ka,
 	target_ulong retcode;
 	int thumb = 0;
 #if defined(TARGET_CONFIG_CPU_32)
+#if 0
 	target_ulong cpsr = env->cpsr;
 
-#if 0
 	/*
 	 * Maybe we need to deliver a 32-bit signal to a 26-bit task.
 	 */
@@ -1088,9 +1088,11 @@ setup_return(CPUState *env, struct emulated_sigaction *ka,
 	env->regs[14] = retcode;
 	env->regs[15] = handler & (thumb ? ~1 : ~3);
 
+#if 0
 #ifdef TARGET_CONFIG_CPU_32
 	env->cpsr = cpsr;
 #endif
+#endif
 
 	return 0;
 }
@@ -1157,6 +1159,7 @@ static int
 restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
 {
 	int err = 0;
+        uint32_t cpsr;
 
 	__get_user_error(env->regs[0], &sc->arm_r0, err);
 	__get_user_error(env->regs[1], &sc->arm_r1, err);
@@ -1175,7 +1178,8 @@ restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
 	__get_user_error(env->regs[14], &sc->arm_lr, err);
 	__get_user_error(env->regs[15], &sc->arm_pc, err);
 #ifdef TARGET_CONFIG_CPU_32
-	__get_user_error(env->cpsr, &sc->arm_cpsr, err);
+	__get_user_error(cpsr, &sc->arm_cpsr, err);
+        cpsr_write(env, cpsr, 0xffffffff);
 #endif
 
 	err |= !valid_user_regs(env);