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