signal.c revision 67e3e6352a37026098019ed61e471e34b33207d4
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 * $Id$ 34 */ 35 36#include "defs.h" 37 38#include <signal.h> 39#include <sys/user.h> 40#include <fcntl.h> 41 42#ifdef SVR4 43#include <sys/ucontext.h> 44#endif /* SVR4 */ 45 46#ifdef HAVE_SYS_REG_H 47# include <sys/reg.h> 48#ifndef PTRACE_PEEKUSR 49# define PTRACE_PEEKUSR PTRACE_PEEKUSER 50#endif 51#ifndef PTRACE_POKEUSR 52# define PTRACE_POKEUSR PTRACE_POKEUSER 53#endif 54#elif defined(HAVE_LINUX_PTRACE_H) 55#undef PTRACE_SYSCALL 56#include <linux/ptrace.h> 57#endif 58 59 60#ifdef LINUX 61 62#ifdef IA64 63# include <asm/ptrace_offsets.h> 64#endif /* !IA64 */ 65 66#if HAVE_ASM_REG_H 67#ifdef SPARC 68# define fpq kernel_fpq 69# define fq kernel_fq 70# define fpu kernel_fpu 71#endif 72#include <asm/reg.h> 73#ifdef SPARC 74# undef fpq 75# undef fq 76# undef fpu 77#endif 78 79#endif /* HAVE_ASM_REG_H */ 80#ifdef HAVE_ASM_SIGCONTEXT_H 81#ifdef SPARC 82typedef struct { 83 struct regs si_regs; 84 int si_mask; 85} m_siginfo_t; 86#elif !defined(IA64) 87#include <asm/sigcontext.h> 88#endif /* SPARC */ 89#else /* !HAVE_ASM_SIGCONTEXT_H */ 90#ifdef I386 91struct sigcontext_struct { 92 unsigned short gs, __gsh; 93 unsigned short fs, __fsh; 94 unsigned short es, __esh; 95 unsigned short ds, __dsh; 96 unsigned long edi; 97 unsigned long esi; 98 unsigned long ebp; 99 unsigned long esp; 100 unsigned long ebx; 101 unsigned long edx; 102 unsigned long ecx; 103 unsigned long eax; 104 unsigned long trapno; 105 unsigned long err; 106 unsigned long eip; 107 unsigned short cs, __csh; 108 unsigned long eflags; 109 unsigned long esp_at_signal; 110 unsigned short ss, __ssh; 111 unsigned long i387; 112 unsigned long oldmask; 113 unsigned long cr2; 114}; 115#else /* !I386 */ 116#ifdef M68K 117struct sigcontext 118{ 119 unsigned long sc_mask; 120 unsigned long sc_usp; 121 unsigned long sc_d0; 122 unsigned long sc_d1; 123 unsigned long sc_a0; 124 unsigned long sc_a1; 125 unsigned short sc_sr; 126 unsigned long sc_pc; 127 unsigned short sc_formatvec; 128}; 129#endif /* M68K */ 130#endif /* !I386 */ 131#endif /* !HAVE_ASM_SIGCONTEXT_H */ 132#ifndef NSIG 133#define NSIG 32 134#endif 135#ifdef ARM 136#undef NSIG 137#define NSIG 32 138#endif 139#endif /* LINUX */ 140 141char *signalent0[] = { 142#include "signalent.h" 143}; 144int nsignals0 = sizeof signalent0 / sizeof signalent0[0]; 145 146#if SUPPORTED_PERSONALITIES >= 2 147char *signalent1[] = { 148#include "signalent1.h" 149}; 150int nsignals1 = sizeof signalent1 / sizeof signalent1[0]; 151#endif /* SUPPORTED_PERSONALITIES >= 2 */ 152 153#if SUPPORTED_PERSONALITIES >= 3 154char *signalent2[] = { 155#include "signalent2.h" 156}; 157int nsignals2 = sizeof signalent2 / sizeof signalent2[0]; 158#endif /* SUPPORTED_PERSONALITIES >= 3 */ 159 160char **signalent; 161int nsignals; 162 163#if defined(SUNOS4) || defined(FREEBSD) 164 165static struct xlat sigvec_flags[] = { 166 { SV_ONSTACK, "SV_ONSTACK" }, 167 { SV_INTERRUPT, "SV_INTERRUPT" }, 168 { SV_RESETHAND, "SV_RESETHAND" }, 169 { SA_NOCLDSTOP, "SA_NOCLDSTOP" }, 170 { 0, NULL }, 171}; 172 173#endif /* SUNOS4 || FREEBSD */ 174 175#ifdef HAVE_SIGACTION 176 177static struct xlat sigact_flags[] = { 178#ifdef SA_RESTORER 179 { SA_RESTORER, "SA_RESTORER" }, 180#endif 181#ifdef SA_STACK 182 { SA_STACK, "SA_STACK" }, 183#endif 184#ifdef SA_RESTART 185 { SA_RESTART, "SA_RESTART" }, 186#endif 187#ifdef SA_INTERRUPT 188 { SA_INTERRUPT, "SA_INTERRUPT" }, 189#endif 190#ifdef SA_NOMASK 191 { SA_NOMASK, "SA_NOMASK" }, 192#endif 193#ifdef SA_ONESHOT 194 { SA_ONESHOT, "SA_ONESHOT" }, 195#endif 196#ifdef SA_SIGINFO 197 { SA_SIGINFO, "SA_SIGINFO" }, 198#endif 199#ifdef SA_RESETHAND 200 { SA_RESETHAND, "SA_RESETHAND" }, 201#endif 202#ifdef SA_ONSTACK 203 { SA_ONSTACK, "SA_ONSTACK" }, 204#endif 205#ifdef SA_NODEFER 206 { SA_NODEFER, "SA_NODEFER" }, 207#endif 208#ifdef SA_NOCLDSTOP 209 { SA_NOCLDSTOP, "SA_NOCLDSTOP" }, 210#endif 211#ifdef SA_NOCLDWAIT 212 { SA_NOCLDWAIT, "SA_NOCLDWAIT" }, 213#endif 214#ifdef _SA_BSDCALL 215 { _SA_BSDCALL, "_SA_BSDCALL" }, 216#endif 217 { 0, NULL }, 218}; 219 220static struct xlat sigprocmaskcmds[] = { 221 { SIG_BLOCK, "SIG_BLOCK" }, 222 { SIG_UNBLOCK, "SIG_UNBLOCK" }, 223 { SIG_SETMASK, "SIG_SETMASK" }, 224#ifdef SIG_SETMASK32 225 { SIG_SETMASK32,"SIG_SETMASK32" }, 226#endif 227 { 0, NULL }, 228}; 229 230#endif /* HAVE_SIGACTION */ 231 232/* Anonymous realtime signals. */ 233/* Under glibc 2.1, SIGRTMIN et al are functions, but __SIGRTMIN is a 234 constant. This is what we want. Otherwise, just use SIGRTMIN. */ 235#ifdef SIGRTMIN 236#ifndef __SIGRTMIN 237#define __SIGRTMIN SIGRTMIN 238#define __SIGRTMAX SIGRTMAX /* likewise */ 239#endif 240#endif 241 242char * 243signame(sig) 244int sig; 245{ 246 static char buf[30]; 247 if (sig < nsignals) { 248 return signalent[sig]; 249#ifdef SIGRTMIN 250 } else if (sig >= __SIGRTMIN && sig <= __SIGRTMAX) { 251 sprintf(buf, "SIGRT_%ld", (long)(sig - __SIGRTMIN)); 252 return buf; 253#endif /* SIGRTMIN */ 254 } else { 255 sprintf(buf, "%d", sig); 256 return buf; 257 } 258} 259 260#ifndef UNIXWARE 261static void 262long_to_sigset(l, s) 263long l; 264sigset_t *s; 265{ 266 sigemptyset(s); 267 *(long *)s = l; 268} 269#endif 270 271static int 272copy_sigset_len(tcp, addr, s, len) 273struct tcb *tcp; 274long addr; 275sigset_t *s; 276int len; 277{ 278 if (len > sizeof(*s)) 279 len = sizeof(*s); 280 sigemptyset(s); 281 if (umoven(tcp, addr, len, (char *)s) < 0) 282 return -1; 283 return 0; 284} 285 286#ifdef LINUX 287/* Original sigset is unsigned long */ 288#define copy_sigset(tcp, addr, s) copy_sigset_len(tcp, addr, s, sizeof(long)) 289#else 290#define copy_sigset(tcp, addr, s) copy_sigset_len(tcp, addr, s, sizeof(sigset_t)) 291#endif 292 293static char * 294sprintsigmask(s, mask, rt) 295char *s; 296sigset_t *mask; 297int rt; /* set might include realtime sigs */ 298{ 299 int i, nsigs; 300 int maxsigs; 301 char *format; 302 static char outstr[256]; 303 304 strcpy(outstr, s); 305 s = outstr + strlen(outstr); 306 nsigs = 0; 307 maxsigs = nsignals; 308#ifdef __SIGRTMAX 309 if (rt) 310 maxsigs = __SIGRTMAX; /* instead */ 311#endif 312 for (i = 1; i < maxsigs; i++) { 313 if (sigismember(mask, i) == 1) 314 nsigs++; 315 } 316 if (nsigs >= nsignals * 2 / 3) { 317 *s++ = '~'; 318 for (i = 1; i < maxsigs; i++) { 319 switch (sigismember(mask, i)) { 320 case 1: 321 sigdelset(mask, i); 322 break; 323 case 0: 324 sigaddset(mask, i); 325 break; 326 } 327 } 328 } 329 format = "%s"; 330 *s++ = '['; 331 for (i = 1; i < maxsigs; i++) { 332 if (sigismember(mask, i) == 1) { 333 /* real-time signals on solaris don't have 334 * signalent entries 335 */ 336 if (i < nsignals) { 337 sprintf(s, format, signalent[i] + 3); 338 } 339 else { 340 char tsig[32]; 341 sprintf(tsig, "%u", i); 342 sprintf(s, format, tsig); 343 } 344 s += strlen(s); 345 format = " %s"; 346 } 347 } 348 *s++ = ']'; 349 *s = '\0'; 350 return outstr; 351} 352 353static void 354printsigmask(mask, rt) 355sigset_t *mask; 356int rt; 357{ 358 tprintf("%s", sprintsigmask("", mask, rt)); 359} 360 361void 362printsignal(nr) 363int nr; 364{ 365 tprintf(signame(nr)); 366} 367 368/* 369 * Check process TCP for the disposition of signal SIG. 370 * Return 1 if the process would somehow manage to survive signal SIG, 371 * else return 0. This routine will never be called with SIGKILL. 372 */ 373int 374sigishandled(tcp, sig) 375struct tcb *tcp; 376int sig; 377{ 378#ifdef LINUX 379 int sfd; 380 char sname[32]; 381 char buf[2048]; 382 char *s; 383 int i; 384 /* We also need to handle RT signals */ 385 unsigned long long signalled, blocked, ignored, caught; 386#endif 387#ifdef SVR4 388 /* 389 * Since procfs doesn't interfere with wait I think it is safe 390 * to punt on this question. If not, the information is there. 391 */ 392 return 1; 393#else /* !SVR4 */ 394 switch (sig) { 395 case SIGCONT: 396 case SIGSTOP: 397 case SIGTSTP: 398 case SIGTTIN: 399 case SIGTTOU: 400 case SIGCHLD: 401 case SIGIO: 402#if defined(SIGURG) && SIGURG != SIGIO 403 case SIGURG: 404#endif 405 case SIGWINCH: 406 /* Gloria Gaynor says ... */ 407 return 1; 408 default: 409 break; 410 } 411#endif /* !SVR4 */ 412#ifdef LINUX 413 414 /* This is incredibly costly but it's worth it. */ 415 /* NOTE: LinuxThreads internally uses SIGRTMIN, SIGRTMIN + 1 and 416 SIGRTMIN + 2, so we can't use the obsolete /proc/%d/stat which 417 doesn't handle real-time signals). */ 418 sprintf(sname, "/proc/%d/status", tcp->pid); 419 if ((sfd = open(sname, O_RDONLY)) == -1) { 420 perror(sname); 421 return 1; 422 } 423 i = read(sfd, buf, sizeof(buf)); 424 buf[i] = '\0'; 425 close(sfd); 426 /* 427 * Skip the extraneous fields. We need to skip 428 * command name has any spaces in it. So be it. 429 */ 430 s = strstr(buf, "SigPnd:\t"); 431 432 if (!s) 433 { 434 fprintf(stderr, "/proc/pid/status format error\n"); 435 return 1; 436 } 437 438 while (*s && *s++ != '\t') 439 ; 440 s += sscanf(s, "%qx", &signalled); 441 while (*s && *s++ != '\t') 442 ; 443 s += sscanf(s, "%qx", &blocked); 444 while (*s && *s++ != '\t') 445 ; 446 s += sscanf(s, "%qx", &ignored); 447 while (*s && *s++ != '\t') 448 ; 449 s += sscanf(s, "%qx", &caught); 450 451#ifdef DEBUG 452 fprintf(stderr, "sigs: %08x %08x %08x %08x\n", 453 signalled, blocked, ignored, caught); 454#endif 455 if ((ignored & (1ULL << sig)) || (caught & (1ULL << sig))) 456 return 1; 457#endif /* LINUX */ 458 459#ifdef SUNOS4 460 void (*u_signal)(); 461 462 if (upeek(tcp->pid, uoff(u_signal[0]) + sig*sizeof(u_signal), 463 (long *) &u_signal) < 0) { 464 return 0; 465 } 466 if (u_signal != SIG_DFL) 467 return 1; 468#endif /* SUNOS4 */ 469 470 return 0; 471} 472 473#if defined(SUNOS4) || defined(FREEBSD) 474 475int 476sys_sigvec(tcp) 477struct tcb *tcp; 478{ 479 struct sigvec sv; 480 long addr; 481 482 if (entering(tcp)) { 483 printsignal(tcp->u_arg[0]); 484 tprintf(", "); 485 addr = tcp->u_arg[1]; 486 } else { 487 addr = tcp->u_arg[2]; 488 } 489 if (addr == 0) 490 tprintf("NULL"); 491 else if (!verbose(tcp)) 492 tprintf("%#lx", addr); 493 else if (umove(tcp, addr, &sv) < 0) 494 tprintf("{...}"); 495 else { 496 switch ((int) sv.sv_handler) { 497 case (int) SIG_ERR: 498 tprintf("{SIG_ERR}"); 499 break; 500 case (int) SIG_DFL: 501 tprintf("{SIG_DFL}"); 502 break; 503 case (int) SIG_IGN: 504 if (tcp->u_arg[0] == SIGTRAP) { 505 tcp->flags |= TCB_SIGTRAPPED; 506 kill(tcp->pid, SIGSTOP); 507 } 508 tprintf("{SIG_IGN}"); 509 break; 510 case (int) SIG_HOLD: 511 if (tcp->u_arg[0] == SIGTRAP) { 512 tcp->flags |= TCB_SIGTRAPPED; 513 kill(tcp->pid, SIGSTOP); 514 } 515 tprintf("SIG_HOLD"); 516 break; 517 default: 518 if (tcp->u_arg[0] == SIGTRAP) { 519 tcp->flags |= TCB_SIGTRAPPED; 520 kill(tcp->pid, SIGSTOP); 521 } 522 tprintf("{%#lx, ", (unsigned long) sv.sv_handler); 523 printsigmask(&sv.sv_mask, 0); 524 tprintf(", "); 525 if (!printflags(sigvec_flags, sv.sv_flags)) 526 tprintf("0"); 527 tprintf("}"); 528 } 529 } 530 if (entering(tcp)) 531 tprintf(", "); 532 return 0; 533} 534 535int 536sys_sigpause(tcp) 537struct tcb *tcp; 538{ 539 if (entering(tcp)) { /* WTA: UD had a bug here: he forgot the braces */ 540 sigset_t sigm; 541 long_to_sigset(tcp->u_arg[0], &sigm); 542 printsigmask(&sigm, 0); 543 } 544 return 0; 545} 546 547int 548sys_sigstack(tcp) 549struct tcb *tcp; 550{ 551 struct sigstack ss; 552 long addr; 553 554 if (entering(tcp)) 555 addr = tcp->u_arg[0]; 556 else 557 addr = tcp->u_arg[1]; 558 if (addr == 0) 559 tprintf("NULL"); 560 else if (umove(tcp, addr, &ss) < 0) 561 tprintf("%#lx", addr); 562 else { 563 tprintf("{ss_sp %#lx ", (unsigned long) ss.ss_sp); 564 tprintf("ss_onstack %s}", ss.ss_onstack ? "YES" : "NO"); 565 } 566 if (entering(tcp)) 567 tprintf(", "); 568 return 0; 569} 570 571int 572sys_sigcleanup(tcp) 573struct tcb *tcp; 574{ 575 return 0; 576} 577 578#endif /* SUNOS4 || FREEBSD */ 579 580#ifndef SVR4 581 582int 583sys_sigsetmask(tcp) 584struct tcb *tcp; 585{ 586 if (entering(tcp)) { 587 sigset_t sigm; 588 long_to_sigset(tcp->u_arg[0], &sigm); 589 printsigmask(&sigm, 0); 590#ifndef USE_PROCFS 591 if ((tcp->u_arg[0] & sigmask(SIGTRAP))) { 592 /* Mark attempt to block SIGTRAP */ 593 tcp->flags |= TCB_SIGTRAPPED; 594 /* Send unblockable signal */ 595 kill(tcp->pid, SIGSTOP); 596 } 597#endif /* !USE_PROCFS */ 598 } 599 else if (!syserror(tcp)) { 600 sigset_t sigm; 601 long_to_sigset(tcp->u_rval, &sigm); 602 tcp->auxstr = sprintsigmask("old mask ", &sigm, 0); 603 604 return RVAL_HEX | RVAL_STR; 605 } 606 return 0; 607} 608 609int 610sys_sigblock(tcp) 611struct tcb *tcp; 612{ 613 return sys_sigsetmask(tcp); 614} 615 616#endif /* !SVR4 */ 617 618#ifdef HAVE_SIGACTION 619 620#ifdef LINUX 621struct old_sigaction { 622 __sighandler_t __sa_handler; 623 unsigned long sa_mask; 624 unsigned long sa_flags; 625 void (*sa_restorer)(void); 626}; 627#define SA_HANDLER __sa_handler 628#endif /* LINUX */ 629 630#ifndef SA_HANDLER 631#define SA_HANDLER sa_handler 632#endif 633 634int 635sys_sigaction(tcp) 636struct tcb *tcp; 637{ 638 long addr; 639#ifdef LINUX 640 sigset_t sigset; 641 struct old_sigaction sa; 642#else 643 struct sigaction sa; 644#endif 645 646 647 if (entering(tcp)) { 648 printsignal(tcp->u_arg[0]); 649 tprintf(", "); 650 addr = tcp->u_arg[1]; 651 } else 652 addr = tcp->u_arg[2]; 653 if (addr == 0) 654 tprintf("NULL"); 655 else if (!verbose(tcp)) 656 tprintf("%#lx", addr); 657 else if (umove(tcp, addr, &sa) < 0) 658 tprintf("{...}"); 659 else { 660 switch ((long) sa.SA_HANDLER) { 661 case (long) SIG_ERR: 662 tprintf("{SIG_ERR}"); 663 break; 664 case (long) SIG_DFL: 665 tprintf("{SIG_DFL}"); 666 break; 667 case (long) SIG_IGN: 668#ifndef USE_PROCFS 669 if (tcp->u_arg[0] == SIGTRAP) { 670 tcp->flags |= TCB_SIGTRAPPED; 671 kill(tcp->pid, SIGSTOP); 672 } 673#endif /* !USE_PROCFS */ 674 tprintf("{SIG_IGN}"); 675 break; 676 default: 677#ifndef USE_PROCFS 678 if (tcp->u_arg[0] == SIGTRAP) { 679 tcp->flags |= TCB_SIGTRAPPED; 680 kill(tcp->pid, SIGSTOP); 681 } 682#endif /* !USE_PROCFS */ 683 tprintf("{%#lx, ", (long) sa.SA_HANDLER); 684#ifndef LINUX 685 printsigmask (&sa.sa_mask, 0); 686#else 687 long_to_sigset(sa.sa_mask, &sigset); 688 printsigmask(&sigset, 0); 689#endif 690 tprintf(", "); 691 if (!printflags(sigact_flags, sa.sa_flags)) 692 tprintf("0"); 693 tprintf("}"); 694 } 695 } 696 if (entering(tcp)) 697 tprintf(", "); 698#ifdef LINUX 699 else 700 tprintf(", %#lx", (unsigned long) sa.sa_restorer); 701#endif 702 return 0; 703} 704 705int 706sys_signal(tcp) 707struct tcb *tcp; 708{ 709 if (entering(tcp)) { 710 printsignal(tcp->u_arg[0]); 711 tprintf(", "); 712 switch (tcp->u_arg[1]) { 713 case (int) SIG_ERR: 714 tprintf("SIG_ERR"); 715 break; 716 case (int) SIG_DFL: 717 tprintf("SIG_DFL"); 718 break; 719 case (int) SIG_IGN: 720#ifndef USE_PROCFS 721 if (tcp->u_arg[0] == SIGTRAP) { 722 tcp->flags |= TCB_SIGTRAPPED; 723 kill(tcp->pid, SIGSTOP); 724 } 725#endif /* !USE_PROCFS */ 726 tprintf("SIG_IGN"); 727 break; 728 default: 729#ifndef USE_PROCFS 730 if (tcp->u_arg[0] == SIGTRAP) { 731 tcp->flags |= TCB_SIGTRAPPED; 732 kill(tcp->pid, SIGSTOP); 733 } 734#endif /* !USE_PROCFS */ 735 tprintf("%#lx", tcp->u_arg[1]); 736 } 737 return 0; 738 } 739 else { 740 switch (tcp->u_rval) { 741 case (int) SIG_ERR: 742 tcp->auxstr = "SIG_ERR"; break; 743 case (int) SIG_DFL: 744 tcp->auxstr = "SIG_DFL"; break; 745 case (int) SIG_IGN: 746 tcp->auxstr = "SIG_IGN"; break; 747 default: 748 tcp->auxstr = NULL; 749 } 750 return RVAL_HEX | RVAL_STR; 751 } 752} 753 754int 755sys_sighold(tcp) 756struct tcb *tcp; 757{ 758 if (entering(tcp)) { 759 printsignal(tcp->u_arg[0]); 760 } 761 return 0; 762} 763 764#endif /* HAVE_SIGACTION */ 765 766#ifdef LINUX 767 768int 769sys_sigreturn(tcp) 770struct tcb *tcp; 771{ 772#ifdef S390 773 long usp; 774 struct sigcontext_struct sc; 775 776 if (entering(tcp)) { 777 tcp->u_arg[0] = 0; 778 if (upeek(tcp->pid,PT_GPR15,&usp)<0) 779 return 0; 780 if (umove(tcp, usp+__SIGNAL_FRAMESIZE, &sc) < 0) 781 return 0; 782 tcp->u_arg[0] = 1; 783 memcpy(&tcp->u_arg[1],&sc.oldmask[0],sizeof(sigset_t)); 784 } else { 785 tcp->u_rval = tcp->u_error = 0; 786 if (tcp->u_arg[0] == 0) 787 return 0; 788 tcp->auxstr = sprintsigmask("mask now ",(sigset_t *)&tcp->u_arg[1]); 789 return RVAL_NONE | RVAL_STR; 790 } 791 return 0; 792#else 793#ifdef I386 794 long esp; 795 struct sigcontext_struct sc; 796 797 if (entering(tcp)) { 798 tcp->u_arg[0] = 0; 799 if (upeek(tcp->pid, 4*UESP, &esp) < 0) 800 return 0; 801 if (umove(tcp, esp, &sc) < 0) 802 return 0; 803 tcp->u_arg[0] = 1; 804 tcp->u_arg[1] = sc.oldmask; 805 } 806 else { 807 sigset_t sigm; 808 long_to_sigset(tcp->u_arg[1], &sigm); 809 tcp->u_rval = tcp->u_error = 0; 810 if (tcp->u_arg[0] == 0) 811 return 0; 812 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); 813 return RVAL_NONE | RVAL_STR; 814 } 815 return 0; 816#else /* !I386 */ 817#ifdef IA64 818 struct sigcontext sc; 819 long sp; 820 821 if (entering(tcp)) { 822 /* offset of sigcontext in the kernel's sigframe structure: */ 823# define SIGFRAME_SC_OFFSET 0x90 824 tcp->u_arg[0] = 0; 825 if (upeek(tcp->pid, PT_R12, &sp) < 0) 826 return 0; 827 if (umove(tcp, sp + 16 + SIGFRAME_SC_OFFSET, &sc) < 0) 828 return 0; 829 tcp->u_arg[0] = 1; 830 memcpy(tcp->u_arg + 1, &sc.sc_mask, sizeof(sc.sc_mask)); 831 } 832 else { 833 sigset_t sigm; 834 835 memcpy(&sigm, tcp->u_arg + 1, sizeof (sigm)); 836 tcp->u_rval = tcp->u_error = 0; 837 if (tcp->u_arg[0] == 0) 838 return 0; 839 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); 840 return RVAL_NONE | RVAL_STR; 841 } 842 return 0; 843#else /* !IA64 */ 844#ifdef POWERPC 845 long esp; 846 struct sigcontext_struct sc; 847 848 if (entering(tcp)) { 849 tcp->u_arg[0] = 0; 850 if (upeek(tcp->pid, 4*PT_R1, &esp) < 0) 851 return 0; 852 if (umove(tcp, esp, &sc) < 0) 853 return 0; 854 tcp->u_arg[0] = 1; 855 tcp->u_arg[1] = sc.oldmask; 856 } 857 else { 858 sigset_t sigm; 859 long_to_sigset(tcp->u_arg[1], &sigm); 860 tcp->u_rval = tcp->u_error = 0; 861 if (tcp->u_arg[0] == 0) 862 return 0; 863 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); 864 return RVAL_NONE | RVAL_STR; 865 } 866 return 0; 867#else /* !POWERPC */ 868#ifdef M68K 869 long usp; 870 struct sigcontext sc; 871 872 if (entering(tcp)) { 873 tcp->u_arg[0] = 0; 874 if (upeek(tcp->pid, 4*PT_USP, &usp) < 0) 875 return 0; 876 if (umove(tcp, usp, &sc) < 0) 877 return 0; 878 tcp->u_arg[0] = 1; 879 tcp->u_arg[1] = sc.sc_mask; 880 } 881 else { 882 sigset_t sigm; 883 long_to_sigset(tcp->u_arg[1], &sigm); 884 tcp->u_rval = tcp->u_error = 0; 885 if (tcp->u_arg[0] == 0) 886 return 0; 887 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); 888 return RVAL_NONE | RVAL_STR; 889 } 890 return 0; 891#else /* !M68K */ 892#ifdef ALPHA 893 long fp; 894 struct sigcontext_struct sc; 895 896 if (entering(tcp)) { 897 tcp->u_arg[0] = 0; 898 if (upeek(tcp->pid, REG_FP, &fp) < 0) 899 return 0; 900 if (umove(tcp, fp, &sc) < 0) 901 return 0; 902 tcp->u_arg[0] = 1; 903 tcp->u_arg[1] = sc.sc_mask; 904 } 905 else { 906 sigset_t sigm; 907 long_to_sigset(tcp->u_arg[1], &sigm); 908 tcp->u_rval = tcp->u_error = 0; 909 if (tcp->u_arg[0] == 0) 910 return 0; 911 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); 912 return RVAL_NONE | RVAL_STR; 913 } 914 return 0; 915#else 916#ifdef SPARC 917 long i1; 918 struct regs regs; 919 m_siginfo_t si; 920 921 if(ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 922 perror("sigreturn: PTRACE_GETREGS "); 923 return 0; 924 } 925 if(entering(tcp)) { 926 tcp->u_arg[0] = 0; 927 i1 = regs.r_o1; 928 if(umove(tcp, i1, &si) < 0) { 929 perror("sigreturn: umove "); 930 return 0; 931 } 932 tcp->u_arg[0] = 1; 933 tcp->u_arg[1] = si.si_mask; 934 } else { 935 sigset_t sigm; 936 long_to_sigset(tcp->u_arg[1], &sigm); 937 tcp->u_rval = tcp->u_error = 0; 938 if(tcp->u_arg[0] == 0) 939 return 0; 940 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); 941 return RVAL_NONE | RVAL_STR; 942 } 943 return 0; 944#else 945#ifdef MIPS 946 long sp; 947 struct sigcontext sc; 948 949 if(entering(tcp)) { 950 tcp->u_arg[0] = 0; 951 if (upeek(tcp->pid, REG_SP, &sp) < 0) 952 return 0; 953 if (umove(tcp, sp, &sc) < 0) 954 return 0; 955 tcp->u_arg[0] = 1; 956 tcp->u_arg[1] = sc.sc_sigset; 957 } else { 958 tcp->u_rval = tcp->u_error = 0; 959 if(tcp->u_arg[0] == 0) 960 return 0; 961 tcp->auxstr = sprintsigmask("mask now ", tcp->u_arg[1]); 962 return RVAL_NONE | RVAL_STR; 963 } 964 return 0; 965#else 966#ifdef HPPA 967#warning NO sys_sigreturn DECODE FOR HPPA 968 return 0; 969#endif /* HPPA */ 970#endif /* MIPS */ 971#endif /* SPARC */ 972#endif /* ALPHA */ 973#endif /* !M68K */ 974#endif /* !POWERPC */ 975#endif /* !IA64 */ 976#endif /* !I386 */ 977#endif /* S390 */ 978} 979 980int 981sys_siggetmask(tcp) 982struct tcb *tcp; 983{ 984 if (exiting(tcp)) { 985 sigset_t sigm; 986 long_to_sigset(tcp->u_rval, &sigm); 987 tcp->auxstr = sprintsigmask("mask ", &sigm, 0); 988 } 989 return RVAL_HEX | RVAL_STR; 990} 991 992int 993sys_sigsuspend(tcp) 994struct tcb *tcp; 995{ 996 if (entering(tcp)) { 997 sigset_t sigm; 998 long_to_sigset(tcp->u_arg[2], &sigm); 999#if 0 1000 /* first two are not really arguments, but print them anyway */ 1001 /* nevermind, they are an anachronism now, too bad... */ 1002 tprintf("%d, %#x, ", tcp->u_arg[0], tcp->u_arg[1]); 1003#endif 1004 printsigmask(&sigm, 0); 1005 } 1006 return 0; 1007} 1008 1009#endif /* LINUX */ 1010 1011#if defined(SVR4) || defined(FREEBSD) 1012 1013int 1014sys_sigsuspend(tcp) 1015struct tcb *tcp; 1016{ 1017 sigset_t sigset; 1018 1019 if (entering(tcp)) { 1020 if (umove(tcp, tcp->u_arg[0], &sigset) < 0) 1021 tprintf("[?]"); 1022 else 1023 printsigmask(&sigset, 0); 1024 } 1025 return 0; 1026} 1027#ifndef FREEBSD 1028static struct xlat ucontext_flags[] = { 1029 { UC_SIGMASK, "UC_SIGMASK" }, 1030 { UC_STACK, "UC_STACK" }, 1031 { UC_CPU, "UC_CPU" }, 1032#ifdef UC_FPU 1033 { UC_FPU, "UC_FPU" }, 1034#endif 1035#ifdef UC_INTR 1036 { UC_INTR, "UC_INTR" }, 1037#endif 1038 { 0, NULL }, 1039}; 1040#endif /* !FREEBSD */ 1041#endif /* SVR4 || FREEBSD */ 1042 1043#if defined SVR4 || defined LINUX || defined FREEBSD 1044#if defined LINUX && !defined SS_ONSTACK 1045#define SS_ONSTACK 1 1046#define SS_DISABLE 2 1047#if __GLIBC_MINOR__ == 0 1048typedef struct 1049{ 1050 __ptr_t ss_sp; 1051 int ss_flags; 1052 size_t ss_size; 1053} stack_t; 1054#endif 1055#endif 1056#ifdef FREEBSD 1057#define stack_t struct sigaltstack 1058#endif 1059 1060static struct xlat sigaltstack_flags[] = { 1061 { SS_ONSTACK, "SS_ONSTACK" }, 1062 { SS_DISABLE, "SS_DISABLE" }, 1063 { 0, NULL }, 1064}; 1065#endif 1066 1067#ifdef SVR4 1068static void 1069printcontext(tcp, ucp) 1070struct tcb *tcp; 1071ucontext_t *ucp; 1072{ 1073 tprintf("{"); 1074 if (!abbrev(tcp)) { 1075 tprintf("uc_flags="); 1076 if (!printflags(ucontext_flags, ucp->uc_flags)) 1077 tprintf("0"); 1078 tprintf(", uc_link=%#lx, ", (unsigned long) ucp->uc_link); 1079 } 1080 tprintf("uc_sigmask="); 1081 printsigmask(&ucp->uc_sigmask, 0); 1082 if (!abbrev(tcp)) { 1083 tprintf(", uc_stack={ss_sp=%#lx, ss_size=%d, ss_flags=", 1084 (unsigned long) ucp->uc_stack.ss_sp, 1085 ucp->uc_stack.ss_size); 1086 if (!printflags(sigaltstack_flags, ucp->uc_stack.ss_flags)) 1087 tprintf("0"); 1088 tprintf("}"); 1089 } 1090 tprintf(", ...}"); 1091} 1092 1093int 1094sys_getcontext(tcp) 1095struct tcb *tcp; 1096{ 1097 ucontext_t uc; 1098 1099 if (exiting(tcp)) { 1100 if (tcp->u_error) 1101 tprintf("%#lx", tcp->u_arg[0]); 1102 else if (!tcp->u_arg[0]) 1103 tprintf("NULL"); 1104 else if (umove(tcp, tcp->u_arg[0], &uc) < 0) 1105 tprintf("{...}"); 1106 else 1107 printcontext(tcp, &uc); 1108 } 1109 return 0; 1110} 1111 1112int 1113sys_setcontext(tcp) 1114struct tcb *tcp; 1115{ 1116 ucontext_t uc; 1117 1118 if (entering(tcp)) { 1119 if (!tcp->u_arg[0]) 1120 tprintf("NULL"); 1121 else if (umove(tcp, tcp->u_arg[0], &uc) < 0) 1122 tprintf("{...}"); 1123 else 1124 printcontext(tcp, &uc); 1125 } 1126 else { 1127 tcp->u_rval = tcp->u_error = 0; 1128 if (tcp->u_arg[0] == 0) 1129 return 0; 1130 return RVAL_NONE; 1131 } 1132 return 0; 1133} 1134 1135#endif /* SVR4 */ 1136 1137#if defined(LINUX) || defined(FREEBSD) 1138 1139static int 1140print_stack_t(tcp, addr) 1141struct tcb *tcp; 1142unsigned long addr; 1143{ 1144 stack_t ss; 1145 if (umove(tcp, addr, &ss) < 0) 1146 return -1; 1147 tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp); 1148 if (!printflags(sigaltstack_flags, ss.ss_flags)) 1149 tprintf("0"); 1150 tprintf(", ss_size=%lu}", (unsigned long) ss.ss_size); 1151 return 0; 1152} 1153 1154int 1155sys_sigaltstack(tcp) 1156 struct tcb *tcp; 1157{ 1158 if (entering(tcp)) { 1159 if (tcp->u_arg[0] == 0) 1160 tprintf("NULL"); 1161 else if (print_stack_t(tcp, tcp->u_arg[0]) < 0) 1162 return -1; 1163 } 1164 else { 1165 tprintf(", "); 1166 if (tcp->u_arg[1] == 0) 1167 tprintf("NULL"); 1168 else if (print_stack_t(tcp, tcp->u_arg[1]) < 0) 1169 return -1; 1170 } 1171 return 0; 1172} 1173#endif 1174 1175#ifdef HAVE_SIGACTION 1176 1177int 1178sys_sigprocmask(tcp) 1179struct tcb *tcp; 1180{ 1181#ifdef ALPHA 1182 if (entering(tcp)) { 1183 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???"); 1184 tprintf(", "); 1185 printsigmask(tcp->u_arg[1], 0); 1186 } 1187 else if (!syserror(tcp)) { 1188 tcp->auxstr = sprintsigmask("old mask ", tcp->u_rval, 0); 1189 return RVAL_HEX | RVAL_STR; 1190 } 1191#else /* !ALPHA */ 1192 sigset_t sigset; 1193 1194 if (entering(tcp)) { 1195#ifdef SVR4 1196 if (tcp->u_arg[0] == 0) 1197 tprintf("0"); 1198 else 1199#endif /* SVR4 */ 1200 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???"); 1201 tprintf(", "); 1202 if (!tcp->u_arg[1]) 1203 tprintf("NULL, "); 1204 else if (copy_sigset(tcp, tcp->u_arg[1], &sigset) < 0) 1205 tprintf("%#lx, ", tcp->u_arg[1]); 1206 else { 1207 printsigmask(&sigset, 0); 1208 tprintf(", "); 1209 } 1210 } 1211 else { 1212 if (!tcp->u_arg[2]) 1213 tprintf("NULL"); 1214 else if (syserror(tcp)) 1215 tprintf("%#lx", tcp->u_arg[2]); 1216 else if (copy_sigset(tcp, tcp->u_arg[2], &sigset) < 0) 1217 tprintf("[?]"); 1218 else 1219 printsigmask(&sigset, 0); 1220 } 1221#endif /* !ALPHA */ 1222 return 0; 1223} 1224 1225#endif /* HAVE_SIGACTION */ 1226 1227int 1228sys_kill(tcp) 1229struct tcb *tcp; 1230{ 1231 if (entering(tcp)) { 1232 tprintf("%ld, %s", tcp->u_arg[0], signame(tcp->u_arg[1])); 1233 } 1234 return 0; 1235} 1236 1237int 1238sys_killpg(tcp) 1239struct tcb *tcp; 1240{ 1241 return sys_kill(tcp); 1242} 1243 1244int 1245sys_sigpending(tcp) 1246struct tcb *tcp; 1247{ 1248 sigset_t sigset; 1249 1250 if (exiting(tcp)) { 1251 if (syserror(tcp)) 1252 tprintf("%#lx", tcp->u_arg[0]); 1253 else if (copy_sigset(tcp, tcp->u_arg[0], &sigset) < 0) 1254 tprintf("[?]"); 1255 else 1256 printsigmask(&sigset, 0); 1257 } 1258 return 0; 1259} 1260 1261#ifdef LINUX 1262 1263 int 1264sys_rt_sigprocmask(tcp) 1265 struct tcb *tcp; 1266{ 1267 sigset_t sigset; 1268 1269 /* Note: arg[3] is the length of the sigset. */ 1270 if (entering(tcp)) { 1271 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???"); 1272 tprintf(", "); 1273 if (!tcp->u_arg[1]) 1274 tprintf("NULL, "); 1275 else if (copy_sigset_len(tcp, tcp->u_arg[1], &sigset, tcp->u_arg[3]) < 0) 1276 tprintf("%#lx, ", tcp->u_arg[1]); 1277 else { 1278 printsigmask(&sigset, 1); 1279 tprintf(", "); 1280 } 1281 } 1282 else { 1283 if (!tcp->u_arg[2]) 1284 1285 tprintf("NULL"); 1286 else if (syserror(tcp)) 1287 tprintf("%#lx", tcp->u_arg[2]); 1288 else if (copy_sigset_len(tcp, tcp->u_arg[2], &sigset, tcp->u_arg[3]) < 0) 1289 tprintf("[?]"); 1290 else 1291 printsigmask(&sigset, 1); 1292 tprintf(", %lu", tcp->u_arg[3]); 1293 } 1294 return 0; 1295} 1296 1297#if __GLIBC_MINOR__ < 1 1298/* Type for data associated with a signal. */ 1299typedef union sigval 1300{ 1301 int sival_int; 1302 void *sival_ptr; 1303} sigval_t; 1304 1305# define __SI_MAX_SIZE 128 1306# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3) 1307 1308typedef struct siginfo 1309{ 1310 int si_signo; /* Signal number. */ 1311 int si_errno; /* If non-zero, an errno value associated with 1312 this signal, as defined in <errno.h>. */ 1313 int si_code; /* Signal code. */ 1314 1315 union 1316 { 1317 int _pad[__SI_PAD_SIZE]; 1318 1319 /* kill(). */ 1320 struct 1321 { 1322 __pid_t si_pid; /* Sending process ID. */ 1323 __uid_t si_uid; /* Real user ID of sending process. */ 1324 } _kill; 1325 1326 /* POSIX.1b timers. */ 1327 struct 1328 { 1329 unsigned int _timer1; 1330 unsigned int _timer2; 1331 } _timer; 1332 1333 /* POSIX.1b signals. */ 1334 struct 1335 { 1336 __pid_t si_pid; /* Sending process ID. */ 1337 __uid_t si_uid; /* Real user ID of sending process. */ 1338 sigval_t si_sigval; /* Signal value. */ 1339 } _rt; 1340 1341 /* SIGCHLD. */ 1342 struct 1343 { 1344 __pid_t si_pid; /* Which child. */ 1345 int si_status; /* Exit value or signal. */ 1346 __clock_t si_utime; 1347 __clock_t si_stime; 1348 } _sigchld; 1349 1350 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */ 1351 struct 1352 { 1353 void *si_addr; /* Faulting insn/memory ref. */ 1354 } _sigfault; 1355 1356 /* SIGPOLL. */ 1357 struct 1358 { 1359 int si_band; /* Band event for SIGPOLL. */ 1360 int si_fd; 1361 } _sigpoll; 1362 } _sifields; 1363} siginfo_t; 1364#endif 1365 1366/* Structure describing the action to be taken when a signal arrives. */ 1367struct new_sigaction 1368{ 1369 union 1370 { 1371 __sighandler_t __sa_handler; 1372 void (*__sa_sigaction) (int, siginfo_t *, void *); 1373 } 1374 __sigaction_handler; 1375 unsigned long sa_flags; 1376 void (*sa_restorer) (void); 1377 unsigned long int sa_mask[2]; 1378}; 1379 1380 1381 int 1382sys_rt_sigaction(tcp) 1383 struct tcb *tcp; 1384{ 1385 struct new_sigaction sa; 1386 sigset_t sigset; 1387 long addr; 1388 1389 if (entering(tcp)) { 1390 printsignal(tcp->u_arg[0]); 1391 tprintf(", "); 1392 addr = tcp->u_arg[1]; 1393 } else 1394 addr = tcp->u_arg[2]; 1395 if (addr == 0) 1396 tprintf("NULL"); 1397 else if (!verbose(tcp)) 1398 tprintf("%#lx", addr); 1399 else if (umove(tcp, addr, &sa) < 0) 1400 tprintf("{...}"); 1401 else { 1402 switch ((long) sa.__sigaction_handler.__sa_handler) { 1403 case (long) SIG_ERR: 1404 tprintf("{SIG_ERR}"); 1405 break; 1406 case (long) SIG_DFL: 1407 tprintf("{SIG_DFL}"); 1408 break; 1409 case (long) SIG_IGN: 1410 tprintf("{SIG_IGN}"); 1411 break; 1412 default: 1413 tprintf("{%#lx, ", 1414 (long) sa.__sigaction_handler.__sa_handler); 1415 sigemptyset(&sigset); 1416#ifdef LINUXSPARC 1417 if (tcp->u_arg[4] <= sizeof(sigset)) 1418 memcpy(&sigset, &sa.sa_mask, tcp->u_arg[4]); 1419#else 1420 if (tcp->u_arg[3] <= sizeof(sigset)) 1421 memcpy(&sigset, &sa.sa_mask, tcp->u_arg[3]); 1422#endif 1423 else 1424 memcpy(&sigset, &sa.sa_mask, sizeof(sigset)); 1425 printsigmask(&sigset, 1); 1426 tprintf(", "); 1427 if (!printflags(sigact_flags, sa.sa_flags)) 1428 tprintf("0"); 1429 tprintf("}"); 1430 } 1431 } 1432 if (entering(tcp)) 1433 tprintf(", "); 1434 else 1435#ifdef LINUXSPARC 1436 tprintf(", %#lx, %lu", tcp->u_arg[3], tcp->u_arg[4]); 1437#elif defined(ALPHA) 1438 tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]); 1439#else 1440 tprintf(", %lu", addr = tcp->u_arg[3]); 1441#endif 1442 return 0; 1443} 1444 1445 int 1446sys_rt_sigpending(tcp) 1447 struct tcb *tcp; 1448{ 1449 sigset_t sigset; 1450 1451 if (exiting(tcp)) { 1452 if (syserror(tcp)) 1453 tprintf("%#lx", tcp->u_arg[0]); 1454 else if (copy_sigset_len(tcp, tcp->u_arg[0], 1455 &sigset, tcp->u_arg[1]) < 0) 1456 tprintf("[?]"); 1457 else 1458 printsigmask(&sigset, 1); 1459 } 1460 return 0; 1461} 1462 int 1463sys_rt_sigsuspend(tcp) 1464 struct tcb *tcp; 1465{ 1466 if (entering(tcp)) { 1467 sigset_t sigm; 1468 if (copy_sigset_len(tcp, tcp->u_arg[0], &sigm, tcp->u_arg[1]) < 0) 1469 tprintf("[?]"); 1470 else 1471 printsigmask(&sigm, 1); 1472 } 1473 return 0; 1474} 1475#ifndef ILL_ILLOPC 1476#define ILL_ILLOPC 1 /* illegal opcode */ 1477#define ILL_ILLOPN 2 /* illegal operand */ 1478#define ILL_ILLADR 3 /* illegal addressing mode */ 1479#define ILL_ILLTRP 4 /* illegal trap */ 1480#define ILL_PRVOPC 5 /* privileged opcode */ 1481#define ILL_PRVREG 6 /* privileged register */ 1482#define ILL_COPROC 7 /* coprocessor error */ 1483#define ILL_BADSTK 8 /* internal stack error */ 1484#define FPE_INTDIV 1 /* integer divide by zero */ 1485#define FPE_INTOVF 2 /* integer overflow */ 1486#define FPE_FLTDIV 3 /* floating point divide by zero */ 1487#define FPE_FLTOVF 4 /* floating point overflow */ 1488#define FPE_FLTUND 5 /* floating point underflow */ 1489#define FPE_FLTRES 6 /* floating point inexact result */ 1490#define FPE_FLTINV 7 /* floating point invalid operation */ 1491#define FPE_FLTSUB 8 /* subscript out of range */ 1492#define SEGV_MAPERR 1 /* address not mapped to object */ 1493#define SEGV_ACCERR 2 /* invalid permissions for mapped object */ 1494#define BUS_ADRALN 1 /* invalid address alignment */ 1495#define BUS_ADRERR 2 /* non-existant physical address */ 1496#define BUS_OBJERR 3 /* object specific hardware error */ 1497#define TRAP_BRKPT 1 /* process breakpoint */ 1498#define TRAP_TRACE 2 /* process trace trap */ 1499#define CLD_EXITED 1 /* child has exited */ 1500#define CLD_KILLED 2 /* child was killed */ 1501#define CLD_DUMPED 3 /* child terminated abnormally */ 1502#define CLD_TRAPPED 4 /* traced child has trapped */ 1503#define CLD_STOPPED 5 /* child has stopped */ 1504#define CLD_CONTINUED 6 /* stopped child has continued */ 1505#define POLL_IN 1 /* data input available */ 1506#define POLL_OUT 2 /* output buffers available */ 1507#define POLL_MSG 3 /* input message available */ 1508#define POLL_ERR 4 /* i/o error */ 1509#define POLL_PRI 5 /* high priority input available */ 1510#define POLL_HUP 6 /* device disconnected */ 1511#define SI_USER 0 /* sent by kill, sigsend, raise */ 1512#define SI_QUEUE -1 /* sent by sigqueue */ 1513#define SI_TIMER -2 /* sent by timer expiration */ 1514#define SI_MESGQ -3 /* sent by real time mesq state change */ 1515#define SI_ASYNCIO -4 /* sent by AIO completion */ 1516#else 1517#undef si_pid 1518#undef si_uid 1519#undef si_status 1520#undef si_utime 1521#undef si_stime 1522#undef si_value 1523#undef si_int 1524#undef si_ptr 1525#undef si_addr 1526#undef si_band 1527#undef si_fd 1528#endif 1529 1530static struct xlat sigill_flags[] = { 1531 {ILL_ILLOPC, "ILL_ILLOPC"}, 1532 {ILL_ILLOPN, "ILL_ILLOPN"}, 1533 {ILL_ILLADR, "ILL_ILLADR"}, 1534 {ILL_ILLTRP, "ILL_ILLTRP"}, 1535 {ILL_PRVOPC, "ILL_PRVOPC"}, 1536 {ILL_PRVREG, "ILL_PRVREG"}, 1537 {ILL_COPROC, "ILL_COPROC"}, 1538 {ILL_BADSTK, "ILL_BADSTK"}, 1539 {0, NULL} 1540}; 1541 1542static struct xlat sigfpe_flags[] = { 1543 {FPE_INTDIV, "FPE_INTDIV"}, 1544 {FPE_INTOVF, "FPE_INTOVF"}, 1545 {FPE_FLTDIV, "FPE_FLTDIV"}, 1546 {FPE_FLTOVF, "FPE_FLTOVF"}, 1547 {FPE_FLTUND, "FPE_FLTUND"}, 1548 {FPE_FLTRES, "FPE_FLTRES"}, 1549 {FPE_FLTINV, "FPE_FLTINV"}, 1550 {FPE_FLTSUB, "FPE_FLTSUB"}, 1551 {0, NULL} 1552}; 1553 1554static struct xlat sigsegv_flags[] = { 1555 {SEGV_MAPERR, "SEGV_MAPERR"}, 1556 {SEGV_ACCERR, "SEGV_ACCERR"}, 1557 {0, NULL} 1558}; 1559 1560static struct xlat sigbus_flags[] = { 1561 {BUS_ADRALN, "BUS_ADRALN"}, 1562 {BUS_ADRERR, "BUS_ADRERR"}, 1563 {BUS_OBJERR, "BUS_OBJERR"}, 1564 {0, NULL} 1565}; 1566 1567static struct xlat sigtrap_flags[] = { 1568 {TRAP_BRKPT, "TRAP_BRKPT"}, 1569 {TRAP_TRACE, "TRAP_TRACE"}, 1570 {0, NULL} 1571}; 1572 1573static struct xlat sigchld_flags[] = { 1574 {CLD_EXITED, "CLD_EXITED"}, 1575 {CLD_KILLED, "CLD_KILLED"}, 1576 {CLD_DUMPED, "CLD_DUMPED"}, 1577 {CLD_TRAPPED, "CLD_TRAPPED"}, 1578 {CLD_STOPPED, "CLD_STOPPED"}, 1579 {CLD_CONTINUED, "CLD_CONTINUED"}, 1580 {0, NULL} 1581}; 1582 1583static struct xlat sigpoll_flags[] = { 1584 {POLL_IN, "POLL_IN"}, 1585 {POLL_OUT, "POLL_OUT"}, 1586 {POLL_MSG, "POLL_MSG"}, 1587 {POLL_ERR, "POLL_ERR"}, 1588 {POLL_PRI, "POLL_PRI"}, 1589 {POLL_HUP, "POLL_HUP"}, 1590 {0, NULL} 1591}; 1592 1593static struct xlat siginfo_flags[] = { 1594 {SI_USER, "SI_USER"}, 1595 {SI_QUEUE, "SI_QUEUE"}, 1596 {SI_TIMER, "SI_TIMER"}, 1597 {SI_MESGQ, "SI_MESGQ"}, 1598 {SI_ASYNCIO, "SI_ASYNCIO"}, 1599 {0, NULL} 1600}; 1601 1602 static void 1603printsiginfo(tcp, si) 1604 struct tcb *tcp; 1605 siginfo_t *si; 1606{ 1607 tprintf("{si_signo="); 1608 printsignal(si->si_signo); 1609 tprintf(", si_errno=%d, si_code=", si->si_errno); 1610 switch(si->si_signo) 1611 { 1612 case SIGILL: 1613 if (!printflags(sigill_flags, si->si_code)) 1614 tprintf("%d /* ILL_??? */", si->si_code); 1615 tprintf(", si_addr=%lx", 1616 (unsigned long) si->_sifields._sigfault.si_addr); 1617 break; 1618 case SIGFPE: 1619 if (!printflags(sigfpe_flags, si->si_code)) 1620 tprintf("%d /* FPE_??? */", si->si_code); 1621 tprintf(", si_addr=%lx", 1622 (unsigned long) si->_sifields._sigfault.si_addr); 1623 break; 1624 case SIGSEGV: 1625 if (!printflags(sigsegv_flags, si->si_code)) 1626 tprintf("%d /* SEGV_??? */", si->si_code); 1627 tprintf(", si_addr=%lx", 1628 (unsigned long) si->_sifields._sigfault.si_addr); 1629 break; 1630 case SIGBUS: 1631 if (!printflags(sigbus_flags, si->si_code)) 1632 tprintf("%d /* BUS_??? */", si->si_code); 1633 tprintf(", si_addr=%lx", 1634 (unsigned long) si->_sifields._sigfault.si_addr); 1635 break; 1636 case SIGTRAP: 1637 if (!printflags(sigtrap_flags, si->si_code)) 1638 tprintf("%d /* TRAP_??? */", si->si_code); 1639 break; 1640 case SIGCHLD: 1641 if (!printflags(sigchld_flags, si->si_code)) 1642 tprintf("%d /* CLD_??? */", si->si_code); 1643 if (!verbose(tcp)) 1644 tprintf(", ..."); 1645 else 1646 tprintf(", si_pid=%d, si_uid=%d, si_status=%d, si_utime=%lu, si_stime=%lu", 1647 si->_sifields._kill.si_pid, 1648 si->_sifields._kill.si_uid, 1649 si->_sifields._sigchld.si_status, 1650 si->_sifields._sigchld.si_utime, 1651 si->_sifields._sigchld.si_stime); 1652 break; 1653 case SIGPOLL: 1654 if (!printflags(sigpoll_flags, si->si_code)) 1655 tprintf("%d /* POLL_??? */", si->si_code); 1656 if (si->si_code == POLL_IN 1657 || si->si_code == POLL_OUT 1658 || si->si_code == POLL_MSG) 1659 tprintf(", si_bind=%lu, si_fd=%d", 1660 (unsigned long) si->_sifields._sigpoll.si_band, 1661 si->_sifields._sigpoll.si_fd); 1662 break; 1663 default: 1664 if (!printflags(siginfo_flags, si->si_code)) 1665 tprintf("%d /* SI_??? */", si->si_code); 1666 tprintf(", si_pid=%lu, si_uid=%lu, si_value={", 1667 (unsigned long) si->_sifields._rt.si_pid, 1668 (unsigned long) si->_sifields._rt.si_uid); 1669 if (!verbose(tcp)) 1670 tprintf("..."); 1671 else { 1672 tprintf("sival_int=%u, sival_ptr=%#lx", 1673 si->_sifields._rt.si_sigval.sival_int, 1674 (unsigned long) si->_sifields._rt.si_sigval.sival_ptr); 1675 } 1676 tprintf("}"); 1677 break; 1678 } 1679 tprintf("}"); 1680} 1681 1682 int 1683sys_rt_sigqueueinfo(tcp) 1684 struct tcb *tcp; 1685{ 1686 if (entering(tcp)) { 1687 siginfo_t si; 1688 tprintf("%lu, ", tcp->u_arg[0]); 1689 printsignal(tcp->u_arg[1]); 1690 tprintf(", "); 1691 if (umove(tcp, tcp->u_arg[2], &si) < 0) 1692 tprintf("%#lx", tcp->u_arg[2]); 1693 else 1694 printsiginfo(&si); 1695 } 1696 return 0; 1697} 1698 1699int sys_rt_sigtimedwait(tcp) 1700 struct tcb *tcp; 1701{ 1702 if (entering(tcp)) { 1703 sigset_t sigset; 1704 1705 if (copy_sigset_len(tcp, tcp->u_arg[0], 1706 &sigset, tcp->u_arg[3]) < 0) 1707 tprintf("[?]"); 1708 else 1709 printsigmask(&sigset, 1); 1710 tprintf(", "); 1711 } 1712 else { 1713 if (syserror(tcp)) 1714 tprintf("%#lx", tcp->u_arg[0]); 1715 else { 1716 siginfo_t si; 1717 if (umove(tcp, tcp->u_arg[1], &si) < 0) 1718 tprintf("%#lx", tcp->u_arg[1]); 1719 else 1720 printsiginfo(&si); 1721 /* XXX For now */ 1722 tprintf(", %#lx", tcp->u_arg[2]); 1723 tprintf(", %d", (int) tcp->u_arg[3]); 1724 } 1725 } 1726 return 0; 1727}; 1728 1729#endif /* LINUX */ 1730 1731