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