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