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