]> granicus.if.org Git - strace/blob - signal.c
Merge SVR4/Linux printsiginfo
[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)
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 #ifdef S390
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]);
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 #ifdef HPPA
1361 #warning NO sys_sigreturn DECODE FOR HPPA
1362         return 0;
1363 #endif /* HPPA */
1364 #endif /* MIPS */
1365 #endif /* SPARC */
1366 #endif /* ALPHA */
1367 #endif /* !M68K */
1368 #endif /* !POWERPC */
1369 #endif /* !IA64 */
1370 #endif /* !I386 */
1371 #endif /* S390 */
1372 }
1373
1374 int
1375 sys_siggetmask(tcp)
1376 struct tcb *tcp;
1377 {
1378         if (exiting(tcp)) {
1379                 sigset_t sigm;
1380                 long_to_sigset(tcp->u_rval, &sigm);
1381                 tcp->auxstr = sprintsigmask("mask ", &sigm, 0);
1382         }
1383         return RVAL_HEX | RVAL_STR;
1384 }
1385
1386 int
1387 sys_sigsuspend(tcp)
1388 struct tcb *tcp;
1389 {
1390         if (entering(tcp)) {
1391                 sigset_t sigm;
1392                 long_to_sigset(tcp->u_arg[2], &sigm);
1393 #if 0
1394                 /* first two are not really arguments, but print them anyway */
1395                 /* nevermind, they are an anachronism now, too bad... */
1396                 tprintf("%d, %#x, ", tcp->u_arg[0], tcp->u_arg[1]);
1397 #endif
1398                 printsigmask(&sigm, 0);
1399         }
1400         return 0;
1401 }
1402
1403 #endif /* LINUX */
1404
1405 #if defined(SVR4) || defined(FREEBSD)
1406
1407 int
1408 sys_sigsuspend(tcp)
1409 struct tcb *tcp;
1410 {
1411         sigset_t sigset;
1412
1413         if (entering(tcp)) {
1414                 if (umove(tcp, tcp->u_arg[0], &sigset) < 0)
1415                         tprintf("[?]");
1416                 else
1417                         printsigmask(&sigset, 0);
1418         }
1419         return 0;
1420 }
1421 #ifndef FREEBSD
1422 static struct xlat ucontext_flags[] = {
1423         { UC_SIGMASK,   "UC_SIGMASK"    },
1424         { UC_STACK,     "UC_STACK"      },
1425         { UC_CPU,       "UC_CPU"        },
1426 #ifdef UC_FPU
1427         { UC_FPU,       "UC_FPU"        },
1428 #endif
1429 #ifdef UC_INTR
1430         { UC_INTR,      "UC_INTR"       },
1431 #endif
1432         { 0,            NULL            },
1433 };
1434 #endif /* !FREEBSD */
1435 #endif /* SVR4 || FREEBSD */
1436
1437 #if defined SVR4 || defined LINUX || defined FREEBSD
1438 #if defined LINUX && !defined SS_ONSTACK
1439 #define SS_ONSTACK      1
1440 #define SS_DISABLE      2
1441 #if __GLIBC_MINOR__ == 0
1442 typedef struct
1443 {
1444         __ptr_t ss_sp;
1445         int ss_flags;
1446         size_t ss_size;
1447 } stack_t;
1448 #endif
1449 #endif
1450 #ifdef FREEBSD
1451 #define stack_t struct sigaltstack
1452 #endif
1453
1454 static struct xlat sigaltstack_flags[] = {
1455         { SS_ONSTACK,   "SS_ONSTACK"    },
1456         { SS_DISABLE,   "SS_DISABLE"    },
1457         { 0,            NULL            },
1458 };
1459 #endif
1460
1461 #ifdef SVR4
1462 static void
1463 printcontext(tcp, ucp)
1464 struct tcb *tcp;
1465 ucontext_t *ucp;
1466 {
1467         tprintf("{");
1468         if (!abbrev(tcp)) {
1469                 tprintf("uc_flags=");
1470                 if (!printflags(ucontext_flags, ucp->uc_flags))
1471                         tprintf("0");
1472                 tprintf(", uc_link=%#lx, ", (unsigned long) ucp->uc_link);
1473         }
1474         tprintf("uc_sigmask=");
1475         printsigmask(&ucp->uc_sigmask, 0);
1476         if (!abbrev(tcp)) {
1477                 tprintf(", uc_stack={ss_sp=%#lx, ss_size=%d, ss_flags=",
1478                         (unsigned long) ucp->uc_stack.ss_sp,
1479                         ucp->uc_stack.ss_size);
1480                 if (!printflags(sigaltstack_flags, ucp->uc_stack.ss_flags))
1481                         tprintf("0");
1482                 tprintf("}");
1483         }
1484         tprintf(", ...}");
1485 }
1486
1487 int
1488 sys_getcontext(tcp)
1489 struct tcb *tcp;
1490 {
1491         ucontext_t uc;
1492
1493         if (exiting(tcp)) {
1494                 if (tcp->u_error)
1495                         tprintf("%#lx", tcp->u_arg[0]);
1496                 else if (!tcp->u_arg[0])
1497                         tprintf("NULL");
1498                 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
1499                         tprintf("{...}");
1500                 else
1501                         printcontext(tcp, &uc);
1502         }
1503         return 0;
1504 }
1505
1506 int
1507 sys_setcontext(tcp)
1508 struct tcb *tcp;
1509 {
1510         ucontext_t uc;
1511
1512         if (entering(tcp)) {
1513                 if (!tcp->u_arg[0])
1514                         tprintf("NULL");
1515                 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
1516                         tprintf("{...}");
1517                 else
1518                         printcontext(tcp, &uc);
1519         }
1520         else {
1521                 tcp->u_rval = tcp->u_error = 0;
1522                 if (tcp->u_arg[0] == 0)
1523                         return 0;
1524                 return RVAL_NONE;
1525         }
1526         return 0;
1527 }
1528
1529 #endif /* SVR4 */
1530
1531 #if defined(LINUX) || defined(FREEBSD)
1532
1533 static int
1534 print_stack_t(tcp, addr)
1535 struct tcb *tcp;
1536 unsigned long addr;
1537 {
1538         stack_t ss;
1539         if (umove(tcp, addr, &ss) < 0)
1540                 return -1;
1541         tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp);
1542         if (!printflags(sigaltstack_flags, ss.ss_flags))
1543                 tprintf("0");
1544         tprintf(", ss_size=%lu}", (unsigned long) ss.ss_size);
1545         return 0;
1546 }
1547
1548 int
1549 sys_sigaltstack(tcp)
1550         struct tcb *tcp;
1551 {
1552         if (entering(tcp)) {
1553                 if (tcp->u_arg[0] == 0)
1554                         tprintf("NULL");
1555                 else if (print_stack_t(tcp, tcp->u_arg[0]) < 0)
1556                         return -1;
1557         }
1558         else {
1559                 tprintf(", ");
1560                 if (tcp->u_arg[1] == 0)
1561                         tprintf("NULL");
1562                 else if (print_stack_t(tcp, tcp->u_arg[1]) < 0)
1563                         return -1;
1564         }
1565         return 0;
1566 }
1567 #endif
1568
1569 #ifdef HAVE_SIGACTION
1570
1571 int
1572 sys_sigprocmask(tcp)
1573 struct tcb *tcp;
1574 {
1575 #ifdef ALPHA
1576         if (entering(tcp)) {
1577                 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1578                 tprintf(", ");
1579                 printsigmask(tcp->u_arg[1], 0);
1580         }
1581         else if (!syserror(tcp)) {
1582                 tcp->auxstr = sprintsigmask("old mask ", tcp->u_rval, 0);
1583                 return RVAL_HEX | RVAL_STR;
1584         }
1585 #else /* !ALPHA */
1586         sigset_t sigset;
1587
1588         if (entering(tcp)) {
1589 #ifdef SVR4
1590                 if (tcp->u_arg[0] == 0)
1591                         tprintf("0");
1592                 else
1593 #endif /* SVR4 */
1594                 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1595                 tprintf(", ");
1596                 if (!tcp->u_arg[1])
1597                         tprintf("NULL, ");
1598                 else if (copy_sigset(tcp, tcp->u_arg[1], &sigset) < 0)
1599                         tprintf("%#lx, ", tcp->u_arg[1]);
1600                 else {
1601                         printsigmask(&sigset, 0);
1602                         tprintf(", ");
1603                 }
1604         }
1605         else {
1606                 if (!tcp->u_arg[2])
1607                         tprintf("NULL");
1608                 else if (syserror(tcp))
1609                         tprintf("%#lx", tcp->u_arg[2]);
1610                 else if (copy_sigset(tcp, tcp->u_arg[2], &sigset) < 0)
1611                         tprintf("[?]");
1612                 else
1613                         printsigmask(&sigset, 0);
1614         }
1615 #endif /* !ALPHA */
1616         return 0;
1617 }
1618
1619 #endif /* HAVE_SIGACTION */
1620
1621 int
1622 sys_kill(tcp)
1623 struct tcb *tcp;
1624 {
1625         if (entering(tcp)) {
1626                 tprintf("%ld, %s", tcp->u_arg[0], signame(tcp->u_arg[1]));
1627         }
1628         return 0;
1629 }
1630
1631 int
1632 sys_killpg(tcp)
1633 struct tcb *tcp;
1634 {
1635         return sys_kill(tcp);
1636 }
1637
1638 int
1639 sys_sigpending(tcp)
1640 struct tcb *tcp;
1641 {
1642         sigset_t sigset;
1643
1644         if (exiting(tcp)) {
1645                 if (syserror(tcp))
1646                         tprintf("%#lx", tcp->u_arg[0]);
1647                 else if (copy_sigset(tcp, tcp->u_arg[0], &sigset) < 0)
1648                         tprintf("[?]");
1649                 else
1650                         printsigmask(&sigset, 0);
1651         }
1652         return 0;
1653 }
1654
1655 int sys_sigwait(tcp)
1656 struct tcb *tcp;
1657 {
1658         sigset_t sigset;
1659
1660         if (entering(tcp)) {
1661                 if (copy_sigset(tcp, tcp->u_arg[0], &sigset) < 0)
1662                         tprintf("[?]");
1663                 else
1664                         printsigmask(&sigset, 0);
1665         }
1666         else {
1667                 if (!syserror(tcp)) {
1668                         tcp->auxstr = signalent[tcp->u_rval];
1669                         return RVAL_DECIMAL | RVAL_STR;
1670                 }
1671         }
1672         return 0;
1673 }
1674
1675 #ifdef LINUX
1676
1677         int
1678 sys_rt_sigprocmask(tcp)
1679         struct tcb *tcp;
1680 {
1681         sigset_t sigset;
1682
1683         /* Note: arg[3] is the length of the sigset. */
1684         if (entering(tcp)) {
1685                 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1686                 tprintf(", ");
1687                 if (!tcp->u_arg[1])
1688                         tprintf("NULL, ");
1689                 else if (copy_sigset_len(tcp, tcp->u_arg[1], &sigset, tcp->u_arg[3]) < 0)
1690                         tprintf("%#lx, ", tcp->u_arg[1]);
1691                 else {
1692                         printsigmask(&sigset, 1);
1693                         tprintf(", ");
1694                 }
1695         }
1696         else {
1697                 if (!tcp->u_arg[2])
1698
1699                         tprintf("NULL");
1700                 else if (syserror(tcp))
1701                         tprintf("%#lx", tcp->u_arg[2]);
1702                 else if (copy_sigset_len(tcp, tcp->u_arg[2], &sigset, tcp->u_arg[3]) < 0)
1703                         tprintf("[?]");
1704                 else
1705                         printsigmask(&sigset, 1);
1706                 tprintf(", %lu", tcp->u_arg[3]);
1707         }
1708         return 0;
1709 }
1710
1711
1712 /* Structure describing the action to be taken when a signal arrives.  */
1713 struct new_sigaction
1714 {
1715         union
1716         {
1717                 __sighandler_t __sa_handler;
1718                 void (*__sa_sigaction) (int, siginfo_t *, void *);
1719         }
1720         __sigaction_handler;
1721         unsigned long sa_flags;
1722         void (*sa_restorer) (void);
1723         unsigned long int sa_mask[2];
1724 };
1725
1726
1727         int
1728 sys_rt_sigaction(tcp)
1729         struct tcb *tcp;
1730 {
1731         struct new_sigaction sa;
1732         sigset_t sigset;
1733         long addr;
1734
1735         if (entering(tcp)) {
1736                 printsignal(tcp->u_arg[0]);
1737                 tprintf(", ");
1738                 addr = tcp->u_arg[1];
1739         } else
1740                 addr = tcp->u_arg[2];
1741         if (addr == 0)
1742                 tprintf("NULL");
1743         else if (!verbose(tcp))
1744                 tprintf("%#lx", addr);
1745         else if (umove(tcp, addr, &sa) < 0)
1746                 tprintf("{...}");
1747         else {
1748                 switch ((long) sa.__sigaction_handler.__sa_handler) {
1749                         case (long) SIG_ERR:
1750                                 tprintf("{SIG_ERR}");
1751                                 break;
1752                         case (long) SIG_DFL:
1753                                 tprintf("{SIG_DFL}");
1754                                 break;
1755                         case (long) SIG_IGN:
1756                                 tprintf("{SIG_IGN}");
1757                                 break;
1758                         default:
1759                                 tprintf("{%#lx, ",
1760                                                 (long) sa.__sigaction_handler.__sa_handler);
1761                                 sigemptyset(&sigset);
1762 #ifdef LINUXSPARC
1763                                 if (tcp->u_arg[4] <= sizeof(sigset))
1764                                         memcpy(&sigset, &sa.sa_mask, tcp->u_arg[4]);
1765 #else
1766                                 if (tcp->u_arg[3] <= sizeof(sigset))
1767                                         memcpy(&sigset, &sa.sa_mask, tcp->u_arg[3]);
1768 #endif
1769                                 else
1770                                         memcpy(&sigset, &sa.sa_mask, sizeof(sigset));
1771                                 printsigmask(&sigset, 1);
1772                                 tprintf(", ");
1773                                 if (!printflags(sigact_flags, sa.sa_flags))
1774                                         tprintf("0");
1775                                 tprintf("}");
1776                 }
1777         }
1778         if (entering(tcp))
1779                 tprintf(", ");
1780         else
1781 #ifdef LINUXSPARC
1782                 tprintf(", %#lx, %lu", tcp->u_arg[3], tcp->u_arg[4]);
1783 #elif defined(ALPHA)
1784                 tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]);
1785 #else
1786                 tprintf(", %lu", addr = tcp->u_arg[3]);
1787 #endif
1788         return 0;
1789 }
1790
1791         int
1792 sys_rt_sigpending(tcp)
1793         struct tcb *tcp;
1794 {
1795         sigset_t sigset;
1796
1797         if (exiting(tcp)) {
1798                 if (syserror(tcp))
1799                         tprintf("%#lx", tcp->u_arg[0]);
1800                 else if (copy_sigset_len(tcp, tcp->u_arg[0],
1801                                          &sigset, tcp->u_arg[1]) < 0)
1802                         tprintf("[?]");
1803                 else
1804                         printsigmask(&sigset, 1);
1805         }
1806         return 0;
1807 }
1808         int
1809 sys_rt_sigsuspend(tcp)
1810         struct tcb *tcp;
1811 {
1812         if (entering(tcp)) {
1813                 sigset_t sigm;
1814                 if (copy_sigset_len(tcp, tcp->u_arg[0], &sigm, tcp->u_arg[1]) < 0)
1815                         tprintf("[?]");
1816                 else
1817                         printsigmask(&sigm, 1);
1818         }
1819         return 0;
1820 }
1821         int
1822 sys_rt_sigqueueinfo(tcp)
1823         struct tcb *tcp;
1824 {
1825         if (entering(tcp)) {
1826                 siginfo_t si;
1827                 tprintf("%lu, ", tcp->u_arg[0]);
1828                 printsignal(tcp->u_arg[1]);
1829                 tprintf(", ");
1830                 if (umove(tcp, tcp->u_arg[2], &si) < 0)
1831                         tprintf("%#lx", tcp->u_arg[2]);
1832                 else
1833                         printsiginfo(&si, verbose (tcp));
1834         }
1835         return 0;
1836 }
1837
1838 int sys_rt_sigtimedwait(tcp)
1839         struct tcb *tcp;
1840 {
1841         if (entering(tcp)) {
1842                 sigset_t sigset;
1843
1844                 if (copy_sigset_len(tcp, tcp->u_arg[0], 
1845                                     &sigset, tcp->u_arg[3]) < 0)
1846                         tprintf("[?]");
1847                 else
1848                         printsigmask(&sigset, 1);
1849                 tprintf(", ");
1850         }
1851         else {
1852                 if (syserror(tcp))
1853                         tprintf("%#lx", tcp->u_arg[0]);
1854                 else {
1855                         siginfo_t si;
1856                         if (umove(tcp, tcp->u_arg[1], &si) < 0)
1857                                 tprintf("%#lx", tcp->u_arg[1]);
1858                         else
1859                                 printsiginfo(&si, verbose (tcp));
1860                         /* XXX For now */
1861                         tprintf(", %#lx", tcp->u_arg[2]);
1862                         tprintf(", %d", (int) tcp->u_arg[3]);
1863                 }
1864         }
1865         return 0;
1866 };
1867
1868 #endif /* LINUX */