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