]> git.proxmox.com Git - mirror_qemu.git/commitdiff
user: move common-user includes to a subdirectory of {bsd,linux}-user/
authorPaolo Bonzini <pbonzini@redhat.com>
Tue, 21 Dec 2021 15:20:32 +0000 (16:20 +0100)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 12 Jan 2022 13:08:29 +0000 (14:08 +0100)
Avoid polluting the compilation of common-user/ with local include files;
making an include file available to common-user/ should be a deliberate
decision in order to keep a clear interface that can be used by both
bsd-user/ and linux-user/.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
36 files changed:
bsd-user/include/special-errno.h [new file with mode: 0644]
bsd-user/meson.build
bsd-user/special-errno.h [deleted file]
linux-user/host/aarch64/host-signal.h [deleted file]
linux-user/host/alpha/host-signal.h [deleted file]
linux-user/host/arm/host-signal.h [deleted file]
linux-user/host/i386/host-signal.h [deleted file]
linux-user/host/loongarch64/host-signal.h [deleted file]
linux-user/host/mips/host-signal.h [deleted file]
linux-user/host/ppc/host-signal.h [deleted file]
linux-user/host/ppc64/host-signal.h [deleted file]
linux-user/host/riscv/host-signal.h [deleted file]
linux-user/host/s390/host-signal.h [deleted file]
linux-user/host/s390x/host-signal.h [deleted file]
linux-user/host/sparc/host-signal.h [deleted file]
linux-user/host/sparc64/host-signal.h [deleted file]
linux-user/host/x32/host-signal.h [deleted file]
linux-user/host/x86_64/host-signal.h [deleted file]
linux-user/include/host/aarch64/host-signal.h [new file with mode: 0644]
linux-user/include/host/alpha/host-signal.h [new file with mode: 0644]
linux-user/include/host/arm/host-signal.h [new file with mode: 0644]
linux-user/include/host/i386/host-signal.h [new file with mode: 0644]
linux-user/include/host/loongarch64/host-signal.h [new file with mode: 0644]
linux-user/include/host/mips/host-signal.h [new file with mode: 0644]
linux-user/include/host/ppc/host-signal.h [new file with mode: 0644]
linux-user/include/host/ppc64/host-signal.h [new file with mode: 0644]
linux-user/include/host/riscv/host-signal.h [new file with mode: 0644]
linux-user/include/host/s390/host-signal.h [new file with mode: 0644]
linux-user/include/host/s390x/host-signal.h [new file with mode: 0644]
linux-user/include/host/sparc/host-signal.h [new file with mode: 0644]
linux-user/include/host/sparc64/host-signal.h [new file with mode: 0644]
linux-user/include/host/x32/host-signal.h [new file with mode: 0644]
linux-user/include/host/x86_64/host-signal.h [new file with mode: 0644]
linux-user/include/special-errno.h [new file with mode: 0644]
linux-user/meson.build
linux-user/special-errno.h [deleted file]

diff --git a/bsd-user/include/special-errno.h b/bsd-user/include/special-errno.h
new file mode 100644 (file)
index 0000000..03599d9
--- /dev/null
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * QEMU internal errno values for implementing user-only POSIX.
+ *
+ *  Copyright (c) 2021 Linaro, Ltd.
+ */
+
+#ifndef SPECIAL_ERRNO_H
+#define SPECIAL_ERRNO_H
+
+/*
+ * All of these are QEMU internal, not visible to the guest.
+ * They should be chosen so as to not overlap with any host
+ * or guest errno.
+ */
+
+/*
+ * This is returned when a system call should be restarted, to tell the
+ * main loop that it should wind the guest PC backwards so it will
+ * re-execute the syscall after handling any pending signals.
+ */
+#define QEMU_ERESTARTSYS  255
+
+#endif /* SPECIAL_ERRNO_H */
index 9fcb80c3fa8060f6d2209284f5369b538003d18a..8380fa44c25c17c16d3c412ba9d12e2773d8f16a 100644 (file)
@@ -4,7 +4,7 @@ endif
 
 bsd_user_ss = ss.source_set()
 
-common_user_inc += include_directories('.')
+common_user_inc += include_directories('include')
 
 bsd_user_ss.add(files(
   'bsdload.c',
diff --git a/bsd-user/special-errno.h b/bsd-user/special-errno.h
deleted file mode 100644 (file)
index 03599d9..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause */
-/*
- * QEMU internal errno values for implementing user-only POSIX.
- *
- *  Copyright (c) 2021 Linaro, Ltd.
- */
-
-#ifndef SPECIAL_ERRNO_H
-#define SPECIAL_ERRNO_H
-
-/*
- * All of these are QEMU internal, not visible to the guest.
- * They should be chosen so as to not overlap with any host
- * or guest errno.
- */
-
-/*
- * This is returned when a system call should be restarted, to tell the
- * main loop that it should wind the guest PC backwards so it will
- * re-execute the syscall after handling any pending signals.
- */
-#define QEMU_ERESTARTSYS  255
-
-#endif /* SPECIAL_ERRNO_H */
diff --git a/linux-user/host/aarch64/host-signal.h b/linux-user/host/aarch64/host-signal.h
deleted file mode 100644 (file)
index 9770b36..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * host-signal.h: signal info dependent on the host architecture
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- * Copyright (c) 2021 Linaro Limited
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef AARCH64_HOST_SIGNAL_H
-#define AARCH64_HOST_SIGNAL_H
-
-/* Pre-3.16 kernel headers don't have these, so provide fallback definitions */
-#ifndef ESR_MAGIC
-#define ESR_MAGIC 0x45535201
-struct esr_context {
-    struct _aarch64_ctx head;
-    uint64_t esr;
-};
-#endif
-
-static inline struct _aarch64_ctx *first_ctx(ucontext_t *uc)
-{
-    return (struct _aarch64_ctx *)&uc->uc_mcontext.__reserved;
-}
-
-static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr)
-{
-    return (struct _aarch64_ctx *)((char *)hdr + hdr->size);
-}
-
-static inline uintptr_t host_signal_pc(ucontext_t *uc)
-{
-    return uc->uc_mcontext.pc;
-}
-
-static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
-{
-    uc->uc_mcontext.pc = pc;
-}
-
-static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
-{
-    struct _aarch64_ctx *hdr;
-    uint32_t insn;
-
-    /* Find the esr_context, which has the WnR bit in it */
-    for (hdr = first_ctx(uc); hdr->magic; hdr = next_ctx(hdr)) {
-        if (hdr->magic == ESR_MAGIC) {
-            struct esr_context const *ec = (struct esr_context const *)hdr;
-            uint64_t esr = ec->esr;
-
-            /* For data aborts ESR.EC is 0b10010x: then bit 6 is the WnR bit */
-            return extract32(esr, 27, 5) == 0x12 && extract32(esr, 6, 1) == 1;
-        }
-    }
-
-    /*
-     * Fall back to parsing instructions; will only be needed
-     * for really ancient (pre-3.16) kernels.
-     */
-    insn = *(uint32_t *)host_signal_pc(uc);
-
-    return (insn & 0xbfff0000) == 0x0c000000   /* C3.3.1 */
-        || (insn & 0xbfe00000) == 0x0c800000   /* C3.3.2 */
-        || (insn & 0xbfdf0000) == 0x0d000000   /* C3.3.3 */
-        || (insn & 0xbfc00000) == 0x0d800000   /* C3.3.4 */
-        || (insn & 0x3f400000) == 0x08000000   /* C3.3.6 */
-        || (insn & 0x3bc00000) == 0x39000000   /* C3.3.13 */
-        || (insn & 0x3fc00000) == 0x3d800000   /* ... 128bit */
-        /* Ignore bits 10, 11 & 21, controlling indexing.  */
-        || (insn & 0x3bc00000) == 0x38000000   /* C3.3.8-12 */
-        || (insn & 0x3fe00000) == 0x3c800000   /* ... 128bit */
-        /* Ignore bits 23 & 24, controlling indexing.  */
-        || (insn & 0x3a400000) == 0x28000000; /* C3.3.7,14-16 */
-}
-
-#endif
diff --git a/linux-user/host/alpha/host-signal.h b/linux-user/host/alpha/host-signal.h
deleted file mode 100644 (file)
index f4c9429..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * host-signal.h: signal info dependent on the host architecture
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- * Copyright (c) 2021 Linaro Limited
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef ALPHA_HOST_SIGNAL_H
-#define ALPHA_HOST_SIGNAL_H
-
-static inline uintptr_t host_signal_pc(ucontext_t *uc)
-{
-    return uc->uc_mcontext.sc_pc;
-}
-
-static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
-{
-    uc->uc_mcontext.sc_pc = pc;
-}
-
-static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
-{
-    uint32_t *pc = (uint32_t *)host_signal_pc(uc);
-    uint32_t insn = *pc;
-
-    /* XXX: need kernel patch to get write flag faster */
-    switch (insn >> 26) {
-    case 0x0d: /* stw */
-    case 0x0e: /* stb */
-    case 0x0f: /* stq_u */
-    case 0x24: /* stf */
-    case 0x25: /* stg */
-    case 0x26: /* sts */
-    case 0x27: /* stt */
-    case 0x2c: /* stl */
-    case 0x2d: /* stq */
-    case 0x2e: /* stl_c */
-    case 0x2f: /* stq_c */
-        return true;
-    }
-    return false;
-}
-
-#endif
diff --git a/linux-user/host/arm/host-signal.h b/linux-user/host/arm/host-signal.h
deleted file mode 100644 (file)
index 6c09577..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * host-signal.h: signal info dependent on the host architecture
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- * Copyright (c) 2021 Linaro Limited
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef ARM_HOST_SIGNAL_H
-#define ARM_HOST_SIGNAL_H
-
-static inline uintptr_t host_signal_pc(ucontext_t *uc)
-{
-    return uc->uc_mcontext.arm_pc;
-}
-
-static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
-{
-    uc->uc_mcontext.arm_pc = pc;
-}
-
-static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
-{
-    /*
-     * In the FSR, bit 11 is WnR, assuming a v6 or
-     * later processor.  On v5 we will always report
-     * this as a read, which will fail later.
-     */
-    uint32_t fsr = uc->uc_mcontext.error_code;
-    return extract32(fsr, 11, 1);
-}
-
-#endif
diff --git a/linux-user/host/i386/host-signal.h b/linux-user/host/i386/host-signal.h
deleted file mode 100644 (file)
index abe1ece..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * host-signal.h: signal info dependent on the host architecture
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- * Copyright (c) 2021 Linaro Limited
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef I386_HOST_SIGNAL_H
-#define I386_HOST_SIGNAL_H
-
-static inline uintptr_t host_signal_pc(ucontext_t *uc)
-{
-    return uc->uc_mcontext.gregs[REG_EIP];
-}
-
-static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
-{
-    uc->uc_mcontext.gregs[REG_EIP] = pc;
-}
-
-static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
-{
-    return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe
-        && (uc->uc_mcontext.gregs[REG_ERR] & 0x2);
-}
-
-#endif
diff --git a/linux-user/host/loongarch64/host-signal.h b/linux-user/host/loongarch64/host-signal.h
deleted file mode 100644 (file)
index 7effa24..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * host-signal.h: signal info dependent on the host architecture
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- * Copyright (c) 2021 WANG Xuerui <git@xen0n.name>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef LOONGARCH64_HOST_SIGNAL_H
-#define LOONGARCH64_HOST_SIGNAL_H
-
-static inline uintptr_t host_signal_pc(ucontext_t *uc)
-{
-    return uc->uc_mcontext.__pc;
-}
-
-static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
-{
-    uc->uc_mcontext.__pc = pc;
-}
-
-static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
-{
-    const uint32_t *pinsn = (const uint32_t *)host_signal_pc(uc);
-    uint32_t insn = pinsn[0];
-
-    /* Detect store by reading the instruction at the program counter.  */
-    switch ((insn >> 26) & 0b111111) {
-    case 0b001000: /* {ll,sc}.[wd] */
-        switch ((insn >> 24) & 0b11) {
-        case 0b01: /* sc.w */
-        case 0b11: /* sc.d */
-            return true;
-        }
-        break;
-    case 0b001001: /* {ld,st}ox4.[wd] ({ld,st}ptr.[wd]) */
-        switch ((insn >> 24) & 0b11) {
-        case 0b01: /* stox4.w (stptr.w) */
-        case 0b11: /* stox4.d (stptr.d) */
-            return true;
-        }
-        break;
-    case 0b001010: /* {ld,st}.* family */
-        switch ((insn >> 22) & 0b1111) {
-        case 0b0100: /* st.b */
-        case 0b0101: /* st.h */
-        case 0b0110: /* st.w */
-        case 0b0111: /* st.d */
-        case 0b1101: /* fst.s */
-        case 0b1111: /* fst.d */
-            return true;
-        }
-        break;
-    case 0b001110: /* indexed, atomic, bounds-checking memory operations */
-        switch ((insn >> 15) & 0b11111111111) {
-        case 0b00000100000: /* stx.b */
-        case 0b00000101000: /* stx.h */
-        case 0b00000110000: /* stx.w */
-        case 0b00000111000: /* stx.d */
-        case 0b00001110000: /* fstx.s */
-        case 0b00001111000: /* fstx.d */
-        case 0b00011101100: /* fstgt.s */
-        case 0b00011101101: /* fstgt.d */
-        case 0b00011101110: /* fstle.s */
-        case 0b00011101111: /* fstle.d */
-        case 0b00011111000: /* stgt.b */
-        case 0b00011111001: /* stgt.h */
-        case 0b00011111010: /* stgt.w */
-        case 0b00011111011: /* stgt.d */
-        case 0b00011111100: /* stle.b */
-        case 0b00011111101: /* stle.h */
-        case 0b00011111110: /* stle.w */
-        case 0b00011111111: /* stle.d */
-        case 0b00011000000 ... 0b00011100011: /* am* insns */
-            return true;
-        }
-        break;
-    }
-
-    return false;
-}
-
-#endif
diff --git a/linux-user/host/mips/host-signal.h b/linux-user/host/mips/host-signal.h
deleted file mode 100644 (file)
index c666ed8..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * host-signal.h: signal info dependent on the host architecture
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- * Copyright (c) 2021 Linaro Limited
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef MIPS_HOST_SIGNAL_H
-#define MIPS_HOST_SIGNAL_H
-
-static inline uintptr_t host_signal_pc(ucontext_t *uc)
-{
-    return uc->uc_mcontext.pc;
-}
-
-static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
-{
-    uc->uc_mcontext.pc = pc;
-}
-
-#if defined(__misp16) || defined(__mips_micromips)
-#error "Unsupported encoding"
-#endif
-
-static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
-{
-    uint32_t insn = *(uint32_t *)host_signal_pc(uc);
-
-    /* Detect all store instructions at program counter. */
-    switch ((insn >> 26) & 077) {
-    case 050: /* SB */
-    case 051: /* SH */
-    case 052: /* SWL */
-    case 053: /* SW */
-    case 054: /* SDL */
-    case 055: /* SDR */
-    case 056: /* SWR */
-    case 070: /* SC */
-    case 071: /* SWC1 */
-    case 074: /* SCD */
-    case 075: /* SDC1 */
-    case 077: /* SD */
-#if !defined(__mips_isa_rev) || __mips_isa_rev < 6
-    case 072: /* SWC2 */
-    case 076: /* SDC2 */
-#endif
-        return true;
-    case 023: /* COP1X */
-        /*
-         * Required in all versions of MIPS64 since
-         * MIPS64r1 and subsequent versions of MIPS32r2.
-         */
-        switch (insn & 077) {
-        case 010: /* SWXC1 */
-        case 011: /* SDXC1 */
-        case 015: /* SUXC1 */
-            return true;
-        }
-        break;
-    }
-    return false;
-}
-
-#endif
diff --git a/linux-user/host/ppc/host-signal.h b/linux-user/host/ppc/host-signal.h
deleted file mode 100644 (file)
index 1d8e658..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * host-signal.h: signal info dependent on the host architecture
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- * Copyright (c) 2021 Linaro Limited
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef PPC_HOST_SIGNAL_H
-#define PPC_HOST_SIGNAL_H
-
-static inline uintptr_t host_signal_pc(ucontext_t *uc)
-{
-    return uc->uc_mcontext.regs->nip;
-}
-
-static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
-{
-    uc->uc_mcontext.regs->nip = pc;
-}
-
-static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
-{
-    return uc->uc_mcontext.regs->trap != 0x400
-        && (uc->uc_mcontext.regs->dsisr & 0x02000000);
-}
-
-#endif
diff --git a/linux-user/host/ppc64/host-signal.h b/linux-user/host/ppc64/host-signal.h
deleted file mode 100644 (file)
index a353c22..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "../ppc/host-signal.h"
diff --git a/linux-user/host/riscv/host-signal.h b/linux-user/host/riscv/host-signal.h
deleted file mode 100644 (file)
index a4f170e..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * host-signal.h: signal info dependent on the host architecture
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- * Copyright (c) 2021 Linaro Limited
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef RISCV_HOST_SIGNAL_H
-#define RISCV_HOST_SIGNAL_H
-
-static inline uintptr_t host_signal_pc(ucontext_t *uc)
-{
-    return uc->uc_mcontext.__gregs[REG_PC];
-}
-
-static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
-{
-    uc->uc_mcontext.__gregs[REG_PC] = pc;
-}
-
-static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
-{
-    /*
-     * Detect store by reading the instruction at the program counter.
-     * Do not read more than 16 bits, because we have not yet determined
-     * the size of the instruction.
-     */
-    const uint16_t *pinsn = (const uint16_t *)host_signal_pc(uc);
-    uint16_t insn = pinsn[0];
-
-    /* 16-bit instructions */
-    switch (insn & 0xe003) {
-    case 0xa000: /* c.fsd */
-    case 0xc000: /* c.sw */
-    case 0xe000: /* c.sd (rv64) / c.fsw (rv32) */
-    case 0xa002: /* c.fsdsp */
-    case 0xc002: /* c.swsp */
-    case 0xe002: /* c.sdsp (rv64) / c.fswsp (rv32) */
-        return true;
-    }
-
-    /* 32-bit instructions, major opcodes */
-    switch (insn & 0x7f) {
-    case 0x23: /* store */
-    case 0x27: /* store-fp */
-        return true;
-    case 0x2f: /* amo */
-        /*
-         * The AMO function code is in bits 25-31, unread as yet.
-         * The AMO functions are LR (read), SC (write), and the
-         * rest are all read-modify-write.
-         */
-        insn = pinsn[1];
-        return (insn >> 11) != 2; /* LR */
-    }
-
-    return false;
-}
-
-#endif
diff --git a/linux-user/host/s390/host-signal.h b/linux-user/host/s390/host-signal.h
deleted file mode 100644 (file)
index a524f2a..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * host-signal.h: signal info dependent on the host architecture
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- * Copyright (c) 2021 Linaro Limited
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef S390_HOST_SIGNAL_H
-#define S390_HOST_SIGNAL_H
-
-static inline uintptr_t host_signal_pc(ucontext_t *uc)
-{
-    return uc->uc_mcontext.psw.addr;
-}
-
-static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
-{
-    uc->uc_mcontext.psw.addr = pc;
-}
-
-static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
-{
-    uint16_t *pinsn = (uint16_t *)host_signal_pc(uc);
-
-    /*
-     * ??? On linux, the non-rt signal handler has 4 (!) arguments instead
-     * of the normal 2 arguments.  The 4th argument contains the "Translation-
-     * Exception Identification for DAT Exceptions" from the hardware (aka
-     * "int_parm_long"), which does in fact contain the is_write value.
-     * The rt signal handler, as far as I can tell, does not give this value
-     * at all.  Not that we could get to it from here even if it were.
-     * So fall back to parsing instructions.  Treat read-modify-write ones as
-     * writes, which is not fully correct, but for tracking self-modifying code
-     * this is better than treating them as reads.  Checking si_addr page flags
-     * might be a viable improvement, albeit a racy one.
-     */
-    /* ??? This is not even close to complete.  */
-    switch (pinsn[0] >> 8) {
-    case 0x50: /* ST */
-    case 0x42: /* STC */
-    case 0x40: /* STH */
-    case 0xba: /* CS */
-    case 0xbb: /* CDS */
-        return true;
-    case 0xc4: /* RIL format insns */
-        switch (pinsn[0] & 0xf) {
-        case 0xf: /* STRL */
-        case 0xb: /* STGRL */
-        case 0x7: /* STHRL */
-            return true;
-        }
-        break;
-    case 0xc8: /* SSF format insns */
-        switch (pinsn[0] & 0xf) {
-        case 0x2: /* CSST */
-            return true;
-        }
-        break;
-    case 0xe3: /* RXY format insns */
-        switch (pinsn[2] & 0xff) {
-        case 0x50: /* STY */
-        case 0x24: /* STG */
-        case 0x72: /* STCY */
-        case 0x70: /* STHY */
-        case 0x8e: /* STPQ */
-        case 0x3f: /* STRVH */
-        case 0x3e: /* STRV */
-        case 0x2f: /* STRVG */
-            return true;
-        }
-        break;
-    case 0xeb: /* RSY format insns */
-        switch (pinsn[2] & 0xff) {
-        case 0x14: /* CSY */
-        case 0x30: /* CSG */
-        case 0x31: /* CDSY */
-        case 0x3e: /* CDSG */
-        case 0xe4: /* LANG */
-        case 0xe6: /* LAOG */
-        case 0xe7: /* LAXG */
-        case 0xe8: /* LAAG */
-        case 0xea: /* LAALG */
-        case 0xf4: /* LAN */
-        case 0xf6: /* LAO */
-        case 0xf7: /* LAX */
-        case 0xfa: /* LAAL */
-        case 0xf8: /* LAA */
-            return true;
-        }
-        break;
-    }
-    return false;
-}
-
-#endif
diff --git a/linux-user/host/s390x/host-signal.h b/linux-user/host/s390x/host-signal.h
deleted file mode 100644 (file)
index 0e83f93..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "../s390/host-signal.h"
diff --git a/linux-user/host/sparc/host-signal.h b/linux-user/host/sparc/host-signal.h
deleted file mode 100644 (file)
index 7342936..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * host-signal.h: signal info dependent on the host architecture
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- * Copyright (c) 2021 Linaro Limited
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef SPARC_HOST_SIGNAL_H
-#define SPARC_HOST_SIGNAL_H
-
-static inline uintptr_t host_signal_pc(ucontext_t *uc)
-{
-#ifdef __arch64__
-    return uc->uc_mcontext.mc_gregs[MC_PC];
-#else
-    return uc->uc_mcontext.gregs[REG_PC];
-#endif
-}
-
-static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
-{
-#ifdef __arch64__
-    uc->uc_mcontext.mc_gregs[MC_PC] = pc;
-#else
-    uc->uc_mcontext.gregs[REG_PC] = pc;
-#endif
-}
-
-static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
-{
-    uint32_t insn = *(uint32_t *)host_signal_pc(uc);
-
-    if ((insn >> 30) == 3) {
-        switch ((insn >> 19) & 0x3f) {
-        case 0x05: /* stb */
-        case 0x15: /* stba */
-        case 0x06: /* sth */
-        case 0x16: /* stha */
-        case 0x04: /* st */
-        case 0x14: /* sta */
-        case 0x07: /* std */
-        case 0x17: /* stda */
-        case 0x0e: /* stx */
-        case 0x1e: /* stxa */
-        case 0x24: /* stf */
-        case 0x34: /* stfa */
-        case 0x27: /* stdf */
-        case 0x37: /* stdfa */
-        case 0x26: /* stqf */
-        case 0x36: /* stqfa */
-        case 0x25: /* stfsr */
-        case 0x3c: /* casa */
-        case 0x3e: /* casxa */
-            return true;
-        }
-    }
-    return false;
-}
-
-#endif
diff --git a/linux-user/host/sparc64/host-signal.h b/linux-user/host/sparc64/host-signal.h
deleted file mode 100644 (file)
index 1191fe2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "../sparc/host-signal.h"
diff --git a/linux-user/host/x32/host-signal.h b/linux-user/host/x32/host-signal.h
deleted file mode 100644 (file)
index 2680059..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "../x86_64/host-signal.h"
diff --git a/linux-user/host/x86_64/host-signal.h b/linux-user/host/x86_64/host-signal.h
deleted file mode 100644 (file)
index c71d597..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * host-signal.h: signal info dependent on the host architecture
- *
- * Copyright (C) 2021 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef X86_64_HOST_SIGNAL_H
-#define X86_64_HOST_SIGNAL_H
-
-static inline uintptr_t host_signal_pc(ucontext_t *uc)
-{
-    return uc->uc_mcontext.gregs[REG_RIP];
-}
-
-static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
-{
-    uc->uc_mcontext.gregs[REG_RIP] = pc;
-}
-
-static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
-{
-    return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe
-        && (uc->uc_mcontext.gregs[REG_ERR] & 0x2);
-}
-
-#endif
diff --git a/linux-user/include/host/aarch64/host-signal.h b/linux-user/include/host/aarch64/host-signal.h
new file mode 100644 (file)
index 0000000..9770b36
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef AARCH64_HOST_SIGNAL_H
+#define AARCH64_HOST_SIGNAL_H
+
+/* Pre-3.16 kernel headers don't have these, so provide fallback definitions */
+#ifndef ESR_MAGIC
+#define ESR_MAGIC 0x45535201
+struct esr_context {
+    struct _aarch64_ctx head;
+    uint64_t esr;
+};
+#endif
+
+static inline struct _aarch64_ctx *first_ctx(ucontext_t *uc)
+{
+    return (struct _aarch64_ctx *)&uc->uc_mcontext.__reserved;
+}
+
+static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr)
+{
+    return (struct _aarch64_ctx *)((char *)hdr + hdr->size);
+}
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.pc;
+}
+
+static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
+{
+    uc->uc_mcontext.pc = pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    struct _aarch64_ctx *hdr;
+    uint32_t insn;
+
+    /* Find the esr_context, which has the WnR bit in it */
+    for (hdr = first_ctx(uc); hdr->magic; hdr = next_ctx(hdr)) {
+        if (hdr->magic == ESR_MAGIC) {
+            struct esr_context const *ec = (struct esr_context const *)hdr;
+            uint64_t esr = ec->esr;
+
+            /* For data aborts ESR.EC is 0b10010x: then bit 6 is the WnR bit */
+            return extract32(esr, 27, 5) == 0x12 && extract32(esr, 6, 1) == 1;
+        }
+    }
+
+    /*
+     * Fall back to parsing instructions; will only be needed
+     * for really ancient (pre-3.16) kernels.
+     */
+    insn = *(uint32_t *)host_signal_pc(uc);
+
+    return (insn & 0xbfff0000) == 0x0c000000   /* C3.3.1 */
+        || (insn & 0xbfe00000) == 0x0c800000   /* C3.3.2 */
+        || (insn & 0xbfdf0000) == 0x0d000000   /* C3.3.3 */
+        || (insn & 0xbfc00000) == 0x0d800000   /* C3.3.4 */
+        || (insn & 0x3f400000) == 0x08000000   /* C3.3.6 */
+        || (insn & 0x3bc00000) == 0x39000000   /* C3.3.13 */
+        || (insn & 0x3fc00000) == 0x3d800000   /* ... 128bit */
+        /* Ignore bits 10, 11 & 21, controlling indexing.  */
+        || (insn & 0x3bc00000) == 0x38000000   /* C3.3.8-12 */
+        || (insn & 0x3fe00000) == 0x3c800000   /* ... 128bit */
+        /* Ignore bits 23 & 24, controlling indexing.  */
+        || (insn & 0x3a400000) == 0x28000000; /* C3.3.7,14-16 */
+}
+
+#endif
diff --git a/linux-user/include/host/alpha/host-signal.h b/linux-user/include/host/alpha/host-signal.h
new file mode 100644 (file)
index 0000000..f4c9429
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef ALPHA_HOST_SIGNAL_H
+#define ALPHA_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.sc_pc;
+}
+
+static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
+{
+    uc->uc_mcontext.sc_pc = pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    uint32_t *pc = (uint32_t *)host_signal_pc(uc);
+    uint32_t insn = *pc;
+
+    /* XXX: need kernel patch to get write flag faster */
+    switch (insn >> 26) {
+    case 0x0d: /* stw */
+    case 0x0e: /* stb */
+    case 0x0f: /* stq_u */
+    case 0x24: /* stf */
+    case 0x25: /* stg */
+    case 0x26: /* sts */
+    case 0x27: /* stt */
+    case 0x2c: /* stl */
+    case 0x2d: /* stq */
+    case 0x2e: /* stl_c */
+    case 0x2f: /* stq_c */
+        return true;
+    }
+    return false;
+}
+
+#endif
diff --git a/linux-user/include/host/arm/host-signal.h b/linux-user/include/host/arm/host-signal.h
new file mode 100644 (file)
index 0000000..6c09577
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef ARM_HOST_SIGNAL_H
+#define ARM_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.arm_pc;
+}
+
+static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
+{
+    uc->uc_mcontext.arm_pc = pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    /*
+     * In the FSR, bit 11 is WnR, assuming a v6 or
+     * later processor.  On v5 we will always report
+     * this as a read, which will fail later.
+     */
+    uint32_t fsr = uc->uc_mcontext.error_code;
+    return extract32(fsr, 11, 1);
+}
+
+#endif
diff --git a/linux-user/include/host/i386/host-signal.h b/linux-user/include/host/i386/host-signal.h
new file mode 100644 (file)
index 0000000..abe1ece
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef I386_HOST_SIGNAL_H
+#define I386_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.gregs[REG_EIP];
+}
+
+static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
+{
+    uc->uc_mcontext.gregs[REG_EIP] = pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe
+        && (uc->uc_mcontext.gregs[REG_ERR] & 0x2);
+}
+
+#endif
diff --git a/linux-user/include/host/loongarch64/host-signal.h b/linux-user/include/host/loongarch64/host-signal.h
new file mode 100644 (file)
index 0000000..7effa24
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 WANG Xuerui <git@xen0n.name>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef LOONGARCH64_HOST_SIGNAL_H
+#define LOONGARCH64_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.__pc;
+}
+
+static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
+{
+    uc->uc_mcontext.__pc = pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    const uint32_t *pinsn = (const uint32_t *)host_signal_pc(uc);
+    uint32_t insn = pinsn[0];
+
+    /* Detect store by reading the instruction at the program counter.  */
+    switch ((insn >> 26) & 0b111111) {
+    case 0b001000: /* {ll,sc}.[wd] */
+        switch ((insn >> 24) & 0b11) {
+        case 0b01: /* sc.w */
+        case 0b11: /* sc.d */
+            return true;
+        }
+        break;
+    case 0b001001: /* {ld,st}ox4.[wd] ({ld,st}ptr.[wd]) */
+        switch ((insn >> 24) & 0b11) {
+        case 0b01: /* stox4.w (stptr.w) */
+        case 0b11: /* stox4.d (stptr.d) */
+            return true;
+        }
+        break;
+    case 0b001010: /* {ld,st}.* family */
+        switch ((insn >> 22) & 0b1111) {
+        case 0b0100: /* st.b */
+        case 0b0101: /* st.h */
+        case 0b0110: /* st.w */
+        case 0b0111: /* st.d */
+        case 0b1101: /* fst.s */
+        case 0b1111: /* fst.d */
+            return true;
+        }
+        break;
+    case 0b001110: /* indexed, atomic, bounds-checking memory operations */
+        switch ((insn >> 15) & 0b11111111111) {
+        case 0b00000100000: /* stx.b */
+        case 0b00000101000: /* stx.h */
+        case 0b00000110000: /* stx.w */
+        case 0b00000111000: /* stx.d */
+        case 0b00001110000: /* fstx.s */
+        case 0b00001111000: /* fstx.d */
+        case 0b00011101100: /* fstgt.s */
+        case 0b00011101101: /* fstgt.d */
+        case 0b00011101110: /* fstle.s */
+        case 0b00011101111: /* fstle.d */
+        case 0b00011111000: /* stgt.b */
+        case 0b00011111001: /* stgt.h */
+        case 0b00011111010: /* stgt.w */
+        case 0b00011111011: /* stgt.d */
+        case 0b00011111100: /* stle.b */
+        case 0b00011111101: /* stle.h */
+        case 0b00011111110: /* stle.w */
+        case 0b00011111111: /* stle.d */
+        case 0b00011000000 ... 0b00011100011: /* am* insns */
+            return true;
+        }
+        break;
+    }
+
+    return false;
+}
+
+#endif
diff --git a/linux-user/include/host/mips/host-signal.h b/linux-user/include/host/mips/host-signal.h
new file mode 100644 (file)
index 0000000..c666ed8
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef MIPS_HOST_SIGNAL_H
+#define MIPS_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.pc;
+}
+
+static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
+{
+    uc->uc_mcontext.pc = pc;
+}
+
+#if defined(__misp16) || defined(__mips_micromips)
+#error "Unsupported encoding"
+#endif
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    uint32_t insn = *(uint32_t *)host_signal_pc(uc);
+
+    /* Detect all store instructions at program counter. */
+    switch ((insn >> 26) & 077) {
+    case 050: /* SB */
+    case 051: /* SH */
+    case 052: /* SWL */
+    case 053: /* SW */
+    case 054: /* SDL */
+    case 055: /* SDR */
+    case 056: /* SWR */
+    case 070: /* SC */
+    case 071: /* SWC1 */
+    case 074: /* SCD */
+    case 075: /* SDC1 */
+    case 077: /* SD */
+#if !defined(__mips_isa_rev) || __mips_isa_rev < 6
+    case 072: /* SWC2 */
+    case 076: /* SDC2 */
+#endif
+        return true;
+    case 023: /* COP1X */
+        /*
+         * Required in all versions of MIPS64 since
+         * MIPS64r1 and subsequent versions of MIPS32r2.
+         */
+        switch (insn & 077) {
+        case 010: /* SWXC1 */
+        case 011: /* SDXC1 */
+        case 015: /* SUXC1 */
+            return true;
+        }
+        break;
+    }
+    return false;
+}
+
+#endif
diff --git a/linux-user/include/host/ppc/host-signal.h b/linux-user/include/host/ppc/host-signal.h
new file mode 100644 (file)
index 0000000..1d8e658
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef PPC_HOST_SIGNAL_H
+#define PPC_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.regs->nip;
+}
+
+static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
+{
+    uc->uc_mcontext.regs->nip = pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    return uc->uc_mcontext.regs->trap != 0x400
+        && (uc->uc_mcontext.regs->dsisr & 0x02000000);
+}
+
+#endif
diff --git a/linux-user/include/host/ppc64/host-signal.h b/linux-user/include/host/ppc64/host-signal.h
new file mode 100644 (file)
index 0000000..a353c22
--- /dev/null
@@ -0,0 +1 @@
+#include "../ppc/host-signal.h"
diff --git a/linux-user/include/host/riscv/host-signal.h b/linux-user/include/host/riscv/host-signal.h
new file mode 100644 (file)
index 0000000..a4f170e
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef RISCV_HOST_SIGNAL_H
+#define RISCV_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.__gregs[REG_PC];
+}
+
+static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
+{
+    uc->uc_mcontext.__gregs[REG_PC] = pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    /*
+     * Detect store by reading the instruction at the program counter.
+     * Do not read more than 16 bits, because we have not yet determined
+     * the size of the instruction.
+     */
+    const uint16_t *pinsn = (const uint16_t *)host_signal_pc(uc);
+    uint16_t insn = pinsn[0];
+
+    /* 16-bit instructions */
+    switch (insn & 0xe003) {
+    case 0xa000: /* c.fsd */
+    case 0xc000: /* c.sw */
+    case 0xe000: /* c.sd (rv64) / c.fsw (rv32) */
+    case 0xa002: /* c.fsdsp */
+    case 0xc002: /* c.swsp */
+    case 0xe002: /* c.sdsp (rv64) / c.fswsp (rv32) */
+        return true;
+    }
+
+    /* 32-bit instructions, major opcodes */
+    switch (insn & 0x7f) {
+    case 0x23: /* store */
+    case 0x27: /* store-fp */
+        return true;
+    case 0x2f: /* amo */
+        /*
+         * The AMO function code is in bits 25-31, unread as yet.
+         * The AMO functions are LR (read), SC (write), and the
+         * rest are all read-modify-write.
+         */
+        insn = pinsn[1];
+        return (insn >> 11) != 2; /* LR */
+    }
+
+    return false;
+}
+
+#endif
diff --git a/linux-user/include/host/s390/host-signal.h b/linux-user/include/host/s390/host-signal.h
new file mode 100644 (file)
index 0000000..a524f2a
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef S390_HOST_SIGNAL_H
+#define S390_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.psw.addr;
+}
+
+static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
+{
+    uc->uc_mcontext.psw.addr = pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    uint16_t *pinsn = (uint16_t *)host_signal_pc(uc);
+
+    /*
+     * ??? On linux, the non-rt signal handler has 4 (!) arguments instead
+     * of the normal 2 arguments.  The 4th argument contains the "Translation-
+     * Exception Identification for DAT Exceptions" from the hardware (aka
+     * "int_parm_long"), which does in fact contain the is_write value.
+     * The rt signal handler, as far as I can tell, does not give this value
+     * at all.  Not that we could get to it from here even if it were.
+     * So fall back to parsing instructions.  Treat read-modify-write ones as
+     * writes, which is not fully correct, but for tracking self-modifying code
+     * this is better than treating them as reads.  Checking si_addr page flags
+     * might be a viable improvement, albeit a racy one.
+     */
+    /* ??? This is not even close to complete.  */
+    switch (pinsn[0] >> 8) {
+    case 0x50: /* ST */
+    case 0x42: /* STC */
+    case 0x40: /* STH */
+    case 0xba: /* CS */
+    case 0xbb: /* CDS */
+        return true;
+    case 0xc4: /* RIL format insns */
+        switch (pinsn[0] & 0xf) {
+        case 0xf: /* STRL */
+        case 0xb: /* STGRL */
+        case 0x7: /* STHRL */
+            return true;
+        }
+        break;
+    case 0xc8: /* SSF format insns */
+        switch (pinsn[0] & 0xf) {
+        case 0x2: /* CSST */
+            return true;
+        }
+        break;
+    case 0xe3: /* RXY format insns */
+        switch (pinsn[2] & 0xff) {
+        case 0x50: /* STY */
+        case 0x24: /* STG */
+        case 0x72: /* STCY */
+        case 0x70: /* STHY */
+        case 0x8e: /* STPQ */
+        case 0x3f: /* STRVH */
+        case 0x3e: /* STRV */
+        case 0x2f: /* STRVG */
+            return true;
+        }
+        break;
+    case 0xeb: /* RSY format insns */
+        switch (pinsn[2] & 0xff) {
+        case 0x14: /* CSY */
+        case 0x30: /* CSG */
+        case 0x31: /* CDSY */
+        case 0x3e: /* CDSG */
+        case 0xe4: /* LANG */
+        case 0xe6: /* LAOG */
+        case 0xe7: /* LAXG */
+        case 0xe8: /* LAAG */
+        case 0xea: /* LAALG */
+        case 0xf4: /* LAN */
+        case 0xf6: /* LAO */
+        case 0xf7: /* LAX */
+        case 0xfa: /* LAAL */
+        case 0xf8: /* LAA */
+            return true;
+        }
+        break;
+    }
+    return false;
+}
+
+#endif
diff --git a/linux-user/include/host/s390x/host-signal.h b/linux-user/include/host/s390x/host-signal.h
new file mode 100644 (file)
index 0000000..0e83f93
--- /dev/null
@@ -0,0 +1 @@
+#include "../s390/host-signal.h"
diff --git a/linux-user/include/host/sparc/host-signal.h b/linux-user/include/host/sparc/host-signal.h
new file mode 100644 (file)
index 0000000..7342936
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef SPARC_HOST_SIGNAL_H
+#define SPARC_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+#ifdef __arch64__
+    return uc->uc_mcontext.mc_gregs[MC_PC];
+#else
+    return uc->uc_mcontext.gregs[REG_PC];
+#endif
+}
+
+static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
+{
+#ifdef __arch64__
+    uc->uc_mcontext.mc_gregs[MC_PC] = pc;
+#else
+    uc->uc_mcontext.gregs[REG_PC] = pc;
+#endif
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    uint32_t insn = *(uint32_t *)host_signal_pc(uc);
+
+    if ((insn >> 30) == 3) {
+        switch ((insn >> 19) & 0x3f) {
+        case 0x05: /* stb */
+        case 0x15: /* stba */
+        case 0x06: /* sth */
+        case 0x16: /* stha */
+        case 0x04: /* st */
+        case 0x14: /* sta */
+        case 0x07: /* std */
+        case 0x17: /* stda */
+        case 0x0e: /* stx */
+        case 0x1e: /* stxa */
+        case 0x24: /* stf */
+        case 0x34: /* stfa */
+        case 0x27: /* stdf */
+        case 0x37: /* stdfa */
+        case 0x26: /* stqf */
+        case 0x36: /* stqfa */
+        case 0x25: /* stfsr */
+        case 0x3c: /* casa */
+        case 0x3e: /* casxa */
+            return true;
+        }
+    }
+    return false;
+}
+
+#endif
diff --git a/linux-user/include/host/sparc64/host-signal.h b/linux-user/include/host/sparc64/host-signal.h
new file mode 100644 (file)
index 0000000..1191fe2
--- /dev/null
@@ -0,0 +1 @@
+#include "../sparc/host-signal.h"
diff --git a/linux-user/include/host/x32/host-signal.h b/linux-user/include/host/x32/host-signal.h
new file mode 100644 (file)
index 0000000..2680059
--- /dev/null
@@ -0,0 +1 @@
+#include "../x86_64/host-signal.h"
diff --git a/linux-user/include/host/x86_64/host-signal.h b/linux-user/include/host/x86_64/host-signal.h
new file mode 100644 (file)
index 0000000..c71d597
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef X86_64_HOST_SIGNAL_H
+#define X86_64_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.gregs[REG_RIP];
+}
+
+static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
+{
+    uc->uc_mcontext.gregs[REG_RIP] = pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe
+        && (uc->uc_mcontext.gregs[REG_ERR] & 0x2);
+}
+
+#endif
diff --git a/linux-user/include/special-errno.h b/linux-user/include/special-errno.h
new file mode 100644 (file)
index 0000000..4120455
--- /dev/null
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU internal errno values for implementing user-only POSIX.
+ *
+ *  Copyright (c) 2003 Fabrice Bellard
+ *  Copyright (c) 2021 Linaro, Ltd.
+ */
+
+#ifndef SPECIAL_ERRNO_H
+#define SPECIAL_ERRNO_H
+
+/*
+ * All of these are QEMU internal, not visible to the guest.
+ * They should be chosen so as to not overlap with any host
+ * or guest errno.
+ */
+
+/*
+ * This is returned when a system call should be restarted, to tell the
+ * main loop that it should wind the guest PC backwards so it will
+ * re-execute the syscall after handling any pending signals.
+ */
+#define QEMU_ERESTARTSYS  512
+
+/*
+ * This is returned after a successful sigreturn syscall, to indicate
+ * that it has correctly set the guest registers and so the main loop
+ * should not touch them.
+ */
+#define QEMU_ESIGRETURN   513
+
+#endif /* SPECIAL_ERRNO_H */
index b2f4afd5e7fe437be4321cf6fb1be31e1fc2d416..de4320af053cd45d5b659c22cfa8ed6fc8a09755 100644 (file)
@@ -4,8 +4,8 @@ endif
 
 linux_user_ss = ss.source_set()
 
-common_user_inc += include_directories('host/' / host_arch)
-common_user_inc += include_directories('.')
+common_user_inc += include_directories('include/host/' / host_arch)
+common_user_inc += include_directories('include')
 
 linux_user_ss.add(files(
   'elfload.c',
diff --git a/linux-user/special-errno.h b/linux-user/special-errno.h
deleted file mode 100644 (file)
index 4120455..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * QEMU internal errno values for implementing user-only POSIX.
- *
- *  Copyright (c) 2003 Fabrice Bellard
- *  Copyright (c) 2021 Linaro, Ltd.
- */
-
-#ifndef SPECIAL_ERRNO_H
-#define SPECIAL_ERRNO_H
-
-/*
- * All of these are QEMU internal, not visible to the guest.
- * They should be chosen so as to not overlap with any host
- * or guest errno.
- */
-
-/*
- * This is returned when a system call should be restarted, to tell the
- * main loop that it should wind the guest PC backwards so it will
- * re-execute the syscall after handling any pending signals.
- */
-#define QEMU_ERESTARTSYS  512
-
-/*
- * This is returned after a successful sigreturn syscall, to indicate
- * that it has correctly set the guest registers and so the main loop
- * should not touch them.
- */
-#define QEMU_ESIGRETURN   513
-
-#endif /* SPECIAL_ERRNO_H */