]> granicus.if.org Git - strace/blob - signal.c
test/clone.c: minor fixup
[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 #ifdef SUNOS4
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 */
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)
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 */
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                 if ((tcp->u_arg[0] & sigmask(SIGTRAP))) {
550                         /* Mark attempt to block SIGTRAP */
551                         tcp->flags |= TCB_SIGTRAPPED;
552                         /* Send unblockable signal */
553                         kill(tcp->pid, SIGSTOP);
554                 }
555         }
556         else if (!syserror(tcp)) {
557                 sigset_t sigm;
558                 long_to_sigset(tcp->u_rval, &sigm);
559                 tcp->auxstr = sprintsigmask("old mask ", &sigm, 0);
560
561                 return RVAL_HEX | RVAL_STR;
562         }
563         return 0;
564 }
565
566 int
567 sys_sigblock(tcp)
568 struct tcb *tcp;
569 {
570         return sys_sigsetmask(tcp);
571 }
572
573 #endif /* !SVR4 */
574
575 #ifdef HAVE_SIGACTION
576
577 #ifdef LINUX
578 struct old_sigaction {
579         __sighandler_t __sa_handler;
580         unsigned long sa_mask;
581         unsigned long sa_flags;
582         void (*sa_restorer)(void);
583 };
584 #define SA_HANDLER __sa_handler
585 #endif /* LINUX */
586
587 #ifndef SA_HANDLER                                                           
588 #define SA_HANDLER sa_handler                                                
589 #endif
590
591 int
592 sys_sigaction(tcp)
593 struct tcb *tcp;
594 {
595         long addr;
596         sigset_t sigset;
597 #ifdef LINUX
598         struct old_sigaction sa;
599 #else
600         struct sigaction sa;
601 #endif
602
603
604         if (entering(tcp)) {
605                 printsignal(tcp->u_arg[0]);
606                 tprintf(", ");
607                 addr = tcp->u_arg[1];
608         } else
609                 addr = tcp->u_arg[2];
610         if (addr == 0)
611                 tprintf("NULL");
612         else if (!verbose(tcp))
613                 tprintf("%#lx", addr);
614         else if (umove(tcp, addr, &sa) < 0)
615                 tprintf("{...}");
616         else {
617                 switch ((long) sa.SA_HANDLER) {
618                 case (long) SIG_ERR:
619                         tprintf("{SIG_ERR}");
620                         break;
621                 case (long) SIG_DFL:
622                         tprintf("{SIG_DFL}");
623                         break;
624                 case (long) SIG_IGN:
625 #ifndef SVR4
626                         if (tcp->u_arg[0] == SIGTRAP) {
627                                 tcp->flags |= TCB_SIGTRAPPED;
628                                 kill(tcp->pid, SIGSTOP);
629                         }
630 #endif /* !SVR4 */
631                         tprintf("{SIG_IGN}");
632                         break;
633                 default:
634 #ifndef SVR4
635                         if (tcp->u_arg[0] == SIGTRAP) {
636                                 tcp->flags |= TCB_SIGTRAPPED;
637                                 kill(tcp->pid, SIGSTOP);
638                         }
639 #endif /* !SVR4 */
640                         tprintf("{%#lx, ", (long) sa.SA_HANDLER);
641 #ifndef LINUX
642                         printsigmask (&sa.sa_mask, 0);
643 #else
644                         long_to_sigset(sa.sa_mask, &sigset);
645                         printsigmask(&sigset, 0);
646 #endif
647                         tprintf(", ");
648                         if (!printflags(sigact_flags, sa.sa_flags))
649                                 tprintf("0");
650                         tprintf("}");
651                 }
652         }
653         if (entering(tcp))
654                 tprintf(", ");
655 #ifdef LINUX
656         else
657                 tprintf(", %#lx", (unsigned long) sa.sa_restorer);
658 #endif
659         return 0;
660 }
661
662 int
663 sys_signal(tcp)
664 struct tcb *tcp;
665 {
666         if (entering(tcp)) {
667                 printsignal(tcp->u_arg[0]);
668                 tprintf(", ");
669                 switch (tcp->u_arg[1]) {
670                 case (int) SIG_ERR:
671                         tprintf("SIG_ERR");
672                         break;
673                 case (int) SIG_DFL:
674                         tprintf("SIG_DFL");
675                         break;
676                 case (int) SIG_IGN:
677 #ifndef SVR4
678                         if (tcp->u_arg[0] == SIGTRAP) {
679                                 tcp->flags |= TCB_SIGTRAPPED;
680                                 kill(tcp->pid, SIGSTOP);
681                         }
682 #endif /* !SVR4 */
683                         tprintf("SIG_IGN");
684                         break;
685                 default:
686 #ifndef SVR4
687                         if (tcp->u_arg[0] == SIGTRAP) {
688                                 tcp->flags |= TCB_SIGTRAPPED;
689                                 kill(tcp->pid, SIGSTOP);
690                         }
691 #endif /* !SVR4 */
692                         tprintf("%#lx", tcp->u_arg[1]);
693                 }
694                 return 0;
695         }
696         else {
697                 switch (tcp->u_rval) {
698                     case (int) SIG_ERR:
699                         tcp->auxstr = "SIG_ERR"; break;
700                     case (int) SIG_DFL:
701                         tcp->auxstr = "SIG_DFL"; break;
702                     case (int) SIG_IGN:
703                         tcp->auxstr = "SIG_IGN"; break;
704                     default:
705                         tcp->auxstr = NULL;
706                 }
707                 return RVAL_HEX | RVAL_STR;
708         }
709 }
710
711 int
712 sys_sighold(tcp)
713 struct tcb *tcp;
714 {
715         if (entering(tcp)) {
716                 printsignal(tcp->u_arg[0]);
717         }
718         return 0;
719 }
720
721 #endif /* HAVE_SIGACTION */
722
723 #ifdef LINUX
724
725 int
726 sys_sigreturn(tcp)
727 struct tcb *tcp;
728 {
729 #ifdef S390
730     long usp;
731     struct sigcontext_struct sc;
732
733     if (entering(tcp)) {
734             tcp->u_arg[0] = 0;
735             if (upeek(tcp->pid,PT_GPR15,&usp)<0)
736                     return 0;
737             if (umove(tcp, usp+__SIGNAL_FRAMESIZE, &sc) < 0)
738                     return 0;
739             tcp->u_arg[0] = 1;
740             memcpy(&tcp->u_arg[1],&sc.oldmask[0],sizeof(sigset_t));
741     } else {
742             tcp->u_rval = tcp->u_error = 0;
743             if (tcp->u_arg[0] == 0)
744                     return 0;
745             tcp->auxstr = sprintsigmask("mask now ",(sigset_t *)&tcp->u_arg[1]);
746             return RVAL_NONE | RVAL_STR;
747     }
748     return 0;
749 #else
750 #ifdef I386
751         long esp;
752         struct sigcontext_struct sc;
753
754         if (entering(tcp)) {
755                 tcp->u_arg[0] = 0;
756                 if (upeek(tcp->pid, 4*UESP, &esp) < 0)
757                         return 0;
758                 if (umove(tcp, esp, &sc) < 0)
759                         return 0;
760                 tcp->u_arg[0] = 1;
761                 tcp->u_arg[1] = sc.oldmask;
762         }
763         else {
764                 sigset_t sigm;
765                 long_to_sigset(tcp->u_arg[1], &sigm);
766                 tcp->u_rval = tcp->u_error = 0;
767                 if (tcp->u_arg[0] == 0)
768                         return 0;
769                 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
770                 return RVAL_NONE | RVAL_STR;
771         }
772         return 0;
773 #else /* !I386 */
774 #ifdef IA64
775         struct sigcontext sc;
776         long sp;
777
778         if (entering(tcp)) {
779                 /* offset of sigcontext in the kernel's sigframe structure: */
780 #               define SIGFRAME_SC_OFFSET       0x90
781                 tcp->u_arg[0] = 0;
782                 if (upeek(tcp->pid, PT_R12, &sp) < 0)
783                         return 0;
784                 if (umove(tcp, sp + 16 + SIGFRAME_SC_OFFSET, &sc) < 0)
785                         return 0;
786                 tcp->u_arg[0] = 1;
787                 memcpy(tcp->u_arg + 1, &sc.sc_mask, sizeof(sc.sc_mask));
788         }
789         else {
790                 sigset_t sigm;
791
792                 memcpy(&sigm, tcp->u_arg + 1, sizeof (sigm));
793                 tcp->u_rval = tcp->u_error = 0;
794                 if (tcp->u_arg[0] == 0)
795                         return 0;
796                 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
797                 return RVAL_NONE | RVAL_STR;
798         }
799         return 0;
800 #else /* !IA64 */
801 #ifdef POWERPC
802        long esp;
803        struct sigcontext_struct sc;
804
805        if (entering(tcp)) {
806                    tcp->u_arg[0] = 0;
807                    if (upeek(tcp->pid, 4*PT_R1, &esp) < 0)
808                            return 0;
809                    if (umove(tcp, esp, &sc) < 0)
810                            return 0;
811                    tcp->u_arg[0] = 1;
812                    tcp->u_arg[1] = sc.oldmask;
813        }
814        else {
815                    sigset_t sigm;
816                    long_to_sigset(tcp->u_arg[1], &sigm);
817                    tcp->u_rval = tcp->u_error = 0;
818                    if (tcp->u_arg[0] == 0)
819                            return 0;
820                    tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
821                    return RVAL_NONE | RVAL_STR;
822        }
823        return 0;
824 #else /* !POWERPC */
825 #ifdef M68K
826         long usp;
827         struct sigcontext sc;
828
829         if (entering(tcp)) {
830             tcp->u_arg[0] = 0;
831             if (upeek(tcp->pid, 4*PT_USP, &usp) < 0)
832                         return 0;
833             if (umove(tcp, usp, &sc) < 0)
834                         return 0;
835             tcp->u_arg[0] = 1;
836             tcp->u_arg[1] = sc.sc_mask;
837         }
838         else {
839             sigset_t sigm;
840             long_to_sigset(tcp->u_arg[1], &sigm);
841             tcp->u_rval = tcp->u_error = 0;
842             if (tcp->u_arg[0] == 0)
843                         return 0;
844             tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
845             return RVAL_NONE | RVAL_STR;
846         }
847         return 0;
848 #else /* !M68K */
849 #ifdef ALPHA
850         long fp;
851         struct sigcontext_struct sc;
852
853         if (entering(tcp)) {
854             tcp->u_arg[0] = 0;
855             if (upeek(tcp->pid, REG_FP, &fp) < 0)
856                         return 0;
857             if (umove(tcp, fp, &sc) < 0)
858                         return 0;
859             tcp->u_arg[0] = 1;
860             tcp->u_arg[1] = sc.sc_mask;
861         }
862         else {
863             sigset_t sigm;
864             long_to_sigset(tcp->u_arg[1], &sigm);
865             tcp->u_rval = tcp->u_error = 0;
866             if (tcp->u_arg[0] == 0)
867                         return 0;
868             tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
869             return RVAL_NONE | RVAL_STR;
870         }
871         return 0;
872 #else
873 #ifdef SPARC
874         long i1;
875         struct regs regs;
876         m_siginfo_t si;
877
878         if(ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
879             perror("sigreturn: PTRACE_GETREGS ");
880             return 0;
881         }
882         if(entering(tcp)) {
883                 tcp->u_arg[0] = 0;
884                 i1 = regs.r_o1;
885                 if(umove(tcp, i1, &si) < 0) {
886                         perror("sigreturn: umove ");
887                         return 0;
888                 }
889                 tcp->u_arg[0] = 1;
890                 tcp->u_arg[1] = si.si_mask;
891         } else {
892                 sigset_t sigm;
893                 long_to_sigset(tcp->u_arg[1], &sigm);
894                 tcp->u_rval = tcp->u_error = 0;
895                 if(tcp->u_arg[0] == 0)
896                         return 0;
897                 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
898                 return RVAL_NONE | RVAL_STR;
899         }
900         return 0;
901 #else  
902 #ifdef MIPS
903         long sp;
904         struct sigcontext sc;
905
906         if(entering(tcp)) {
907                 tcp->u_arg[0] = 0;
908                 if (upeek(tcp->pid, REG_SP, &sp) < 0)
909                         return 0;
910                 if (umove(tcp, sp, &sc) < 0)
911                         return 0;
912                 tcp->u_arg[0] = 1;
913                 tcp->u_arg[1] = sc.sc_sigset;
914         } else {
915                 tcp->u_rval = tcp->u_error = 0;
916                 if(tcp->u_arg[0] == 0)
917                         return 0;
918                 tcp->auxstr = sprintsigmask("mask now ", tcp->u_arg[1]);
919                 return RVAL_NONE | RVAL_STR;
920         }
921         return 0;
922 #endif /* MIPS */
923 #endif /* SPARC */
924 #endif /* ALPHA */
925 #endif /* !M68K */
926 #endif /* !POWERPC */
927 #endif /* !IA64 */
928 #endif /* !I386 */
929 #endif /* S390 */
930 }
931
932 int
933 sys_siggetmask(tcp)
934 struct tcb *tcp;
935 {
936         if (exiting(tcp)) {
937                 sigset_t sigm;
938                 long_to_sigset(tcp->u_rval, &sigm);
939                 tcp->auxstr = sprintsigmask("mask ", &sigm, 0);
940         }
941         return RVAL_HEX | RVAL_STR;
942 }
943
944 int
945 sys_sigsuspend(tcp)
946 struct tcb *tcp;
947 {
948         if (entering(tcp)) {
949                 sigset_t sigm;
950                 long_to_sigset(tcp->u_arg[2], &sigm);
951 #if 0
952                 /* first two are not really arguments, but print them anyway */
953                 /* nevermind, they are an anachronism now, too bad... */
954                 tprintf("%d, %#x, ", tcp->u_arg[0], tcp->u_arg[1]);
955 #endif
956                 printsigmask(&sigm, 0);
957         }
958         return 0;
959 }
960
961 #endif /* LINUX */
962
963 #ifdef SVR4
964
965 int
966 sys_sigsuspend(tcp)
967 struct tcb *tcp;
968 {
969         sigset_t sigset;
970
971         if (entering(tcp)) {
972                 if (umove(tcp, tcp->u_arg[0], &sigset) < 0)
973                         tprintf("[?]");
974                 else
975                         printsigmask(&sigset, 0);
976         }
977         return 0;
978 }
979 static struct xlat ucontext_flags[] = {
980         { UC_SIGMASK,   "UC_SIGMASK"    },
981         { UC_STACK,     "UC_STACK"      },
982         { UC_CPU,       "UC_CPU"        },
983 #ifdef UC_FPU
984         { UC_FPU,       "UC_FPU"        },
985 #endif
986 #ifdef UC_INTR
987         { UC_INTR,      "UC_INTR"       },
988 #endif
989         { 0,            NULL            },
990 };
991
992 #endif
993
994 #if defined SVR4 || defined LINUX
995 #if defined LINUX && !defined SS_ONSTACK
996 #define SS_ONSTACK      1
997 #define SS_DISABLE      2
998 #if __GLIBC_MINOR__ == 0
999 typedef struct
1000 {
1001         __ptr_t ss_sp;
1002         int ss_flags;
1003         size_t ss_size;
1004 } stack_t;
1005 #endif
1006 #endif
1007
1008 static struct xlat sigaltstack_flags[] = {
1009         { SS_ONSTACK,   "SS_ONSTACK"    },
1010         { SS_DISABLE,   "SS_DISABLE"    },
1011         { 0,            NULL            },
1012 };
1013 #endif
1014
1015 #ifdef SVR4
1016 static void
1017 printcontext(tcp, ucp)
1018 struct tcb *tcp;
1019 ucontext_t *ucp;
1020 {
1021         tprintf("{");
1022         if (!abbrev(tcp)) {
1023                 tprintf("uc_flags=");
1024                 if (!printflags(ucontext_flags, ucp->uc_flags))
1025                         tprintf("0");
1026                 tprintf(", uc_link=%#lx, ", (unsigned long) ucp->uc_link);
1027         }
1028         tprintf("uc_sigmask=");
1029         printsigmask(ucp->uc_sigmask, 0);
1030         if (!abbrev(tcp)) {
1031                 tprintf(", uc_stack={ss_sp=%#lx, ss_size=%d, ss_flags=",
1032                         (unsigned long) ucp->uc_stack.ss_sp,
1033                         ucp->uc_stack.ss_size);
1034                 if (!printflags(sigaltstack_flags, ucp->uc_stack.ss_flags))
1035                         tprintf("0");
1036                 tprintf("}");
1037         }
1038         tprintf(", ...}");
1039 }
1040
1041 int
1042 sys_getcontext(tcp)
1043 struct tcb *tcp;
1044 {
1045         ucontext_t uc;
1046
1047         if (exiting(tcp)) {
1048                 if (tcp->u_error)
1049                         tprintf("%#lx", tcp->u_arg[0]);
1050                 else if (!tcp->u_arg[0])
1051                         tprintf("NULL");
1052                 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
1053                         tprintf("{...}");
1054                 else
1055                         printcontext(tcp, &uc);
1056         }
1057         return 0;
1058 }
1059
1060 int
1061 sys_setcontext(tcp)
1062 struct tcb *tcp;
1063 {
1064         ucontext_t uc;
1065
1066         if (entering(tcp)) {
1067                 if (!tcp->u_arg[0])
1068                         tprintf("NULL");
1069                 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
1070                         tprintf("{...}");
1071                 else
1072                         printcontext(tcp, &uc);
1073         }
1074         else {
1075                 tcp->u_rval = tcp->u_error = 0;
1076                 if (tcp->u_arg[0] == 0)
1077                         return 0;
1078                 return RVAL_NONE;
1079         }
1080         return 0;
1081 }
1082
1083 #endif /* SVR4 */
1084
1085 #ifdef LINUX
1086
1087 static int
1088 print_stack_t(tcp, addr)
1089 struct tcb *tcp;
1090 unsigned long addr;
1091 {
1092         stack_t ss;
1093         if (umove(tcp, addr, &ss) < 0)
1094                 return -1;
1095         tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp);
1096         if (!printflags(sigaltstack_flags, ss.ss_flags))
1097                 tprintf("0");
1098         tprintf(", ss_size=%lu}", (unsigned long) ss.ss_size);
1099         return 0;
1100 }
1101
1102 int
1103 sys_sigaltstack(tcp)
1104         struct tcb *tcp;
1105 {
1106         if (entering(tcp)) {
1107                 if (tcp->u_arg[0] == 0)
1108                         tprintf("NULL");
1109                 else if (print_stack_t(tcp, tcp->u_arg[0]) < 0)
1110                         return -1;
1111         }
1112         else {
1113                 tprintf(", ");
1114                 if (tcp->u_arg[1] == 0)
1115                         tprintf("NULL");
1116                 else if (print_stack_t(tcp, tcp->u_arg[1]) < 0)
1117                         return -1;
1118         }
1119         return 0;
1120 }
1121 #endif
1122
1123 #ifdef HAVE_SIGACTION
1124
1125 int
1126 sys_sigprocmask(tcp)
1127 struct tcb *tcp;
1128 {
1129 #ifdef ALPHA
1130         if (entering(tcp)) {
1131                 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1132                 tprintf(", ");
1133                 printsigmask(tcp->u_arg[1], 0);
1134         }
1135         else if (!syserror(tcp)) {
1136                 tcp->auxstr = sprintsigmask("old mask ", tcp->u_rval, 0);
1137                 return RVAL_HEX | RVAL_STR;
1138         }
1139 #else /* !ALPHA */
1140         sigset_t sigset;
1141
1142         if (entering(tcp)) {
1143 #ifdef SVR4
1144                 if (tcp->u_arg[0] == 0)
1145                         tprintf("0");
1146                 else
1147 #endif /* SVR4 */
1148                 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1149                 tprintf(", ");
1150                 if (!tcp->u_arg[1])
1151                         tprintf("NULL, ");
1152                 else if (copy_sigset(tcp, tcp->u_arg[1], &sigset) < 0)
1153                         tprintf("%#lx, ", tcp->u_arg[1]);
1154                 else {
1155                         printsigmask(&sigset, 0);
1156                         tprintf(", ");
1157                 }
1158         }
1159         else {
1160                 if (!tcp->u_arg[2])
1161                         tprintf("NULL");
1162                 else if (syserror(tcp))
1163                         tprintf("%#lx", tcp->u_arg[2]);
1164                 else if (copy_sigset(tcp, tcp->u_arg[2], &sigset) < 0)
1165                         tprintf("[?]");
1166                 else
1167                         printsigmask(&sigset, 0);
1168         }
1169 #endif /* !ALPHA */
1170         return 0;
1171 }
1172
1173 #endif /* HAVE_SIGACTION */
1174
1175 int
1176 sys_kill(tcp)
1177 struct tcb *tcp;
1178 {
1179         if (entering(tcp)) {
1180                 tprintf("%ld, %s", tcp->u_arg[0], signame(tcp->u_arg[1]));
1181         }
1182         return 0;
1183 }
1184
1185 int
1186 sys_killpg(tcp)
1187 struct tcb *tcp;
1188 {
1189         return sys_kill(tcp);
1190 }
1191
1192 int
1193 sys_sigpending(tcp)
1194 struct tcb *tcp;
1195 {
1196         sigset_t sigset;
1197
1198         if (exiting(tcp)) {
1199                 if (syserror(tcp))
1200                         tprintf("%#lx", tcp->u_arg[0]);
1201                 else if (copy_sigset(tcp, tcp->u_arg[0], &sigset) < 0)
1202                         tprintf("[?]");
1203                 else
1204                         printsigmask(&sigset, 0);
1205         }
1206         return 0;
1207 }
1208
1209 #ifdef LINUX
1210
1211         int
1212 sys_rt_sigprocmask(tcp)
1213         struct tcb *tcp;
1214 {
1215         sigset_t sigset;
1216
1217         /* Note: arg[3] is the length of the sigset. */
1218         if (entering(tcp)) {
1219                 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1220                 tprintf(", ");
1221                 if (!tcp->u_arg[1])
1222                         tprintf("NULL, ");
1223                 else if (copy_sigset_len(tcp, tcp->u_arg[1], &sigset, tcp->u_arg[3]) < 0)
1224                         tprintf("%#lx, ", tcp->u_arg[1]);
1225                 else {
1226                         printsigmask(&sigset, 1);
1227                         tprintf(", ");
1228                 }
1229         }
1230         else {
1231                 if (!tcp->u_arg[2])
1232
1233                         tprintf("NULL");
1234                 else if (syserror(tcp))
1235                         tprintf("%#lx", tcp->u_arg[2]);
1236                 else if (copy_sigset_len(tcp, tcp->u_arg[2], &sigset, tcp->u_arg[3]) < 0)
1237                         tprintf("[?]");
1238                 else
1239                         printsigmask(&sigset, 1);
1240                 tprintf(", %lu", tcp->u_arg[3]);
1241         }
1242         return 0;
1243 }
1244
1245 #if __GLIBC_MINOR__ < 1
1246 /* Type for data associated with a signal.  */
1247 typedef union sigval
1248 {
1249         int sival_int;
1250         void *sival_ptr;
1251 } sigval_t;
1252
1253 # define __SI_MAX_SIZE     128
1254 # define __SI_PAD_SIZE     ((__SI_MAX_SIZE / sizeof (int)) - 3)
1255
1256 typedef struct siginfo
1257 {
1258         int si_signo;               /* Signal number.  */
1259         int si_errno;               /* If non-zero, an errno value associated with
1260                                                                    this signal, as defined in <errno.h>.  */
1261         int si_code;                /* Signal code.  */
1262
1263         union
1264         {
1265                 int _pad[__SI_PAD_SIZE];
1266
1267                 /* kill().  */
1268                 struct
1269                 {
1270                         __pid_t si_pid;     /* Sending process ID.  */
1271                         __uid_t si_uid;     /* Real user ID of sending process.  */
1272                 } _kill;
1273
1274                 /* POSIX.1b timers.  */
1275                 struct
1276                 {
1277                         unsigned int _timer1;
1278                         unsigned int _timer2;
1279                 } _timer;
1280
1281                 /* POSIX.1b signals.  */
1282                 struct
1283                 {
1284                         __pid_t si_pid;     /* Sending process ID.  */
1285                         __uid_t si_uid;     /* Real user ID of sending process.  */
1286                         sigval_t si_sigval; /* Signal value.  */
1287                 } _rt;
1288
1289                 /* SIGCHLD.  */
1290                 struct
1291                 {
1292                         __pid_t si_pid;     /* Which child.  */
1293                         int si_status;      /* Exit value or signal.  */
1294                         __clock_t si_utime;
1295                         __clock_t si_stime;
1296                 } _sigchld;
1297
1298                 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS.  */
1299                 struct
1300                 {
1301                         void *si_addr;      /* Faulting insn/memory ref.  */
1302                 } _sigfault;
1303
1304                 /* SIGPOLL.  */
1305                 struct
1306                 {
1307                         int si_band;        /* Band event for SIGPOLL.  */
1308                         int si_fd;
1309                 } _sigpoll;
1310         } _sifields;
1311 } siginfo_t;
1312 #endif
1313
1314 /* Structure describing the action to be taken when a signal arrives.  */
1315 struct new_sigaction
1316 {
1317         union
1318         {
1319                 __sighandler_t __sa_handler;
1320                 void (*__sa_sigaction) (int, siginfo_t *, void *);
1321         }
1322         __sigaction_handler;
1323         unsigned long sa_flags;
1324         void (*sa_restorer) (void);
1325         unsigned long int sa_mask[2];
1326 };
1327
1328
1329         int
1330 sys_rt_sigaction(tcp)
1331         struct tcb *tcp;
1332 {
1333         struct new_sigaction sa;
1334         sigset_t sigset;
1335         long addr;
1336
1337         if (entering(tcp)) {
1338                 printsignal(tcp->u_arg[0]);
1339                 tprintf(", ");
1340                 addr = tcp->u_arg[1];
1341         } else
1342                 addr = tcp->u_arg[2];
1343         if (addr == 0)
1344                 tprintf("NULL");
1345         else if (!verbose(tcp))
1346                 tprintf("%#lx", addr);
1347         else if (umove(tcp, addr, &sa) < 0)
1348                 tprintf("{...}");
1349         else {
1350                 switch ((long) sa.__sigaction_handler.__sa_handler) {
1351                         case (long) SIG_ERR:
1352                                 tprintf("{SIG_ERR}");
1353                                 break;
1354                         case (long) SIG_DFL:
1355                                 tprintf("{SIG_DFL}");
1356                                 break;
1357                         case (long) SIG_IGN:
1358                                 tprintf("{SIG_IGN}");
1359                                 break;
1360                         default:
1361                                 tprintf("{%#lx, ",
1362                                                 (long) sa.__sigaction_handler.__sa_handler);
1363                                 sigemptyset(&sigset);
1364 #ifdef LINUXSPARC
1365                                 if (tcp->u_arg[4] <= sizeof(sigset))
1366                                         memcpy(&sigset, &sa.sa_mask, tcp->u_arg[4]);
1367 #else
1368                                 if (tcp->u_arg[3] <= sizeof(sigset))
1369                                         memcpy(&sigset, &sa.sa_mask, tcp->u_arg[3]);
1370 #endif
1371                                 else
1372                                         memcpy(&sigset, &sa.sa_mask, sizeof(sigset));
1373                                 printsigmask(&sigset, 1);
1374                                 tprintf(", ");
1375                                 if (!printflags(sigact_flags, sa.sa_flags))
1376                                         tprintf("0");
1377                                 tprintf("}");
1378                 }
1379         }
1380         if (entering(tcp))
1381                 tprintf(", ");
1382         else
1383 #ifdef LINUXSPARC
1384                 tprintf(", %#lx, %lu", tcp->u_arg[3], tcp->u_arg[4]);
1385 #elif defined(ALPHA)
1386                 tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]);
1387 #else
1388                 tprintf(", %lu", addr = tcp->u_arg[3]);
1389 #endif
1390         return 0;
1391 }
1392
1393         int
1394 sys_rt_sigpending(tcp)
1395         struct tcb *tcp;
1396 {
1397         sigset_t sigset;
1398
1399         if (exiting(tcp)) {
1400                 if (syserror(tcp))
1401                         tprintf("%#lx", tcp->u_arg[0]);
1402                 else if (copy_sigset_len(tcp, tcp->u_arg[0],
1403                                          &sigset, tcp->u_arg[1]) < 0)
1404                         tprintf("[?]");
1405                 else
1406                         printsigmask(&sigset, 1);
1407         }
1408         return 0;
1409 }
1410         int
1411 sys_rt_sigsuspend(tcp)
1412         struct tcb *tcp;
1413 {
1414         if (entering(tcp)) {
1415                 sigset_t sigm;
1416                 if (copy_sigset_len(tcp, tcp->u_arg[0], &sigm, tcp->u_arg[1]) < 0)
1417                         tprintf("[?]");
1418                 else
1419                         printsigmask(&sigm, 1);
1420         }
1421         return 0;
1422 }
1423 #ifndef ILL_ILLOPC
1424 #define ILL_ILLOPC      1       /* illegal opcode */
1425 #define ILL_ILLOPN      2       /* illegal operand */
1426 #define ILL_ILLADR      3       /* illegal addressing mode */
1427 #define ILL_ILLTRP      4       /* illegal trap */
1428 #define ILL_PRVOPC      5       /* privileged opcode */
1429 #define ILL_PRVREG      6       /* privileged register */
1430 #define ILL_COPROC      7       /* coprocessor error */
1431 #define ILL_BADSTK      8       /* internal stack error */
1432 #define FPE_INTDIV      1       /* integer divide by zero */
1433 #define FPE_INTOVF      2       /* integer overflow */
1434 #define FPE_FLTDIV      3       /* floating point divide by zero */
1435 #define FPE_FLTOVF      4       /* floating point overflow */
1436 #define FPE_FLTUND      5       /* floating point underflow */
1437 #define FPE_FLTRES      6       /* floating point inexact result */
1438 #define FPE_FLTINV      7       /* floating point invalid operation */
1439 #define FPE_FLTSUB      8       /* subscript out of range */
1440 #define SEGV_MAPERR     1       /* address not mapped to object */
1441 #define SEGV_ACCERR     2       /* invalid permissions for mapped object */
1442 #define BUS_ADRALN      1       /* invalid address alignment */
1443 #define BUS_ADRERR      2       /* non-existant physical address */
1444 #define BUS_OBJERR      3       /* object specific hardware error */
1445 #define TRAP_BRKPT      1       /* process breakpoint */
1446 #define TRAP_TRACE      2       /* process trace trap */
1447 #define CLD_EXITED      1       /* child has exited */
1448 #define CLD_KILLED      2       /* child was killed */
1449 #define CLD_DUMPED      3       /* child terminated abnormally */
1450 #define CLD_TRAPPED     4       /* traced child has trapped */
1451 #define CLD_STOPPED     5       /* child has stopped */
1452 #define CLD_CONTINUED   6       /* stopped child has continued */
1453 #define POLL_IN         1       /* data input available */
1454 #define POLL_OUT        2       /* output buffers available */
1455 #define POLL_MSG        3       /* input message available */
1456 #define POLL_ERR        4       /* i/o error */
1457 #define POLL_PRI        5       /* high priority input available */
1458 #define POLL_HUP        6       /* device disconnected */
1459 #define SI_USER         0       /* sent by kill, sigsend, raise */
1460 #define SI_QUEUE        -1      /* sent by sigqueue */
1461 #define SI_TIMER        -2      /* sent by timer expiration */
1462 #define SI_MESGQ        -3      /* sent by real time mesq state change */
1463 #define SI_ASYNCIO      -4      /* sent by AIO completion */
1464 #else
1465 #undef si_pid
1466 #undef si_uid
1467 #undef si_status
1468 #undef si_utime
1469 #undef si_stime
1470 #undef si_value
1471 #undef si_int
1472 #undef si_ptr
1473 #undef si_addr
1474 #undef si_band
1475 #undef si_fd
1476 #endif
1477
1478 static struct xlat sigill_flags[] = {
1479         {ILL_ILLOPC, "ILL_ILLOPC"},
1480         {ILL_ILLOPN, "ILL_ILLOPN"},
1481         {ILL_ILLADR, "ILL_ILLADR"},
1482         {ILL_ILLTRP, "ILL_ILLTRP"},
1483         {ILL_PRVOPC, "ILL_PRVOPC"},
1484         {ILL_PRVREG, "ILL_PRVREG"},
1485         {ILL_COPROC, "ILL_COPROC"},
1486         {ILL_BADSTK, "ILL_BADSTK"},
1487         {0, NULL}
1488 };
1489
1490 static struct xlat sigfpe_flags[] = {
1491         {FPE_INTDIV, "FPE_INTDIV"},
1492         {FPE_INTOVF, "FPE_INTOVF"},
1493         {FPE_FLTDIV, "FPE_FLTDIV"},
1494         {FPE_FLTOVF, "FPE_FLTOVF"},
1495         {FPE_FLTUND, "FPE_FLTUND"},
1496         {FPE_FLTRES, "FPE_FLTRES"},
1497         {FPE_FLTINV, "FPE_FLTINV"},
1498         {FPE_FLTSUB, "FPE_FLTSUB"},
1499         {0, NULL}
1500 };
1501
1502 static struct xlat sigsegv_flags[] = {
1503         {SEGV_MAPERR, "SEGV_MAPERR"},
1504         {SEGV_ACCERR, "SEGV_ACCERR"},
1505         {0, NULL}
1506 };
1507
1508 static struct xlat sigbus_flags[] = {
1509         {BUS_ADRALN, "BUS_ADRALN"},
1510         {BUS_ADRERR, "BUS_ADRERR"},
1511         {BUS_OBJERR, "BUS_OBJERR"},
1512         {0, NULL}
1513 };
1514
1515 static struct xlat sigtrap_flags[] = {
1516         {TRAP_BRKPT, "TRAP_BRKPT"},
1517         {TRAP_TRACE, "TRAP_TRACE"},
1518         {0, NULL}
1519 };
1520
1521 static struct xlat sigchld_flags[] = {
1522         {CLD_EXITED, "CLD_EXITED"},
1523         {CLD_KILLED, "CLD_KILLED"},
1524         {CLD_DUMPED, "CLD_DUMPED"},
1525         {CLD_TRAPPED, "CLD_TRAPPED"},
1526         {CLD_STOPPED, "CLD_STOPPED"},
1527         {CLD_CONTINUED, "CLD_CONTINUED"},
1528         {0, NULL}
1529 };
1530
1531 static struct xlat sigpoll_flags[] = {
1532         {POLL_IN, "POLL_IN"},
1533         {POLL_OUT, "POLL_OUT"},
1534         {POLL_MSG, "POLL_MSG"},
1535         {POLL_ERR, "POLL_ERR"},
1536         {POLL_PRI, "POLL_PRI"},
1537         {POLL_HUP, "POLL_HUP"},
1538         {0, NULL}
1539 };
1540
1541 static struct xlat siginfo_flags[] = {
1542         {SI_USER, "SI_USER"},
1543         {SI_QUEUE, "SI_QUEUE"},
1544         {SI_TIMER, "SI_TIMER"},
1545         {SI_MESGQ, "SI_MESGQ"},
1546         {SI_ASYNCIO, "SI_ASYNCIO"},
1547         {0, NULL}
1548 };
1549
1550         static void
1551 printsiginfo(tcp, si)
1552         struct tcb *tcp;
1553         siginfo_t *si;
1554 {
1555         tprintf("{si_signo=");
1556         printsignal(si->si_signo);
1557         tprintf(", si_errno=%d, si_code=", si->si_errno);
1558         switch(si->si_signo)
1559         {
1560                 case SIGILL:
1561                         if (!printflags(sigill_flags, si->si_code))
1562                                 tprintf("%d /* ILL_??? */", si->si_code);
1563                         tprintf(", si_addr=%lx",
1564                                         (unsigned long) si->_sifields._sigfault.si_addr);
1565                         break;
1566                 case SIGFPE:
1567                         if (!printflags(sigfpe_flags, si->si_code))
1568                                 tprintf("%d /* FPE_??? */", si->si_code);
1569                         tprintf(", si_addr=%lx",
1570                                         (unsigned long) si->_sifields._sigfault.si_addr);
1571                         break;
1572                 case SIGSEGV:
1573                         if (!printflags(sigsegv_flags, si->si_code))
1574                                 tprintf("%d /* SEGV_??? */", si->si_code);
1575                         tprintf(", si_addr=%lx",
1576                                         (unsigned long) si->_sifields._sigfault.si_addr);
1577                         break;
1578                 case SIGBUS:
1579                         if (!printflags(sigbus_flags, si->si_code))
1580                                 tprintf("%d /* BUS_??? */", si->si_code);
1581                         tprintf(", si_addr=%lx",
1582                                         (unsigned long) si->_sifields._sigfault.si_addr);
1583                         break;
1584                 case SIGTRAP:
1585                         if (!printflags(sigtrap_flags, si->si_code))
1586                                 tprintf("%d /* TRAP_??? */", si->si_code);
1587                         break;
1588                 case SIGCHLD:
1589                         if (!printflags(sigchld_flags, si->si_code))
1590                                 tprintf("%d /* CLD_??? */", si->si_code);
1591                         if (!verbose(tcp))
1592                                 tprintf(", ...");
1593                         else
1594                                 tprintf(", si_pid=%d, si_uid=%d, si_status=%d, si_utime=%lu, si_stime=%lu",
1595                                                 si->_sifields._kill.si_pid,
1596                                                 si->_sifields._kill.si_uid,
1597                                                 si->_sifields._sigchld.si_status,
1598                                                 si->_sifields._sigchld.si_utime,
1599                                                 si->_sifields._sigchld.si_stime);
1600                         break;
1601                 case SIGPOLL:
1602                         if (!printflags(sigpoll_flags, si->si_code))
1603                                 tprintf("%d /* POLL_??? */", si->si_code);
1604                         if (si->si_code == POLL_IN
1605                                         || si->si_code == POLL_OUT
1606                                         || si->si_code == POLL_MSG)
1607                                 tprintf(", si_bind=%lu, si_fd=%d",
1608                                                 (unsigned long) si->_sifields._sigpoll.si_band,
1609                                                 si->_sifields._sigpoll.si_fd);
1610                         break;
1611                 default:
1612                         if (!printflags(siginfo_flags, si->si_code))
1613                                 tprintf("%d /* SI_??? */", si->si_code);
1614                         tprintf(", si_pid=%lu, si_uid=%lu, si_value={",
1615                                         (unsigned long) si->_sifields._rt.si_pid,
1616                                         (unsigned long) si->_sifields._rt.si_uid);
1617                         if (!verbose(tcp))
1618                                 tprintf("...");
1619                         else {
1620                                 tprintf("sival_int=%u, sival_ptr=%#lx",
1621                                                 si->_sifields._rt.si_sigval.sival_int,
1622                                                 (unsigned long) si->_sifields._rt.si_sigval.sival_ptr);
1623                         }
1624                         tprintf("}");
1625                         break;
1626         }
1627         tprintf("}");
1628 }
1629
1630         int
1631 sys_rt_sigqueueinfo(tcp)
1632         struct tcb *tcp;
1633 {
1634         if (entering(tcp)) {
1635                 siginfo_t si;
1636                 tprintf("%lu, ", tcp->u_arg[0]);
1637                 printsignal(tcp->u_arg[1]);
1638                 tprintf(", ");
1639                 if (umove(tcp, tcp->u_arg[2], &si) < 0)
1640                         tprintf("%#lx", tcp->u_arg[2]);
1641                 else
1642                         printsiginfo(&si);
1643         }
1644         return 0;
1645 }
1646
1647 int sys_rt_sigtimedwait(tcp)
1648         struct tcb *tcp;
1649 {
1650         if (entering(tcp)) {
1651                 sigset_t sigset;
1652
1653                 if (copy_sigset_len(tcp, tcp->u_arg[0], 
1654                                     &sigset, tcp->u_arg[3]) < 0)
1655                         tprintf("[?]");
1656                 else
1657                         printsigmask(&sigset, 1);
1658                 tprintf(", ");
1659         }
1660         else {
1661                 if (syserror(tcp))
1662                         tprintf("%#lx", tcp->u_arg[0]);
1663                 else {
1664                         siginfo_t si;
1665                         if (umove(tcp, tcp->u_arg[1], &si) < 0)
1666                                 tprintf("%#lx", tcp->u_arg[1]);
1667                         else
1668                                 printsiginfo(&si);
1669                         /* XXX For now */
1670                         tprintf(", %#lx", tcp->u_arg[2]);
1671                         tprintf(", %d", (int) tcp->u_arg[3]);
1672                 }
1673         }
1674         return 0;
1675 };
1676
1677 #endif /* LINUX */
1678