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