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