1 /*
2  * host-signal.h: signal info dependent on the host architecture
3  *
4  * Copyright (c) 2003-2005 Fabrice Bellard
5  * Copyright (c) 2021 Linaro Limited
6  *
7  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
8  * See the COPYING file in the top-level directory.
9  */
10 
11 #ifndef S390_HOST_SIGNAL_H
12 #define S390_HOST_SIGNAL_H
13 
14 /* The third argument to a SA_SIGINFO handler is ucontext_t. */
15 typedef ucontext_t host_sigcontext;
16 
17 static inline uintptr_t host_signal_pc(host_sigcontext *uc)
18 {
19     return uc->uc_mcontext.psw.addr;
20 }
21 
22 static inline void host_signal_set_pc(host_sigcontext *uc, uintptr_t pc)
23 {
24     uc->uc_mcontext.psw.addr = pc;
25 }
26 
27 static inline void *host_signal_mask(host_sigcontext *uc)
28 {
29     return &uc->uc_sigmask;
30 }
31 
32 static inline bool host_signal_write(siginfo_t *info, host_sigcontext *uc)
33 {
34     uint16_t *pinsn = (uint16_t *)host_signal_pc(uc);
35 
36     /*
37      * ??? On linux, the non-rt signal handler has 4 (!) arguments instead
38      * of the normal 2 arguments.  The 4th argument contains the "Translation-
39      * Exception Identification for DAT Exceptions" from the hardware (aka
40      * "int_parm_long"), which does in fact contain the is_write value.
41      * The rt signal handler, as far as I can tell, does not give this value
42      * at all.  Not that we could get to it from here even if it were.
43      * So fall back to parsing instructions.  Treat read-modify-write ones as
44      * writes, which is not fully correct, but for tracking self-modifying code
45      * this is better than treating them as reads.  Checking si_addr page flags
46      * might be a viable improvement, albeit a racy one.
47      */
48     /* ??? This is not even close to complete.  */
49     switch (pinsn[0] >> 8) {
50     case 0x50: /* ST */
51     case 0x42: /* STC */
52     case 0x40: /* STH */
53     case 0x44: /* EX */
54     case 0xba: /* CS */
55     case 0xbb: /* CDS */
56         return true;
57     case 0xc4: /* RIL format insns */
58         switch (pinsn[0] & 0xf) {
59         case 0xf: /* STRL */
60         case 0xb: /* STGRL */
61         case 0x7: /* STHRL */
62             return true;
63         }
64         break;
65     case 0xc6: /* RIL-b format insns */
66         switch (pinsn[0] & 0xf) {
67         case 0x0: /* EXRL */
68             return true;
69         }
70         break;
71     case 0xc8: /* SSF format insns */
72         switch (pinsn[0] & 0xf) {
73         case 0x2: /* CSST */
74             return true;
75         }
76         break;
77     case 0xe3: /* RXY format insns */
78         switch (pinsn[2] & 0xff) {
79         case 0x50: /* STY */
80         case 0x24: /* STG */
81         case 0x72: /* STCY */
82         case 0x70: /* STHY */
83         case 0x8e: /* STPQ */
84         case 0x3f: /* STRVH */
85         case 0x3e: /* STRV */
86         case 0x2f: /* STRVG */
87             return true;
88         }
89         break;
90     case 0xe6:
91         switch (pinsn[2] & 0xff) {
92         case 0x09: /* VSTEBRH */
93         case 0x0a: /* VSTEBRG */
94         case 0x0b: /* VSTEBRF */
95         case 0x0e: /* VSTBR */
96         case 0x0f: /* VSTER */
97         case 0x3f: /* VSTRLR */
98             return true;
99         }
100         break;
101     case 0xe7:
102         switch (pinsn[2] & 0xff) {
103         case 0x08: /* VSTEB */
104         case 0x09: /* VSTEH */
105         case 0x0a: /* VSTEG */
106         case 0x0b: /* VSTEF */
107         case 0x0e: /* VST */
108         case 0x1a: /* VSCEG */
109         case 0x1b: /* VSCEF */
110         case 0x3e: /* VSTM */
111         case 0x3f: /* VSTL */
112             return true;
113         }
114         break;
115     case 0xeb: /* RSY format insns */
116         switch (pinsn[2] & 0xff) {
117         case 0x14: /* CSY */
118         case 0x30: /* CSG */
119         case 0x31: /* CDSY */
120         case 0x3e: /* CDSG */
121         case 0xe4: /* LANG */
122         case 0xe6: /* LAOG */
123         case 0xe7: /* LAXG */
124         case 0xe8: /* LAAG */
125         case 0xea: /* LAALG */
126         case 0xf4: /* LAN */
127         case 0xf6: /* LAO */
128         case 0xf7: /* LAX */
129         case 0xfa: /* LAAL */
130         case 0xf8: /* LAA */
131             return true;
132         }
133         break;
134     }
135     return false;
136 }
137 
138 #endif
139