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