linux-user pull request 20220111
siginfo_t cleanup more prtctl() update target_struct.h cleanup -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEEzS913cjjpNwuT1Fz8ww4vT8vvjwFAmHd3/QSHGxhdXJlbnRA dml2aWVyLmV1AAoJEPMMOL0/L748Dd8P/17YoylgR93nPL//v1hbd2lpENhhany/ Oz3YDxETLmPPaMZtKCiMiZ5OtoojvD5PS4SrRDaaP+hfF+KdDIcLpIjMje1jonf+ H9IDYUlDRym4ucYvK+ZwPzz/+rMq/iaYT8ih0XvPKjEmbewtWeuIFgmCo8a6fvxg Aci+r4NxfjUeN7nN8oltxUx4DbS1uEJEm+HDCxFxEh26fN0ab+0wiBl93swQ71MG OoHG8KNJTiLre4TBtqJCbVSDqTIq+aorwus9Fh4qwCsqZA0TesRlAcq+TjoSbc2m eAr5kcarxVhI/qLkRlq9epPn/GlULdzlU1YOuM5bOpdOwJlmeiQTlDKUG2CtQ4Ym kvzxkMNVyb5jfUzYHt0oJHPnHXGGCXNSVUQ5rL51igOQWCn/IJ89kmqhcyObPrTZ eFkjplkl+BvhwCJl1SgbMaTJxeI9iwR5jsZwwikTlNmyy2twh93lEPmWyJezYsln A8QxNOWBgSvitPriZqq5nYgTQ/uARtkMhrNjwKYF5NvWUF2Z3ps1S5IgRwk2W2r+ LFldwPmDeUkxsTXtVE7IWGqFFZG1ttQ5wyfNq82Ft7Cdem8bhOmQ0fxQqa7YmUrU 0EdNAQ/X9SIhjswy5+woArBTbybefDS3cY9ZUM3D/AOWe+gyFNktQ2UemDWXaPVf Xl5TF8k1Alko =/Z6c -----END PGP SIGNATURE----- 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:
commit
91f5f7a5df
@ -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"
|
||||
|
@ -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"
|
||||
|
58
linux-user/generic/target_structs.h
Normal file
58
linux-user/generic/target_structs.h
Normal file
@ -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"
|
||||
|
@ -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 */
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -1,46 +1 @@
|
||||
/*
|
||||
* RISC-V specific structures for linux-user
|
||||
*
|
||||
* This is a copy of ../aarch64/target_structs.h atm.
|
||||
*
|
||||
*/
|
||||
#ifndef RISCV_TARGET_STRUCTS_H
|
||||
#define RISCV_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"
|
||||
|
@ -58,7 +58,6 @@ void cpu_loop(CPUS390XState *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
int trapnr, n, sig;
|
||||
target_siginfo_t info;
|
||||
target_ulong addr;
|
||||
abi_long ret;
|
||||
|
||||
@ -158,11 +157,7 @@ void cpu_loop(CPUS390XState *env)
|
||||
*/
|
||||
env->psw.addr += env->int_pgm_ilen;
|
||||
do_signal:
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
info.si_code = n;
|
||||
info._sifields._sigfault._addr = addr;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(sig, n, addr);
|
||||
break;
|
||||
|
||||
case EXCP_ATOMIC:
|
||||
|
@ -28,7 +28,6 @@ void cpu_loop(CPUSH4State *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
int trapnr, ret;
|
||||
target_siginfo_t info;
|
||||
|
||||
while (1) {
|
||||
bool arch_interrupt = true;
|
||||
@ -60,10 +59,7 @@ void cpu_loop(CPUSH4State *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 @@
|
||||
/*
|
||||
* SH4 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 SH4_TARGET_STRUCTS_H
|
||||
#define SH4_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"
|
||||
|
@ -155,7 +155,6 @@ void cpu_loop (CPUSPARCState *env)
|
||||
CPUState *cs = env_cpu(env);
|
||||
int trapnr;
|
||||
abi_long ret;
|
||||
target_siginfo_t info;
|
||||
|
||||
while (1) {
|
||||
cpu_exec_start(cs);
|
||||
@ -241,19 +240,10 @@ void cpu_loop (CPUSPARCState *env)
|
||||
/* just indicate that signals should be handled asap */
|
||||
break;
|
||||
case TT_ILL_INSN:
|
||||
{
|
||||
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_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);
|
||||
|
@ -6444,11 +6444,15 @@ static abi_long do_prctl(CPUArchState *env, abi_long option, abi_long arg2,
|
||||
int deathsig;
|
||||
ret = get_errno(prctl(PR_GET_PDEATHSIG, &deathsig,
|
||||
arg3, arg4, arg5));
|
||||
if (!is_error(ret) && arg2 && put_user_s32(deathsig, arg2)) {
|
||||
if (!is_error(ret) &&
|
||||
put_user_s32(host_to_target_signal(deathsig), arg2)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
case PR_SET_PDEATHSIG:
|
||||
return get_errno(prctl(PR_SET_PDEATHSIG, target_to_host_signal(arg2),
|
||||
arg3, arg4, arg5));
|
||||
case PR_GET_NAME:
|
||||
{
|
||||
void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
|
||||
@ -6500,10 +6504,15 @@ static abi_long do_prctl(CPUArchState *env, abi_long option, abi_long arg2,
|
||||
case PR_SET_UNALIGN:
|
||||
return do_prctl_set_unalign(env, arg2);
|
||||
|
||||
case PR_CAP_AMBIENT:
|
||||
case PR_CAPBSET_READ:
|
||||
case PR_CAPBSET_DROP:
|
||||
case PR_GET_DUMPABLE:
|
||||
case PR_SET_DUMPABLE:
|
||||
case PR_GET_KEEPCAPS:
|
||||
case PR_SET_KEEPCAPS:
|
||||
case PR_GET_SECUREBITS:
|
||||
case PR_SET_SECUREBITS:
|
||||
case PR_GET_TIMING:
|
||||
case PR_SET_TIMING:
|
||||
case PR_GET_TIMERSLACK:
|
||||
@ -6927,6 +6936,14 @@ typedef abi_long from_flock64_fn(struct flock64 *fl, abi_ulong target_addr);
|
||||
typedef abi_long to_flock64_fn(abi_ulong target_addr, const struct flock64 *fl);
|
||||
|
||||
#if defined(TARGET_ARM) && TARGET_ABI_BITS == 32
|
||||
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;
|
||||
|
||||
static inline abi_long copy_from_user_oabi_flock64(struct flock64 *fl,
|
||||
abi_ulong target_flock_addr)
|
||||
{
|
||||
|
@ -688,7 +688,7 @@ typedef struct target_siginfo {
|
||||
#define TARGET_FPE_FLTINV (7) /* floating point invalid operation */
|
||||
#define TARGET_FPE_FLTSUB (8) /* subscript out of range */
|
||||
#define TARGET_FPE_FLTUNK (14) /* undiagnosed fp exception */
|
||||
#define TARGET_NSIGFPE 15
|
||||
#define TARGET_FPE_CONDTRAP (15) /* trap on condition */
|
||||
|
||||
/*
|
||||
* SIGSEGV si_codes
|
||||
@ -715,6 +715,7 @@ typedef struct target_siginfo {
|
||||
#define TARGET_TRAP_TRACE (2) /* process trace trap */
|
||||
#define TARGET_TRAP_BRANCH (3) /* process taken branch trap */
|
||||
#define TARGET_TRAP_HWBKPT (4) /* hardware breakpoint/watchpoint */
|
||||
#define TARGET_TRAP_UNK (5) /* undiagnosed trap */
|
||||
|
||||
struct target_rlimit {
|
||||
abi_ulong rlim_cur;
|
||||
|
@ -19,41 +19,7 @@
|
||||
#ifndef X86_64_TARGET_STRUCTS_H
|
||||
#define X86_64_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;
|
||||
};
|
||||
#include "../generic/target_structs.h"
|
||||
|
||||
/* The x86 definition differs from the generic one in that the
|
||||
* two padding fields exist whether the ABI is 32 bits or 64 bits.
|
||||
|
@ -126,7 +126,6 @@ static void xtensa_underflow12(CPUXtensaState *env)
|
||||
void cpu_loop(CPUXtensaState *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
target_siginfo_t info;
|
||||
abi_ulong ret;
|
||||
int trapnr;
|
||||
|
||||
@ -163,14 +162,12 @@ void cpu_loop(CPUXtensaState *env)
|
||||
case EXC_USER:
|
||||
switch (env->sregs[EXCCAUSE]) {
|
||||
case ILLEGAL_INSTRUCTION_CAUSE:
|
||||
force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC,
|
||||
env->sregs[EPC1]);
|
||||
break;
|
||||
case PRIVILEGED_CAUSE:
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code =
|
||||
env->sregs[EXCCAUSE] == ILLEGAL_INSTRUCTION_CAUSE ?
|
||||
TARGET_ILL_ILLOPC : TARGET_ILL_PRVOPC;
|
||||
info._sifields._sigfault._addr = env->sregs[EPC1];
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVOPC,
|
||||
env->sregs[EPC1]);
|
||||
break;
|
||||
|
||||
case SYSCALL_CAUSE:
|
||||
@ -219,11 +216,8 @@ void cpu_loop(CPUXtensaState *env)
|
||||
break;
|
||||
|
||||
case INTEGER_DIVIDE_BY_ZERO_CAUSE:
|
||||
info.si_signo = TARGET_SIGFPE;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_FPE_INTDIV;
|
||||
info._sifields._sigfault._addr = env->sregs[EPC1];
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTDIV,
|
||||
env->sregs[EPC1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -232,10 +226,8 @@ void cpu_loop(CPUXtensaState *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->sregs[EPC1]);
|
||||
break;
|
||||
case EXC_DEBUG:
|
||||
default:
|
||||
|
@ -822,7 +822,7 @@ static void gen_pool16c_insn(DisasContext *ctx)
|
||||
gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
|
||||
break;
|
||||
case BREAK16:
|
||||
generate_exception_end(ctx, EXCP_BREAK);
|
||||
generate_exception_break(ctx, extract32(ctx->opcode, 0, 4));
|
||||
break;
|
||||
case SDBBP16:
|
||||
if (is_uhi(extract32(ctx->opcode, 0, 4))) {
|
||||
@ -937,7 +937,7 @@ static void gen_pool16c_r6_insn(DisasContext *ctx)
|
||||
break;
|
||||
case R6_BREAK16:
|
||||
/* BREAK16 */
|
||||
generate_exception(ctx, EXCP_BREAK);
|
||||
generate_exception_break(ctx, extract32(ctx->opcode, 6, 4));
|
||||
break;
|
||||
case R6_SDBBP16:
|
||||
/* SDBBP16 */
|
||||
@ -1047,7 +1047,7 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
|
||||
case TNE:
|
||||
mips32_op = OPC_TNE;
|
||||
do_trap:
|
||||
gen_trap(ctx, mips32_op, rs, rt, -1);
|
||||
gen_trap(ctx, mips32_op, rs, rt, -1, extract32(ctx->opcode, 12, 4));
|
||||
break;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
case MFC0:
|
||||
@ -1812,7 +1812,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
|
||||
gen_pool32axf(env, ctx, rt, rs);
|
||||
break;
|
||||
case BREAK32:
|
||||
generate_exception_end(ctx, EXCP_BREAK);
|
||||
generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
|
||||
break;
|
||||
case SIGRIE:
|
||||
check_insn(ctx, ISA_MIPS_R6);
|
||||
@ -2439,7 +2439,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
|
||||
check_insn_opc_removed(ctx, ISA_MIPS_R6);
|
||||
mips32_op = OPC_TEQI;
|
||||
do_trapi:
|
||||
gen_trap(ctx, mips32_op, rs, -1, imm);
|
||||
gen_trap(ctx, mips32_op, rs, -1, imm, 0);
|
||||
break;
|
||||
|
||||
case BNEZC:
|
||||
|
@ -969,7 +969,7 @@ static int decode_ase_mips16e(CPUMIPSState *env, DisasContext *ctx)
|
||||
gen_slt(ctx, OPC_SLTU, 24, rx, ry);
|
||||
break;
|
||||
case RR_BREAK:
|
||||
generate_exception_end(ctx, EXCP_BREAK);
|
||||
generate_exception_break(ctx, extract32(ctx->opcode, 5, 6));
|
||||
break;
|
||||
case RR_SLLV:
|
||||
gen_shift(ctx, OPC_SLLV, ry, rx, ry);
|
||||
|
@ -1268,11 +1268,11 @@ static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
|
||||
switch (extract32(ctx->opcode, 10, 1)) {
|
||||
case NM_TEQ:
|
||||
check_nms(ctx);
|
||||
gen_trap(ctx, OPC_TEQ, rs, rt, -1);
|
||||
gen_trap(ctx, OPC_TEQ, rs, rt, -1, rd);
|
||||
break;
|
||||
case NM_TNE:
|
||||
check_nms(ctx);
|
||||
gen_trap(ctx, OPC_TNE, rs, rt, -1);
|
||||
gen_trap(ctx, OPC_TNE, rs, rt, -1, rd);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -1367,6 +1367,16 @@ void generate_exception_end(DisasContext *ctx, int excp)
|
||||
generate_exception_err(ctx, excp, 0);
|
||||
}
|
||||
|
||||
void generate_exception_break(DisasContext *ctx, int code)
|
||||
{
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
/* Pass the break code along to cpu_loop. */
|
||||
tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
|
||||
offsetof(CPUMIPSState, error_code));
|
||||
#endif
|
||||
generate_exception_end(ctx, EXCP_BREAK);
|
||||
}
|
||||
|
||||
void gen_reserved_instruction(DisasContext *ctx)
|
||||
{
|
||||
generate_exception_end(ctx, EXCP_RI);
|
||||
@ -4723,7 +4733,7 @@ static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
|
||||
|
||||
/* Traps */
|
||||
static void gen_trap(DisasContext *ctx, uint32_t opc,
|
||||
int rs, int rt, int16_t imm)
|
||||
int rs, int rt, int16_t imm, int code)
|
||||
{
|
||||
int cond;
|
||||
TCGv t0 = tcg_temp_new();
|
||||
@ -4768,6 +4778,11 @@ static void gen_trap(DisasContext *ctx, uint32_t opc,
|
||||
case OPC_TGEU: /* rs >= rs unsigned */
|
||||
case OPC_TGEIU: /* r0 >= 0 unsigned */
|
||||
/* Always trap */
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
/* Pass the break code along to cpu_loop. */
|
||||
tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
|
||||
offsetof(CPUMIPSState, error_code));
|
||||
#endif
|
||||
generate_exception_end(ctx, EXCP_TRAP);
|
||||
break;
|
||||
case OPC_TLT: /* rs < rs */
|
||||
@ -4808,6 +4823,18 @@ static void gen_trap(DisasContext *ctx, uint32_t opc,
|
||||
tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
|
||||
break;
|
||||
}
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
/* Pass the break code along to cpu_loop. */
|
||||
tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
|
||||
offsetof(CPUMIPSState, error_code));
|
||||
#endif
|
||||
/* Like save_cpu_state, only don't update saved values. */
|
||||
if (ctx->base.pc_next != ctx->saved_pc) {
|
||||
gen_save_pc(ctx->base.pc_next);
|
||||
}
|
||||
if (ctx->hflags != ctx->saved_hflags) {
|
||||
tcg_gen_movi_i32(hflags, ctx->hflags);
|
||||
}
|
||||
generate_exception(ctx, EXCP_TRAP);
|
||||
gen_set_label(l1);
|
||||
}
|
||||
@ -14145,7 +14172,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
|
||||
case OPC_TEQ:
|
||||
case OPC_TNE:
|
||||
check_insn(ctx, ISA_MIPS2);
|
||||
gen_trap(ctx, op1, rs, rt, -1);
|
||||
gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10));
|
||||
break;
|
||||
case OPC_PMON:
|
||||
/* Pmon entry point, also R4010 selsl */
|
||||
@ -14160,7 +14187,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
|
||||
generate_exception_end(ctx, EXCP_SYSCALL);
|
||||
break;
|
||||
case OPC_BREAK:
|
||||
generate_exception_end(ctx, EXCP_BREAK);
|
||||
generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
|
||||
break;
|
||||
case OPC_SYNC:
|
||||
check_insn(ctx, ISA_MIPS2);
|
||||
@ -15279,11 +15306,10 @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
|
||||
case OPC_TLTI:
|
||||
case OPC_TLTIU:
|
||||
case OPC_TEQI:
|
||||
|
||||
case OPC_TNEI:
|
||||
check_insn(ctx, ISA_MIPS2);
|
||||
check_insn_opc_removed(ctx, ISA_MIPS_R6);
|
||||
gen_trap(ctx, op1, rs, -1, imm);
|
||||
gen_trap(ctx, op1, rs, -1, imm, 0);
|
||||
break;
|
||||
case OPC_SIGRIE:
|
||||
check_insn(ctx, ISA_MIPS_R6);
|
||||
|
@ -129,6 +129,7 @@ enum {
|
||||
void generate_exception(DisasContext *ctx, int excp);
|
||||
void generate_exception_err(DisasContext *ctx, int excp, int err);
|
||||
void generate_exception_end(DisasContext *ctx, int excp);
|
||||
void generate_exception_break(DisasContext *ctx, int code);
|
||||
void gen_reserved_instruction(DisasContext *ctx);
|
||||
|
||||
void check_insn(DisasContext *ctx, uint64_t flags);
|
||||
|
Loading…
Reference in New Issue
Block a user