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