mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/lvivier-gitlab/tags/linux-user-for-7.0-pull-request' into staging
linux-user pull request 20220111 siginfo_t cleanup more prtctl() update target_struct.h cleanup # gpg: Signature made Tue 11 Jan 2022 19:52:20 GMT # gpg: using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C # gpg: issuer "laurent@vivier.eu" # gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full] # gpg: aka "Laurent Vivier <laurent@vivier.eu>" [full] # gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full] # Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C * remotes/lvivier-gitlab/tags/linux-user-for-7.0-pull-request: (30 commits) linux-user: Implement capability prctls linux-user: Implement PR_SET_PDEATHSIG linux-user: Map signal number in PR_GET_PDEATHSIG linux-user: Do not special-case NULL for PR_GET_PDEATHSIG linux-user: Move target_struct.h generic definitions to generic/ linux-user/arm: Move target_oabi_flock64 out of target_structs.h linux-user/xtensa: Use force_sig_fault linux-user/sparc: Use force_sig_fault linux-user/sh4: Use force_sig_fault linux-user/s390x: Use force_sig_fault linux-user/riscv: Use force_sig_fault linux-user/ppc: Use force_sig_fault linux-user/openrisc: Use force_sig_fault target/mips: Extract trap code into env->error_code target/mips: Extract break code into env->error_code linux-user/mips: Use force_sig_fault linux-user/mips: Improve do_break linux-user/microblaze: Fix SIGFPE si_codes linux-user/microblaze: Use force_sig_fault linux-user/m68k: Use force_sig_fault ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -1,58 +1 @@
|
||||
/*
|
||||
* ARM AArch64 specific structures for linux-user
|
||||
*
|
||||
* Copyright (c) 2013 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef AARCH64_TARGET_STRUCTS_H
|
||||
#define AARCH64_TARGET_STRUCTS_H
|
||||
|
||||
struct target_ipc_perm {
|
||||
abi_int __key; /* Key. */
|
||||
abi_uint uid; /* Owner's user ID. */
|
||||
abi_uint gid; /* Owner's group ID. */
|
||||
abi_uint cuid; /* Creator's user ID. */
|
||||
abi_uint cgid; /* Creator's group ID. */
|
||||
abi_ushort mode; /* Read/write permission. */
|
||||
abi_ushort __pad1;
|
||||
abi_ushort __seq; /* Sequence number. */
|
||||
abi_ushort __pad2;
|
||||
abi_ulong __unused1;
|
||||
abi_ulong __unused2;
|
||||
};
|
||||
|
||||
struct target_shmid_ds {
|
||||
struct target_ipc_perm shm_perm; /* operation permission struct */
|
||||
abi_long shm_segsz; /* size of segment in bytes */
|
||||
abi_ulong shm_atime; /* time of last shmat() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused1;
|
||||
#endif
|
||||
abi_ulong shm_dtime; /* time of last shmdt() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused2;
|
||||
#endif
|
||||
abi_ulong shm_ctime; /* time of last change by shmctl() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused3;
|
||||
#endif
|
||||
abi_int shm_cpid; /* pid of creator */
|
||||
abi_int shm_lpid; /* pid of last shmop */
|
||||
abi_ulong shm_nattch; /* number of current attaches */
|
||||
abi_ulong __unused4;
|
||||
abi_ulong __unused5;
|
||||
};
|
||||
|
||||
#endif
|
||||
#include "../generic/target_structs.h"
|
||||
|
||||
+19
-42
@@ -27,8 +27,7 @@
|
||||
void cpu_loop(CPUAlphaState *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
int trapnr;
|
||||
target_siginfo_t info;
|
||||
int trapnr, si_code;
|
||||
abi_long sysret;
|
||||
|
||||
while (1) {
|
||||
@@ -56,18 +55,10 @@ void cpu_loop(CPUAlphaState *env)
|
||||
break;
|
||||
case EXCP_OPCDEC:
|
||||
do_sigill:
|
||||
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);
|
||||
force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->pc);
|
||||
break;
|
||||
case EXCP_ARITH:
|
||||
info.si_signo = TARGET_SIGFPE;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_FPE_FLTINV;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGFPE, TARGET_FPE_FLTINV, env->pc);
|
||||
break;
|
||||
case EXCP_FEN:
|
||||
/* No-op. Linux simply re-enables the FPU. */
|
||||
@@ -76,20 +67,10 @@ void cpu_loop(CPUAlphaState *env)
|
||||
switch (env->error_code) {
|
||||
case 0x80:
|
||||
/* BPT */
|
||||
info.si_signo = TARGET_SIGTRAP;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
goto do_sigtrap_brkpt;
|
||||
case 0x81:
|
||||
/* BUGCHK */
|
||||
info.si_signo = TARGET_SIGTRAP;
|
||||
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;
|
||||
goto do_sigtrap_unk;
|
||||
case 0x83:
|
||||
/* CALLSYS */
|
||||
trapnr = env->ir[IR_V0];
|
||||
@@ -130,47 +111,43 @@ void cpu_loop(CPUAlphaState *env)
|
||||
abort();
|
||||
case 0xAA:
|
||||
/* GENTRAP */
|
||||
info.si_signo = TARGET_SIGFPE;
|
||||
switch (env->ir[IR_A0]) {
|
||||
case TARGET_GEN_INTOVF:
|
||||
info.si_code = TARGET_FPE_INTOVF;
|
||||
si_code = TARGET_FPE_INTOVF;
|
||||
break;
|
||||
case TARGET_GEN_INTDIV:
|
||||
info.si_code = TARGET_FPE_INTDIV;
|
||||
si_code = TARGET_FPE_INTDIV;
|
||||
break;
|
||||
case TARGET_GEN_FLTOVF:
|
||||
info.si_code = TARGET_FPE_FLTOVF;
|
||||
si_code = TARGET_FPE_FLTOVF;
|
||||
break;
|
||||
case TARGET_GEN_FLTUND:
|
||||
info.si_code = TARGET_FPE_FLTUND;
|
||||
si_code = TARGET_FPE_FLTUND;
|
||||
break;
|
||||
case TARGET_GEN_FLTINV:
|
||||
info.si_code = TARGET_FPE_FLTINV;
|
||||
si_code = TARGET_FPE_FLTINV;
|
||||
break;
|
||||
case TARGET_GEN_FLTINE:
|
||||
info.si_code = TARGET_FPE_FLTRES;
|
||||
si_code = TARGET_FPE_FLTRES;
|
||||
break;
|
||||
case TARGET_GEN_ROPRAND:
|
||||
info.si_code = 0;
|
||||
si_code = TARGET_FPE_FLTUNK;
|
||||
break;
|
||||
default:
|
||||
info.si_signo = TARGET_SIGTRAP;
|
||||
info.si_code = 0;
|
||||
break;
|
||||
goto do_sigtrap_unk;
|
||||
}
|
||||
info.si_errno = 0;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
|
||||
break;
|
||||
default:
|
||||
goto do_sigill;
|
||||
}
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
info.si_signo = TARGET_SIGTRAP;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
do_sigtrap_brkpt:
|
||||
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
|
||||
break;
|
||||
do_sigtrap_unk:
|
||||
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_UNK, env->pc);
|
||||
break;
|
||||
case EXCP_INTERRUPT:
|
||||
/* Just indicate that signals should be handled asap. */
|
||||
|
||||
@@ -1,59 +1 @@
|
||||
/*
|
||||
* ARM specific structures for linux-user
|
||||
*
|
||||
* Copyright (c) 2013 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef ARM_TARGET_STRUCTS_H
|
||||
#define ARM_TARGET_STRUCTS_H
|
||||
|
||||
struct target_ipc_perm {
|
||||
abi_int __key; /* Key. */
|
||||
abi_uint uid; /* Owner's user ID. */
|
||||
abi_uint gid; /* Owner's group ID. */
|
||||
abi_uint cuid; /* Creator's user ID. */
|
||||
abi_uint cgid; /* Creator's group ID. */
|
||||
abi_ushort mode; /* Read/write permission. */
|
||||
abi_ushort __pad1;
|
||||
abi_ushort __seq; /* Sequence number. */
|
||||
abi_ushort __pad2;
|
||||
abi_ulong __unused1;
|
||||
abi_ulong __unused2;
|
||||
};
|
||||
|
||||
struct target_shmid_ds {
|
||||
struct target_ipc_perm shm_perm; /* operation permission struct */
|
||||
abi_long shm_segsz; /* size of segment in bytes */
|
||||
abi_ulong shm_atime; /* time of last shmat() */
|
||||
abi_ulong __unused1;
|
||||
abi_ulong shm_dtime; /* time of last shmdt() */
|
||||
abi_ulong __unused2;
|
||||
abi_ulong shm_ctime; /* time of last change by shmctl() */
|
||||
abi_ulong __unused3;
|
||||
abi_int shm_cpid; /* pid of creator */
|
||||
abi_int shm_lpid; /* pid of last shmop */
|
||||
abi_ulong shm_nattch; /* number of current attaches */
|
||||
abi_ulong __unused4;
|
||||
abi_ulong __unused5;
|
||||
};
|
||||
|
||||
struct target_oabi_flock64 {
|
||||
abi_short l_type;
|
||||
abi_short l_whence;
|
||||
abi_llong l_start;
|
||||
abi_llong l_len;
|
||||
abi_int l_pid;
|
||||
} QEMU_PACKED;
|
||||
#endif
|
||||
#include "../generic/target_structs.h"
|
||||
|
||||
@@ -28,8 +28,7 @@ void cpu_loop(CPUCRISState *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
int trapnr, ret;
|
||||
target_siginfo_t info;
|
||||
|
||||
|
||||
while (1) {
|
||||
cpu_exec_start(cs);
|
||||
trapnr = cpu_exec(cs);
|
||||
@@ -38,8 +37,8 @@ void cpu_loop(CPUCRISState *env)
|
||||
|
||||
switch (trapnr) {
|
||||
case EXCP_INTERRUPT:
|
||||
/* just indicate that signals should be handled asap */
|
||||
break;
|
||||
/* just indicate that signals should be handled asap */
|
||||
break;
|
||||
case EXCP_BREAK:
|
||||
ret = do_syscall(env,
|
||||
env->regs[9],
|
||||
@@ -57,10 +56,7 @@ void cpu_loop(CPUCRISState *env)
|
||||
}
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
info.si_signo = TARGET_SIGTRAP;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
|
||||
break;
|
||||
case EXCP_ATOMIC:
|
||||
cpu_exec_step_atomic(cs);
|
||||
|
||||
@@ -1,58 +1 @@
|
||||
/*
|
||||
* CRIS specific structures for linux-user
|
||||
*
|
||||
* Copyright (c) 2013 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef CRIS_TARGET_STRUCTS_H
|
||||
#define CRIS_TARGET_STRUCTS_H
|
||||
|
||||
struct target_ipc_perm {
|
||||
abi_int __key; /* Key. */
|
||||
abi_uint uid; /* Owner's user ID. */
|
||||
abi_uint gid; /* Owner's group ID. */
|
||||
abi_uint cuid; /* Creator's user ID. */
|
||||
abi_uint cgid; /* Creator's group ID. */
|
||||
abi_ushort mode; /* Read/write permission. */
|
||||
abi_ushort __pad1;
|
||||
abi_ushort __seq; /* Sequence number. */
|
||||
abi_ushort __pad2;
|
||||
abi_ulong __unused1;
|
||||
abi_ulong __unused2;
|
||||
};
|
||||
|
||||
struct target_shmid_ds {
|
||||
struct target_ipc_perm shm_perm; /* operation permission struct */
|
||||
abi_long shm_segsz; /* size of segment in bytes */
|
||||
abi_ulong shm_atime; /* time of last shmat() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused1;
|
||||
#endif
|
||||
abi_ulong shm_dtime; /* time of last shmdt() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused2;
|
||||
#endif
|
||||
abi_ulong shm_ctime; /* time of last change by shmctl() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused3;
|
||||
#endif
|
||||
abi_int shm_cpid; /* pid of creator */
|
||||
abi_int shm_lpid; /* pid of last shmop */
|
||||
abi_ulong shm_nattch; /* number of current attaches */
|
||||
abi_ulong __unused4;
|
||||
abi_ulong __unused5;
|
||||
};
|
||||
|
||||
#endif
|
||||
#include "../generic/target_structs.h"
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Generic structures for linux-user
|
||||
*
|
||||
* Copyright (c) 2013 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef GENERIC_TARGET_STRUCTS_H
|
||||
#define GENERIC_TARGET_STRUCTS_H
|
||||
|
||||
struct target_ipc_perm {
|
||||
abi_int __key; /* Key. */
|
||||
abi_uint uid; /* Owner's user ID. */
|
||||
abi_uint gid; /* Owner's group ID. */
|
||||
abi_uint cuid; /* Creator's user ID. */
|
||||
abi_uint cgid; /* Creator's group ID. */
|
||||
abi_ushort mode; /* Read/write permission. */
|
||||
abi_ushort __pad1;
|
||||
abi_ushort __seq; /* Sequence number. */
|
||||
abi_ushort __pad2;
|
||||
abi_ulong __unused1;
|
||||
abi_ulong __unused2;
|
||||
};
|
||||
|
||||
struct target_shmid_ds {
|
||||
struct target_ipc_perm shm_perm; /* operation permission struct */
|
||||
abi_long shm_segsz; /* size of segment in bytes */
|
||||
abi_ulong shm_atime; /* time of last shmat() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused1;
|
||||
#endif
|
||||
abi_ulong shm_dtime; /* time of last shmdt() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused2;
|
||||
#endif
|
||||
abi_ulong shm_ctime; /* time of last change by shmctl() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused3;
|
||||
#endif
|
||||
abi_int shm_cpid; /* pid of creator */
|
||||
abi_int shm_lpid; /* pid of last shmop */
|
||||
abi_ulong shm_nattch; /* number of current attaches */
|
||||
abi_ulong __unused4;
|
||||
abi_ulong __unused5;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,54 +1 @@
|
||||
/*
|
||||
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Hexagon specific structures for linux-user
|
||||
*/
|
||||
#ifndef HEXAGON_TARGET_STRUCTS_H
|
||||
#define HEXAGON_TARGET_STRUCTS_H
|
||||
|
||||
struct target_ipc_perm {
|
||||
abi_int __key; /* Key. */
|
||||
abi_uint uid; /* Owner's user ID. */
|
||||
abi_uint gid; /* Owner's group ID. */
|
||||
abi_uint cuid; /* Creator's user ID. */
|
||||
abi_uint cgid; /* Creator's group ID. */
|
||||
abi_ushort mode; /* Read/write permission. */
|
||||
abi_ushort __pad1;
|
||||
abi_ushort __seq; /* Sequence number. */
|
||||
abi_ushort __pad2;
|
||||
abi_ulong __unused1;
|
||||
abi_ulong __unused2;
|
||||
};
|
||||
|
||||
struct target_shmid_ds {
|
||||
struct target_ipc_perm shm_perm; /* operation permission struct */
|
||||
abi_long shm_segsz; /* size of segment in bytes */
|
||||
abi_ulong shm_atime; /* time of last shmat() */
|
||||
abi_ulong __unused1;
|
||||
abi_ulong shm_dtime; /* time of last shmdt() */
|
||||
abi_ulong __unused2;
|
||||
abi_ulong shm_ctime; /* time of last change by shmctl() */
|
||||
abi_ulong __unused3;
|
||||
abi_int shm_cpid; /* pid of creator */
|
||||
abi_int shm_lpid; /* pid of last shmop */
|
||||
abi_ulong shm_nattch; /* number of current attaches */
|
||||
abi_ulong __unused4;
|
||||
abi_ulong __unused5;
|
||||
};
|
||||
|
||||
#endif
|
||||
#include "../generic/target_structs.h"
|
||||
|
||||
+11
-15
@@ -110,7 +110,6 @@ static abi_ulong hppa_lws(CPUHPPAState *env)
|
||||
void cpu_loop(CPUHPPAState *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
target_siginfo_t info;
|
||||
abi_ulong ret;
|
||||
int trapnr;
|
||||
|
||||
@@ -145,28 +144,25 @@ void cpu_loop(CPUHPPAState *env)
|
||||
env->iaoq_b = env->gr[31] + 4;
|
||||
break;
|
||||
case EXCP_ILL:
|
||||
force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN, env->iaoq_f);
|
||||
break;
|
||||
case EXCP_PRIV_OPR:
|
||||
force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVOPC, env->iaoq_f);
|
||||
break;
|
||||
case EXCP_PRIV_REG:
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->iaoq_f;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVREG, env->iaoq_f);
|
||||
break;
|
||||
case EXCP_OVERFLOW:
|
||||
force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTOVF, env->iaoq_f);
|
||||
break;
|
||||
case EXCP_COND:
|
||||
force_sig_fault(TARGET_SIGFPE, TARGET_FPE_CONDTRAP, env->iaoq_f);
|
||||
break;
|
||||
case EXCP_ASSIST:
|
||||
info.si_signo = TARGET_SIGFPE;
|
||||
info.si_errno = 0;
|
||||
info.si_code = 0;
|
||||
info._sifields._sigfault._addr = env->iaoq_f;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGFPE, 0, env->iaoq_f);
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
info.si_signo = TARGET_SIGTRAP;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->iaoq_f);
|
||||
break;
|
||||
case EXCP_INTERRUPT:
|
||||
/* just indicate that signals should be handled asap */
|
||||
|
||||
+33
-45
@@ -84,17 +84,6 @@ static void set_idt(int n, unsigned int dpl)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gen_signal(CPUX86State *env, int sig, int code, abi_ptr addr)
|
||||
{
|
||||
target_siginfo_t info = {
|
||||
.si_signo = sig,
|
||||
.si_code = code,
|
||||
._sifields._sigfault._addr = addr
|
||||
};
|
||||
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
|
||||
#ifdef TARGET_X86_64
|
||||
static bool write_ok_or_segv(CPUX86State *env, abi_ptr addr, size_t len)
|
||||
{
|
||||
@@ -107,7 +96,7 @@ static bool write_ok_or_segv(CPUX86State *env, abi_ptr addr, size_t len)
|
||||
}
|
||||
|
||||
env->error_code = PG_ERROR_W_MASK | PG_ERROR_U_MASK;
|
||||
gen_signal(env, TARGET_SIGSEGV, TARGET_SEGV_MAPERR, addr);
|
||||
force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR, addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -193,11 +182,21 @@ static void emulate_vsyscall(CPUX86State *env)
|
||||
return;
|
||||
|
||||
sigsegv:
|
||||
/* Like force_sig(SIGSEGV). */
|
||||
gen_signal(env, TARGET_SIGSEGV, TARGET_SI_KERNEL, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool maybe_handle_vm86_trap(CPUX86State *env, int trapnr)
|
||||
{
|
||||
#ifndef TARGET_X86_64
|
||||
if (env->eflags & VM_MASK) {
|
||||
handle_vm86_trap(env, trapnr);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void cpu_loop(CPUX86State *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
@@ -255,65 +254,54 @@ void cpu_loop(CPUX86State *env)
|
||||
#endif
|
||||
case EXCP0B_NOSEG:
|
||||
case EXCP0C_STACK:
|
||||
gen_signal(env, TARGET_SIGBUS, TARGET_SI_KERNEL, 0);
|
||||
force_sig(TARGET_SIGBUS);
|
||||
break;
|
||||
case EXCP0D_GPF:
|
||||
/* XXX: potential problem if ABI32 */
|
||||
#ifndef TARGET_X86_64
|
||||
if (env->eflags & VM_MASK) {
|
||||
handle_vm86_fault(env);
|
||||
if (maybe_handle_vm86_trap(env, trapnr)) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
gen_signal(env, TARGET_SIGSEGV, TARGET_SI_KERNEL, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
break;
|
||||
case EXCP0E_PAGE:
|
||||
gen_signal(env, TARGET_SIGSEGV,
|
||||
(env->error_code & 1 ?
|
||||
TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR),
|
||||
env->cr[2]);
|
||||
force_sig_fault(TARGET_SIGSEGV,
|
||||
(env->error_code & PG_ERROR_P_MASK ?
|
||||
TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR),
|
||||
env->cr[2]);
|
||||
break;
|
||||
case EXCP00_DIVZ:
|
||||
#ifndef TARGET_X86_64
|
||||
if (env->eflags & VM_MASK) {
|
||||
handle_vm86_trap(env, trapnr);
|
||||
if (maybe_handle_vm86_trap(env, trapnr)) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
gen_signal(env, TARGET_SIGFPE, TARGET_FPE_INTDIV, env->eip);
|
||||
force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTDIV, env->eip);
|
||||
break;
|
||||
case EXCP01_DB:
|
||||
case EXCP03_INT3:
|
||||
#ifndef TARGET_X86_64
|
||||
if (env->eflags & VM_MASK) {
|
||||
handle_vm86_trap(env, trapnr);
|
||||
if (maybe_handle_vm86_trap(env, trapnr)) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (trapnr == EXCP01_DB) {
|
||||
gen_signal(env, TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->eip);
|
||||
} else {
|
||||
gen_signal(env, TARGET_SIGTRAP, TARGET_SI_KERNEL, 0);
|
||||
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->eip);
|
||||
break;
|
||||
case EXCP03_INT3:
|
||||
if (maybe_handle_vm86_trap(env, trapnr)) {
|
||||
break;
|
||||
}
|
||||
force_sig(TARGET_SIGTRAP);
|
||||
break;
|
||||
case EXCP04_INTO:
|
||||
case EXCP05_BOUND:
|
||||
#ifndef TARGET_X86_64
|
||||
if (env->eflags & VM_MASK) {
|
||||
handle_vm86_trap(env, trapnr);
|
||||
if (maybe_handle_vm86_trap(env, trapnr)) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
gen_signal(env, TARGET_SIGSEGV, TARGET_SI_KERNEL, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
break;
|
||||
case EXCP06_ILLOP:
|
||||
gen_signal(env, TARGET_SIGILL, TARGET_ILL_ILLOPN, env->eip);
|
||||
force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN, env->eip);
|
||||
break;
|
||||
case EXCP_INTERRUPT:
|
||||
/* just indicate that signals should be handled asap */
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
gen_signal(env, TARGET_SIGTRAP, TARGET_TRAP_BRKPT, 0);
|
||||
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->eip);
|
||||
break;
|
||||
case EXCP_ATOMIC:
|
||||
cpu_exec_step_atomic(cs);
|
||||
|
||||
@@ -1,58 +1 @@
|
||||
/*
|
||||
* i386 specific structures for linux-user
|
||||
*
|
||||
* Copyright (c) 2013 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef I386_TARGET_STRUCTS_H
|
||||
#define I386_TARGET_STRUCTS_H
|
||||
|
||||
struct target_ipc_perm {
|
||||
abi_int __key; /* Key. */
|
||||
abi_uint uid; /* Owner's user ID. */
|
||||
abi_uint gid; /* Owner's group ID. */
|
||||
abi_uint cuid; /* Creator's user ID. */
|
||||
abi_uint cgid; /* Creator's group ID. */
|
||||
abi_ushort mode; /* Read/write permission. */
|
||||
abi_ushort __pad1;
|
||||
abi_ushort __seq; /* Sequence number. */
|
||||
abi_ushort __pad2;
|
||||
abi_ulong __unused1;
|
||||
abi_ulong __unused2;
|
||||
};
|
||||
|
||||
struct target_shmid_ds {
|
||||
struct target_ipc_perm shm_perm; /* operation permission struct */
|
||||
abi_long shm_segsz; /* size of segment in bytes */
|
||||
abi_ulong shm_atime; /* time of last shmat() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused1;
|
||||
#endif
|
||||
abi_ulong shm_dtime; /* time of last shmdt() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused2;
|
||||
#endif
|
||||
abi_ulong shm_ctime; /* time of last change by shmctl() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused3;
|
||||
#endif
|
||||
abi_int shm_cpid; /* pid of creator */
|
||||
abi_int shm_lpid; /* pid of last shmop */
|
||||
abi_ulong shm_nattch; /* number of current attaches */
|
||||
abi_ulong __unused4;
|
||||
abi_ulong __unused5;
|
||||
};
|
||||
|
||||
#endif
|
||||
#include "../generic/target_structs.h"
|
||||
|
||||
@@ -29,7 +29,6 @@ void cpu_loop(CPUM68KState *env)
|
||||
CPUState *cs = env_cpu(env);
|
||||
int trapnr;
|
||||
unsigned int n;
|
||||
target_siginfo_t info;
|
||||
|
||||
for(;;) {
|
||||
cpu_exec_start(cs);
|
||||
@@ -46,25 +45,13 @@ void cpu_loop(CPUM68KState *env)
|
||||
case EXCP_ILLEGAL:
|
||||
case EXCP_LINEA:
|
||||
case EXCP_LINEF:
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN, env->pc);
|
||||
break;
|
||||
case EXCP_CHK:
|
||||
info.si_signo = TARGET_SIGFPE;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_FPE_INTOVF;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTOVF, env->pc);
|
||||
break;
|
||||
case EXCP_DIV0:
|
||||
info.si_signo = TARGET_SIGFPE;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_FPE_INTDIV;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTDIV, env->pc);
|
||||
break;
|
||||
case EXCP_TRAP0:
|
||||
{
|
||||
@@ -91,10 +78,7 @@ void cpu_loop(CPUM68KState *env)
|
||||
/* just indicate that signals should be handled asap */
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
info.si_signo = TARGET_SIGTRAP;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
|
||||
break;
|
||||
case EXCP_ATOMIC:
|
||||
cpu_exec_step_atomic(cs);
|
||||
|
||||
@@ -1,58 +1 @@
|
||||
/*
|
||||
* m68k specific structures for linux-user
|
||||
*
|
||||
* Copyright (c) 2013 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef M68K_TARGET_STRUCTS_H
|
||||
#define M68K_TARGET_STRUCTS_H
|
||||
|
||||
struct target_ipc_perm {
|
||||
abi_int __key; /* Key. */
|
||||
abi_uint uid; /* Owner's user ID. */
|
||||
abi_uint gid; /* Owner's group ID. */
|
||||
abi_uint cuid; /* Creator's user ID. */
|
||||
abi_uint cgid; /* Creator's group ID. */
|
||||
abi_ushort mode; /* Read/write permission. */
|
||||
abi_ushort __pad1;
|
||||
abi_ushort __seq; /* Sequence number. */
|
||||
abi_ushort __pad2;
|
||||
abi_ulong __unused1;
|
||||
abi_ulong __unused2;
|
||||
};
|
||||
|
||||
struct target_shmid_ds {
|
||||
struct target_ipc_perm shm_perm; /* operation permission struct */
|
||||
abi_long shm_segsz; /* size of segment in bytes */
|
||||
abi_ulong shm_atime; /* time of last shmat() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused1;
|
||||
#endif
|
||||
abi_ulong shm_dtime; /* time of last shmdt() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused2;
|
||||
#endif
|
||||
abi_ulong shm_ctime; /* time of last change by shmctl() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused3;
|
||||
#endif
|
||||
abi_int shm_cpid; /* pid of creator */
|
||||
abi_int shm_lpid; /* pid of last shmop */
|
||||
abi_ulong shm_nattch; /* number of current attaches */
|
||||
abi_ulong __unused4;
|
||||
abi_ulong __unused5;
|
||||
};
|
||||
|
||||
#endif
|
||||
#include "../generic/target_structs.h"
|
||||
|
||||
@@ -27,9 +27,8 @@
|
||||
void cpu_loop(CPUMBState *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
int trapnr, ret;
|
||||
target_siginfo_t info;
|
||||
|
||||
int trapnr, ret, si_code;
|
||||
|
||||
while (1) {
|
||||
cpu_exec_start(cs);
|
||||
trapnr = cpu_exec(cs);
|
||||
@@ -38,8 +37,8 @@ void cpu_loop(CPUMBState *env)
|
||||
|
||||
switch (trapnr) {
|
||||
case EXCP_INTERRUPT:
|
||||
/* just indicate that signals should be handled asap */
|
||||
break;
|
||||
/* just indicate that signals should be handled asap */
|
||||
break;
|
||||
case EXCP_SYSCALL:
|
||||
/* Return address is 4 bytes after the call. */
|
||||
env->regs[14] += 4;
|
||||
@@ -67,6 +66,7 @@ void cpu_loop(CPUMBState *env)
|
||||
*/
|
||||
env->regs[14] = env->pc;
|
||||
break;
|
||||
|
||||
case EXCP_HW_EXCP:
|
||||
env->regs[17] = env->pc + 4;
|
||||
if (env->iflags & D_FLAG) {
|
||||
@@ -74,42 +74,41 @@ void cpu_loop(CPUMBState *env)
|
||||
env->pc -= 4;
|
||||
/* FIXME: if branch was immed, replay the imm as well. */
|
||||
}
|
||||
|
||||
env->iflags &= ~(IMM_FLAG | D_FLAG);
|
||||
|
||||
switch (env->esr & 31) {
|
||||
case ESR_EC_DIVZERO:
|
||||
info.si_signo = TARGET_SIGFPE;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_FPE_FLTDIV;
|
||||
info._sifields._sigfault._addr = 0;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case ESR_EC_FPU:
|
||||
info.si_signo = TARGET_SIGFPE;
|
||||
info.si_errno = 0;
|
||||
if (env->fsr & FSR_IO) {
|
||||
info.si_code = TARGET_FPE_FLTINV;
|
||||
}
|
||||
if (env->fsr & FSR_DZ) {
|
||||
info.si_code = TARGET_FPE_FLTDIV;
|
||||
}
|
||||
info._sifields._sigfault._addr = 0;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unhandled hw-exception: 0x%x\n",
|
||||
env->esr & ESR_EC_MASK);
|
||||
cpu_dump_state(cs, stderr, 0);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
case ESR_EC_DIVZERO:
|
||||
si_code = TARGET_FPE_INTDIV;
|
||||
break;
|
||||
case ESR_EC_FPU:
|
||||
/*
|
||||
* Note that the kernel passes along fsr as si_code
|
||||
* if there's no recognized bit set. Possibly this
|
||||
* implies that si_code is 0, but follow the structure.
|
||||
*/
|
||||
si_code = env->fsr;
|
||||
if (si_code & FSR_IO) {
|
||||
si_code = TARGET_FPE_FLTINV;
|
||||
} else if (si_code & FSR_OF) {
|
||||
si_code = TARGET_FPE_FLTOVF;
|
||||
} else if (si_code & FSR_UF) {
|
||||
si_code = TARGET_FPE_FLTUND;
|
||||
} else if (si_code & FSR_DZ) {
|
||||
si_code = TARGET_FPE_FLTDIV;
|
||||
} else if (si_code & FSR_DO) {
|
||||
si_code = TARGET_FPE_FLTRES;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unhandled hw-exception: 0x%x\n",
|
||||
env->esr & ESR_EC_MASK);
|
||||
cpu_dump_state(cs, stderr, 0);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
|
||||
break;
|
||||
|
||||
case EXCP_DEBUG:
|
||||
info.si_signo = TARGET_SIGTRAP;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
|
||||
break;
|
||||
case EXCP_ATOMIC:
|
||||
cpu_exec_step_atomic(cs);
|
||||
|
||||
@@ -1,58 +1 @@
|
||||
/*
|
||||
* MicroBlaze specific structures for linux-user
|
||||
*
|
||||
* Copyright (c) 2013 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef MICROBLAZE_TARGET_STRUCTS_H
|
||||
#define MICROBLAZE_TARGET_STRUCTS_H
|
||||
|
||||
struct target_ipc_perm {
|
||||
abi_int __key; /* Key. */
|
||||
abi_uint uid; /* Owner's user ID. */
|
||||
abi_uint gid; /* Owner's group ID. */
|
||||
abi_uint cuid; /* Creator's user ID. */
|
||||
abi_uint cgid; /* Creator's group ID. */
|
||||
abi_ushort mode; /* Read/write permission. */
|
||||
abi_ushort __pad1;
|
||||
abi_ushort __seq; /* Sequence number. */
|
||||
abi_ushort __pad2;
|
||||
abi_ulong __unused1;
|
||||
abi_ulong __unused2;
|
||||
};
|
||||
|
||||
struct target_shmid_ds {
|
||||
struct target_ipc_perm shm_perm; /* operation permission struct */
|
||||
abi_long shm_segsz; /* size of segment in bytes */
|
||||
abi_ulong shm_atime; /* time of last shmat() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused1;
|
||||
#endif
|
||||
abi_ulong shm_dtime; /* time of last shmdt() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused2;
|
||||
#endif
|
||||
abi_ulong shm_ctime; /* time of last change by shmctl() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused3;
|
||||
#endif
|
||||
abi_int shm_cpid; /* pid of creator */
|
||||
abi_int shm_lpid; /* pid of last shmop */
|
||||
abi_ulong shm_nattch; /* number of current attaches */
|
||||
abi_ulong __unused4;
|
||||
abi_ulong __unused5;
|
||||
};
|
||||
|
||||
#endif
|
||||
#include "../generic/target_structs.h"
|
||||
|
||||
+33
-133
@@ -40,36 +40,32 @@ enum {
|
||||
BRK_DIVZERO = 7
|
||||
};
|
||||
|
||||
static int do_break(CPUMIPSState *env, target_siginfo_t *info,
|
||||
unsigned int code)
|
||||
static void do_tr_or_bp(CPUMIPSState *env, unsigned int code, bool trap)
|
||||
{
|
||||
int ret = -1;
|
||||
target_ulong pc = env->active_tc.PC;
|
||||
|
||||
switch (code) {
|
||||
case BRK_OVERFLOW:
|
||||
force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTOVF, pc);
|
||||
break;
|
||||
case BRK_DIVZERO:
|
||||
info->si_signo = TARGET_SIGFPE;
|
||||
info->si_errno = 0;
|
||||
info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV;
|
||||
queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info);
|
||||
ret = 0;
|
||||
force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTDIV, pc);
|
||||
break;
|
||||
default:
|
||||
info->si_signo = TARGET_SIGTRAP;
|
||||
info->si_errno = 0;
|
||||
queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info);
|
||||
ret = 0;
|
||||
if (trap) {
|
||||
force_sig(TARGET_SIGTRAP);
|
||||
} else {
|
||||
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, pc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void cpu_loop(CPUMIPSState *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
target_siginfo_t info;
|
||||
int trapnr;
|
||||
int trapnr, si_code;
|
||||
unsigned int code;
|
||||
abi_long ret;
|
||||
# ifdef TARGET_ABI_MIPSO32
|
||||
unsigned int syscall_num;
|
||||
@@ -160,149 +156,53 @@ done_syscall:
|
||||
break;
|
||||
case EXCP_CpU:
|
||||
case EXCP_RI:
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = 0;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
case EXCP_DSPDIS:
|
||||
force_sig(TARGET_SIGILL);
|
||||
break;
|
||||
case EXCP_INTERRUPT:
|
||||
/* just indicate that signals should be handled asap */
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
info.si_signo = TARGET_SIGTRAP;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_DSPDIS:
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPC;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT,
|
||||
env->active_tc.PC);
|
||||
break;
|
||||
case EXCP_FPE:
|
||||
info.si_signo = TARGET_SIGFPE;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_FPE_FLTUNK;
|
||||
si_code = TARGET_FPE_FLTUNK;
|
||||
if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_INVALID) {
|
||||
info.si_code = TARGET_FPE_FLTINV;
|
||||
si_code = TARGET_FPE_FLTINV;
|
||||
} else if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_DIV0) {
|
||||
info.si_code = TARGET_FPE_FLTDIV;
|
||||
si_code = TARGET_FPE_FLTDIV;
|
||||
} else if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_OVERFLOW) {
|
||||
info.si_code = TARGET_FPE_FLTOVF;
|
||||
si_code = TARGET_FPE_FLTOVF;
|
||||
} else if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_UNDERFLOW) {
|
||||
info.si_code = TARGET_FPE_FLTUND;
|
||||
si_code = TARGET_FPE_FLTUND;
|
||||
} else if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_INEXACT) {
|
||||
info.si_code = TARGET_FPE_FLTRES;
|
||||
si_code = TARGET_FPE_FLTRES;
|
||||
}
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGFPE, si_code, env->active_tc.PC);
|
||||
break;
|
||||
|
||||
/* The code below was inspired by the MIPS Linux kernel trap
|
||||
* handling code in arch/mips/kernel/traps.c.
|
||||
*/
|
||||
case EXCP_BREAK:
|
||||
{
|
||||
abi_ulong trap_instr;
|
||||
unsigned int code;
|
||||
|
||||
if (env->hflags & MIPS_HFLAG_M16) {
|
||||
if (env->insn_flags & ASE_MICROMIPS) {
|
||||
/* microMIPS mode */
|
||||
ret = get_user_u16(trap_instr, env->active_tc.PC);
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((trap_instr >> 10) == 0x11) {
|
||||
/* 16-bit instruction */
|
||||
code = trap_instr & 0xf;
|
||||
} else {
|
||||
/* 32-bit instruction */
|
||||
abi_ulong instr_lo;
|
||||
|
||||
ret = get_user_u16(instr_lo,
|
||||
env->active_tc.PC + 2);
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
trap_instr = (trap_instr << 16) | instr_lo;
|
||||
code = ((trap_instr >> 6) & ((1 << 20) - 1));
|
||||
/* Unfortunately, microMIPS also suffers from
|
||||
the old assembler bug... */
|
||||
if (code >= (1 << 10)) {
|
||||
code >>= 10;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* MIPS16e mode */
|
||||
ret = get_user_u16(trap_instr, env->active_tc.PC);
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
code = (trap_instr >> 6) & 0x3f;
|
||||
}
|
||||
} else {
|
||||
ret = get_user_u32(trap_instr, env->active_tc.PC);
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* As described in the original Linux kernel code, the
|
||||
* below checks on 'code' are to work around an old
|
||||
* assembly bug.
|
||||
*/
|
||||
code = ((trap_instr >> 6) & ((1 << 20) - 1));
|
||||
if (code >= (1 << 10)) {
|
||||
code >>= 10;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_break(env, &info, code) != 0) {
|
||||
goto error;
|
||||
}
|
||||
/*
|
||||
* As described in the original Linux kernel code, the below
|
||||
* checks on 'code' are to work around an old assembly bug.
|
||||
*/
|
||||
code = env->error_code;
|
||||
if (code >= (1 << 10)) {
|
||||
code >>= 10;
|
||||
}
|
||||
do_tr_or_bp(env, code, false);
|
||||
break;
|
||||
case EXCP_TRAP:
|
||||
{
|
||||
abi_ulong trap_instr;
|
||||
unsigned int code = 0;
|
||||
|
||||
if (env->hflags & MIPS_HFLAG_M16) {
|
||||
/* microMIPS mode */
|
||||
abi_ulong instr[2];
|
||||
|
||||
ret = get_user_u16(instr[0], env->active_tc.PC) ||
|
||||
get_user_u16(instr[1], env->active_tc.PC + 2);
|
||||
|
||||
trap_instr = (instr[0] << 16) | instr[1];
|
||||
} else {
|
||||
ret = get_user_u32(trap_instr, env->active_tc.PC);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* The immediate versions don't provide a code. */
|
||||
if (!(trap_instr & 0xFC000000)) {
|
||||
if (env->hflags & MIPS_HFLAG_M16) {
|
||||
/* microMIPS mode */
|
||||
code = ((trap_instr >> 12) & ((1 << 4) - 1));
|
||||
} else {
|
||||
code = ((trap_instr >> 6) & ((1 << 10) - 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (do_break(env, &info, code) != 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
do_tr_or_bp(env, env->error_code, true);
|
||||
break;
|
||||
case EXCP_ATOMIC:
|
||||
cpu_exec_step_atomic(cs);
|
||||
break;
|
||||
default:
|
||||
error:
|
||||
EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
|
||||
abort();
|
||||
}
|
||||
|
||||
@@ -1,58 +1 @@
|
||||
/*
|
||||
* Nios2 specific structures for linux-user
|
||||
*
|
||||
* Copyright (c) 2016 Marek Vasut <marex@denx.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef NIOS2_TARGET_STRUCTS_H
|
||||
#define NIOS2_TARGET_STRUCTS_H
|
||||
|
||||
struct target_ipc_perm {
|
||||
abi_int __key; /* Key. */
|
||||
abi_uint uid; /* Owner's user ID. */
|
||||
abi_uint gid; /* Owner's group ID. */
|
||||
abi_uint cuid; /* Creator's user ID. */
|
||||
abi_uint cgid; /* Creator's group ID. */
|
||||
abi_ushort mode; /* Read/write permission. */
|
||||
abi_ushort __pad1;
|
||||
abi_ushort __seq; /* Sequence number. */
|
||||
abi_ushort __pad2;
|
||||
abi_ulong __unused1;
|
||||
abi_ulong __unused2;
|
||||
};
|
||||
|
||||
struct target_shmid_ds {
|
||||
struct target_ipc_perm shm_perm; /* operation permission struct */
|
||||
abi_long shm_segsz; /* size of segment in bytes */
|
||||
abi_ulong shm_atime; /* time of last shmat() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused1;
|
||||
#endif
|
||||
abi_ulong shm_dtime; /* time of last shmdt() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused2;
|
||||
#endif
|
||||
abi_ulong shm_ctime; /* time of last change by shmctl() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused3;
|
||||
#endif
|
||||
abi_int shm_cpid; /* pid of creator */
|
||||
abi_int shm_lpid; /* pid of last shmop */
|
||||
abi_ulong shm_nattch; /* number of current attaches */
|
||||
abi_ulong __unused4;
|
||||
abi_ulong __unused5;
|
||||
};
|
||||
|
||||
#endif
|
||||
#include "../generic/target_structs.h"
|
||||
|
||||
@@ -29,7 +29,6 @@ void cpu_loop(CPUOpenRISCState *env)
|
||||
CPUState *cs = env_cpu(env);
|
||||
int trapnr;
|
||||
abi_long ret;
|
||||
target_siginfo_t info;
|
||||
|
||||
for (;;) {
|
||||
cpu_exec_start(cs);
|
||||
@@ -55,27 +54,16 @@ void cpu_loop(CPUOpenRISCState *env)
|
||||
}
|
||||
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);
|
||||
force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, env->eear);
|
||||
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);
|
||||
force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->pc);
|
||||
break;
|
||||
case EXCP_INTERRUPT:
|
||||
/* We processed the pending cpu work above. */
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
info.si_signo = TARGET_SIGTRAP;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
|
||||
break;
|
||||
case EXCP_ATOMIC:
|
||||
cpu_exec_step_atomic(cs);
|
||||
|
||||
@@ -1,58 +1 @@
|
||||
/*
|
||||
* OpenRISC specific structures for linux-user
|
||||
*
|
||||
* Copyright (c) 2013 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef OPENRISC_TARGET_STRUCTS_H
|
||||
#define OPENRISC_TARGET_STRUCTS_H
|
||||
|
||||
struct target_ipc_perm {
|
||||
abi_int __key; /* Key. */
|
||||
abi_uint uid; /* Owner's user ID. */
|
||||
abi_uint gid; /* Owner's group ID. */
|
||||
abi_uint cuid; /* Creator's user ID. */
|
||||
abi_uint cgid; /* Creator's group ID. */
|
||||
abi_ushort mode; /* Read/write permission. */
|
||||
abi_ushort __pad1;
|
||||
abi_ushort __seq; /* Sequence number. */
|
||||
abi_ushort __pad2;
|
||||
abi_ulong __unused1;
|
||||
abi_ulong __unused2;
|
||||
};
|
||||
|
||||
struct target_shmid_ds {
|
||||
struct target_ipc_perm shm_perm; /* operation permission struct */
|
||||
abi_long shm_segsz; /* size of segment in bytes */
|
||||
abi_ulong shm_atime; /* time of last shmat() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused1;
|
||||
#endif
|
||||
abi_ulong shm_dtime; /* time of last shmdt() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused2;
|
||||
#endif
|
||||
abi_ulong shm_ctime; /* time of last change by shmctl() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused3;
|
||||
#endif
|
||||
abi_int shm_cpid; /* pid of creator */
|
||||
abi_int shm_lpid; /* pid of last shmop */
|
||||
abi_ulong shm_nattch; /* number of current attaches */
|
||||
abi_ulong __unused4;
|
||||
abi_ulong __unused5;
|
||||
};
|
||||
|
||||
#endif
|
||||
#include "../generic/target_structs.h"
|
||||
|
||||
+28
-108
@@ -76,8 +76,7 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
|
||||
void cpu_loop(CPUPPCState *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
target_siginfo_t info;
|
||||
int trapnr;
|
||||
int trapnr, si_signo, si_code;
|
||||
target_ulong ret;
|
||||
|
||||
for(;;) {
|
||||
@@ -102,61 +101,10 @@ void cpu_loop(CPUPPCState *env)
|
||||
"Aborting\n");
|
||||
break;
|
||||
case POWERPC_EXCP_DSI: /* Data storage exception */
|
||||
/* XXX: check this. Seems bugged */
|
||||
switch (env->error_code & 0xFF000000) {
|
||||
case 0x40000000:
|
||||
case 0x42000000:
|
||||
info.si_signo = TARGET_SIGSEGV;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
break;
|
||||
case 0x04000000:
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLADR;
|
||||
break;
|
||||
case 0x08000000:
|
||||
info.si_signo = TARGET_SIGSEGV;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SEGV_ACCERR;
|
||||
break;
|
||||
default:
|
||||
/* Let's send a regular segfault... */
|
||||
EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
|
||||
env->error_code);
|
||||
info.si_signo = TARGET_SIGSEGV;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
break;
|
||||
}
|
||||
info._sifields._sigfault._addr = env->spr[SPR_DAR];
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_ISI: /* Instruction storage exception */
|
||||
/* XXX: check this */
|
||||
switch (env->error_code & 0xFF000000) {
|
||||
case 0x40000000:
|
||||
info.si_signo = TARGET_SIGSEGV;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
break;
|
||||
case 0x10000000:
|
||||
case 0x08000000:
|
||||
info.si_signo = TARGET_SIGSEGV;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SEGV_ACCERR;
|
||||
break;
|
||||
default:
|
||||
/* Let's send a regular segfault... */
|
||||
EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
|
||||
env->error_code);
|
||||
info.si_signo = TARGET_SIGSEGV;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
break;
|
||||
}
|
||||
info._sifields._sigfault._addr = env->nip - 4;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
/* FIXME: handle maperr in ppc_cpu_record_sigsegv. */
|
||||
force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR,
|
||||
env->spr[SPR_DAR]);
|
||||
break;
|
||||
case POWERPC_EXCP_EXTERNAL: /* External input */
|
||||
cpu_abort(cs, "External interrupt while in user mode. "
|
||||
@@ -167,24 +115,23 @@ void cpu_loop(CPUPPCState *env)
|
||||
/* XXX: check this */
|
||||
switch (env->error_code & ~0xF) {
|
||||
case POWERPC_EXCP_FP:
|
||||
info.si_signo = TARGET_SIGFPE;
|
||||
info.si_errno = 0;
|
||||
si_signo = TARGET_SIGFPE;
|
||||
switch (env->error_code & 0xF) {
|
||||
case POWERPC_EXCP_FP_OX:
|
||||
info.si_code = TARGET_FPE_FLTOVF;
|
||||
si_code = TARGET_FPE_FLTOVF;
|
||||
break;
|
||||
case POWERPC_EXCP_FP_UX:
|
||||
info.si_code = TARGET_FPE_FLTUND;
|
||||
si_code = TARGET_FPE_FLTUND;
|
||||
break;
|
||||
case POWERPC_EXCP_FP_ZX:
|
||||
case POWERPC_EXCP_FP_VXZDZ:
|
||||
info.si_code = TARGET_FPE_FLTDIV;
|
||||
si_code = TARGET_FPE_FLTDIV;
|
||||
break;
|
||||
case POWERPC_EXCP_FP_XX:
|
||||
info.si_code = TARGET_FPE_FLTRES;
|
||||
si_code = TARGET_FPE_FLTRES;
|
||||
break;
|
||||
case POWERPC_EXCP_FP_VXSOFT:
|
||||
info.si_code = TARGET_FPE_FLTINV;
|
||||
si_code = TARGET_FPE_FLTINV;
|
||||
break;
|
||||
case POWERPC_EXCP_FP_VXSNAN:
|
||||
case POWERPC_EXCP_FP_VXISI:
|
||||
@@ -193,51 +140,50 @@ void cpu_loop(CPUPPCState *env)
|
||||
case POWERPC_EXCP_FP_VXVC:
|
||||
case POWERPC_EXCP_FP_VXSQRT:
|
||||
case POWERPC_EXCP_FP_VXCVI:
|
||||
info.si_code = TARGET_FPE_FLTSUB;
|
||||
si_code = TARGET_FPE_FLTSUB;
|
||||
break;
|
||||
default:
|
||||
EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",
|
||||
env->error_code);
|
||||
si_code = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case POWERPC_EXCP_INVAL:
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
si_signo = TARGET_SIGILL;
|
||||
switch (env->error_code & 0xF) {
|
||||
case POWERPC_EXCP_INVAL_INVAL:
|
||||
info.si_code = TARGET_ILL_ILLOPC;
|
||||
si_code = TARGET_ILL_ILLOPC;
|
||||
break;
|
||||
case POWERPC_EXCP_INVAL_LSWX:
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
si_code = TARGET_ILL_ILLOPN;
|
||||
break;
|
||||
case POWERPC_EXCP_INVAL_SPR:
|
||||
info.si_code = TARGET_ILL_PRVREG;
|
||||
si_code = TARGET_ILL_PRVREG;
|
||||
break;
|
||||
case POWERPC_EXCP_INVAL_FP:
|
||||
info.si_code = TARGET_ILL_COPROC;
|
||||
si_code = TARGET_ILL_COPROC;
|
||||
break;
|
||||
default:
|
||||
EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",
|
||||
env->error_code & 0xF);
|
||||
info.si_code = TARGET_ILL_ILLADR;
|
||||
si_code = TARGET_ILL_ILLADR;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case POWERPC_EXCP_PRIV:
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
si_signo = TARGET_SIGILL;
|
||||
switch (env->error_code & 0xF) {
|
||||
case POWERPC_EXCP_PRIV_OPC:
|
||||
info.si_code = TARGET_ILL_PRVOPC;
|
||||
si_code = TARGET_ILL_PRVOPC;
|
||||
break;
|
||||
case POWERPC_EXCP_PRIV_REG:
|
||||
info.si_code = TARGET_ILL_PRVREG;
|
||||
si_code = TARGET_ILL_PRVREG;
|
||||
break;
|
||||
default:
|
||||
EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",
|
||||
env->error_code & 0xF);
|
||||
info.si_code = TARGET_ILL_PRVOPC;
|
||||
si_code = TARGET_ILL_PRVOPC;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -250,28 +196,19 @@ void cpu_loop(CPUPPCState *env)
|
||||
env->error_code);
|
||||
break;
|
||||
}
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(si_signo, si_code, env->nip);
|
||||
break;
|
||||
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_COPROC;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
|
||||
case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */
|
||||
case POWERPC_EXCP_VPU: /* Vector unavailable exception */
|
||||
force_sig_fault(TARGET_SIGILL, TARGET_ILL_COPROC, env->nip);
|
||||
break;
|
||||
case POWERPC_EXCP_SYSCALL: /* System call exception */
|
||||
case POWERPC_EXCP_SYSCALL_VECTORED:
|
||||
cpu_abort(cs, "Syscall exception while in user mode. "
|
||||
"Aborting\n");
|
||||
break;
|
||||
case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_COPROC;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_DECR: /* Decrementer exception */
|
||||
cpu_abort(cs, "Decrementer interrupt while in user mode. "
|
||||
"Aborting\n");
|
||||
@@ -292,13 +229,6 @@ void cpu_loop(CPUPPCState *env)
|
||||
cpu_abort(cs, "Instruction TLB exception while in user mode. "
|
||||
"Aborting\n");
|
||||
break;
|
||||
case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_COPROC;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */
|
||||
cpu_abort(cs, "Embedded floating-point data IRQ not handled\n");
|
||||
break;
|
||||
@@ -355,13 +285,6 @@ void cpu_loop(CPUPPCState *env)
|
||||
cpu_abort(cs, "Hypervisor instruction segment exception "
|
||||
"while in user mode. Aborting\n");
|
||||
break;
|
||||
case POWERPC_EXCP_VPU: /* Vector unavailable exception */
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_COPROC;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */
|
||||
cpu_abort(cs, "Programmable interval timer interrupt "
|
||||
"while in user mode. Aborting\n");
|
||||
@@ -444,10 +367,7 @@ void cpu_loop(CPUPPCState *env)
|
||||
env->gpr[3] = ret;
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
info.si_signo = TARGET_SIGTRAP;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_TRAP_BRKPT;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->nip);
|
||||
break;
|
||||
case EXCP_INTERRUPT:
|
||||
/* just indicate that signals should be handled asap */
|
||||
|
||||
@@ -30,8 +30,7 @@
|
||||
void cpu_loop(CPURISCVState *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
int trapnr, signum, sigcode;
|
||||
target_ulong sigaddr;
|
||||
int trapnr;
|
||||
target_ulong ret;
|
||||
|
||||
for (;;) {
|
||||
@@ -40,10 +39,6 @@ void cpu_loop(CPURISCVState *env)
|
||||
cpu_exec_end(cs);
|
||||
process_queued_cpu_work(cs);
|
||||
|
||||
signum = 0;
|
||||
sigcode = 0;
|
||||
sigaddr = 0;
|
||||
|
||||
switch (trapnr) {
|
||||
case EXCP_INTERRUPT:
|
||||
/* just indicate that signals should be handled asap */
|
||||
@@ -79,39 +74,23 @@ void cpu_loop(CPURISCVState *env)
|
||||
}
|
||||
break;
|
||||
case RISCV_EXCP_ILLEGAL_INST:
|
||||
signum = TARGET_SIGILL;
|
||||
sigcode = TARGET_ILL_ILLOPC;
|
||||
force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->pc);
|
||||
break;
|
||||
case RISCV_EXCP_BREAKPOINT:
|
||||
signum = TARGET_SIGTRAP;
|
||||
sigcode = TARGET_TRAP_BRKPT;
|
||||
sigaddr = env->pc;
|
||||
case EXCP_DEBUG:
|
||||
gdbstep:
|
||||
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
|
||||
break;
|
||||
case RISCV_EXCP_SEMIHOST:
|
||||
env->gpr[xA0] = do_common_semihosting(cs);
|
||||
env->pc += 4;
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
gdbstep:
|
||||
signum = TARGET_SIGTRAP;
|
||||
sigcode = TARGET_TRAP_BRKPT;
|
||||
break;
|
||||
default:
|
||||
EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
|
||||
trapnr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (signum) {
|
||||
target_siginfo_t info = {
|
||||
.si_signo = signum,
|
||||
.si_errno = 0,
|
||||
.si_code = sigcode,
|
||||
._sifields._sigfault._addr = sigaddr
|
||||
};
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
|
||||
process_pending_signals(env);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user