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 * 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 <signal.h>
36
37#ifndef NSIG
38# warning NSIG is not defined, using 32
39# define NSIG 32
40#elif NSIG < 32
41# error NSIG < 32
42#endif
43
44/* The libc headers do not define this constant since it should only be
45   used by the implementation.  So we define it here.  */
46#ifndef SA_RESTORER
47# ifdef ASM_SA_RESTORER
48#  define SA_RESTORER ASM_SA_RESTORER
49# endif
50#endif
51
52/*
53 * Some architectures define SA_RESTORER in their headers,
54 * but do not actually have sa_restorer.
55 *
56 * Some architectures, otherwise, do not define SA_RESTORER in their headers,
57 * but actually have sa_restorer.
58 */
59#ifdef SA_RESTORER
60# if defined HPPA || defined IA64
61#  define HAVE_SA_RESTORER 0
62# else
63#  define HAVE_SA_RESTORER 1
64# endif
65#else /* !SA_RESTORER */
66# if defined SPARC || defined SPARC64 || defined M68K
67#  define HAVE_SA_RESTORER 1
68# else
69#  define HAVE_SA_RESTORER 0
70# endif
71#endif
72
73#include "xlat/sigact_flags.h"
74#include "xlat/sigprocmaskcmds.h"
75
76/* Anonymous realtime signals. */
77#ifndef ASM_SIGRTMIN
78/* Linux kernel >= 3.18 defines SIGRTMIN to 32 on all architectures. */
79# define ASM_SIGRTMIN 32
80#endif
81#ifndef ASM_SIGRTMAX
82/* Under glibc 2.1, SIGRTMAX et al are functions, but __SIGRTMAX is a
83   constant.  This is what we want.  Otherwise, just use SIGRTMAX. */
84# ifdef SIGRTMAX
85#  ifndef __SIGRTMAX
86#   define __SIGRTMAX SIGRTMAX
87#  endif
88# endif
89# ifdef __SIGRTMAX
90#  define ASM_SIGRTMAX __SIGRTMAX
91# endif
92#endif
93
94/* Note on the size of sigset_t:
95 *
96 * In glibc, sigset_t is an array with space for 1024 bits (!),
97 * even though all arches supported by Linux have only 64 signals
98 * except MIPS, which has 128. IOW, it is 128 bytes long.
99 *
100 * In-kernel sigset_t is sized correctly (it is either 64 or 128 bit long).
101 * However, some old syscall return only 32 lower bits (one word).
102 * Example: sys_sigpending vs sys_rt_sigpending.
103 *
104 * Be aware of this fact when you try to
105 *     memcpy(&tcp->u_arg[1], &something, sizeof(sigset_t))
106 * - sizeof(sigset_t) is much bigger than you think,
107 * it may overflow tcp->u_arg[] array, and it may try to copy more data
108 * than is really available in <something>.
109 * Similarly,
110 *     umoven(tcp, addr, sizeof(sigset_t), &sigset)
111 * may be a bad idea: it'll try to read much more data than needed
112 * to fetch a sigset_t.
113 * Use (NSIG / 8) as a size instead.
114 */
115
116const char *
117signame(const int sig)
118{
119	static char buf[sizeof("SIGRT_%u") + sizeof(int)*3];
120
121	if (sig >= 0) {
122		const unsigned int s = sig;
123
124		if (s < nsignals)
125			return signalent[s];
126#ifdef ASM_SIGRTMAX
127		if (s >= ASM_SIGRTMIN && s <= ASM_SIGRTMAX) {
128			sprintf(buf, "SIGRT_%u", s - ASM_SIGRTMIN);
129			return buf;
130		}
131#endif
132	}
133	sprintf(buf, "%d", sig);
134	return buf;
135}
136
137static unsigned int
138popcount32(const uint32_t *a, unsigned int size)
139{
140	unsigned int count = 0;
141
142	for (; size; ++a, --size) {
143		uint32_t x = *a;
144
145#ifdef HAVE___BUILTIN_POPCOUNT
146		count += __builtin_popcount(x);
147#else
148		for (; x; ++count)
149			x &= x - 1;
150#endif
151	}
152
153	return count;
154}
155
156const char *
157sprintsigmask_n(const char *prefix, const void *sig_mask, unsigned int bytes)
158{
159	/*
160	 * The maximum number of signal names to be printed is NSIG * 2 / 3.
161	 * Most of signal names have length 7,
162	 * average length of signal names is less than 7.
163	 * The length of prefix string does not exceed 16.
164	 */
165	static char outstr[128 + 8 * (NSIG * 2 / 3)];
166
167	char *s;
168	const uint32_t *mask;
169	uint32_t inverted_mask[NSIG / 32];
170	unsigned int size;
171	int i;
172	char sep;
173
174	s = stpcpy(outstr, prefix);
175
176	mask = sig_mask;
177	/* length of signal mask in 4-byte words */
178	size = (bytes >= NSIG / 8) ? NSIG / 32 : (bytes + 3) / 4;
179
180	/* check whether 2/3 or more bits are set */
181	if (popcount32(mask, size) >= size * 32 * 2 / 3) {
182		/* show those signals that are NOT in the mask */
183		unsigned int j;
184		for (j = 0; j < size; ++j)
185			inverted_mask[j] = ~mask[j];
186		mask = inverted_mask;
187		*s++ = '~';
188	}
189
190	sep = '[';
191	for (i = 0; (i = next_set_bit(mask, i, size * 32)) >= 0; ) {
192		++i;
193		*s++ = sep;
194		if ((unsigned) i < nsignals) {
195			s = stpcpy(s, signalent[i] + 3);
196		}
197#ifdef ASM_SIGRTMAX
198		else if (i >= ASM_SIGRTMIN && i <= ASM_SIGRTMAX) {
199			s += sprintf(s, "RT_%u", i - ASM_SIGRTMIN);
200		}
201#endif
202		else {
203			s += sprintf(s, "%u", i);
204		}
205		sep = ' ';
206	}
207	if (sep == '[')
208		*s++ = sep;
209	*s++ = ']';
210	*s = '\0';
211	return outstr;
212}
213
214#define sprintsigmask_val(prefix, mask) \
215	sprintsigmask_n((prefix), &(mask), sizeof(mask))
216
217#define tprintsigmask_val(prefix, mask) \
218	tprints(sprintsigmask_n((prefix), &(mask), sizeof(mask)))
219
220void
221printsignal(int nr)
222{
223	tprints(signame(nr));
224}
225
226void
227print_sigset_addr_len(struct tcb *tcp, long addr, long len)
228{
229	char mask[NSIG / 8];
230
231	/* Here len is usually equals NSIG / 8 or current_wordsize.
232	 * But we code this defensively:
233	 */
234	if (len < 0) {
235		printaddr(addr);
236		return;
237	}
238	if (len >= NSIG / 8)
239		len = NSIG / 8;
240	else
241		len = (len + 3) & ~3;
242
243	if (umoven_or_printaddr(tcp, addr, len, mask))
244		return;
245	tprints(sprintsigmask_n("", mask, len));
246}
247
248SYS_FUNC(sigsetmask)
249{
250	if (entering(tcp)) {
251		tprintsigmask_val("", tcp->u_arg[0]);
252	}
253	else if (!syserror(tcp)) {
254		tcp->auxstr = sprintsigmask_val("old mask ", tcp->u_rval);
255		return RVAL_HEX | RVAL_STR;
256	}
257	return 0;
258}
259
260#ifdef HAVE_SIGACTION
261
262struct old_sigaction {
263	/* sa_handler may be a libc #define, need to use other name: */
264#ifdef MIPS
265	unsigned int sa_flags;
266	void (*__sa_handler)(int);
267	/* Kernel treats sa_mask as an array of longs. */
268	unsigned long sa_mask[NSIG / sizeof(long) ? NSIG / sizeof(long) : 1];
269#else
270	void (*__sa_handler)(int);
271	unsigned long sa_mask;
272	unsigned long sa_flags;
273#endif /* !MIPS */
274#if HAVE_SA_RESTORER
275	void (*sa_restorer)(void);
276#endif
277};
278
279struct old_sigaction32 {
280	/* sa_handler may be a libc #define, need to use other name: */
281	uint32_t __sa_handler;
282	uint32_t sa_mask;
283	uint32_t sa_flags;
284#if HAVE_SA_RESTORER
285	uint32_t sa_restorer;
286#endif
287};
288
289static void
290decode_old_sigaction(struct tcb *tcp, long addr)
291{
292	struct old_sigaction sa;
293
294#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
295	if (current_wordsize != sizeof(sa.__sa_handler) && current_wordsize == 4) {
296		struct old_sigaction32 sa32;
297
298		if (umove_or_printaddr(tcp, addr, &sa32))
299			return;
300
301		memset(&sa, 0, sizeof(sa));
302		sa.__sa_handler = (void*)(uintptr_t)sa32.__sa_handler;
303		sa.sa_flags = sa32.sa_flags;
304#if HAVE_SA_RESTORER && defined SA_RESTORER
305		sa.sa_restorer = (void*)(uintptr_t)sa32.sa_restorer;
306#endif
307		sa.sa_mask = sa32.sa_mask;
308	} else
309#endif
310	if (umove_or_printaddr(tcp, addr, &sa))
311		return;
312
313	/* Architectures using function pointers, like
314	 * hppa, may need to manipulate the function pointer
315	 * to compute the result of a comparison. However,
316	 * the __sa_handler function pointer exists only in
317	 * the address space of the traced process, and can't
318	 * be manipulated by strace. In order to prevent the
319	 * compiler from generating code to manipulate
320	 * __sa_handler we cast the function pointers to long. */
321	tprints("{");
322	if ((long)sa.__sa_handler == (long)SIG_ERR)
323		tprints("SIG_ERR");
324	else if ((long)sa.__sa_handler == (long)SIG_DFL)
325		tprints("SIG_DFL");
326	else if ((long)sa.__sa_handler == (long)SIG_IGN)
327		tprints("SIG_IGN");
328	else
329		printaddr((long) sa.__sa_handler);
330	tprints(", ");
331#ifdef MIPS
332	tprintsigmask_addr("", sa.sa_mask);
333#else
334	tprintsigmask_val("", sa.sa_mask);
335#endif
336	tprints(", ");
337	printflags(sigact_flags, sa.sa_flags, "SA_???");
338#if HAVE_SA_RESTORER && defined SA_RESTORER
339	if (sa.sa_flags & SA_RESTORER)
340		tprintf(", %p", sa.sa_restorer);
341#endif
342	tprints("}");
343}
344
345SYS_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
357SYS_FUNC(signal)
358{
359	if (entering(tcp)) {
360		printsignal(tcp->u_arg[0]);
361		tprints(", ");
362		switch (tcp->u_arg[1]) {
363		case (long) SIG_ERR:
364			tprints("SIG_ERR");
365			break;
366		case (long) SIG_DFL:
367			tprints("SIG_DFL");
368			break;
369		case (long) SIG_IGN:
370			tprints("SIG_IGN");
371			break;
372		default:
373			printaddr(tcp->u_arg[1]);
374		}
375		return 0;
376	}
377	else if (!syserror(tcp)) {
378		switch (tcp->u_rval) {
379		case (long) SIG_ERR:
380			tcp->auxstr = "SIG_ERR"; break;
381		case (long) SIG_DFL:
382			tcp->auxstr = "SIG_DFL"; break;
383		case (long) SIG_IGN:
384			tcp->auxstr = "SIG_IGN"; break;
385		default:
386			tcp->auxstr = NULL;
387		}
388		return RVAL_HEX | RVAL_STR;
389	}
390	return 0;
391}
392
393#endif /* HAVE_SIGACTION */
394
395SYS_FUNC(siggetmask)
396{
397	if (exiting(tcp)) {
398		tcp->auxstr = sprintsigmask_val("mask ", tcp->u_rval);
399	}
400	return RVAL_HEX | RVAL_STR;
401}
402
403SYS_FUNC(sigsuspend)
404{
405	tprintsigmask_val("", tcp->u_arg[2]);
406
407	return RVAL_DECODED;
408}
409
410#ifdef HAVE_SIGACTION
411
412/* "Old" sigprocmask, which operates with word-sized signal masks */
413SYS_FUNC(sigprocmask)
414{
415# ifdef ALPHA
416	if (entering(tcp)) {
417		/*
418		 * Alpha/OSF is different: it doesn't pass in two pointers,
419		 * but rather passes in the new bitmask as an argument and
420		 * then returns the old bitmask.  This "works" because we
421		 * only have 64 signals to worry about.  If you want more,
422		 * use of the rt_sigprocmask syscall is required.
423		 * Alpha:
424		 *	old = osf_sigprocmask(how, new);
425		 * Everyone else:
426		 *	ret = sigprocmask(how, &new, &old, ...);
427		 */
428		printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
429		tprintsigmask_val(", ", tcp->u_arg[1]);
430	}
431	else if (!syserror(tcp)) {
432		tcp->auxstr = sprintsigmask_val("old mask ", tcp->u_rval);
433		return RVAL_HEX | RVAL_STR;
434	}
435# else /* !ALPHA */
436	if (entering(tcp)) {
437		printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
438		tprints(", ");
439		print_sigset_addr_len(tcp, tcp->u_arg[1], current_wordsize);
440		tprints(", ");
441	}
442	else {
443		print_sigset_addr_len(tcp, tcp->u_arg[2], current_wordsize);
444	}
445# endif /* !ALPHA */
446	return 0;
447}
448
449#endif /* HAVE_SIGACTION */
450
451SYS_FUNC(kill)
452{
453	tprintf("%ld, %s",
454		widen_to_long(tcp->u_arg[0]),
455		signame(tcp->u_arg[1]));
456
457	return RVAL_DECODED;
458}
459
460SYS_FUNC(tgkill)
461{
462	tprintf("%ld, %ld, %s",
463		widen_to_long(tcp->u_arg[0]),
464		widen_to_long(tcp->u_arg[1]),
465		signame(tcp->u_arg[2]));
466
467	return RVAL_DECODED;
468}
469
470SYS_FUNC(sigpending)
471{
472	if (exiting(tcp))
473		print_sigset_addr_len(tcp, tcp->u_arg[0], current_wordsize);
474	return 0;
475}
476
477SYS_FUNC(rt_sigprocmask)
478{
479	/* Note: arg[3] is the length of the sigset. Kernel requires NSIG / 8 */
480	if (entering(tcp)) {
481		printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
482		tprints(", ");
483		print_sigset_addr_len(tcp, tcp->u_arg[1], tcp->u_arg[3]);
484		tprints(", ");
485	}
486	else {
487		print_sigset_addr_len(tcp, tcp->u_arg[2], tcp->u_arg[3]);
488		tprintf(", %lu", tcp->u_arg[3]);
489	}
490	return 0;
491}
492
493/* Structure describing the action to be taken when a signal arrives.  */
494struct new_sigaction
495{
496	/* sa_handler may be a libc #define, need to use other name: */
497#ifdef MIPS
498	unsigned int sa_flags;
499	void (*__sa_handler)(int);
500#else
501	void (*__sa_handler)(int);
502	unsigned long sa_flags;
503#endif /* !MIPS */
504#if HAVE_SA_RESTORER
505	void (*sa_restorer)(void);
506#endif
507	/* Kernel treats sa_mask as an array of longs. */
508	unsigned long sa_mask[NSIG / sizeof(long) ? NSIG / sizeof(long) : 1];
509};
510/* Same for i386-on-x86_64 and similar cases */
511struct new_sigaction32
512{
513	uint32_t __sa_handler;
514	uint32_t sa_flags;
515#if HAVE_SA_RESTORER
516	uint32_t sa_restorer;
517#endif
518	uint32_t sa_mask[2 * (NSIG / sizeof(long) ? NSIG / sizeof(long) : 1)];
519};
520
521static void
522decode_new_sigaction(struct tcb *tcp, long addr)
523{
524	struct new_sigaction sa;
525
526#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
527	if (current_wordsize != sizeof(sa.sa_flags) && current_wordsize == 4) {
528		struct new_sigaction32 sa32;
529
530		if (umove_or_printaddr(tcp, addr, &sa32))
531			return;
532
533		memset(&sa, 0, sizeof(sa));
534		sa.__sa_handler = (void*)(unsigned long)sa32.__sa_handler;
535		sa.sa_flags     = sa32.sa_flags;
536#if HAVE_SA_RESTORER && defined SA_RESTORER
537		sa.sa_restorer  = (void*)(unsigned long)sa32.sa_restorer;
538#endif
539		/* Kernel treats sa_mask as an array of longs.
540		 * For 32-bit process, "long" is uint32_t, thus, for example,
541		 * 32th bit in sa_mask will end up as bit 0 in sa_mask[1].
542		 * But for (64-bit) kernel, 32th bit in sa_mask is
543		 * 32th bit in 0th (64-bit) long!
544		 * For little-endian, it's the same.
545		 * For big-endian, we swap 32-bit words.
546		 */
547		sa.sa_mask[0] = sa32.sa_mask[0] + ((long)(sa32.sa_mask[1]) << 32);
548	} else
549#endif
550	if (umove_or_printaddr(tcp, addr, &sa))
551		return;
552
553	/* Architectures using function pointers, like
554	 * hppa, may need to manipulate the function pointer
555	 * to compute the result of a comparison. However,
556	 * the __sa_handler function pointer exists only in
557	 * the address space of the traced process, and can't
558	 * be manipulated by strace. In order to prevent the
559	 * compiler from generating code to manipulate
560	 * __sa_handler we cast the function pointers to long. */
561	if ((long)sa.__sa_handler == (long)SIG_ERR)
562		tprints("{SIG_ERR, ");
563	else if ((long)sa.__sa_handler == (long)SIG_DFL)
564		tprints("{SIG_DFL, ");
565	else if ((long)sa.__sa_handler == (long)SIG_IGN)
566		tprints("{SIG_IGN, ");
567	else
568		tprintf("{%#lx, ", (long) sa.__sa_handler);
569	/*
570	 * Sigset size is in tcp->u_arg[4] (SPARC)
571	 * or in tcp->u_arg[3] (all other),
572	 * but kernel won't handle sys_rt_sigaction
573	 * with wrong sigset size (just returns EINVAL instead).
574	 * We just fetch the right size, which is NSIG / 8.
575	 */
576	tprintsigmask_val("", sa.sa_mask);
577	tprints(", ");
578
579	printflags(sigact_flags, sa.sa_flags, "SA_???");
580#if HAVE_SA_RESTORER && defined SA_RESTORER
581	if (sa.sa_flags & SA_RESTORER)
582		tprintf(", %p", sa.sa_restorer);
583#endif
584	tprints("}");
585}
586
587SYS_FUNC(rt_sigaction)
588{
589	if (entering(tcp)) {
590		printsignal(tcp->u_arg[0]);
591		tprints(", ");
592		decode_new_sigaction(tcp, tcp->u_arg[1]);
593		tprints(", ");
594	} else {
595		decode_new_sigaction(tcp, tcp->u_arg[2]);
596#if defined(SPARC) || defined(SPARC64)
597		tprintf(", %#lx, %lu", tcp->u_arg[3], tcp->u_arg[4]);
598#elif defined(ALPHA)
599		tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]);
600#else
601		tprintf(", %lu", tcp->u_arg[3]);
602#endif
603	}
604	return 0;
605}
606
607SYS_FUNC(rt_sigpending)
608{
609	if (exiting(tcp)) {
610		/*
611		 * One of the few syscalls where sigset size (arg[1])
612		 * is allowed to be <= NSIG / 8, not strictly ==.
613		 * This allows non-rt sigpending() syscall
614		 * to reuse rt_sigpending() code in kernel.
615		 */
616		print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[1]);
617		tprintf(", %lu", tcp->u_arg[1]);
618	}
619	return 0;
620}
621
622SYS_FUNC(rt_sigsuspend)
623{
624	/* NB: kernel requires arg[1] == NSIG / 8 */
625	print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[1]);
626	tprintf(", %lu", tcp->u_arg[1]);
627
628	return RVAL_DECODED;
629}
630
631static void
632print_sigqueueinfo(struct tcb *tcp, int sig, unsigned long uinfo)
633{
634	printsignal(sig);
635	tprints(", ");
636	printsiginfo_at(tcp, uinfo);
637}
638
639SYS_FUNC(rt_sigqueueinfo)
640{
641	tprintf("%lu, ", tcp->u_arg[0]);
642	print_sigqueueinfo(tcp, tcp->u_arg[1], tcp->u_arg[2]);
643
644	return RVAL_DECODED;
645}
646
647SYS_FUNC(rt_tgsigqueueinfo)
648{
649	tprintf("%lu, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
650	print_sigqueueinfo(tcp, tcp->u_arg[2], tcp->u_arg[3]);
651
652	return RVAL_DECODED;
653}
654
655SYS_FUNC(rt_sigtimedwait)
656{
657	/* NB: kernel requires arg[3] == NSIG / 8 */
658	if (entering(tcp)) {
659		print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[3]);
660		tprints(", ");
661		/* This is the only "return" parameter, */
662		if (tcp->u_arg[1] != 0)
663			return 0;
664		/* ... if it's NULL, can decode all on entry */
665		tprints("NULL, ");
666	}
667	else if (tcp->u_arg[1] != 0) {
668		/* syscall exit, and u_arg[1] wasn't NULL */
669		printsiginfo_at(tcp, tcp->u_arg[1]);
670		tprints(", ");
671	}
672	else {
673		/* syscall exit, and u_arg[1] was NULL */
674		return 0;
675	}
676
677	/*
678	 * Since the timeout parameter is read by the kernel
679	 * on entering syscall, it has to be decoded the same way
680	 * whether the syscall has failed or not.
681	 */
682	temporarily_clear_syserror(tcp);
683	print_timespec(tcp, tcp->u_arg[2]);
684	restore_cleared_syserror(tcp);
685
686	tprintf(", %lu", tcp->u_arg[3]);
687	return 0;
688};
689
690SYS_FUNC(restart_syscall)
691{
692	tprintf("<... resuming interrupted %s ...>",
693		tcp->s_prev_ent ? tcp->s_prev_ent->sys_name : "system call");
694
695	return RVAL_DECODED;
696}
697