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