Branch data Line data Source code
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, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 : : * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 : : * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 : : * Linux for s390 port by D.J. Barrow
8 : : * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
9 : : * Copyright (C) 2001-2017 The strace developers.
10 : : * All rights reserved.
11 : : *
12 : : * Redistribution and use in source and binary forms, with or without
13 : : * modification, are permitted provided that the following conditions
14 : : * are met:
15 : : * 1. Redistributions of source code must retain the above copyright
16 : : * notice, this list of conditions and the following disclaimer.
17 : : * 2. Redistributions in binary form must reproduce the above copyright
18 : : * notice, this list of conditions and the following disclaimer in the
19 : : * documentation and/or other materials provided with the distribution.
20 : : * 3. The name of the author may not be used to endorse or promote products
21 : : * derived from this software without specific prior written permission.
22 : : *
23 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 : : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 : : */
34 : :
35 : : #include "defs.h"
36 : : #include "nsig.h"
37 : :
38 : : /* The libc headers do not define this constant since it should only be
39 : : used by the implementation. So we define it here. */
40 : : #ifndef SA_RESTORER
41 : : # ifdef ASM_SA_RESTORER
42 : : # define SA_RESTORER ASM_SA_RESTORER
43 : : # endif
44 : : #endif
45 : :
46 : : /*
47 : : * Some architectures define SA_RESTORER in their headers,
48 : : * but do not actually have sa_restorer.
49 : : *
50 : : * Some architectures, otherwise, do not define SA_RESTORER in their headers,
51 : : * but actually have sa_restorer.
52 : : */
53 : : #ifdef SA_RESTORER
54 : : # if defined HPPA || defined IA64
55 : : # define HAVE_SA_RESTORER 0
56 : : # else
57 : : # define HAVE_SA_RESTORER 1
58 : : # endif
59 : : #else /* !SA_RESTORER */
60 : : # if defined SPARC || defined SPARC64 || defined M68K
61 : : # define HAVE_SA_RESTORER 1
62 : : # else
63 : : # define HAVE_SA_RESTORER 0
64 : : # endif
65 : : #endif
66 : :
67 : : #include "xlat/sa_handler_values.h"
68 : : #include "xlat/sigact_flags.h"
69 : : #include "xlat/sigprocmaskcmds.h"
70 : :
71 : : /* Anonymous realtime signals. */
72 : : #ifndef ASM_SIGRTMIN
73 : : /* Linux kernel >= 3.18 defines SIGRTMIN to 32 on all architectures. */
74 : : # define ASM_SIGRTMIN 32
75 : : #endif
76 : : #ifndef ASM_SIGRTMAX
77 : : /* Under glibc 2.1, SIGRTMAX et al are functions, but __SIGRTMAX is a
78 : : constant. This is what we want. Otherwise, just use SIGRTMAX. */
79 : : # ifdef SIGRTMAX
80 : : # ifndef __SIGRTMAX
81 : : # define __SIGRTMAX SIGRTMAX
82 : : # endif
83 : : # endif
84 : : # ifdef __SIGRTMAX
85 : : # define ASM_SIGRTMAX __SIGRTMAX
86 : : # endif
87 : : #endif
88 : :
89 : : /* Note on the size of sigset_t:
90 : : *
91 : : * In glibc, sigset_t is an array with space for 1024 bits (!),
92 : : * even though all arches supported by Linux have only 64 signals
93 : : * except MIPS, which has 128. IOW, it is 128 bytes long.
94 : : *
95 : : * In-kernel sigset_t is sized correctly (it is either 64 or 128 bit long).
96 : : * However, some old syscall return only 32 lower bits (one word).
97 : : * Example: sys_sigpending vs sys_rt_sigpending.
98 : : *
99 : : * Be aware of this fact when you try to
100 : : * memcpy(&tcp->u_arg[1], &something, sizeof(sigset_t))
101 : : * - sizeof(sigset_t) is much bigger than you think,
102 : : * it may overflow tcp->u_arg[] array, and it may try to copy more data
103 : : * than is really available in <something>.
104 : : * Similarly,
105 : : * umoven(tcp, addr, sizeof(sigset_t), &sigset)
106 : : * may be a bad idea: it'll try to read much more data than needed
107 : : * to fetch a sigset_t.
108 : : * Use NSIG_BYTES as a size instead.
109 : : */
110 : :
111 : : static const char *
112 : 48 : get_sa_handler_str(kernel_ulong_t handler)
113 : : {
114 : 48 : return xlookup(sa_handler_values, handler);
115 : : }
116 : :
117 : : static void
118 : 48 : print_sa_handler(kernel_ulong_t handler)
119 : : {
120 : 48 : const char *sa_handler_str = get_sa_handler_str(handler);
121 : :
122 [ + + ]: 48 : if (sa_handler_str)
123 : 36 : tprints(sa_handler_str);
124 : : else
125 : 12 : printaddr(handler);
126 : 48 : }
127 : :
128 : : const char *
129 : 75067 : signame(const int sig)
130 : : {
131 : : static char buf[sizeof("SIGRT_%u") + sizeof(int)*3];
132 : :
133 [ + + ]: 75067 : if (sig >= 0) {
134 : 75061 : const unsigned int s = sig;
135 : :
136 [ + + ]: 75061 : if (s < nsignals)
137 : 12125 : return signalent[s];
138 : : #ifdef ASM_SIGRTMAX
139 [ + - ][ + + ]: 62936 : if (s >= ASM_SIGRTMIN && s <= (unsigned int) ASM_SIGRTMAX) {
140 : 960 : sprintf(buf, "SIGRT_%u", s - ASM_SIGRTMIN);
141 : 960 : return buf;
142 : : }
143 : : #endif
144 : : }
145 : 61982 : sprintf(buf, "%d", sig);
146 : 61982 : return buf;
147 : : }
148 : :
149 : : static unsigned int
150 : 346 : popcount32(const uint32_t *a, unsigned int size)
151 : : {
152 : 346 : unsigned int count = 0;
153 : :
154 [ + + ]: 981 : for (; size; ++a, --size) {
155 : 635 : uint32_t x = *a;
156 : :
157 : : #ifdef HAVE___BUILTIN_POPCOUNT
158 : 635 : count += __builtin_popcount(x);
159 : : #else
160 : : for (; x; ++count)
161 : : x &= x - 1;
162 : : #endif
163 : : }
164 : :
165 : 346 : return count;
166 : : }
167 : :
168 : : const char *
169 : 346 : sprintsigmask_n(const char *prefix, const void *sig_mask, unsigned int bytes)
170 : : {
171 : : /*
172 : : * The maximum number of signal names to be printed
173 : : * is NSIG_BYTES * 8 * 2 / 3.
174 : : * Most of signal names have length 7,
175 : : * average length of signal names is less than 7.
176 : : * The length of prefix string does not exceed 16.
177 : : */
178 : : static char outstr[128 + 8 * (NSIG_BYTES * 8 * 2 / 3)];
179 : :
180 : : char *s;
181 : : const uint32_t *mask;
182 : : uint32_t inverted_mask[NSIG_BYTES / 4];
183 : : unsigned int size;
184 : : int i;
185 : : char sep;
186 : :
187 : 346 : s = stpcpy(outstr, prefix);
188 : :
189 : 346 : mask = sig_mask;
190 : : /* length of signal mask in 4-byte words */
191 [ + + ]: 346 : size = (bytes >= NSIG_BYTES) ? NSIG_BYTES / 4 : (bytes + 3) / 4;
192 : :
193 : : /* check whether 2/3 or more bits are set */
194 [ + + ]: 346 : if (popcount32(mask, size) >= size * (4 * 8) * 2 / 3) {
195 : : /* show those signals that are NOT in the mask */
196 : : unsigned int j;
197 [ + + ]: 150 : for (j = 0; j < size; ++j)
198 : 99 : inverted_mask[j] = ~mask[j];
199 : 51 : mask = inverted_mask;
200 : 51 : *s++ = '~';
201 : : }
202 : :
203 : 346 : sep = '[';
204 [ + + ]: 937 : for (i = 0; (i = next_set_bit(mask, i, size * (4 * 8))) >= 0; ) {
205 : 591 : ++i;
206 : 591 : *s++ = sep;
207 [ + + ]: 591 : if ((unsigned) i < nsignals) {
208 : 550 : s = stpcpy(s, signalent[i] + 3);
209 : : }
210 : : #ifdef ASM_SIGRTMAX
211 [ + - ][ + - ]: 41 : else if (i >= ASM_SIGRTMIN && i <= ASM_SIGRTMAX) {
212 : 41 : s += sprintf(s, "RT_%u", i - ASM_SIGRTMIN);
213 : : }
214 : : #endif
215 : : else {
216 : 0 : s += sprintf(s, "%u", i);
217 : : }
218 : 591 : sep = ' ';
219 : : }
220 [ + + ]: 346 : if (sep == '[')
221 : 98 : *s++ = sep;
222 : 346 : *s++ = ']';
223 : 346 : *s = '\0';
224 : 346 : return outstr;
225 : : }
226 : :
227 : : #define sprintsigmask_val(prefix, mask) \
228 : : sprintsigmask_n((prefix), &(mask), sizeof(mask))
229 : :
230 : : #define tprintsigmask_val(prefix, mask) \
231 : : tprints(sprintsigmask_n((prefix), &(mask), sizeof(mask)))
232 : :
233 : : void
234 : 1110 : printsignal(int nr)
235 : : {
236 : 1110 : tprints(signame(nr));
237 : 1110 : }
238 : :
239 : : static void
240 : 649 : print_sigset_addr_len_limit(struct tcb *const tcp, const kernel_ulong_t addr,
241 : : const kernel_ulong_t len, const unsigned int min_len)
242 : : {
243 : : /*
244 : : * Here len is usually equal to NSIG_BYTES or current_wordsize.
245 : : * But we code this defensively:
246 : : */
247 [ + + ][ + + ]: 649 : if (len < min_len || len > NSIG_BYTES) {
248 : 279 : printaddr(addr);
249 : 352 : return;
250 : : }
251 : 370 : int mask[NSIG_BYTES / sizeof(int)] = {};
252 [ + + ]: 370 : if (umoven_or_printaddr(tcp, addr, len, mask))
253 : 73 : return;
254 : 297 : tprints(sprintsigmask_n("", mask, len));
255 : : }
256 : :
257 : : void
258 : 523 : print_sigset_addr_len(struct tcb *const tcp, const kernel_ulong_t addr,
259 : : const kernel_ulong_t len)
260 : : {
261 : 523 : print_sigset_addr_len_limit(tcp, addr, len, current_wordsize);
262 : 523 : }
263 : :
264 : : void
265 : 6 : print_sigset_addr(struct tcb *const tcp, const kernel_ulong_t addr)
266 : : {
267 : 6 : print_sigset_addr_len_limit(tcp, addr, NSIG_BYTES, NSIG_BYTES);
268 : 6 : }
269 : :
270 : 0 : SYS_FUNC(sigsetmask)
271 : : {
272 [ # # ]: 0 : if (entering(tcp)) {
273 : 0 : tprintsigmask_val("", tcp->u_arg[0]);
274 : : }
275 [ # # ]: 0 : else if (!syserror(tcp)) {
276 : 0 : tcp->auxstr = sprintsigmask_val("old mask ", tcp->u_rval);
277 : 0 : return RVAL_HEX | RVAL_STR;
278 : : }
279 : 0 : return 0;
280 : : }
281 : :
282 : : struct old_sigaction {
283 : : /* sa_handler may be a libc #define, need to use other name: */
284 : : #ifdef MIPS
285 : : unsigned int sa_flags;
286 : : unsigned long sa_handler__;
287 : : /* Kernel treats sa_mask as an array of longs. */
288 : : unsigned long sa_mask[NSIG / sizeof(long)];
289 : : #else
290 : : unsigned long sa_handler__;
291 : : unsigned long sa_mask;
292 : : unsigned long sa_flags;
293 : : #endif /* !MIPS */
294 : : #if HAVE_SA_RESTORER
295 : : unsigned long sa_restorer;
296 : : #endif
297 : : };
298 : :
299 : : struct old_sigaction32 {
300 : : /* sa_handler may be a libc #define, need to use other name: */
301 : : uint32_t sa_handler__;
302 : : uint32_t sa_mask;
303 : : uint32_t sa_flags;
304 : : #if HAVE_SA_RESTORER
305 : : uint32_t sa_restorer;
306 : : #endif
307 : : };
308 : :
309 : : static void
310 : 0 : decode_old_sigaction(struct tcb *const tcp, const kernel_ulong_t addr)
311 : : {
312 : : struct old_sigaction sa;
313 : :
314 : : #ifndef current_wordsize
315 [ # # ]: 0 : if (current_wordsize < sizeof(sa.sa_handler__)) {
316 : : struct old_sigaction32 sa32;
317 : :
318 [ # # ]: 0 : if (umove_or_printaddr(tcp, addr, &sa32))
319 : 0 : return;
320 : :
321 : 0 : memset(&sa, 0, sizeof(sa));
322 : 0 : sa.sa_handler__ = sa32.sa_handler__;
323 : 0 : sa.sa_flags = sa32.sa_flags;
324 : : #if HAVE_SA_RESTORER && defined SA_RESTORER
325 : 0 : sa.sa_restorer = sa32.sa_restorer;
326 : : #endif
327 : 0 : sa.sa_mask = sa32.sa_mask;
328 : : } else
329 : : #endif
330 [ # # ]: 0 : if (umove_or_printaddr(tcp, addr, &sa))
331 : 0 : return;
332 : :
333 : 0 : tprints("{sa_handler=");
334 : 0 : print_sa_handler(sa.sa_handler__);
335 : 0 : tprints(", sa_mask=");
336 : : #ifdef MIPS
337 : : tprintsigmask_addr("", sa.sa_mask);
338 : : #else
339 : 0 : tprintsigmask_val("", sa.sa_mask);
340 : : #endif
341 : 0 : tprints(", sa_flags=");
342 : 0 : printflags(sigact_flags, sa.sa_flags, "SA_???");
343 : : #if HAVE_SA_RESTORER && defined SA_RESTORER
344 [ # # ]: 0 : if (sa.sa_flags & SA_RESTORER) {
345 : 0 : tprints(", sa_restorer=");
346 : 0 : printaddr(sa.sa_restorer);
347 : : }
348 : : #endif
349 : 0 : tprints("}");
350 : : }
351 : :
352 : 0 : SYS_FUNC(sigaction)
353 : : {
354 [ # # ]: 0 : if (entering(tcp)) {
355 : 0 : printsignal(tcp->u_arg[0]);
356 : 0 : tprints(", ");
357 : 0 : decode_old_sigaction(tcp, tcp->u_arg[1]);
358 : 0 : tprints(", ");
359 : : } else
360 : 0 : decode_old_sigaction(tcp, tcp->u_arg[2]);
361 : 0 : return 0;
362 : : }
363 : :
364 : 0 : SYS_FUNC(signal)
365 : : {
366 [ # # ]: 0 : if (entering(tcp)) {
367 : 0 : printsignal(tcp->u_arg[0]);
368 : 0 : tprints(", ");
369 : 0 : print_sa_handler(tcp->u_arg[1]);
370 : 0 : return 0;
371 [ # # ]: 0 : } else if (!syserror(tcp)) {
372 : 0 : tcp->auxstr = get_sa_handler_str(tcp->u_rval);
373 : 0 : return RVAL_HEX | RVAL_STR;
374 : : }
375 : 0 : return 0;
376 : : }
377 : :
378 : 0 : SYS_FUNC(siggetmask)
379 : : {
380 [ # # ]: 0 : if (exiting(tcp)) {
381 : 0 : tcp->auxstr = sprintsigmask_val("mask ", tcp->u_rval);
382 : : }
383 : 0 : return RVAL_HEX | RVAL_STR;
384 : : }
385 : :
386 : 0 : SYS_FUNC(sigsuspend)
387 : : {
388 : 0 : tprintsigmask_val("", tcp->u_arg[2]);
389 : :
390 : 0 : return RVAL_DECODED;
391 : : }
392 : :
393 : : /* "Old" sigprocmask, which operates with word-sized signal masks */
394 : 0 : SYS_FUNC(sigprocmask)
395 : : {
396 : : # ifdef ALPHA
397 : : if (entering(tcp)) {
398 : : /*
399 : : * Alpha/OSF is different: it doesn't pass in two pointers,
400 : : * but rather passes in the new bitmask as an argument and
401 : : * then returns the old bitmask. This "works" because we
402 : : * only have 64 signals to worry about. If you want more,
403 : : * use of the rt_sigprocmask syscall is required.
404 : : * Alpha:
405 : : * old = osf_sigprocmask(how, new);
406 : : * Everyone else:
407 : : * ret = sigprocmask(how, &new, &old, ...);
408 : : */
409 : : printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
410 : : tprintsigmask_val(", ", tcp->u_arg[1]);
411 : : }
412 : : else if (!syserror(tcp)) {
413 : : tcp->auxstr = sprintsigmask_val("old mask ", tcp->u_rval);
414 : : return RVAL_HEX | RVAL_STR;
415 : : }
416 : : # else /* !ALPHA */
417 [ # # ]: 0 : if (entering(tcp)) {
418 : 0 : printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
419 : 0 : tprints(", ");
420 : 0 : print_sigset_addr_len(tcp, tcp->u_arg[1], current_wordsize);
421 : 0 : tprints(", ");
422 : : }
423 : : else {
424 : 0 : print_sigset_addr_len(tcp, tcp->u_arg[2], current_wordsize);
425 : : }
426 : : # endif /* !ALPHA */
427 : 0 : return 0;
428 : : }
429 : :
430 : 192 : SYS_FUNC(kill)
431 : : {
432 : 192 : tprintf("%d, %s",
433 : 192 : (int) tcp->u_arg[0],
434 : 192 : signame(tcp->u_arg[1]));
435 : :
436 : 192 : return RVAL_DECODED;
437 : : }
438 : :
439 : 0 : SYS_FUNC(tgkill)
440 : : {
441 : 0 : tprintf("%d, %d, %s",
442 : 0 : (int) tcp->u_arg[0],
443 : 0 : (int) tcp->u_arg[1],
444 : 0 : signame(tcp->u_arg[2]));
445 : :
446 : 0 : return RVAL_DECODED;
447 : : }
448 : :
449 : 0 : SYS_FUNC(sigpending)
450 : : {
451 [ # # ]: 0 : if (exiting(tcp))
452 : 0 : print_sigset_addr_len(tcp, tcp->u_arg[0], current_wordsize);
453 : 0 : return 0;
454 : : }
455 : :
456 : 228 : SYS_FUNC(rt_sigprocmask)
457 : : {
458 : : /* Note: arg[3] is the length of the sigset. Kernel requires NSIG_BYTES */
459 [ + + ]: 228 : if (entering(tcp)) {
460 : 114 : printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
461 : 114 : tprints(", ");
462 : 114 : print_sigset_addr_len(tcp, tcp->u_arg[1], tcp->u_arg[3]);
463 : 114 : tprints(", ");
464 : : }
465 : : else {
466 : 114 : print_sigset_addr_len(tcp, tcp->u_arg[2], tcp->u_arg[3]);
467 : 114 : tprintf(", %" PRI_klu, tcp->u_arg[3]);
468 : : }
469 : 228 : return 0;
470 : : }
471 : :
472 : : /* Structure describing the action to be taken when a signal arrives. */
473 : : struct new_sigaction
474 : : {
475 : : /* sa_handler may be a libc #define, need to use other name: */
476 : : #ifdef MIPS
477 : : unsigned int sa_flags;
478 : : unsigned long sa_handler__;
479 : : #else
480 : : unsigned long sa_handler__;
481 : : unsigned long sa_flags;
482 : : #endif /* !MIPS */
483 : : #if HAVE_SA_RESTORER
484 : : unsigned long sa_restorer;
485 : : #endif
486 : : /* Kernel treats sa_mask as an array of longs. */
487 : : unsigned long sa_mask[NSIG / sizeof(long)];
488 : : };
489 : : /* Same for i386-on-x86_64 and similar cases */
490 : : struct new_sigaction32
491 : : {
492 : : uint32_t sa_handler__;
493 : : uint32_t sa_flags;
494 : : #if HAVE_SA_RESTORER
495 : : uint32_t sa_restorer;
496 : : #endif
497 : : uint32_t sa_mask[2 * (NSIG / sizeof(long))];
498 : : };
499 : :
500 : : static void
501 : 48 : decode_new_sigaction(struct tcb *const tcp, const kernel_ulong_t addr)
502 : : {
503 : : struct new_sigaction sa;
504 : :
505 : : #ifndef current_wordsize
506 [ + + ]: 48 : if (current_wordsize < sizeof(sa.sa_handler__)) {
507 : : struct new_sigaction32 sa32;
508 : :
509 [ - + ]: 8 : if (umove_or_printaddr(tcp, addr, &sa32))
510 : 0 : return;
511 : :
512 : 8 : memset(&sa, 0, sizeof(sa));
513 : 8 : sa.sa_handler__ = sa32.sa_handler__;
514 : 8 : sa.sa_flags = sa32.sa_flags;
515 : : #if HAVE_SA_RESTORER && defined SA_RESTORER
516 : 8 : sa.sa_restorer = sa32.sa_restorer;
517 : : #endif
518 : : /* Kernel treats sa_mask as an array of longs.
519 : : * For 32-bit process, "long" is uint32_t, thus, for example,
520 : : * 32th bit in sa_mask will end up as bit 0 in sa_mask[1].
521 : : * But for (64-bit) kernel, 32th bit in sa_mask is
522 : : * 32th bit in 0th (64-bit) long!
523 : : * For little-endian, it's the same.
524 : : * For big-endian, we swap 32-bit words.
525 : : */
526 : 8 : sa.sa_mask[0] = ULONG_LONG(sa32.sa_mask[0], sa32.sa_mask[1]);
527 : : } else
528 : : #endif
529 [ - + ]: 40 : if (umove_or_printaddr(tcp, addr, &sa))
530 : 0 : return;
531 : :
532 : 48 : tprints("{sa_handler=");
533 : 48 : print_sa_handler(sa.sa_handler__);
534 : 48 : tprints(", sa_mask=");
535 : : /*
536 : : * Sigset size is in tcp->u_arg[4] (SPARC)
537 : : * or in tcp->u_arg[3] (all other),
538 : : * but kernel won't handle sys_rt_sigaction
539 : : * with wrong sigset size (just returns EINVAL instead).
540 : : * We just fetch the right size, which is NSIG_BYTES.
541 : : */
542 : 48 : tprintsigmask_val("", sa.sa_mask);
543 : 48 : tprints(", sa_flags=");
544 : :
545 : 48 : printflags(sigact_flags, sa.sa_flags, "SA_???");
546 : : #if HAVE_SA_RESTORER && defined SA_RESTORER
547 [ + + ]: 48 : if (sa.sa_flags & SA_RESTORER) {
548 : 35 : tprints(", sa_restorer=");
549 : 35 : printaddr(sa.sa_restorer);
550 : : }
551 : : #endif
552 : 48 : tprints("}");
553 : : }
554 : :
555 : 48 : SYS_FUNC(rt_sigaction)
556 : : {
557 [ + + ]: 48 : if (entering(tcp)) {
558 : 24 : printsignal(tcp->u_arg[0]);
559 : 24 : tprints(", ");
560 : 24 : decode_new_sigaction(tcp, tcp->u_arg[1]);
561 : 24 : tprints(", ");
562 : : } else {
563 : 24 : decode_new_sigaction(tcp, tcp->u_arg[2]);
564 : : #if defined(SPARC) || defined(SPARC64)
565 : : tprintf(", %#" PRI_klx ", %" PRI_klu, tcp->u_arg[3], tcp->u_arg[4]);
566 : : #elif defined(ALPHA)
567 : : tprintf(", %" PRI_klu ", %#" PRI_klx, tcp->u_arg[3], tcp->u_arg[4]);
568 : : #else
569 : 24 : tprintf(", %" PRI_klu, tcp->u_arg[3]);
570 : : #endif
571 : : }
572 : 48 : return 0;
573 : : }
574 : :
575 : 240 : SYS_FUNC(rt_sigpending)
576 : : {
577 [ + + ]: 240 : if (exiting(tcp)) {
578 : : /*
579 : : * One of the few syscalls where sigset size (arg[1])
580 : : * is allowed to be <= NSIG_BYTES, not strictly ==.
581 : : * This allows non-rt sigpending() syscall
582 : : * to reuse rt_sigpending() code in kernel.
583 : : */
584 : 120 : print_sigset_addr_len_limit(tcp, tcp->u_arg[0],
585 : : tcp->u_arg[1], 1);
586 : 120 : tprintf(", %" PRI_klu, tcp->u_arg[1]);
587 : : }
588 : 240 : return 0;
589 : : }
590 : :
591 : 103 : SYS_FUNC(rt_sigsuspend)
592 : : {
593 : : /* NB: kernel requires arg[1] == NSIG_BYTES */
594 : 103 : print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[1]);
595 : 103 : tprintf(", %" PRI_klu, tcp->u_arg[1]);
596 : :
597 : 103 : return RVAL_DECODED;
598 : : }
599 : :
600 : : static void
601 : 12 : print_sigqueueinfo(struct tcb *const tcp, const int sig,
602 : : const kernel_ulong_t addr)
603 : : {
604 : 12 : printsignal(sig);
605 : 12 : tprints(", ");
606 : 12 : printsiginfo_at(tcp, addr);
607 : 12 : }
608 : :
609 : 6 : SYS_FUNC(rt_sigqueueinfo)
610 : : {
611 : 6 : tprintf("%d, ", (int) tcp->u_arg[0]);
612 : 6 : print_sigqueueinfo(tcp, tcp->u_arg[1], tcp->u_arg[2]);
613 : :
614 : 6 : return RVAL_DECODED;
615 : : }
616 : :
617 : 6 : SYS_FUNC(rt_tgsigqueueinfo)
618 : : {
619 : 6 : tprintf("%d, %d, ", (int) tcp->u_arg[0], (int) tcp->u_arg[1]);
620 : 6 : print_sigqueueinfo(tcp, tcp->u_arg[2], tcp->u_arg[3]);
621 : :
622 : 6 : return RVAL_DECODED;
623 : : }
624 : :
625 : 192 : SYS_FUNC(rt_sigtimedwait)
626 : : {
627 : : /* NB: kernel requires arg[3] == NSIG_BYTES */
628 [ + + ]: 192 : if (entering(tcp)) {
629 : 96 : print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[3]);
630 : 96 : tprints(", ");
631 [ + + ][ - + ]: 96 : if (!(tcp->u_arg[1] && verbose(tcp))) {
632 : : /*
633 : : * This is the only "return" parameter,
634 : : * if we are not going to fetch it on exit,
635 : : * decode all parameters on entry.
636 : : */
637 : 60 : printaddr(tcp->u_arg[1]);
638 : 60 : tprints(", ");
639 : 60 : print_timespec(tcp, tcp->u_arg[2]);
640 : 60 : tprintf(", %" PRI_klu, tcp->u_arg[3]);
641 : : } else {
642 : 36 : char *sts = xstrdup(sprint_timespec(tcp, tcp->u_arg[2]));
643 : 96 : set_tcb_priv_data(tcp, sts, free);
644 : : }
645 : : } else {
646 [ + + ][ + - ]: 96 : if (tcp->u_arg[1] && verbose(tcp)) {
647 : 36 : printsiginfo_at(tcp, tcp->u_arg[1]);
648 : 36 : tprints(", ");
649 : 36 : tprints(get_tcb_priv_data(tcp));
650 : 36 : tprintf(", %" PRI_klu, tcp->u_arg[3]);
651 : : }
652 : :
653 [ + + ][ + - ]: 96 : if (!syserror(tcp) && tcp->u_rval) {
654 : 12 : tcp->auxstr = signame(tcp->u_rval);
655 : 12 : return RVAL_STR;
656 : : }
657 : : }
658 : 180 : return 0;
659 : : };
660 : :
661 : 12 : SYS_FUNC(restart_syscall)
662 : : {
663 [ + - ]: 12 : tprintf("<... resuming interrupted %s ...>",
664 : 24 : tcp->s_prev_ent ? tcp->s_prev_ent->sys_name : "system call");
665 : :
666 : 12 : return RVAL_DECODED;
667 : : }
|