1 /*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993-1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 2001 John Hughes <john@Calva.COM>
7 * Copyright (c) 2013 Denys Vlasenko <vda.linux@googlemail.com>
8 * Copyright (c) 2011-2015 Dmitry V. Levin <ldv@strace.io>
9 * Copyright (c) 2015 Elvira Khabirova <lineprinter0@gmail.com>
10 * Copyright (c) 2015-2023 The strace developers.
11 * All rights reserved.
12 *
13 * SPDX-License-Identifier: LGPL-2.1-or-later
14 */
15
16 #include "defs.h"
17
18 #include DEF_MPERS_TYPE(siginfo_t)
19
20 #include <signal.h>
21 #include <linux/audit.h>
22
23 #include MPERS_DEFS
24
25 #ifndef IN_MPERS
26 # include "printsiginfo.h"
27 #endif
28
29 #define XLAT_MACROS_ONLY
30 /* For xlat/audit_arch.h */
31 # include "xlat/elf_em.h"
32 #undef XLAT_MACROS_ONLY
33
34 #include "xlat/audit_arch.h"
35 #include "xlat/sigbus_codes.h"
36 #include "xlat/sigchld_codes.h"
37 #include "xlat/sigfpe_codes.h"
38 #include "xlat/sigill_codes.h"
39 #include "xlat/siginfo_codes.h"
40 #include "xlat/sigpoll_codes.h"
41 #include "xlat/sigprof_codes.h"
42 #include "xlat/sigsegv_codes.h"
43 #include "xlat/sigsys_codes.h"
44 #include "xlat/sigtrap_codes.h"
45
46 #ifdef ALPHA
47 # include "xlat/alpha_trap_codes.h"
48 #endif
49
50 #ifdef SIGEMT
51 # include "xlat/sigemt_codes.h"
52 #endif
53
54 #ifdef HAVE_SIGINFO_T_SI_PERF_FLAGS
55 # include "xlat/sigtrap_perf_flags.h"
56 #endif
57
58 #ifndef SI_FROMUSER
59 # define SI_FROMUSER(sip) ((sip)->si_code <= 0)
60 #endif
61
62 static void
63 printsigsource(struct tcb *tcp, const siginfo_t *sip)
64 {
65 tprint_struct_next();
66 PRINT_FIELD_TGID(*sip, si_pid, tcp);
67 tprint_struct_next();
68 PRINT_FIELD_ID(*sip, si_uid);
69 }
70
71 static void
72 printsigval(const siginfo_t *sip)
73 {
74 tprint_struct_next();
75 PRINT_FIELD_D(*sip, si_int);
76 tprint_struct_next();
77 PRINT_FIELD_PTR(*sip, si_ptr);
78 }
79
80 static void
81 print_si_code(const unsigned int si_code, const int si_signo)
82 {
83 static const struct xlat * const si_codes[] = {
84 [SIGTRAP] = sigtrap_codes,
85 [SIGCHLD] = sigchld_codes,
86 [SIGIO] = sigpoll_codes, /* SIGPOLL */
87 [SIGPROF] = sigprof_codes,
88 [SIGILL] = sigill_codes,
89 #ifdef SIGEMT
90 [SIGEMT] = sigemt_codes,
91 #endif
92 [SIGFPE] = sigfpe_codes,
93 [SIGSEGV] = sigsegv_codes,
94 [SIGBUS] = sigbus_codes,
95 [SIGSYS] = sigsys_codes,
96 };
97
98 const char *code = xlookup(siginfo_codes, si_code);
99
100 if (!code && (unsigned int) si_signo < ARRAY_SIZE(si_codes)
101 && si_codes[si_signo])
102 code = xlookup(si_codes[si_signo], si_code);
103
104 print_xlat_ex(si_code, code, XLAT_STYLE_DEFAULT);
105 }
106
107 static void
108 print_si_info(struct tcb *tcp, const siginfo_t *sip)
109 {
110 if (sip->si_errno) {
111 tprint_struct_next();
112 PRINT_FIELD_ERR_U(*sip, si_errno);
113 }
114
115 if (SI_FROMUSER(sip)) {
116 switch (sip->si_code) {
117 case SI_USER:
118 printsigsource(tcp, sip);
119 break;
120 case SI_TKILL:
121 printsigsource(tcp, sip);
122 break;
123 #if defined HAVE_SIGINFO_T_SI_TIMERID && defined HAVE_SIGINFO_T_SI_OVERRUN
124 case SI_TIMER:
125 tprint_struct_next();
126 PRINT_FIELD_X(*sip, si_timerid);
127 tprint_struct_next();
128 PRINT_FIELD_D(*sip, si_overrun);
129 printsigval(sip);
130 break;
131 #endif
132 case SI_SIGIO:
133 tprint_struct_next();
134 PRINT_FIELD_D(*sip, si_band);
135 tprint_struct_next();
136 PRINT_FIELD_FD(*sip, si_fd, tcp);
137 break;
138 default:
139 printsigsource(tcp, sip);
140 if (sip->si_ptr)
141 printsigval(sip);
142 break;
143 }
144 } else {
145 switch (sip->si_signo) {
146 case SIGCHLD:
147 printsigsource(tcp, sip);
148 if (sip->si_code == CLD_EXITED) {
149 tprint_struct_next();
150 PRINT_FIELD_D(*sip, si_status);
151 } else {
152 tprint_struct_next();
153 PRINT_FIELD_OBJ_VAL(*sip, si_status, printsignal);
154 }
155 tprint_struct_next();
156 PRINT_FIELD_CLOCK_T(*sip, si_utime);
157 tprint_struct_next();
158 PRINT_FIELD_CLOCK_T(*sip, si_stime);
159 break;
160 case SIGILL:
161 tprint_struct_next();
162 PRINT_FIELD_PTR(*sip, si_addr);
163 #if defined(SPARC) || defined(SPARC64)
164 tprint_struct_next();
165 PRINT_FIELD_D(*sip, si_trapno);
166 #endif /* SPARC || SPARC64 */
167 break;
168 case SIGFPE:
169 tprint_struct_next();
170 PRINT_FIELD_PTR(*sip, si_addr);
171 #if defined ALPHA && defined HAVE_SIGINFO_T_SI_TRAPNO
172 tprint_struct_next();
173 PRINT_FIELD_XVAL_D(*sip, si_trapno, alpha_trap_codes,
174 "GEN_???");
175 #endif /* ALPHA */
176 break;
177 case SIGBUS:
178 tprint_struct_next();
179 PRINT_FIELD_PTR(*sip, si_addr);
180 #if !defined(BUS_OPFETCH) && defined(HAVE_SIGINFO_T_SI_ADDR_LSB)
181 switch (sip->si_code) {
182 case BUS_MCEERR_AR:
183 case BUS_MCEERR_AO:
184 tprint_struct_next();
185 PRINT_FIELD_X(*sip, si_addr_lsb);
186 break;
187 }
188 #endif /* !BUS_OPFETCH && HAVE_SIGINFO_T_SI_ADDR_LSB */
189 break;
190 case SIGSEGV:
191 tprint_struct_next();
192 PRINT_FIELD_PTR(*sip, si_addr);
193 #if (!defined(SEGV_STACKFLOW) && defined(HAVE_SIGINFO_T_SI_LOWER)) \
194 || (!defined(__SEGV_PSTKOVF) && defined(HAVE_SIGINFO_T_SI_PKEY))
195 switch (sip->si_code) {
196 # if !defined(SEGV_STACKFLOW) && defined(HAVE_SIGINFO_T_SI_LOWER)
197 case SEGV_BNDERR:
198 tprint_struct_next();
199 PRINT_FIELD_PTR(*sip, si_lower);
200 tprint_struct_next();
201 PRINT_FIELD_PTR(*sip, si_upper);
202 break;
203 # endif /* !SEGV_STACKFLOW && HAVE_SIGINFO_T_SI_LOWER */
204 # if !defined(__SEGV_PSTKOVF) && defined(HAVE_SIGINFO_T_SI_PKEY)
205 case SEGV_PKUERR:
206 tprint_struct_next();
207 PRINT_FIELD_U(*sip, si_pkey);
208 break;
209 # endif /* !__SEGV_PSTKOVF && HAVE_SIGINFO_T_SI_PKEY */
210 }
211 #endif /* !SEGV_STACKFLOW && HAVE_SIGINFO_T_SI_LOWER
212 * || !__SEGV_PSTKOVF && HAVE_SIGINFO_T_SI_PKEY */
213 break;
214 case SIGTRAP:
215 tprint_struct_next();
216 PRINT_FIELD_PTR(*sip, si_addr);
217 #if (defined ALPHA && defined HAVE_SIGINFO_T_SI_TRAPNO) \
218 || defined HAVE_SIGINFO_T_SI_PERF_DATA
219 switch (sip->si_code) {
220 # if defined ALPHA && defined HAVE_SIGINFO_T_SI_TRAPNO
221 case TRAP_UNK:
222 tprint_struct_next();
223 PRINT_FIELD_XVAL_D(*sip, si_trapno,
224 alpha_trap_codes, "GEN_???");
225 break;
226 # endif /* ALPHA && HAVE_SIGINFO_T_SI_TRAPNO */
227 # ifdef HAVE_SIGINFO_T_SI_PERF_DATA
228 case TRAP_PERF:
229 tprint_struct_next();
230 PRINT_FIELD_X(*sip, si_perf_data);
231 # ifdef HAVE_SIGINFO_T_SI_PERF_TYPE
232 tprint_struct_next();
233 PRINT_FIELD_XVAL(*sip, si_perf_type,
234 perf_type_id, "PERF_TYPE_???");
235 # endif /* HAVE_SIGINFO_T_SI_PERF_TYPE */
236 # ifdef HAVE_SIGINFO_T_SI_PERF_FLAGS
237 tprint_struct_next();
238 PRINT_FIELD_FLAGS(*sip, si_perf_flags,
239 sigtrap_perf_flags,
240 "TRAP_PERF_FLAG_???");
241 # endif /* HAVE_SIGINFO_T_SI_PERF_FLAGS */
242 # endif /* HAVE_SIGINFO_T_SI_PERF_DATA */
243 }
244 #endif /* ALPHA || HAVE_SIGINFO_T_SI_PERF_DATA */
245 break;
246 #ifdef SIGEMT
247 case SIGEMT:
248 tprint_struct_next();
249 PRINT_FIELD_PTR(*sip, si_addr);
250 break;
251 #endif
252 case SIGIO: /* SIGPOLL */
253 switch (sip->si_code) {
254 case POLL_IN: case POLL_OUT: case POLL_MSG:
255 case POLL_ERR: case POLL_PRI: case POLL_HUP:
256 tprint_struct_next();
257 PRINT_FIELD_D(*sip, si_band);
258 tprint_struct_next();
259 PRINT_FIELD_FD(*sip, si_fd, tcp);
260 break;
261 }
262 break;
263 #ifdef HAVE_SIGINFO_T_SI_SYSCALL
264 case SIGSYS:
265 tprint_struct_next();
266 PRINT_FIELD_PTR(*sip, si_call_addr);
267 tprint_struct_next();
268 PRINT_FIELD_SYSCALL_NAME(*sip, si_syscall,
269 sip->si_arch);
270 tprint_struct_next();
271 PRINT_FIELD_XVAL(*sip, si_arch, audit_arch,
272 "AUDIT_ARCH_???");
273 break;
274 #endif
275 default:
276 if (sip->si_pid || sip->si_uid)
277 printsigsource(tcp, sip);
278 if (sip->si_ptr)
279 printsigval(sip);
280 }
281 }
282 }
283
284 #ifdef IN_MPERS
285 static
286 #endif
287 void
288 printsiginfo(struct tcb *tcp, const siginfo_t *sip)
289 {
290 tprint_struct_begin();
291
292 if (sip->si_signo) {
293 PRINT_FIELD_OBJ_VAL(*sip, si_signo, printsignal);
294 tprint_struct_next();
295 PRINT_FIELD_OBJ_VAL(*sip, si_code, print_si_code,
296 sip->si_signo);
297
298 #ifdef SI_NOINFO
299 if (sip->si_code != SI_NOINFO)
300 #endif
301 print_si_info(tcp, sip);
302 }
303
304 tprint_struct_end();
305 }
306
307 MPERS_PRINTER_DECL(void, printsiginfo_at,
308 struct tcb *const tcp, const kernel_ulong_t addr)
309 {
310 siginfo_t si;
311
312 if (!umove_or_printaddr(tcp, addr, &si))
313 printsiginfo(tcp, &si);
314 }
315
316 static bool
317 print_siginfo_t(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
318 {
319 printsiginfo(tcp, (const siginfo_t *) elem_buf);
320 return true;
321 }
322
323 MPERS_PRINTER_DECL(void, print_siginfo_array, struct tcb *const tcp,
324 const kernel_ulong_t addr, const kernel_ulong_t len)
325 {
326 siginfo_t si;
327
328 print_array(tcp, addr, len, &si, sizeof(si),
329 tfetch_mem, print_siginfo_t, 0);
330 }