]> granicus.if.org Git - strace/blob - signal.c
7f39fe9a61923749205ad45c2004f7aedc4813cc
[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  *      $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
82 typedef struct {
83         struct regs             si_regs;
84         int                     si_mask;
85 } m_siginfo_t;
86 #elif !defined(IA64) && !defined(X86_64)
87 #include <asm/sigcontext.h>
88 #endif /* SPARC */
89 #else /* !HAVE_ASM_SIGCONTEXT_H */
90 #ifdef I386
91 struct 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
117 struct 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
141 char *signalent0[] = {
142 #include "signalent.h"
143 };
144 int nsignals0 = sizeof signalent0 / sizeof signalent0[0];
145
146 #if SUPPORTED_PERSONALITIES >= 2
147 char *signalent1[] = {
148 #include "signalent1.h"
149 };
150 int nsignals1 = sizeof signalent1 / sizeof signalent1[0];
151 #endif /* SUPPORTED_PERSONALITIES >= 2 */
152
153 #if SUPPORTED_PERSONALITIES >= 3
154 char *signalent2[] = {
155 #include "signalent2.h"
156 };
157 int nsignals2 = sizeof signalent2 / sizeof signalent2[0];
158 #endif /* SUPPORTED_PERSONALITIES >= 3 */
159
160 char **signalent;
161 int nsignals;
162
163 #if defined(SUNOS4) || defined(FREEBSD)
164
165 static 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
177 static 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
220 static 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
242 char *
243 signame(sig)
244 int 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
261 static void
262 long_to_sigset(l, s)
263 long l;
264 sigset_t *s;
265 {
266         sigemptyset(s);
267         *(long *)s = l;
268 }
269 #endif
270
271 static int
272 copy_sigset_len(tcp, addr, s, len)
273 struct tcb *tcp;
274 long addr;
275 sigset_t *s;
276 int 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
293 static char *
294 sprintsigmask(s, mask, rt)
295 char *s;
296 sigset_t *mask;
297 int 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
353 static void
354 printsigmask(mask, rt)
355 sigset_t *mask;
356 int rt;
357 {
358         tprintf("%s", sprintsigmask("", mask, rt));
359 }
360
361 void
362 printsignal(nr)
363 int nr;
364 {
365         tprintf(signame(nr));
366 }
367
368 #ifdef LINUX
369
370 #ifndef ILL_ILLOPC
371 #define ILL_ILLOPC      1       /* illegal opcode */
372 #define ILL_ILLOPN      2       /* illegal operand */
373 #define ILL_ILLADR      3       /* illegal addressing mode */
374 #define ILL_ILLTRP      4       /* illegal trap */
375 #define ILL_PRVOPC      5       /* privileged opcode */
376 #define ILL_PRVREG      6       /* privileged register */
377 #define ILL_COPROC      7       /* coprocessor error */
378 #define ILL_BADSTK      8       /* internal stack error */
379 #define FPE_INTDIV      1       /* integer divide by zero */
380 #define FPE_INTOVF      2       /* integer overflow */
381 #define FPE_FLTDIV      3       /* floating point divide by zero */
382 #define FPE_FLTOVF      4       /* floating point overflow */
383 #define FPE_FLTUND      5       /* floating point underflow */
384 #define FPE_FLTRES      6       /* floating point inexact result */
385 #define FPE_FLTINV      7       /* floating point invalid operation */
386 #define FPE_FLTSUB      8       /* subscript out of range */
387 #define SEGV_MAPERR     1       /* address not mapped to object */
388 #define SEGV_ACCERR     2       /* invalid permissions for mapped object */
389 #define BUS_ADRALN      1       /* invalid address alignment */
390 #define BUS_ADRERR      2       /* non-existant physical address */
391 #define BUS_OBJERR      3       /* object specific hardware error */
392 #define TRAP_BRKPT      1       /* process breakpoint */
393 #define TRAP_TRACE      2       /* process trace trap */
394 #define CLD_EXITED      1       /* child has exited */
395 #define CLD_KILLED      2       /* child was killed */
396 #define CLD_DUMPED      3       /* child terminated abnormally */
397 #define CLD_TRAPPED     4       /* traced child has trapped */
398 #define CLD_STOPPED     5       /* child has stopped */
399 #define CLD_CONTINUED   6       /* stopped child has continued */
400 #define POLL_IN         1       /* data input available */
401 #define POLL_OUT        2       /* output buffers available */
402 #define POLL_MSG        3       /* input message available */
403 #define POLL_ERR        4       /* i/o error */
404 #define POLL_PRI        5       /* high priority input available */
405 #define POLL_HUP        6       /* device disconnected */
406 #define SI_USER         0       /* sent by kill, sigsend, raise */
407 #define SI_QUEUE        -1      /* sent by sigqueue */
408 #define SI_TIMER        -2      /* sent by timer expiration */
409 #define SI_MESGQ        -3      /* sent by real time mesq state change */
410 #define SI_ASYNCIO      -4      /* sent by AIO completion */
411 #endif
412
413 #if __GLIBC_MINOR__ < 1
414 /* Type for data associated with a signal.  */
415 typedef union sigval
416 {
417         int sival_int;
418         void *sival_ptr;
419 } sigval_t;
420
421 # define __SI_MAX_SIZE     128
422 # define __SI_PAD_SIZE     ((__SI_MAX_SIZE / sizeof (int)) - 3)
423
424 typedef struct siginfo
425 {
426         int si_signo;               /* Signal number.  */
427         int si_errno;               /* If non-zero, an errno value associated with
428                                                                    this signal, as defined in <errno.h>.  */
429         int si_code;                /* Signal code.  */
430
431         union
432         {
433                 int _pad[__SI_PAD_SIZE];
434
435                 /* kill().  */
436                 struct
437                 {
438                         __pid_t si_pid;     /* Sending process ID.  */
439                         __uid_t si_uid;     /* Real user ID of sending process.  */
440                 } _kill;
441
442                 /* POSIX.1b timers.  */
443                 struct
444                 {
445                         unsigned int _timer1;
446                         unsigned int _timer2;
447                 } _timer;
448
449                 /* POSIX.1b signals.  */
450                 struct
451                 {
452                         __pid_t si_pid;     /* Sending process ID.  */
453                         __uid_t si_uid;     /* Real user ID of sending process.  */
454                         sigval_t si_sigval; /* Signal value.  */
455                 } _rt;
456
457                 /* SIGCHLD.  */
458                 struct
459                 {
460                         __pid_t si_pid;     /* Which child.  */
461                         int si_status;      /* Exit value or signal.  */
462                         __clock_t si_utime;
463                         __clock_t si_stime;
464                 } _sigchld;
465
466                 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS.  */
467                 struct
468                 {
469                         void *si_addr;      /* Faulting insn/memory ref.  */
470                 } _sigfault;
471
472                 /* SIGPOLL.  */
473                 struct
474                 {
475                         int si_band;        /* Band event for SIGPOLL.  */
476                         int si_fd;
477                 } _sigpoll;
478         } _sifields;
479 } siginfo_t;
480
481 #define si_pid          _sifields._kill.si_pid
482 #define si_uid          _sifields._kill.si_uid
483 #define si_status       _sifields._sigchld.si_status
484 #define si_utime        _sifields._sigchld.si_utime
485 #define si_stime        _sifields._sigchld.si_stime
486 #define si_value        _sifields._rt.si_sigval
487 #define si_int          _sifields._rt.si_sigval.sival_int
488 #define si_ptr          _sifields._rt.si_sigval.sival_ptr
489 #define si_addr         _sifields._sigfault.si_addr
490 #define si_band         _sifields._sigpoll.si_band
491 #define si_fd           _sifields._sigpoll.si_fd
492
493 #endif
494
495 #endif
496
497 #if defined (SVR4) || defined (LINUX)
498
499 static struct xlat siginfo_codes[] = {
500 #ifdef SI_NOINFO
501         { SI_NOINFO,    "SI_NOINFO"     },
502 #endif
503 #ifdef SI_USER
504         { SI_USER,      "SI_USER"       },
505 #endif
506 #ifdef SI_LWP
507         { SI_LWP,       "SI_LWP"        },
508 #endif
509 #ifdef SI_QUEUE
510         { SI_QUEUE,     "SI_QUEUE"      },
511 #endif
512 #ifdef SI_TIMER
513         { SI_TIMER,     "SI_TIMER"      },
514 #endif
515 #ifdef SI_ASYNCIO
516         { SI_ASYNCIO,   "SI_ASYNCIO"    },
517 #endif
518 #ifdef SI_MESGQ
519         { SI_MESGQ,     "SI_MESGQ"      },
520 #endif
521         { 0,            NULL            },
522 };
523
524 static struct xlat sigill_codes[] = {
525         { ILL_ILLOPC,   "ILL_ILLOPC"    },
526         { ILL_ILLOPN,   "ILL_ILLOPN"    },
527         { ILL_ILLADR,   "ILL_ILLADR"    },
528         { ILL_ILLTRP,   "ILL_ILLTRP"    },
529         { ILL_PRVOPC,   "ILL_PRVOPC"    },
530         { ILL_PRVREG,   "ILL_PRVREG"    },
531         { ILL_COPROC,   "ILL_COPROC"    },
532         { ILL_BADSTK,   "ILL_BADSTK"    },
533         { 0,            NULL            },
534 };
535
536 static struct xlat sigfpe_codes[] = {
537         { FPE_INTDIV,   "FPE_INTDIV"    },
538         { FPE_INTOVF,   "FPE_INTOVF"    },
539         { FPE_FLTDIV,   "FPE_FLTDIV"    },
540         { FPE_FLTOVF,   "FPE_FLTOVF"    },
541         { FPE_FLTUND,   "FPE_FLTUND"    },
542         { FPE_FLTRES,   "FPE_FLTRES"    },
543         { FPE_FLTINV,   "FPE_FLTINV"    },
544         { FPE_FLTSUB,   "FPE_FLTSUB"    },
545         { 0,            NULL            },
546 };
547
548 static struct xlat sigtrap_codes[] = {
549         { TRAP_BRKPT,   "TRAP_BRKPT"    },
550         { TRAP_TRACE,   "TRAP_TRACE"    },
551         { 0,            NULL            },
552 };
553
554 static struct xlat sigchld_codes[] = {
555         { CLD_EXITED,   "CLD_EXITED"    },
556         { CLD_KILLED,   "CLD_KILLED"    },
557         { CLD_DUMPED,   "CLD_DUMPED"    },
558         { CLD_TRAPPED,  "CLD_TRAPPED"   },
559         { CLD_STOPPED,  "CLD_STOPPED"   },
560         { CLD_CONTINUED,"CLD_CONTINUED" },
561         { 0,            NULL            },
562 };
563
564 static struct xlat sigpoll_codes[] = {
565         { POLL_IN,      "POLL_IN"       },
566         { POLL_OUT,     "POLL_OUT"      },
567         { POLL_MSG,     "POLL_MSG"      },
568         { POLL_ERR,     "POLL_ERR"      },
569         { POLL_PRI,     "POLL_PRI"      },
570         { POLL_HUP,     "POLL_HUP"      },
571         { 0,            NULL            },
572 };
573
574 static struct xlat sigprof_codes[] = {
575 #ifdef PROF_SIG
576         { PROF_SIG,     "PROF_SIG"      },
577 #endif
578         { 0,            NULL            },
579 };
580
581 #ifdef SIGEMT
582 static struct xlat sigemt_codes[] = {
583 #ifdef EMT_TAGOVF
584         { EMT_TAGOVF,   "EMT_TAGOVF"    },
585 #endif
586         { 0,            NULL            },
587 };
588 #endif
589
590 static struct xlat sigsegv_codes[] = {
591         { SEGV_MAPERR,  "SEGV_MAPERR"   },
592         { SEGV_ACCERR,  "SEGV_ACCERR"   },
593         { 0,            NULL            },
594 };
595
596 static struct xlat sigbus_codes[] = {
597         { BUS_ADRALN,   "BUS_ADRALN"    },
598         { BUS_ADRERR,   "BUS_ADRERR"    },
599         { BUS_OBJERR,   "BUS_OBJERR"    },
600         { 0,            NULL            },
601 };
602
603 void
604 printsiginfo(sip, verbose)
605 siginfo_t *sip;
606 int verbose;
607 {
608         char *code;
609
610         if (sip->si_signo == 0) {
611                 tprintf ("{}");
612                 return;
613         }
614         tprintf("{si_signo=");
615         printsignal(sip->si_signo);
616         code = xlookup(siginfo_codes, sip->si_code);
617         if (!code) {
618                 switch (sip->si_signo) {
619                 case SIGTRAP:
620                         code = xlookup(sigtrap_codes, sip->si_code);
621                         break;
622                 case SIGCHLD:
623                         code = xlookup(sigchld_codes, sip->si_code);
624                         break;
625                 case SIGPOLL:
626                         code = xlookup(sigpoll_codes, sip->si_code);
627                         break;
628                 case SIGPROF:
629                         code = xlookup(sigprof_codes, sip->si_code);
630                         break;
631                 case SIGILL:
632                         code = xlookup(sigill_codes, sip->si_code);
633                         break;
634 #ifdef SIGEMT
635                 case SIGEMT:
636                         code = xlookup(sigemt_codes, sip->si_code);
637                         break;
638 #endif
639                 case SIGFPE:
640                         code = xlookup(sigfpe_codes, sip->si_code);
641                         break;
642                 case SIGSEGV:
643                         code = xlookup(sigsegv_codes, sip->si_code);
644                         break;
645                 case SIGBUS:
646                         code = xlookup(sigbus_codes, sip->si_code);
647                         break;
648                 }
649         }
650         if (code)
651                 tprintf(", si_code=%s", code);
652         else
653                 tprintf(", si_code=%#x", sip->si_code);
654 #ifdef SI_NOINFO
655         if (sip->si_code != SI_NOINFO)
656 #endif
657         {
658                 if (sip->si_errno) {
659                         if (sip->si_errno < 0 || sip->si_errno >= nerrnos)
660                                 tprintf(", si_errno=%d", sip->si_errno);
661                         else
662                                 tprintf(", si_errno=%s",
663                                         errnoent[sip->si_errno]);
664                 }
665 #ifdef SI_FROMUSER
666                 if (SI_FROMUSER(sip)) {
667                         tprintf(", si_pid=%ld, si_uid=%ld",
668                                 sip->si_pid, sip->si_uid);
669 #ifdef SI_QUEUE
670                         switch (sip->si_code) {
671                         case SI_QUEUE:
672 #ifdef SI_TIMER
673                         case SI_TIMER:
674 #endif /* SI_QUEUE */
675                         case SI_ASYNCIO:
676 #ifdef SI_MESGQ
677                         case SI_MESGQ:
678 #endif /* SI_MESGQ */
679                                 tprintf(", si_value=%d",
680                                         sip->si_value.sival_int);
681                                 break;
682                         }
683 #endif /* SI_QUEUE */
684                 }
685                 else
686 #endif /* SI_FROMUSER */
687                 {
688                         switch (sip->si_signo) {
689                         case SIGCHLD:
690                                 tprintf(", si_pid=%ld, si_status=",
691                                         (long) sip->si_pid);
692                                 if (sip->si_code == CLD_EXITED)
693                                         tprintf("%d", sip->si_status);
694                                 else
695                                         printsignal(sip->si_status);
696 #if LINUX
697                                 if (!verbose)
698                                         tprintf(", ...");
699                                 else
700                                         tprintf(", si_utime=%lu, si_stime=%lu",
701                                                 sip->si_utime,
702                                                 sip->si_stime);
703 #endif
704                                 break;
705                         case SIGILL: case SIGFPE:
706                         case SIGSEGV: case SIGBUS:
707                                 tprintf(", si_addr=%#lx",
708                                         (unsigned long) sip->si_addr);
709                                 break;
710                         case SIGPOLL:
711                                 switch (sip->si_code) {
712                                 case POLL_IN: case POLL_OUT: case POLL_MSG:
713                                         tprintf(", si_band=%ld",
714                                                 (long) sip->si_band);
715                                         break;
716                                 }
717                                 break;
718 #ifdef LINUX
719                         default:
720                                 tprintf(", si_pid=%lu, si_uid=%lu, ",
721                                         (unsigned long) sip->si_pid,
722                                         (unsigned long) sip->si_uid);
723                                 if (!verbose)
724                                         tprintf("...");
725                                 else {
726                                         tprintf("si_value={int=%u, ptr=%#lx}",
727                                                 sip->si_int,
728                                                 (unsigned long) sip->si_ptr);
729                                 }
730 #endif
731                                 
732                         }
733                 }
734         }
735         tprintf("}");
736 }
737
738 #endif /* SVR4 || LINUX */
739
740 #ifdef LINUX
741
742 static void
743 parse_sigset_t (const char *str, sigset_t *set)
744 {
745         unsigned int digit;
746         int i;
747
748         sigemptyset(set);
749
750         for (i = _NSIG - 4; i >= 0; i -= 4, ++str) {
751                 if (*str >= 'a')
752                         digit = (*str - 'a') + 10;
753                 else
754                         digit = *str - '0';
755                 if (digit & 1)
756                         sigaddset(set, i + 1);
757                 if (digit & 2)
758                         sigaddset(set, i + 2);
759                 if (digit & 4)
760                         sigaddset(set, i + 3);
761                 if (digit & 8)
762                         sigaddset(set, i + 4);
763         }
764 }
765
766 #endif
767
768 /*
769  * Check process TCP for the disposition of signal SIG.
770  * Return 1 if the process would somehow manage to  survive signal SIG,
771  * else return 0.  This routine will never be called with SIGKILL.
772  */
773 int
774 sigishandled(tcp, sig)
775 struct tcb *tcp;
776 int sig;
777 {
778 #ifdef LINUX
779         int sfd;
780         char sname[32];
781         char buf[2048];
782         char *s;
783         int i;
784         sigset_t ignored, caught;
785 #endif
786 #ifdef SVR4
787         /*
788          * Since procfs doesn't interfere with wait I think it is safe
789          * to punt on this question.  If not, the information is there.
790          */
791         return 1;
792 #else /* !SVR4 */
793         switch (sig) {
794         case SIGCONT:
795         case SIGSTOP:
796         case SIGTSTP:
797         case SIGTTIN:
798         case SIGTTOU:
799         case SIGCHLD:
800         case SIGIO:
801 #if defined(SIGURG) && SIGURG != SIGIO
802         case SIGURG:
803 #endif
804         case SIGWINCH:
805                 /* Gloria Gaynor says ... */
806                 return 1;
807         default:
808                 break;
809         }
810 #endif /* !SVR4 */
811 #ifdef LINUX
812
813         /* This is incredibly costly but it's worth it. */
814         /* NOTE: LinuxThreads internally uses SIGRTMIN, SIGRTMIN + 1 and
815            SIGRTMIN + 2, so we can't use the obsolete /proc/%d/stat which
816            doesn't handle real-time signals). */
817         sprintf(sname, "/proc/%d/status", tcp->pid);
818         if ((sfd = open(sname, O_RDONLY)) == -1) {
819                 perror(sname);
820                 return 1;
821         }
822         i = read(sfd, buf, sizeof(buf));
823         buf[i] = '\0';
824         close(sfd);
825         /*
826          * Skip the extraneous fields. We need to skip
827          * command name has any spaces in it.  So be it.
828          */
829         s = strstr(buf, "SigIgn:\t");
830         if (!s)
831         {
832                 fprintf(stderr, "/proc/pid/status format error\n");
833                 return 1;
834         }
835         parse_sigset_t(s + 8, &ignored);
836
837         s = strstr(buf, "SigCgt:\t");
838         if (!s)
839         {
840                 fprintf(stderr, "/proc/pid/status format error\n");
841                 return 1;
842         }
843         parse_sigset_t(s + 8, &caught);
844
845 #ifdef DEBUG
846         fprintf(stderr, "sigs: %016qx %016qx (sig=%d)\n",
847                 *(long long *) &ignored, *(long long *) &caught, sig);
848 #endif
849         if (sigismember(&ignored, sig) || sigismember(&caught, sig))
850                 return 1;
851 #endif /* LINUX */
852
853 #ifdef SUNOS4
854         void (*u_signal)();
855
856         if (upeek(tcp->pid, uoff(u_signal[0]) + sig*sizeof(u_signal),
857             (long *) &u_signal) < 0) {
858                 return 0;
859         }
860         if (u_signal != SIG_DFL)
861                 return 1;
862 #endif /* SUNOS4 */
863
864         return 0;
865 }
866
867 #if defined(SUNOS4) || defined(FREEBSD)
868
869 int
870 sys_sigvec(tcp)
871 struct tcb *tcp;
872 {
873         struct sigvec sv;
874         long addr;
875
876         if (entering(tcp)) {
877                 printsignal(tcp->u_arg[0]);
878                 tprintf(", ");
879                 addr = tcp->u_arg[1];
880         } else {
881                 addr = tcp->u_arg[2];
882         }
883         if (addr == 0)
884                 tprintf("NULL");
885         else if (!verbose(tcp))
886                 tprintf("%#lx", addr);
887         else if (umove(tcp, addr, &sv) < 0)
888                 tprintf("{...}");
889         else {
890                 switch ((int) sv.sv_handler) {
891                 case (int) SIG_ERR:
892                         tprintf("{SIG_ERR}");
893                         break;
894                 case (int) SIG_DFL:
895                         tprintf("{SIG_DFL}");
896                         break;
897                 case (int) SIG_IGN:
898                         if (tcp->u_arg[0] == SIGTRAP) {
899                                 tcp->flags |= TCB_SIGTRAPPED;
900                                 kill(tcp->pid, SIGSTOP);
901                         }
902                         tprintf("{SIG_IGN}");
903                         break;
904                 case (int) SIG_HOLD:
905                         if (tcp->u_arg[0] == SIGTRAP) {
906                                 tcp->flags |= TCB_SIGTRAPPED;
907                                 kill(tcp->pid, SIGSTOP);
908                         }
909                         tprintf("SIG_HOLD");
910                         break;
911                 default:
912                         if (tcp->u_arg[0] == SIGTRAP) {
913                                 tcp->flags |= TCB_SIGTRAPPED;
914                                 kill(tcp->pid, SIGSTOP);
915                         }
916                         tprintf("{%#lx, ", (unsigned long) sv.sv_handler);
917                         printsigmask(&sv.sv_mask, 0);
918                         tprintf(", ");
919                         if (!printflags(sigvec_flags, sv.sv_flags))
920                                 tprintf("0");
921                         tprintf("}");
922                 }
923         }
924         if (entering(tcp))
925                 tprintf(", ");
926         return 0;
927 }
928
929 int
930 sys_sigpause(tcp)
931 struct tcb *tcp;
932 {
933         if (entering(tcp)) {    /* WTA: UD had a bug here: he forgot the braces */
934                 sigset_t sigm;
935                 long_to_sigset(tcp->u_arg[0], &sigm);
936                 printsigmask(&sigm, 0);
937         }
938         return 0;
939 }
940
941 int
942 sys_sigstack(tcp)
943 struct tcb *tcp;
944 {
945         struct sigstack ss;
946         long addr;
947
948         if (entering(tcp))
949                 addr = tcp->u_arg[0];
950         else
951                 addr = tcp->u_arg[1];
952         if (addr == 0)
953                 tprintf("NULL");
954         else if (umove(tcp, addr, &ss) < 0)
955                 tprintf("%#lx", addr);
956         else {
957                 tprintf("{ss_sp %#lx ", (unsigned long) ss.ss_sp);
958                 tprintf("ss_onstack %s}", ss.ss_onstack ? "YES" : "NO");
959         }
960         if (entering(tcp))
961                 tprintf(", ");
962         return 0;
963 }
964
965 int
966 sys_sigcleanup(tcp)
967 struct tcb *tcp;
968 {
969         return 0;
970 }
971
972 #endif /* SUNOS4 || FREEBSD */
973
974 #ifndef SVR4
975
976 int
977 sys_sigsetmask(tcp)
978 struct tcb *tcp;
979 {
980         if (entering(tcp)) {
981                 sigset_t sigm;
982                 long_to_sigset(tcp->u_arg[0], &sigm);
983                 printsigmask(&sigm, 0);
984 #ifndef USE_PROCFS
985                 if ((tcp->u_arg[0] & sigmask(SIGTRAP))) {
986                         /* Mark attempt to block SIGTRAP */
987                         tcp->flags |= TCB_SIGTRAPPED;
988                         /* Send unblockable signal */
989                         kill(tcp->pid, SIGSTOP);
990                 }
991 #endif /* !USE_PROCFS */                
992         }
993         else if (!syserror(tcp)) {
994                 sigset_t sigm;
995                 long_to_sigset(tcp->u_rval, &sigm);
996                 tcp->auxstr = sprintsigmask("old mask ", &sigm, 0);
997
998                 return RVAL_HEX | RVAL_STR;
999         }
1000         return 0;
1001 }
1002
1003 int
1004 sys_sigblock(tcp)
1005 struct tcb *tcp;
1006 {
1007         return sys_sigsetmask(tcp);
1008 }
1009
1010 #endif /* !SVR4 */
1011
1012 #ifdef HAVE_SIGACTION
1013
1014 #ifdef LINUX
1015 struct old_sigaction {
1016         __sighandler_t __sa_handler;
1017         unsigned long sa_mask;
1018         unsigned long sa_flags;
1019         void (*sa_restorer)(void);
1020 };
1021 #define SA_HANDLER __sa_handler
1022 #endif /* LINUX */
1023
1024 #ifndef SA_HANDLER                                                           
1025 #define SA_HANDLER sa_handler                                                
1026 #endif
1027
1028 int
1029 sys_sigaction(tcp)
1030 struct tcb *tcp;
1031 {
1032         long addr;
1033 #ifdef LINUX
1034         sigset_t sigset;
1035         struct old_sigaction sa;
1036 #else
1037         struct sigaction sa;
1038 #endif
1039
1040
1041         if (entering(tcp)) {
1042                 printsignal(tcp->u_arg[0]);
1043                 tprintf(", ");
1044                 addr = tcp->u_arg[1];
1045         } else
1046                 addr = tcp->u_arg[2];
1047         if (addr == 0)
1048                 tprintf("NULL");
1049         else if (!verbose(tcp))
1050                 tprintf("%#lx", addr);
1051         else if (umove(tcp, addr, &sa) < 0)
1052                 tprintf("{...}");
1053         else {
1054                 switch ((long) sa.SA_HANDLER) {
1055                 case (long) SIG_ERR:
1056                         tprintf("{SIG_ERR}");
1057                         break;
1058                 case (long) SIG_DFL:
1059                         tprintf("{SIG_DFL}");
1060                         break;
1061                 case (long) SIG_IGN:
1062 #ifndef USE_PROCFS
1063                         if (tcp->u_arg[0] == SIGTRAP) {
1064                                 tcp->flags |= TCB_SIGTRAPPED;
1065                                 kill(tcp->pid, SIGSTOP);
1066                         }
1067 #endif /* !USE_PROCFS */
1068                         tprintf("{SIG_IGN}");
1069                         break;
1070                 default:
1071 #ifndef USE_PROCFS
1072                         if (tcp->u_arg[0] == SIGTRAP) {
1073                                 tcp->flags |= TCB_SIGTRAPPED;
1074                                 kill(tcp->pid, SIGSTOP);
1075                         }
1076 #endif /* !USE_PROCFS */
1077                         tprintf("{%#lx, ", (long) sa.SA_HANDLER);
1078 #ifndef LINUX
1079                         printsigmask (&sa.sa_mask, 0);
1080 #else
1081                         long_to_sigset(sa.sa_mask, &sigset);
1082                         printsigmask(&sigset, 0);
1083 #endif
1084                         tprintf(", ");
1085                         if (!printflags(sigact_flags, sa.sa_flags))
1086                                 tprintf("0");
1087                         tprintf("}");
1088                 }
1089         }
1090         if (entering(tcp))
1091                 tprintf(", ");
1092 #ifdef LINUX
1093         else
1094                 tprintf(", %#lx", (unsigned long) sa.sa_restorer);
1095 #endif
1096         return 0;
1097 }
1098
1099 int
1100 sys_signal(tcp)
1101 struct tcb *tcp;
1102 {
1103         if (entering(tcp)) {
1104                 printsignal(tcp->u_arg[0]);
1105                 tprintf(", ");
1106                 switch (tcp->u_arg[1]) {
1107                 case (int) SIG_ERR:
1108                         tprintf("SIG_ERR");
1109                         break;
1110                 case (int) SIG_DFL:
1111                         tprintf("SIG_DFL");
1112                         break;
1113                 case (int) SIG_IGN:
1114 #ifndef USE_PROCFS
1115                         if (tcp->u_arg[0] == SIGTRAP) {
1116                                 tcp->flags |= TCB_SIGTRAPPED;
1117                                 kill(tcp->pid, SIGSTOP);
1118                         }
1119 #endif /* !USE_PROCFS */
1120                         tprintf("SIG_IGN");
1121                         break;
1122                 default:
1123 #ifndef USE_PROCFS
1124                         if (tcp->u_arg[0] == SIGTRAP) {
1125                                 tcp->flags |= TCB_SIGTRAPPED;
1126                                 kill(tcp->pid, SIGSTOP);
1127                         }
1128 #endif /* !USE_PROCFS */
1129                         tprintf("%#lx", tcp->u_arg[1]);
1130                 }
1131                 return 0;
1132         }
1133         else {
1134                 switch (tcp->u_rval) {
1135                     case (int) SIG_ERR:
1136                         tcp->auxstr = "SIG_ERR"; break;
1137                     case (int) SIG_DFL:
1138                         tcp->auxstr = "SIG_DFL"; break;
1139                     case (int) SIG_IGN:
1140                         tcp->auxstr = "SIG_IGN"; break;
1141                     default:
1142                         tcp->auxstr = NULL;
1143                 }
1144                 return RVAL_HEX | RVAL_STR;
1145         }
1146 }
1147
1148 int
1149 sys_sighold(tcp)
1150 struct tcb *tcp;
1151 {
1152         if (entering(tcp)) {
1153                 printsignal(tcp->u_arg[0]);
1154         }
1155         return 0;
1156 }
1157
1158 #endif /* HAVE_SIGACTION */
1159
1160 #ifdef LINUX
1161
1162 int
1163 sys_sigreturn(tcp)
1164 struct tcb *tcp;
1165 {
1166 #if defined(S390) || defined(S390X)
1167     long usp;
1168     struct sigcontext_struct sc;
1169
1170     if (entering(tcp)) {
1171             tcp->u_arg[0] = 0;
1172             if (upeek(tcp->pid,PT_GPR15,&usp)<0)
1173                     return 0;
1174             if (umove(tcp, usp+__SIGNAL_FRAMESIZE, &sc) < 0)
1175                     return 0;
1176             tcp->u_arg[0] = 1;
1177             memcpy(&tcp->u_arg[1],&sc.oldmask[0],sizeof(sigset_t));
1178     } else {
1179             tcp->u_rval = tcp->u_error = 0;
1180             if (tcp->u_arg[0] == 0)
1181                     return 0;
1182             tcp->auxstr = sprintsigmask("mask now ",(sigset_t *)&tcp->u_arg[1],0);
1183             return RVAL_NONE | RVAL_STR;
1184     }
1185     return 0;
1186 #else
1187 #ifdef I386
1188         long esp;
1189         struct sigcontext_struct sc;
1190
1191         if (entering(tcp)) {
1192                 tcp->u_arg[0] = 0;
1193                 if (upeek(tcp->pid, 4*UESP, &esp) < 0)
1194                         return 0;
1195                 if (umove(tcp, esp, &sc) < 0)
1196                         return 0;
1197                 tcp->u_arg[0] = 1;
1198                 tcp->u_arg[1] = sc.oldmask;
1199         }
1200         else {
1201                 sigset_t sigm;
1202                 long_to_sigset(tcp->u_arg[1], &sigm);
1203                 tcp->u_rval = tcp->u_error = 0;
1204                 if (tcp->u_arg[0] == 0)
1205                         return 0;
1206                 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1207                 return RVAL_NONE | RVAL_STR;
1208         }
1209         return 0;
1210 #else /* !I386 */
1211 #ifdef IA64
1212         struct sigcontext sc;
1213         long sp;
1214
1215         if (entering(tcp)) {
1216                 /* offset of sigcontext in the kernel's sigframe structure: */
1217 #               define SIGFRAME_SC_OFFSET       0x90
1218                 tcp->u_arg[0] = 0;
1219                 if (upeek(tcp->pid, PT_R12, &sp) < 0)
1220                         return 0;
1221                 if (umove(tcp, sp + 16 + SIGFRAME_SC_OFFSET, &sc) < 0)
1222                         return 0;
1223                 tcp->u_arg[0] = 1;
1224                 memcpy(tcp->u_arg + 1, &sc.sc_mask, sizeof(sc.sc_mask));
1225         }
1226         else {
1227                 sigset_t sigm;
1228
1229                 memcpy(&sigm, tcp->u_arg + 1, sizeof (sigm));
1230                 tcp->u_rval = tcp->u_error = 0;
1231                 if (tcp->u_arg[0] == 0)
1232                         return 0;
1233                 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1234                 return RVAL_NONE | RVAL_STR;
1235         }
1236         return 0;
1237 #else /* !IA64 */
1238 #ifdef POWERPC
1239        long esp;
1240        struct sigcontext_struct sc;
1241
1242        if (entering(tcp)) {
1243                    tcp->u_arg[0] = 0;
1244                    if (upeek(tcp->pid, 4*PT_R1, &esp) < 0)
1245                            return 0;
1246                    if (umove(tcp, esp, &sc) < 0)
1247                            return 0;
1248                    tcp->u_arg[0] = 1;
1249                    tcp->u_arg[1] = sc.oldmask;
1250        }
1251        else {
1252                    sigset_t sigm;
1253                    long_to_sigset(tcp->u_arg[1], &sigm);
1254                    tcp->u_rval = tcp->u_error = 0;
1255                    if (tcp->u_arg[0] == 0)
1256                            return 0;
1257                    tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1258                    return RVAL_NONE | RVAL_STR;
1259        }
1260        return 0;
1261 #else /* !POWERPC */
1262 #ifdef M68K
1263         long usp;
1264         struct sigcontext sc;
1265
1266         if (entering(tcp)) {
1267             tcp->u_arg[0] = 0;
1268             if (upeek(tcp->pid, 4*PT_USP, &usp) < 0)
1269                         return 0;
1270             if (umove(tcp, usp, &sc) < 0)
1271                         return 0;
1272             tcp->u_arg[0] = 1;
1273             tcp->u_arg[1] = sc.sc_mask;
1274         }
1275         else {
1276             sigset_t sigm;
1277             long_to_sigset(tcp->u_arg[1], &sigm);
1278             tcp->u_rval = tcp->u_error = 0;
1279             if (tcp->u_arg[0] == 0)
1280                         return 0;
1281             tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1282             return RVAL_NONE | RVAL_STR;
1283         }
1284         return 0;
1285 #else /* !M68K */
1286 #ifdef ALPHA
1287         long fp;
1288         struct sigcontext_struct sc;
1289
1290         if (entering(tcp)) {
1291             tcp->u_arg[0] = 0;
1292             if (upeek(tcp->pid, REG_FP, &fp) < 0)
1293                         return 0;
1294             if (umove(tcp, fp, &sc) < 0)
1295                         return 0;
1296             tcp->u_arg[0] = 1;
1297             tcp->u_arg[1] = sc.sc_mask;
1298         }
1299         else {
1300             sigset_t sigm;
1301             long_to_sigset(tcp->u_arg[1], &sigm);
1302             tcp->u_rval = tcp->u_error = 0;
1303             if (tcp->u_arg[0] == 0)
1304                         return 0;
1305             tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1306             return RVAL_NONE | RVAL_STR;
1307         }
1308         return 0;
1309 #else
1310 #ifdef SPARC
1311         long i1;
1312         struct regs regs;
1313         m_siginfo_t si;
1314
1315         if(ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1316             perror("sigreturn: PTRACE_GETREGS ");
1317             return 0;
1318         }
1319         if(entering(tcp)) {
1320                 tcp->u_arg[0] = 0;
1321                 i1 = regs.r_o1;
1322                 if(umove(tcp, i1, &si) < 0) {
1323                         perror("sigreturn: umove ");
1324                         return 0;
1325                 }
1326                 tcp->u_arg[0] = 1;
1327                 tcp->u_arg[1] = si.si_mask;
1328         } else {
1329                 sigset_t sigm;
1330                 long_to_sigset(tcp->u_arg[1], &sigm);
1331                 tcp->u_rval = tcp->u_error = 0;
1332                 if(tcp->u_arg[0] == 0)
1333                         return 0;
1334                 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1335                 return RVAL_NONE | RVAL_STR;
1336         }
1337         return 0;
1338 #else  
1339 #ifdef MIPS
1340         long sp;
1341         struct sigcontext sc;
1342
1343         if(entering(tcp)) {
1344                 tcp->u_arg[0] = 0;
1345                 if (upeek(tcp->pid, REG_SP, &sp) < 0)
1346                         return 0;
1347                 if (umove(tcp, sp, &sc) < 0)
1348                         return 0;
1349                 tcp->u_arg[0] = 1;
1350                 tcp->u_arg[1] = sc.sc_sigset;
1351         } else {
1352                 tcp->u_rval = tcp->u_error = 0;
1353                 if(tcp->u_arg[0] == 0)
1354                         return 0;
1355                 tcp->auxstr = sprintsigmask("mask now ", tcp->u_arg[1]);
1356                 return RVAL_NONE | RVAL_STR;
1357         }
1358         return 0;
1359 #else
1360 #warning No sys_sigreturn() for this architecture
1361 #warning         (no problem, just a reminder :-)
1362         return 0;
1363 #endif /* MIPS */
1364 #endif /* SPARC */
1365 #endif /* ALPHA */
1366 #endif /* !M68K */
1367 #endif /* !POWERPC */
1368 #endif /* !IA64 */
1369 #endif /* !I386 */
1370 #endif /* S390 */
1371 }
1372
1373 int
1374 sys_siggetmask(tcp)
1375 struct tcb *tcp;
1376 {
1377         if (exiting(tcp)) {
1378                 sigset_t sigm;
1379                 long_to_sigset(tcp->u_rval, &sigm);
1380                 tcp->auxstr = sprintsigmask("mask ", &sigm, 0);
1381         }
1382         return RVAL_HEX | RVAL_STR;
1383 }
1384
1385 int
1386 sys_sigsuspend(tcp)
1387 struct tcb *tcp;
1388 {
1389         if (entering(tcp)) {
1390                 sigset_t sigm;
1391                 long_to_sigset(tcp->u_arg[2], &sigm);
1392 #if 0
1393                 /* first two are not really arguments, but print them anyway */
1394                 /* nevermind, they are an anachronism now, too bad... */
1395                 tprintf("%d, %#x, ", tcp->u_arg[0], tcp->u_arg[1]);
1396 #endif
1397                 printsigmask(&sigm, 0);
1398         }
1399         return 0;
1400 }
1401
1402 #endif /* LINUX */
1403
1404 #if defined(SVR4) || defined(FREEBSD)
1405
1406 int
1407 sys_sigsuspend(tcp)
1408 struct tcb *tcp;
1409 {
1410         sigset_t sigset;
1411
1412         if (entering(tcp)) {
1413                 if (umove(tcp, tcp->u_arg[0], &sigset) < 0)
1414                         tprintf("[?]");
1415                 else
1416                         printsigmask(&sigset, 0);
1417         }
1418         return 0;
1419 }
1420 #ifndef FREEBSD
1421 static struct xlat ucontext_flags[] = {
1422         { UC_SIGMASK,   "UC_SIGMASK"    },
1423         { UC_STACK,     "UC_STACK"      },
1424         { UC_CPU,       "UC_CPU"        },
1425 #ifdef UC_FPU
1426         { UC_FPU,       "UC_FPU"        },
1427 #endif
1428 #ifdef UC_INTR
1429         { UC_INTR,      "UC_INTR"       },
1430 #endif
1431         { 0,            NULL            },
1432 };
1433 #endif /* !FREEBSD */
1434 #endif /* SVR4 || FREEBSD */
1435
1436 #if defined SVR4 || defined LINUX || defined FREEBSD
1437 #if defined LINUX && !defined SS_ONSTACK
1438 #define SS_ONSTACK      1
1439 #define SS_DISABLE      2
1440 #if __GLIBC_MINOR__ == 0
1441 typedef struct
1442 {
1443         __ptr_t ss_sp;
1444         int ss_flags;
1445         size_t ss_size;
1446 } stack_t;
1447 #endif
1448 #endif
1449 #ifdef FREEBSD
1450 #define stack_t struct sigaltstack
1451 #endif
1452
1453 static struct xlat sigaltstack_flags[] = {
1454         { SS_ONSTACK,   "SS_ONSTACK"    },
1455         { SS_DISABLE,   "SS_DISABLE"    },
1456         { 0,            NULL            },
1457 };
1458 #endif
1459
1460 #ifdef SVR4
1461 static void
1462 printcontext(tcp, ucp)
1463 struct tcb *tcp;
1464 ucontext_t *ucp;
1465 {
1466         tprintf("{");
1467         if (!abbrev(tcp)) {
1468                 tprintf("uc_flags=");
1469                 if (!printflags(ucontext_flags, ucp->uc_flags))
1470                         tprintf("0");
1471                 tprintf(", uc_link=%#lx, ", (unsigned long) ucp->uc_link);
1472         }
1473         tprintf("uc_sigmask=");
1474         printsigmask(&ucp->uc_sigmask, 0);
1475         if (!abbrev(tcp)) {
1476                 tprintf(", uc_stack={ss_sp=%#lx, ss_size=%d, ss_flags=",
1477                         (unsigned long) ucp->uc_stack.ss_sp,
1478                         ucp->uc_stack.ss_size);
1479                 if (!printflags(sigaltstack_flags, ucp->uc_stack.ss_flags))
1480                         tprintf("0");
1481                 tprintf("}");
1482         }
1483         tprintf(", ...}");
1484 }
1485
1486 int
1487 sys_getcontext(tcp)
1488 struct tcb *tcp;
1489 {
1490         ucontext_t uc;
1491
1492         if (exiting(tcp)) {
1493                 if (tcp->u_error)
1494                         tprintf("%#lx", tcp->u_arg[0]);
1495                 else if (!tcp->u_arg[0])
1496                         tprintf("NULL");
1497                 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
1498                         tprintf("{...}");
1499                 else
1500                         printcontext(tcp, &uc);
1501         }
1502         return 0;
1503 }
1504
1505 int
1506 sys_setcontext(tcp)
1507 struct tcb *tcp;
1508 {
1509         ucontext_t uc;
1510
1511         if (entering(tcp)) {
1512                 if (!tcp->u_arg[0])
1513                         tprintf("NULL");
1514                 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
1515                         tprintf("{...}");
1516                 else
1517                         printcontext(tcp, &uc);
1518         }
1519         else {
1520                 tcp->u_rval = tcp->u_error = 0;
1521                 if (tcp->u_arg[0] == 0)
1522                         return 0;
1523                 return RVAL_NONE;
1524         }
1525         return 0;
1526 }
1527
1528 #endif /* SVR4 */
1529
1530 #if defined(LINUX) || defined(FREEBSD)
1531
1532 static int
1533 print_stack_t(tcp, addr)
1534 struct tcb *tcp;
1535 unsigned long addr;
1536 {
1537         stack_t ss;
1538         if (umove(tcp, addr, &ss) < 0)
1539                 return -1;
1540         tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp);
1541         if (!printflags(sigaltstack_flags, ss.ss_flags))
1542                 tprintf("0");
1543         tprintf(", ss_size=%lu}", (unsigned long) ss.ss_size);
1544         return 0;
1545 }
1546
1547 int
1548 sys_sigaltstack(tcp)
1549         struct tcb *tcp;
1550 {
1551         if (entering(tcp)) {
1552                 if (tcp->u_arg[0] == 0)
1553                         tprintf("NULL");
1554                 else if (print_stack_t(tcp, tcp->u_arg[0]) < 0)
1555                         return -1;
1556         }
1557         else {
1558                 tprintf(", ");
1559                 if (tcp->u_arg[1] == 0)
1560                         tprintf("NULL");
1561                 else if (print_stack_t(tcp, tcp->u_arg[1]) < 0)
1562                         return -1;
1563         }
1564         return 0;
1565 }
1566 #endif
1567
1568 #ifdef HAVE_SIGACTION
1569
1570 int
1571 sys_sigprocmask(tcp)
1572 struct tcb *tcp;
1573 {
1574 #ifdef ALPHA
1575         if (entering(tcp)) {
1576                 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1577                 tprintf(", ");
1578                 printsigmask(tcp->u_arg[1], 0);
1579         }
1580         else if (!syserror(tcp)) {
1581                 tcp->auxstr = sprintsigmask("old mask ", tcp->u_rval, 0);
1582                 return RVAL_HEX | RVAL_STR;
1583         }
1584 #else /* !ALPHA */
1585         sigset_t sigset;
1586
1587         if (entering(tcp)) {
1588 #ifdef SVR4
1589                 if (tcp->u_arg[0] == 0)
1590                         tprintf("0");
1591                 else
1592 #endif /* SVR4 */
1593                 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1594                 tprintf(", ");
1595                 if (!tcp->u_arg[1])
1596                         tprintf("NULL, ");
1597                 else if (copy_sigset(tcp, tcp->u_arg[1], &sigset) < 0)
1598                         tprintf("%#lx, ", tcp->u_arg[1]);
1599                 else {
1600                         printsigmask(&sigset, 0);
1601                         tprintf(", ");
1602                 }
1603         }
1604         else {
1605                 if (!tcp->u_arg[2])
1606                         tprintf("NULL");
1607                 else if (syserror(tcp))
1608                         tprintf("%#lx", tcp->u_arg[2]);
1609                 else if (copy_sigset(tcp, tcp->u_arg[2], &sigset) < 0)
1610                         tprintf("[?]");
1611                 else
1612                         printsigmask(&sigset, 0);
1613         }
1614 #endif /* !ALPHA */
1615         return 0;
1616 }
1617
1618 #endif /* HAVE_SIGACTION */
1619
1620 int
1621 sys_kill(tcp)
1622 struct tcb *tcp;
1623 {
1624         if (entering(tcp)) {
1625                 tprintf("%ld, %s", tcp->u_arg[0], signame(tcp->u_arg[1]));
1626         }
1627         return 0;
1628 }
1629
1630 int
1631 sys_killpg(tcp)
1632 struct tcb *tcp;
1633 {
1634         return sys_kill(tcp);
1635 }
1636
1637 int
1638 sys_sigpending(tcp)
1639 struct tcb *tcp;
1640 {
1641         sigset_t sigset;
1642
1643         if (exiting(tcp)) {
1644                 if (syserror(tcp))
1645                         tprintf("%#lx", tcp->u_arg[0]);
1646                 else if (copy_sigset(tcp, tcp->u_arg[0], &sigset) < 0)
1647                         tprintf("[?]");
1648                 else
1649                         printsigmask(&sigset, 0);
1650         }
1651         return 0;
1652 }
1653
1654 int sys_sigwait(tcp)
1655 struct tcb *tcp;
1656 {
1657         sigset_t sigset;
1658
1659         if (entering(tcp)) {
1660                 if (copy_sigset(tcp, tcp->u_arg[0], &sigset) < 0)
1661                         tprintf("[?]");
1662                 else
1663                         printsigmask(&sigset, 0);
1664         }
1665         else {
1666                 if (!syserror(tcp)) {
1667                         tcp->auxstr = signalent[tcp->u_rval];
1668                         return RVAL_DECIMAL | RVAL_STR;
1669                 }
1670         }
1671         return 0;
1672 }
1673
1674 #ifdef LINUX
1675
1676         int
1677 sys_rt_sigprocmask(tcp)
1678         struct tcb *tcp;
1679 {
1680         sigset_t sigset;
1681
1682         /* Note: arg[3] is the length of the sigset. */
1683         if (entering(tcp)) {
1684                 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1685                 tprintf(", ");
1686                 if (!tcp->u_arg[1])
1687                         tprintf("NULL, ");
1688                 else if (copy_sigset_len(tcp, tcp->u_arg[1], &sigset, tcp->u_arg[3]) < 0)
1689                         tprintf("%#lx, ", tcp->u_arg[1]);
1690                 else {
1691                         printsigmask(&sigset, 1);
1692                         tprintf(", ");
1693                 }
1694         }
1695         else {
1696                 if (!tcp->u_arg[2])
1697
1698                         tprintf("NULL");
1699                 else if (syserror(tcp))
1700                         tprintf("%#lx", tcp->u_arg[2]);
1701                 else if (copy_sigset_len(tcp, tcp->u_arg[2], &sigset, tcp->u_arg[3]) < 0)
1702                         tprintf("[?]");
1703                 else
1704                         printsigmask(&sigset, 1);
1705                 tprintf(", %lu", tcp->u_arg[3]);
1706         }
1707         return 0;
1708 }
1709
1710
1711 /* Structure describing the action to be taken when a signal arrives.  */
1712 struct new_sigaction
1713 {
1714         union
1715         {
1716                 __sighandler_t __sa_handler;
1717                 void (*__sa_sigaction) (int, siginfo_t *, void *);
1718         }
1719         __sigaction_handler;
1720         unsigned long sa_flags;
1721         void (*sa_restorer) (void);
1722         unsigned long int sa_mask[2];
1723 };
1724
1725
1726         int
1727 sys_rt_sigaction(tcp)
1728         struct tcb *tcp;
1729 {
1730         struct new_sigaction sa;
1731         sigset_t sigset;
1732         long addr;
1733
1734         if (entering(tcp)) {
1735                 printsignal(tcp->u_arg[0]);
1736                 tprintf(", ");
1737                 addr = tcp->u_arg[1];
1738         } else
1739                 addr = tcp->u_arg[2];
1740         if (addr == 0)
1741                 tprintf("NULL");
1742         else if (!verbose(tcp))
1743                 tprintf("%#lx", addr);
1744         else if (umove(tcp, addr, &sa) < 0)
1745                 tprintf("{...}");
1746         else {
1747                 switch ((long) sa.__sigaction_handler.__sa_handler) {
1748                         case (long) SIG_ERR:
1749                                 tprintf("{SIG_ERR}");
1750                                 break;
1751                         case (long) SIG_DFL:
1752                                 tprintf("{SIG_DFL}");
1753                                 break;
1754                         case (long) SIG_IGN:
1755                                 tprintf("{SIG_IGN}");
1756                                 break;
1757                         default:
1758                                 tprintf("{%#lx, ",
1759                                                 (long) sa.__sigaction_handler.__sa_handler);
1760                                 sigemptyset(&sigset);
1761 #ifdef LINUXSPARC
1762                                 if (tcp->u_arg[4] <= sizeof(sigset))
1763                                         memcpy(&sigset, &sa.sa_mask, tcp->u_arg[4]);
1764 #else
1765                                 if (tcp->u_arg[3] <= sizeof(sigset))
1766                                         memcpy(&sigset, &sa.sa_mask, tcp->u_arg[3]);
1767 #endif
1768                                 else
1769                                         memcpy(&sigset, &sa.sa_mask, sizeof(sigset));
1770                                 printsigmask(&sigset, 1);
1771                                 tprintf(", ");
1772                                 if (!printflags(sigact_flags, sa.sa_flags))
1773                                         tprintf("0");
1774                                 tprintf("}");
1775                 }
1776         }
1777         if (entering(tcp))
1778                 tprintf(", ");
1779         else
1780 #ifdef LINUXSPARC
1781                 tprintf(", %#lx, %lu", tcp->u_arg[3], tcp->u_arg[4]);
1782 #elif defined(ALPHA)
1783                 tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]);
1784 #else
1785                 tprintf(", %lu", addr = tcp->u_arg[3]);
1786 #endif
1787         return 0;
1788 }
1789
1790         int
1791 sys_rt_sigpending(tcp)
1792         struct tcb *tcp;
1793 {
1794         sigset_t sigset;
1795
1796         if (exiting(tcp)) {
1797                 if (syserror(tcp))
1798                         tprintf("%#lx", tcp->u_arg[0]);
1799                 else if (copy_sigset_len(tcp, tcp->u_arg[0],
1800                                          &sigset, tcp->u_arg[1]) < 0)
1801                         tprintf("[?]");
1802                 else
1803                         printsigmask(&sigset, 1);
1804         }
1805         return 0;
1806 }
1807         int
1808 sys_rt_sigsuspend(tcp)
1809         struct tcb *tcp;
1810 {
1811         if (entering(tcp)) {
1812                 sigset_t sigm;
1813                 if (copy_sigset_len(tcp, tcp->u_arg[0], &sigm, tcp->u_arg[1]) < 0)
1814                         tprintf("[?]");
1815                 else
1816                         printsigmask(&sigm, 1);
1817         }
1818         return 0;
1819 }
1820         int
1821 sys_rt_sigqueueinfo(tcp)
1822         struct tcb *tcp;
1823 {
1824         if (entering(tcp)) {
1825                 siginfo_t si;
1826                 tprintf("%lu, ", tcp->u_arg[0]);
1827                 printsignal(tcp->u_arg[1]);
1828                 tprintf(", ");
1829                 if (umove(tcp, tcp->u_arg[2], &si) < 0)
1830                         tprintf("%#lx", tcp->u_arg[2]);
1831                 else
1832                         printsiginfo(&si, verbose (tcp));
1833         }
1834         return 0;
1835 }
1836
1837 int sys_rt_sigtimedwait(tcp)
1838         struct tcb *tcp;
1839 {
1840         if (entering(tcp)) {
1841                 sigset_t sigset;
1842
1843                 if (copy_sigset_len(tcp, tcp->u_arg[0], 
1844                                     &sigset, tcp->u_arg[3]) < 0)
1845                         tprintf("[?]");
1846                 else
1847                         printsigmask(&sigset, 1);
1848                 tprintf(", ");
1849         }
1850         else {
1851                 if (syserror(tcp))
1852                         tprintf("%#lx", tcp->u_arg[0]);
1853                 else {
1854                         siginfo_t si;
1855                         if (umove(tcp, tcp->u_arg[1], &si) < 0)
1856                                 tprintf("%#lx", tcp->u_arg[1]);
1857                         else
1858                                 printsiginfo(&si, verbose (tcp));
1859                         /* XXX For now */
1860                         tprintf(", %#lx", tcp->u_arg[2]);
1861                         tprintf(", %d", (int) tcp->u_arg[3]);
1862                 }
1863         }
1864         return 0;
1865 };
1866
1867 #endif /* LINUX */