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