diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2021-09-17 10:57:06 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2021-11-02 07:00:51 -0400 |
commit | 97be8c6a95138291ee8736690e8bc0dd6db9e27e (patch) | |
tree | d29686cbe2c7e2cdd1cf24bc3c04fc9d03fe0404 /linux-user/host | |
parent | b12161120af8467bc28159adf0c1bfb0fbc4ed70 (diff) |
linux-user/host/riscv: Populate host_signal.h
Split host_signal_pc and host_signal_write out of user-exec.c.
Reviewed-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'linux-user/host')
-rw-r--r-- | linux-user/host/riscv/host-signal.h | 86 |
1 files changed, 85 insertions, 1 deletions
diff --git a/linux-user/host/riscv/host-signal.h b/linux-user/host/riscv/host-signal.h index f4b4d65031..df145b1527 100644 --- a/linux-user/host/riscv/host-signal.h +++ b/linux-user/host/riscv/host-signal.h @@ -1 +1,85 @@ -#define HOST_SIGNAL_PLACEHOLDER +/* + * 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 bool host_signal_write(siginfo_t *info, ucontext_t *uc) +{ + uint32_t insn = *(uint32_t *)host_signal_pc(uc); + + /* + * Detect store by reading the instruction at the program + * counter. Note: we currently only generate 32-bit + * instructions so we thus only detect 32-bit stores + */ + switch (((insn >> 0) & 0b11)) { + case 3: + switch (((insn >> 2) & 0b11111)) { + case 8: + switch (((insn >> 12) & 0b111)) { + case 0: /* sb */ + case 1: /* sh */ + case 2: /* sw */ + case 3: /* sd */ + case 4: /* sq */ + return true; + default: + break; + } + break; + case 9: + switch (((insn >> 12) & 0b111)) { + case 2: /* fsw */ + case 3: /* fsd */ + case 4: /* fsq */ + return true; + default: + break; + } + break; + default: + break; + } + } + + /* Check for compressed instructions */ + switch (((insn >> 13) & 0b111)) { + case 7: + switch (insn & 0b11) { + case 0: /*c.sd */ + case 2: /* c.sdsp */ + return true; + default: + break; + } + break; + case 6: + switch (insn & 0b11) { + case 0: /* c.sw */ + case 3: /* c.swsp */ + return true; + default: + break; + } + break; + default: + break; + } + + return false; +} + +#endif |