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