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