diff options
Diffstat (limited to 'linux-user')
| -rw-r--r-- | linux-user/elfload.c | 3 | ||||
| -rw-r--r-- | linux-user/main.c | 98 | ||||
| -rw-r--r-- | linux-user/openrisc/target_cpu.h | 4 | ||||
| -rw-r--r-- | linux-user/openrisc/target_syscall.h | 2 |
4 files changed, 46 insertions, 61 deletions
diff --git a/linux-user/elfload.c b/linux-user/elfload.c index c66cbbe84b..8271227339 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1054,9 +1054,8 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, for (i = 0; i < 32; i++) { (*regs)[i] = tswapreg(env->gpr[i]); } - (*regs)[32] = tswapreg(env->pc); - (*regs)[33] = tswapreg(env->sr); + (*regs)[33] = tswapreg(cpu_get_sr(env)); } #define ELF_HWCAP 0 #define ELF_PLATFORM NULL diff --git a/linux-user/main.c b/linux-user/main.c index e588f58f2a..4fd49ce6b6 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -2574,52 +2574,17 @@ kuser_fail: void cpu_loop(CPUOpenRISCState *env) { CPUState *cs = CPU(openrisc_env_get_cpu(env)); - int trapnr, gdbsig; + int trapnr; abi_long ret; + target_siginfo_t info; for (;;) { cpu_exec_start(cs); trapnr = cpu_exec(cs); cpu_exec_end(cs); process_queued_cpu_work(cs); - gdbsig = 0; switch (trapnr) { - case EXCP_RESET: - qemu_log_mask(CPU_LOG_INT, "\nReset request, exit, pc is %#x\n", env->pc); - exit(EXIT_FAILURE); - break; - case EXCP_BUSERR: - qemu_log_mask(CPU_LOG_INT, "\nBus error, exit, pc is %#x\n", env->pc); - gdbsig = TARGET_SIGBUS; - break; - case EXCP_DPF: - case EXCP_IPF: - cpu_dump_state(cs, stderr, fprintf, 0); - gdbsig = TARGET_SIGSEGV; - break; - case EXCP_TICK: - qemu_log_mask(CPU_LOG_INT, "\nTick time interrupt pc is %#x\n", env->pc); - break; - case EXCP_ALIGN: - qemu_log_mask(CPU_LOG_INT, "\nAlignment pc is %#x\n", env->pc); - gdbsig = TARGET_SIGBUS; - break; - case EXCP_ILLEGAL: - qemu_log_mask(CPU_LOG_INT, "\nIllegal instructionpc is %#x\n", env->pc); - gdbsig = TARGET_SIGILL; - break; - case EXCP_INT: - qemu_log_mask(CPU_LOG_INT, "\nExternal interruptpc is %#x\n", env->pc); - break; - case EXCP_DTLBMISS: - case EXCP_ITLBMISS: - qemu_log_mask(CPU_LOG_INT, "\nTLB miss\n"); - break; - case EXCP_RANGE: - qemu_log_mask(CPU_LOG_INT, "\nRange\n"); - gdbsig = TARGET_SIGSEGV; - break; case EXCP_SYSCALL: env->pc += 4; /* 0xc00; */ ret = do_syscall(env, @@ -2636,32 +2601,54 @@ void cpu_loop(CPUOpenRISCState *env) env->gpr[11] = ret; } break; + case EXCP_DPF: + case EXCP_IPF: + case EXCP_RANGE: + info.si_signo = TARGET_SIGSEGV; + info.si_errno = 0; + info.si_code = TARGET_SEGV_MAPERR; + info._sifields._sigfault._addr = env->pc; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + break; + case EXCP_ALIGN: + info.si_signo = TARGET_SIGBUS; + info.si_errno = 0; + info.si_code = TARGET_BUS_ADRALN; + info._sifields._sigfault._addr = env->pc; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + break; + case EXCP_ILLEGAL: + info.si_signo = TARGET_SIGILL; + info.si_errno = 0; + info.si_code = TARGET_ILL_ILLOPC; + info._sifields._sigfault._addr = env->pc; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + break; case EXCP_FPE: - qemu_log_mask(CPU_LOG_INT, "\nFloating point error\n"); + info.si_signo = TARGET_SIGFPE; + info.si_errno = 0; + info.si_code = 0; + info._sifields._sigfault._addr = env->pc; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); break; - case EXCP_TRAP: - qemu_log_mask(CPU_LOG_INT, "\nTrap\n"); - gdbsig = TARGET_SIGTRAP; + case EXCP_INTERRUPT: + /* We processed the pending cpu work above. */ break; - case EXCP_NR: - qemu_log_mask(CPU_LOG_INT, "\nNR\n"); + case EXCP_DEBUG: + trapnr = gdb_handlesig(cs, TARGET_SIGTRAP); + if (trapnr) { + info.si_signo = trapnr; + info.si_errno = 0; + info.si_code = TARGET_TRAP_BRKPT; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + } break; case EXCP_ATOMIC: cpu_exec_step_atomic(cs); break; default: - EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n", - trapnr); - gdbsig = TARGET_SIGILL; - break; - } - if (gdbsig) { - gdb_handlesig(cs, gdbsig); - if (gdbsig != TARGET_SIGTRAP) { - exit(EXIT_FAILURE); - } + g_assert_not_reached(); } - process_pending_signals(env); } } @@ -4778,9 +4765,8 @@ int main(int argc, char **argv, char **envp) for (i = 0; i < 32; i++) { env->gpr[i] = regs->gpr[i]; } - - env->sr = regs->sr; env->pc = regs->pc; + cpu_set_sr(env, regs->sr); } #elif defined(TARGET_SH4) { diff --git a/linux-user/openrisc/target_cpu.h b/linux-user/openrisc/target_cpu.h index a21ed1aff8..f283d96a93 100644 --- a/linux-user/openrisc/target_cpu.h +++ b/linux-user/openrisc/target_cpu.h @@ -30,9 +30,7 @@ static inline void cpu_clone_regs(CPUOpenRISCState *env, target_ulong newsp) static inline void cpu_set_tls(CPUOpenRISCState *env, target_ulong newtls) { - /* Linux kernel 3.10 does not pay any attention to CLONE_SETTLS - * in copy_thread(), so QEMU need not do so either. - */ + env->gpr[10] = newtls; } #endif diff --git a/linux-user/openrisc/target_syscall.h b/linux-user/openrisc/target_syscall.h index 9d3380f9a8..03104f80af 100644 --- a/linux-user/openrisc/target_syscall.h +++ b/linux-user/openrisc/target_syscall.h @@ -31,4 +31,6 @@ struct target_pt_regs { #define TARGET_MLOCKALL_MCL_CURRENT 1 #define TARGET_MLOCKALL_MCL_FUTURE 2 +#define MMAP_SHIFT TARGET_PAGE_BITS + #endif /* OPENRISC_TARGET_SYSCALL_H */ |