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