aboutsummaryrefslogtreecommitdiff
path: root/linux-user/host
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2021-09-17 10:57:06 -0700
committerRichard Henderson <richard.henderson@linaro.org>2021-11-02 07:00:51 -0400
commit97be8c6a95138291ee8736690e8bc0dd6db9e27e (patch)
treed29686cbe2c7e2cdd1cf24bc3c04fc9d03fe0404 /linux-user/host
parentb12161120af8467bc28159adf0c1bfb0fbc4ed70 (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.h86
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