From: Paolo Bonzini Date: Tue, 21 Dec 2021 15:20:32 +0000 (+0100) Subject: user: move common-user includes to a subdirectory of {bsd,linux}-user/ X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=05a248715cef192336a594afed812871a52efc1f;p=qemu.git user: move common-user includes to a subdirectory of {bsd,linux}-user/ 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 Signed-off-by: Paolo Bonzini --- diff --git a/bsd-user/include/special-errno.h b/bsd-user/include/special-errno.h new file mode 100644 index 0000000000..03599d9b5a --- /dev/null +++ b/bsd-user/include/special-errno.h @@ -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 */ diff --git a/bsd-user/meson.build b/bsd-user/meson.build index 9fcb80c3fa..8380fa44c2 100644 --- a/bsd-user/meson.build +++ b/bsd-user/meson.build @@ -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 index 03599d9b5a..0000000000 --- a/bsd-user/special-errno.h +++ /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 index 9770b36dc1..0000000000 --- a/linux-user/host/aarch64/host-signal.h +++ /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 index f4c942948a..0000000000 --- a/linux-user/host/alpha/host-signal.h +++ /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 index 6c095773c0..0000000000 --- a/linux-user/host/arm/host-signal.h +++ /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 index abe1ece5c9..0000000000 --- a/linux-user/host/i386/host-signal.h +++ /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 index 7effa24251..0000000000 --- a/linux-user/host/loongarch64/host-signal.h +++ /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 - * - * 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 index c666ed8c3f..0000000000 --- a/linux-user/host/mips/host-signal.h +++ /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 index 1d8e658ff7..0000000000 --- a/linux-user/host/ppc/host-signal.h +++ /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 index a353c22a90..0000000000 --- a/linux-user/host/ppc64/host-signal.h +++ /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 index a4f170efb0..0000000000 --- a/linux-user/host/riscv/host-signal.h +++ /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 index a524f2ab00..0000000000 --- a/linux-user/host/s390/host-signal.h +++ /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 index 0e83f9358d..0000000000 --- a/linux-user/host/s390x/host-signal.h +++ /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 index 7342936071..0000000000 --- a/linux-user/host/sparc/host-signal.h +++ /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 index 1191fe2d40..0000000000 --- a/linux-user/host/sparc64/host-signal.h +++ /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 index 26800591d3..0000000000 --- a/linux-user/host/x32/host-signal.h +++ /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 index c71d597eb2..0000000000 --- a/linux-user/host/x86_64/host-signal.h +++ /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 index 0000000000..9770b36dc1 --- /dev/null +++ b/linux-user/include/host/aarch64/host-signal.h @@ -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 index 0000000000..f4c942948a --- /dev/null +++ b/linux-user/include/host/alpha/host-signal.h @@ -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 index 0000000000..6c095773c0 --- /dev/null +++ b/linux-user/include/host/arm/host-signal.h @@ -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 index 0000000000..abe1ece5c9 --- /dev/null +++ b/linux-user/include/host/i386/host-signal.h @@ -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 index 0000000000..7effa24251 --- /dev/null +++ b/linux-user/include/host/loongarch64/host-signal.h @@ -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 + * + * 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 index 0000000000..c666ed8c3f --- /dev/null +++ b/linux-user/include/host/mips/host-signal.h @@ -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 index 0000000000..1d8e658ff7 --- /dev/null +++ b/linux-user/include/host/ppc/host-signal.h @@ -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 index 0000000000..a353c22a90 --- /dev/null +++ b/linux-user/include/host/ppc64/host-signal.h @@ -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 index 0000000000..a4f170efb0 --- /dev/null +++ b/linux-user/include/host/riscv/host-signal.h @@ -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 index 0000000000..a524f2ab00 --- /dev/null +++ b/linux-user/include/host/s390/host-signal.h @@ -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 index 0000000000..0e83f9358d --- /dev/null +++ b/linux-user/include/host/s390x/host-signal.h @@ -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 index 0000000000..7342936071 --- /dev/null +++ b/linux-user/include/host/sparc/host-signal.h @@ -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 index 0000000000..1191fe2d40 --- /dev/null +++ b/linux-user/include/host/sparc64/host-signal.h @@ -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 index 0000000000..26800591d3 --- /dev/null +++ b/linux-user/include/host/x32/host-signal.h @@ -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 index 0000000000..c71d597eb2 --- /dev/null +++ b/linux-user/include/host/x86_64/host-signal.h @@ -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 index 0000000000..4120455baa --- /dev/null +++ b/linux-user/include/special-errno.h @@ -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 */ diff --git a/linux-user/meson.build b/linux-user/meson.build index b2f4afd5e7..de4320af05 100644 --- a/linux-user/meson.build +++ b/linux-user/meson.build @@ -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 index 4120455baa..0000000000 --- a/linux-user/special-errno.h +++ /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 */