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:
Peter Maydell 2022-01-12 11:51:47 +00:00
commit 91f5f7a5df
34 changed files with 318 additions and 1161 deletions

View File

@ -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"

View File

@ -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. */

View File

@ -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"

View File

@ -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);

View File

@ -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"

View 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

View File

@ -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"

View File

@ -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 */

View File

@ -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);

View File

@ -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"

View File

@ -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);

View File

@ -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"

View File

@ -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);

View File

@ -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"

View File

@ -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();
}

View File

@ -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"

View File

@ -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);

View File

@ -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"

View File

@ -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 */

View File

@ -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);
}
}

View File

@ -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"

View File

@ -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:

View File

@ -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);

View File

@ -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"

View File

@ -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);

View File

@ -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)
{

View File

@ -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;

View File

@ -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.

View File

@ -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:

View File

@ -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:

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);