blob: 422bebb48d045920f1c77be1fe69c757c4b004ee [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
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>
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00005 * 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>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00009 * 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
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000038#include <signal.h>
39#include <sys/user.h>
40#include <fcntl.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000041
42#ifdef SVR4
43#include <sys/ucontext.h>
44#endif /* SVR4 */
45
Wichert Akkerman36915a11999-07-13 15:45:02 +000046#ifdef HAVE_SYS_REG_H
47# include <sys/reg.h>
Wichert Akkerman15dea971999-10-06 13:06:34 +000048#ifndef PTRACE_PEEKUSR
Wichert Akkerman36915a11999-07-13 15:45:02 +000049# define PTRACE_PEEKUSR PTRACE_PEEKUSER
Wichert Akkerman15dea971999-10-06 13:06:34 +000050#endif
51#ifndef PTRACE_POKEUSR
Wichert Akkerman36915a11999-07-13 15:45:02 +000052# define PTRACE_POKEUSR PTRACE_POKEUSER
Wichert Akkerman2e2553a1999-05-09 00:29:58 +000053#endif
Wichert Akkermanfaf72222000-02-19 23:59:03 +000054#elif defined(HAVE_LINUX_PTRACE_H)
55#undef PTRACE_SYSCALL
Roland McGrathb0acdfd2004-03-01 21:31:02 +000056# 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
Wichert Akkermanfaf72222000-02-19 23:59:03 +000062#include <linux/ptrace.h>
Roland McGrathb0acdfd2004-03-01 21:31:02 +000063# undef ia64_fpreg
64# undef pt_all_user_regs
Wichert Akkerman15dea971999-10-06 13:06:34 +000065#endif
Wichert Akkerman36915a11999-07-13 15:45:02 +000066
Wichert Akkermanfaf72222000-02-19 23:59:03 +000067
Wichert Akkerman36915a11999-07-13 15:45:02 +000068#ifdef LINUX
69
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +000070#ifdef IA64
71# include <asm/ptrace_offsets.h>
72#endif /* !IA64 */
73
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000074#if HAVE_ASM_REG_H
Roland McGrath30ff45e2003-01-30 20:15:23 +000075# ifdef SPARC
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000076# define fpq kernel_fpq
77# define fq kernel_fq
78# define fpu kernel_fpu
Roland McGrath30ff45e2003-01-30 20:15:23 +000079# endif
80# include <asm/reg.h>
81# ifdef SPARC
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000082# undef fpq
83# undef fq
Roland McGratha39c5a12002-12-17 05:10:37 +000084# undef fpu
Roland McGrath30ff45e2003-01-30 20:15:23 +000085# endif
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000086#endif /* HAVE_ASM_REG_H */
Roland McGrath30ff45e2003-01-30 20:15:23 +000087
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000088#ifdef SPARC
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000089typedef struct {
Wichert Akkerman9ce1a631999-08-29 23:15:07 +000090 struct regs si_regs;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000091 int si_mask;
92} m_siginfo_t;
Roland McGrath30ff45e2003-01-30 20:15:23 +000093#elif defined HAVE_ASM_SIGCONTEXT_H
94#if !defined(IA64) && !defined(X86_64)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000095#include <asm/sigcontext.h>
Roland McGrath30ff45e2003-01-30 20:15:23 +000096#endif /* !IA64 && !X86_64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000097#else /* !HAVE_ASM_SIGCONTEXT_H */
98#ifdef I386
99struct sigcontext_struct {
100 unsigned short gs, __gsh;
101 unsigned short fs, __fsh;
102 unsigned short es, __esh;
103 unsigned short ds, __dsh;
104 unsigned long edi;
105 unsigned long esi;
106 unsigned long ebp;
107 unsigned long esp;
108 unsigned long ebx;
109 unsigned long edx;
110 unsigned long ecx;
111 unsigned long eax;
112 unsigned long trapno;
113 unsigned long err;
114 unsigned long eip;
115 unsigned short cs, __csh;
116 unsigned long eflags;
117 unsigned long esp_at_signal;
118 unsigned short ss, __ssh;
119 unsigned long i387;
120 unsigned long oldmask;
121 unsigned long cr2;
122};
123#else /* !I386 */
124#ifdef M68K
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000125struct sigcontext
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000126{
127 unsigned long sc_mask;
128 unsigned long sc_usp;
129 unsigned long sc_d0;
130 unsigned long sc_d1;
131 unsigned long sc_a0;
132 unsigned long sc_a1;
133 unsigned short sc_sr;
134 unsigned long sc_pc;
135 unsigned short sc_formatvec;
136};
137#endif /* M68K */
138#endif /* !I386 */
139#endif /* !HAVE_ASM_SIGCONTEXT_H */
140#ifndef NSIG
141#define NSIG 32
142#endif
143#ifdef ARM
144#undef NSIG
145#define NSIG 32
146#endif
147#endif /* LINUX */
148
149char *signalent0[] = {
150#include "signalent.h"
151};
152int nsignals0 = sizeof signalent0 / sizeof signalent0[0];
153
154#if SUPPORTED_PERSONALITIES >= 2
155char *signalent1[] = {
156#include "signalent1.h"
157};
158int nsignals1 = sizeof signalent1 / sizeof signalent1[0];
159#endif /* SUPPORTED_PERSONALITIES >= 2 */
160
161#if SUPPORTED_PERSONALITIES >= 3
162char *signalent2[] = {
163#include "signalent2.h"
164};
165int nsignals2 = sizeof signalent2 / sizeof signalent2[0];
166#endif /* SUPPORTED_PERSONALITIES >= 3 */
167
168char **signalent;
169int nsignals;
170
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000171#if defined(SUNOS4) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000172
173static struct xlat sigvec_flags[] = {
174 { SV_ONSTACK, "SV_ONSTACK" },
175 { SV_INTERRUPT, "SV_INTERRUPT" },
176 { SV_RESETHAND, "SV_RESETHAND" },
177 { SA_NOCLDSTOP, "SA_NOCLDSTOP" },
178 { 0, NULL },
179};
180
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000181#endif /* SUNOS4 || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000182
183#ifdef HAVE_SIGACTION
184
Roland McGrath2638cb42002-12-15 23:58:41 +0000185#if defined LINUX && defined I386
186/* The libc headers do not define this constant since it should only be
187 used by the implementation. So wwe define it here. */
188# ifndef SA_RESTORER
189# define SA_RESTORER 0x04000000
190# endif
191#endif
192
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000193static struct xlat sigact_flags[] = {
Wichert Akkermanc7926982000-04-10 22:22:31 +0000194#ifdef SA_RESTORER
195 { SA_RESTORER, "SA_RESTORER" },
196#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000197#ifdef SA_STACK
198 { SA_STACK, "SA_STACK" },
199#endif
200#ifdef SA_RESTART
201 { SA_RESTART, "SA_RESTART" },
202#endif
203#ifdef SA_INTERRUPT
204 { SA_INTERRUPT, "SA_INTERRUPT" },
205#endif
206#ifdef SA_NOMASK
207 { SA_NOMASK, "SA_NOMASK" },
208#endif
209#ifdef SA_ONESHOT
210 { SA_ONESHOT, "SA_ONESHOT" },
211#endif
212#ifdef SA_SIGINFO
213 { SA_SIGINFO, "SA_SIGINFO" },
214#endif
215#ifdef SA_RESETHAND
216 { SA_RESETHAND, "SA_RESETHAND" },
217#endif
218#ifdef SA_ONSTACK
219 { SA_ONSTACK, "SA_ONSTACK" },
220#endif
221#ifdef SA_NODEFER
222 { SA_NODEFER, "SA_NODEFER" },
223#endif
224#ifdef SA_NOCLDSTOP
225 { SA_NOCLDSTOP, "SA_NOCLDSTOP" },
226#endif
227#ifdef SA_NOCLDWAIT
228 { SA_NOCLDWAIT, "SA_NOCLDWAIT" },
229#endif
230#ifdef _SA_BSDCALL
231 { _SA_BSDCALL, "_SA_BSDCALL" },
232#endif
233 { 0, NULL },
234};
235
236static struct xlat sigprocmaskcmds[] = {
237 { SIG_BLOCK, "SIG_BLOCK" },
238 { SIG_UNBLOCK, "SIG_UNBLOCK" },
239 { SIG_SETMASK, "SIG_SETMASK" },
240#ifdef SIG_SETMASK32
241 { SIG_SETMASK32,"SIG_SETMASK32" },
242#endif
243 { 0, NULL },
244};
245
246#endif /* HAVE_SIGACTION */
247
Nate Sammonsce780fc1999-03-29 23:23:13 +0000248/* Anonymous realtime signals. */
249/* Under glibc 2.1, SIGRTMIN et al are functions, but __SIGRTMIN is a
250 constant. This is what we want. Otherwise, just use SIGRTMIN. */
251#ifdef SIGRTMIN
252#ifndef __SIGRTMIN
253#define __SIGRTMIN SIGRTMIN
254#define __SIGRTMAX SIGRTMAX /* likewise */
255#endif
256#endif
257
258char *
259signame(sig)
260int sig;
261{
262 static char buf[30];
263 if (sig < nsignals) {
264 return signalent[sig];
265#ifdef SIGRTMIN
Nate Sammons3080aa41999-03-30 00:16:41 +0000266 } else if (sig >= __SIGRTMIN && sig <= __SIGRTMAX) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000267 sprintf(buf, "SIGRT_%ld", (long)(sig - __SIGRTMIN));
Nate Sammonsce780fc1999-03-29 23:23:13 +0000268 return buf;
269#endif /* SIGRTMIN */
270 } else {
271 sprintf(buf, "%d", sig);
272 return buf;
273 }
274}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000275
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000276#ifndef UNIXWARE
Nate Sammons4a121431999-04-06 01:19:39 +0000277static void
278long_to_sigset(l, s)
279long l;
280sigset_t *s;
281{
282 sigemptyset(s);
283 *(long *)s = l;
284}
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000285#endif
Nate Sammons4a121431999-04-06 01:19:39 +0000286
287static int
288copy_sigset_len(tcp, addr, s, len)
289struct tcb *tcp;
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000290long addr;
Nate Sammons4a121431999-04-06 01:19:39 +0000291sigset_t *s;
292int len;
293{
294 if (len > sizeof(*s))
295 len = sizeof(*s);
296 sigemptyset(s);
297 if (umoven(tcp, addr, len, (char *)s) < 0)
298 return -1;
299 return 0;
300}
301
302#ifdef LINUX
303/* Original sigset is unsigned long */
304#define copy_sigset(tcp, addr, s) copy_sigset_len(tcp, addr, s, sizeof(long))
305#else
306#define copy_sigset(tcp, addr, s) copy_sigset_len(tcp, addr, s, sizeof(sigset_t))
307#endif
308
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000309static char *
Nate Sammons4a121431999-04-06 01:19:39 +0000310sprintsigmask(s, mask, rt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000311char *s;
312sigset_t *mask;
Nate Sammons4a121431999-04-06 01:19:39 +0000313int rt; /* set might include realtime sigs */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000314{
315 int i, nsigs;
Nate Sammons4a121431999-04-06 01:19:39 +0000316 int maxsigs;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000317 char *format;
Roland McGratha39c5a12002-12-17 05:10:37 +0000318 static char outstr[8 * sizeof(sigset_t) * 8];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000319
320 strcpy(outstr, s);
321 s = outstr + strlen(outstr);
322 nsigs = 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000323 maxsigs = nsignals;
324#ifdef __SIGRTMAX
325 if (rt)
326 maxsigs = __SIGRTMAX; /* instead */
327#endif
328 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000329 if (sigismember(mask, i) == 1)
330 nsigs++;
331 }
332 if (nsigs >= nsignals * 2 / 3) {
333 *s++ = '~';
Nate Sammons4a121431999-04-06 01:19:39 +0000334 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000335 switch (sigismember(mask, i)) {
336 case 1:
337 sigdelset(mask, i);
338 break;
339 case 0:
340 sigaddset(mask, i);
341 break;
342 }
343 }
344 }
345 format = "%s";
346 *s++ = '[';
Nate Sammons4a121431999-04-06 01:19:39 +0000347 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000348 if (sigismember(mask, i) == 1) {
John Hughesbdf48f52001-03-06 15:08:09 +0000349 /* real-time signals on solaris don't have
350 * signalent entries
351 */
352 if (i < nsignals) {
353 sprintf(s, format, signalent[i] + 3);
354 }
Roland McGrath90b4cb52003-09-23 22:19:32 +0000355#ifdef SIGRTMIN
356 else if (i >= __SIGRTMIN && i <= __SIGRTMAX) {
357 char tsig[40];
358 sprintf(tsig, "RT_%u", i - __SIGRTMIN);
359 sprintf(s, format, tsig);
360 }
361#endif /* SIGRTMIN */
John Hughesbdf48f52001-03-06 15:08:09 +0000362 else {
363 char tsig[32];
364 sprintf(tsig, "%u", i);
365 sprintf(s, format, tsig);
366 }
367 s += strlen(s);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000368 format = " %s";
369 }
370 }
371 *s++ = ']';
372 *s = '\0';
373 return outstr;
374}
375
376static void
Nate Sammons4a121431999-04-06 01:19:39 +0000377printsigmask(mask, rt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000378sigset_t *mask;
Nate Sammons4a121431999-04-06 01:19:39 +0000379int rt;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000380{
Nate Sammons4a121431999-04-06 01:19:39 +0000381 tprintf("%s", sprintsigmask("", mask, rt));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000382}
383
384void
385printsignal(nr)
386int nr;
387{
Nate Sammonsce780fc1999-03-29 23:23:13 +0000388 tprintf(signame(nr));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000389}
390
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000391#ifdef LINUX
392
John Hughes58265892001-10-18 15:13:53 +0000393#ifndef ILL_ILLOPC
394#define ILL_ILLOPC 1 /* illegal opcode */
395#define ILL_ILLOPN 2 /* illegal operand */
396#define ILL_ILLADR 3 /* illegal addressing mode */
397#define ILL_ILLTRP 4 /* illegal trap */
398#define ILL_PRVOPC 5 /* privileged opcode */
399#define ILL_PRVREG 6 /* privileged register */
400#define ILL_COPROC 7 /* coprocessor error */
401#define ILL_BADSTK 8 /* internal stack error */
402#define FPE_INTDIV 1 /* integer divide by zero */
403#define FPE_INTOVF 2 /* integer overflow */
404#define FPE_FLTDIV 3 /* floating point divide by zero */
405#define FPE_FLTOVF 4 /* floating point overflow */
406#define FPE_FLTUND 5 /* floating point underflow */
407#define FPE_FLTRES 6 /* floating point inexact result */
408#define FPE_FLTINV 7 /* floating point invalid operation */
409#define FPE_FLTSUB 8 /* subscript out of range */
410#define SEGV_MAPERR 1 /* address not mapped to object */
411#define SEGV_ACCERR 2 /* invalid permissions for mapped object */
412#define BUS_ADRALN 1 /* invalid address alignment */
413#define BUS_ADRERR 2 /* non-existant physical address */
414#define BUS_OBJERR 3 /* object specific hardware error */
415#define TRAP_BRKPT 1 /* process breakpoint */
416#define TRAP_TRACE 2 /* process trace trap */
417#define CLD_EXITED 1 /* child has exited */
418#define CLD_KILLED 2 /* child was killed */
419#define CLD_DUMPED 3 /* child terminated abnormally */
420#define CLD_TRAPPED 4 /* traced child has trapped */
421#define CLD_STOPPED 5 /* child has stopped */
422#define CLD_CONTINUED 6 /* stopped child has continued */
423#define POLL_IN 1 /* data input available */
424#define POLL_OUT 2 /* output buffers available */
425#define POLL_MSG 3 /* input message available */
426#define POLL_ERR 4 /* i/o error */
427#define POLL_PRI 5 /* high priority input available */
428#define POLL_HUP 6 /* device disconnected */
429#define SI_USER 0 /* sent by kill, sigsend, raise */
430#define SI_QUEUE -1 /* sent by sigqueue */
431#define SI_TIMER -2 /* sent by timer expiration */
432#define SI_MESGQ -3 /* sent by real time mesq state change */
433#define SI_ASYNCIO -4 /* sent by AIO completion */
Roland McGrath941b7402003-05-23 00:29:02 +0000434#define SI_SIGIO -5 /* Sent by SIGIO */
435#define SI_TKILL -6 /* Sent by tkill */
John Hughes58265892001-10-18 15:13:53 +0000436#endif
437
438#if __GLIBC_MINOR__ < 1
439/* Type for data associated with a signal. */
440typedef union sigval
441{
442 int sival_int;
443 void *sival_ptr;
444} sigval_t;
445
446# define __SI_MAX_SIZE 128
447# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
448
449typedef struct siginfo
450{
451 int si_signo; /* Signal number. */
452 int si_errno; /* If non-zero, an errno value associated with
453 this signal, as defined in <errno.h>. */
454 int si_code; /* Signal code. */
455
456 union
457 {
458 int _pad[__SI_PAD_SIZE];
459
460 /* kill(). */
461 struct
462 {
463 __pid_t si_pid; /* Sending process ID. */
464 __uid_t si_uid; /* Real user ID of sending process. */
465 } _kill;
466
467 /* POSIX.1b timers. */
468 struct
469 {
470 unsigned int _timer1;
471 unsigned int _timer2;
472 } _timer;
473
474 /* POSIX.1b signals. */
475 struct
476 {
477 __pid_t si_pid; /* Sending process ID. */
478 __uid_t si_uid; /* Real user ID of sending process. */
479 sigval_t si_sigval; /* Signal value. */
480 } _rt;
481
482 /* SIGCHLD. */
483 struct
484 {
485 __pid_t si_pid; /* Which child. */
486 int si_status; /* Exit value or signal. */
487 __clock_t si_utime;
488 __clock_t si_stime;
489 } _sigchld;
490
491 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
492 struct
493 {
494 void *si_addr; /* Faulting insn/memory ref. */
495 } _sigfault;
496
497 /* SIGPOLL. */
498 struct
499 {
500 int si_band; /* Band event for SIGPOLL. */
501 int si_fd;
502 } _sigpoll;
503 } _sifields;
504} siginfo_t;
505
506#define si_pid _sifields._kill.si_pid
507#define si_uid _sifields._kill.si_uid
508#define si_status _sifields._sigchld.si_status
509#define si_utime _sifields._sigchld.si_utime
510#define si_stime _sifields._sigchld.si_stime
511#define si_value _sifields._rt.si_sigval
512#define si_int _sifields._rt.si_sigval.sival_int
513#define si_ptr _sifields._rt.si_sigval.sival_ptr
514#define si_addr _sifields._sigfault.si_addr
515#define si_band _sifields._sigpoll.si_band
516#define si_fd _sifields._sigpoll.si_fd
517
518#endif
519
520#endif
521
522#if defined (SVR4) || defined (LINUX)
523
524static struct xlat siginfo_codes[] = {
525#ifdef SI_NOINFO
526 { SI_NOINFO, "SI_NOINFO" },
527#endif
528#ifdef SI_USER
529 { SI_USER, "SI_USER" },
530#endif
531#ifdef SI_LWP
532 { SI_LWP, "SI_LWP" },
533#endif
534#ifdef SI_QUEUE
535 { SI_QUEUE, "SI_QUEUE" },
536#endif
537#ifdef SI_TIMER
538 { SI_TIMER, "SI_TIMER" },
539#endif
540#ifdef SI_ASYNCIO
541 { SI_ASYNCIO, "SI_ASYNCIO" },
542#endif
543#ifdef SI_MESGQ
544 { SI_MESGQ, "SI_MESGQ" },
545#endif
Roland McGrath941b7402003-05-23 00:29:02 +0000546#ifdef SI_SIGIO
547 { SI_SIGIO, "SI_SIGIO" },
548#endif
549#ifdef SI_TKILL
550 { SI_TKILL, "SI_TKILL" },
551#endif
John Hughes58265892001-10-18 15:13:53 +0000552 { 0, NULL },
553};
554
555static struct xlat sigill_codes[] = {
556 { ILL_ILLOPC, "ILL_ILLOPC" },
557 { ILL_ILLOPN, "ILL_ILLOPN" },
558 { ILL_ILLADR, "ILL_ILLADR" },
559 { ILL_ILLTRP, "ILL_ILLTRP" },
560 { ILL_PRVOPC, "ILL_PRVOPC" },
561 { ILL_PRVREG, "ILL_PRVREG" },
562 { ILL_COPROC, "ILL_COPROC" },
563 { ILL_BADSTK, "ILL_BADSTK" },
564 { 0, NULL },
565};
566
567static struct xlat sigfpe_codes[] = {
568 { FPE_INTDIV, "FPE_INTDIV" },
569 { FPE_INTOVF, "FPE_INTOVF" },
570 { FPE_FLTDIV, "FPE_FLTDIV" },
571 { FPE_FLTOVF, "FPE_FLTOVF" },
572 { FPE_FLTUND, "FPE_FLTUND" },
573 { FPE_FLTRES, "FPE_FLTRES" },
574 { FPE_FLTINV, "FPE_FLTINV" },
575 { FPE_FLTSUB, "FPE_FLTSUB" },
576 { 0, NULL },
577};
578
579static struct xlat sigtrap_codes[] = {
580 { TRAP_BRKPT, "TRAP_BRKPT" },
581 { TRAP_TRACE, "TRAP_TRACE" },
582 { 0, NULL },
583};
584
585static struct xlat sigchld_codes[] = {
586 { CLD_EXITED, "CLD_EXITED" },
587 { CLD_KILLED, "CLD_KILLED" },
588 { CLD_DUMPED, "CLD_DUMPED" },
589 { CLD_TRAPPED, "CLD_TRAPPED" },
590 { CLD_STOPPED, "CLD_STOPPED" },
591 { CLD_CONTINUED,"CLD_CONTINUED" },
592 { 0, NULL },
593};
594
595static struct xlat sigpoll_codes[] = {
596 { POLL_IN, "POLL_IN" },
597 { POLL_OUT, "POLL_OUT" },
598 { POLL_MSG, "POLL_MSG" },
599 { POLL_ERR, "POLL_ERR" },
600 { POLL_PRI, "POLL_PRI" },
601 { POLL_HUP, "POLL_HUP" },
602 { 0, NULL },
603};
604
605static struct xlat sigprof_codes[] = {
606#ifdef PROF_SIG
607 { PROF_SIG, "PROF_SIG" },
608#endif
609 { 0, NULL },
610};
611
612#ifdef SIGEMT
613static struct xlat sigemt_codes[] = {
614#ifdef EMT_TAGOVF
615 { EMT_TAGOVF, "EMT_TAGOVF" },
616#endif
617 { 0, NULL },
618};
619#endif
620
621static struct xlat sigsegv_codes[] = {
622 { SEGV_MAPERR, "SEGV_MAPERR" },
623 { SEGV_ACCERR, "SEGV_ACCERR" },
624 { 0, NULL },
625};
626
627static struct xlat sigbus_codes[] = {
628 { BUS_ADRALN, "BUS_ADRALN" },
629 { BUS_ADRERR, "BUS_ADRERR" },
630 { BUS_OBJERR, "BUS_OBJERR" },
631 { 0, NULL },
632};
633
634void
635printsiginfo(sip, verbose)
636siginfo_t *sip;
637int verbose;
638{
639 char *code;
640
641 if (sip->si_signo == 0) {
642 tprintf ("{}");
643 return;
644 }
645 tprintf("{si_signo=");
646 printsignal(sip->si_signo);
647 code = xlookup(siginfo_codes, sip->si_code);
648 if (!code) {
649 switch (sip->si_signo) {
650 case SIGTRAP:
651 code = xlookup(sigtrap_codes, sip->si_code);
652 break;
653 case SIGCHLD:
654 code = xlookup(sigchld_codes, sip->si_code);
655 break;
656 case SIGPOLL:
657 code = xlookup(sigpoll_codes, sip->si_code);
658 break;
659 case SIGPROF:
660 code = xlookup(sigprof_codes, sip->si_code);
661 break;
662 case SIGILL:
663 code = xlookup(sigill_codes, sip->si_code);
664 break;
665#ifdef SIGEMT
666 case SIGEMT:
667 code = xlookup(sigemt_codes, sip->si_code);
668 break;
669#endif
670 case SIGFPE:
671 code = xlookup(sigfpe_codes, sip->si_code);
672 break;
673 case SIGSEGV:
674 code = xlookup(sigsegv_codes, sip->si_code);
675 break;
676 case SIGBUS:
677 code = xlookup(sigbus_codes, sip->si_code);
678 break;
679 }
680 }
681 if (code)
682 tprintf(", si_code=%s", code);
683 else
684 tprintf(", si_code=%#x", sip->si_code);
685#ifdef SI_NOINFO
686 if (sip->si_code != SI_NOINFO)
687#endif
688 {
689 if (sip->si_errno) {
690 if (sip->si_errno < 0 || sip->si_errno >= nerrnos)
691 tprintf(", si_errno=%d", sip->si_errno);
692 else
693 tprintf(", si_errno=%s",
694 errnoent[sip->si_errno]);
695 }
696#ifdef SI_FROMUSER
697 if (SI_FROMUSER(sip)) {
698 tprintf(", si_pid=%ld, si_uid=%ld",
699 sip->si_pid, sip->si_uid);
700#ifdef SI_QUEUE
701 switch (sip->si_code) {
702 case SI_QUEUE:
703#ifdef SI_TIMER
704 case SI_TIMER:
705#endif /* SI_QUEUE */
706 case SI_ASYNCIO:
707#ifdef SI_MESGQ
708 case SI_MESGQ:
709#endif /* SI_MESGQ */
710 tprintf(", si_value=%d",
711 sip->si_value.sival_int);
712 break;
713 }
714#endif /* SI_QUEUE */
715 }
716 else
717#endif /* SI_FROMUSER */
718 {
719 switch (sip->si_signo) {
720 case SIGCHLD:
721 tprintf(", si_pid=%ld, si_status=",
722 (long) sip->si_pid);
723 if (sip->si_code == CLD_EXITED)
724 tprintf("%d", sip->si_status);
725 else
726 printsignal(sip->si_status);
727#if LINUX
728 if (!verbose)
729 tprintf(", ...");
730 else
731 tprintf(", si_utime=%lu, si_stime=%lu",
732 sip->si_utime,
733 sip->si_stime);
734#endif
735 break;
736 case SIGILL: case SIGFPE:
737 case SIGSEGV: case SIGBUS:
738 tprintf(", si_addr=%#lx",
739 (unsigned long) sip->si_addr);
740 break;
741 case SIGPOLL:
742 switch (sip->si_code) {
743 case POLL_IN: case POLL_OUT: case POLL_MSG:
744 tprintf(", si_band=%ld",
745 (long) sip->si_band);
746 break;
747 }
748 break;
749#ifdef LINUX
750 default:
751 tprintf(", si_pid=%lu, si_uid=%lu, ",
752 (unsigned long) sip->si_pid,
753 (unsigned long) sip->si_uid);
754 if (!verbose)
755 tprintf("...");
756 else {
757 tprintf("si_value={int=%u, ptr=%#lx}",
758 sip->si_int,
759 (unsigned long) sip->si_ptr);
760 }
761#endif
Roland McGratha39c5a12002-12-17 05:10:37 +0000762
John Hughes58265892001-10-18 15:13:53 +0000763 }
764 }
765 }
766 tprintf("}");
767}
768
769#endif /* SVR4 || LINUX */
770
771#ifdef LINUX
772
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000773static void
774parse_sigset_t (const char *str, sigset_t *set)
775{
Roland McGrathc38feca2003-10-01 07:50:28 +0000776 const char *p;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000777 unsigned int digit;
778 int i;
779
780 sigemptyset(set);
781
Roland McGrathc38feca2003-10-01 07:50:28 +0000782 p = strchr(str, '\n');
783 if (p == NULL)
784 p = strchr(str, '\0');
785 for (i = 0; p-- > str; i += 4) {
786 if (*p >= '0' && *p <= '9')
787 digit = *p - '0';
788 else if (*p >= 'a' && *p <= 'f')
789 digit = *p - 'a';
790 else if (*p >= 'A' && *p <= 'F')
791 digit = *p - 'A';
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000792 else
Roland McGrathc38feca2003-10-01 07:50:28 +0000793 break;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000794 if (digit & 1)
795 sigaddset(set, i + 1);
796 if (digit & 2)
797 sigaddset(set, i + 2);
798 if (digit & 4)
799 sigaddset(set, i + 3);
800 if (digit & 8)
801 sigaddset(set, i + 4);
802 }
803}
804
805#endif
806
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000807/*
808 * Check process TCP for the disposition of signal SIG.
809 * Return 1 if the process would somehow manage to survive signal SIG,
810 * else return 0. This routine will never be called with SIGKILL.
811 */
812int
813sigishandled(tcp, sig)
814struct tcb *tcp;
815int sig;
816{
817#ifdef LINUX
818 int sfd;
819 char sname[32];
Wichert Akkermand5c2dae2001-04-12 09:10:24 +0000820 char buf[2048];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000821 char *s;
822 int i;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000823 sigset_t ignored, caught;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000824#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000825#ifdef SVR4
826 /*
827 * Since procfs doesn't interfere with wait I think it is safe
828 * to punt on this question. If not, the information is there.
829 */
830 return 1;
831#else /* !SVR4 */
832 switch (sig) {
833 case SIGCONT:
834 case SIGSTOP:
835 case SIGTSTP:
836 case SIGTTIN:
837 case SIGTTOU:
838 case SIGCHLD:
839 case SIGIO:
840#if defined(SIGURG) && SIGURG != SIGIO
841 case SIGURG:
842#endif
843 case SIGWINCH:
844 /* Gloria Gaynor says ... */
845 return 1;
846 default:
847 break;
848 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000849#endif /* !SVR4 */
Wichert Akkermand5c2dae2001-04-12 09:10:24 +0000850#ifdef LINUX
851
852 /* This is incredibly costly but it's worth it. */
853 /* NOTE: LinuxThreads internally uses SIGRTMIN, SIGRTMIN + 1 and
854 SIGRTMIN + 2, so we can't use the obsolete /proc/%d/stat which
855 doesn't handle real-time signals). */
856 sprintf(sname, "/proc/%d/status", tcp->pid);
857 if ((sfd = open(sname, O_RDONLY)) == -1) {
858 perror(sname);
859 return 1;
860 }
861 i = read(sfd, buf, sizeof(buf));
862 buf[i] = '\0';
863 close(sfd);
864 /*
865 * Skip the extraneous fields. We need to skip
866 * command name has any spaces in it. So be it.
867 */
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000868 s = strstr(buf, "SigIgn:\t");
Wichert Akkermand5c2dae2001-04-12 09:10:24 +0000869 if (!s)
870 {
871 fprintf(stderr, "/proc/pid/status format error\n");
872 return 1;
873 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000874 parse_sigset_t(s + 8, &ignored);
Wichert Akkermand5c2dae2001-04-12 09:10:24 +0000875
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000876 s = strstr(buf, "SigCgt:\t");
877 if (!s)
878 {
879 fprintf(stderr, "/proc/pid/status format error\n");
880 return 1;
881 }
882 parse_sigset_t(s + 8, &caught);
Wichert Akkermand5c2dae2001-04-12 09:10:24 +0000883
884#ifdef DEBUG
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000885 fprintf(stderr, "sigs: %016qx %016qx (sig=%d)\n",
886 *(long long *) &ignored, *(long long *) &caught, sig);
Wichert Akkermand5c2dae2001-04-12 09:10:24 +0000887#endif
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000888 if (sigismember(&ignored, sig) || sigismember(&caught, sig))
Wichert Akkermand5c2dae2001-04-12 09:10:24 +0000889 return 1;
890#endif /* LINUX */
891
892#ifdef SUNOS4
893 void (*u_signal)();
894
895 if (upeek(tcp->pid, uoff(u_signal[0]) + sig*sizeof(u_signal),
896 (long *) &u_signal) < 0) {
897 return 0;
898 }
899 if (u_signal != SIG_DFL)
900 return 1;
901#endif /* SUNOS4 */
902
903 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000904}
905
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000906#if defined(SUNOS4) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000907
908int
909sys_sigvec(tcp)
910struct tcb *tcp;
911{
912 struct sigvec sv;
913 long addr;
914
915 if (entering(tcp)) {
916 printsignal(tcp->u_arg[0]);
917 tprintf(", ");
918 addr = tcp->u_arg[1];
919 } else {
920 addr = tcp->u_arg[2];
921 }
922 if (addr == 0)
923 tprintf("NULL");
924 else if (!verbose(tcp))
925 tprintf("%#lx", addr);
926 else if (umove(tcp, addr, &sv) < 0)
927 tprintf("{...}");
928 else {
929 switch ((int) sv.sv_handler) {
930 case (int) SIG_ERR:
931 tprintf("{SIG_ERR}");
932 break;
933 case (int) SIG_DFL:
934 tprintf("{SIG_DFL}");
935 break;
936 case (int) SIG_IGN:
937 if (tcp->u_arg[0] == SIGTRAP) {
938 tcp->flags |= TCB_SIGTRAPPED;
939 kill(tcp->pid, SIGSTOP);
940 }
941 tprintf("{SIG_IGN}");
942 break;
943 case (int) SIG_HOLD:
944 if (tcp->u_arg[0] == SIGTRAP) {
945 tcp->flags |= TCB_SIGTRAPPED;
946 kill(tcp->pid, SIGSTOP);
947 }
948 tprintf("SIG_HOLD");
949 break;
950 default:
951 if (tcp->u_arg[0] == SIGTRAP) {
952 tcp->flags |= TCB_SIGTRAPPED;
953 kill(tcp->pid, SIGSTOP);
954 }
955 tprintf("{%#lx, ", (unsigned long) sv.sv_handler);
Nate Sammons4a121431999-04-06 01:19:39 +0000956 printsigmask(&sv.sv_mask, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000957 tprintf(", ");
958 if (!printflags(sigvec_flags, sv.sv_flags))
959 tprintf("0");
960 tprintf("}");
961 }
962 }
963 if (entering(tcp))
964 tprintf(", ");
965 return 0;
966}
967
968int
969sys_sigpause(tcp)
970struct tcb *tcp;
971{
972 if (entering(tcp)) { /* WTA: UD had a bug here: he forgot the braces */
Nate Sammons4a121431999-04-06 01:19:39 +0000973 sigset_t sigm;
974 long_to_sigset(tcp->u_arg[0], &sigm);
975 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000976 }
977 return 0;
978}
979
980int
981sys_sigstack(tcp)
982struct tcb *tcp;
983{
984 struct sigstack ss;
985 long addr;
986
987 if (entering(tcp))
988 addr = tcp->u_arg[0];
989 else
990 addr = tcp->u_arg[1];
991 if (addr == 0)
992 tprintf("NULL");
993 else if (umove(tcp, addr, &ss) < 0)
994 tprintf("%#lx", addr);
995 else {
996 tprintf("{ss_sp %#lx ", (unsigned long) ss.ss_sp);
997 tprintf("ss_onstack %s}", ss.ss_onstack ? "YES" : "NO");
998 }
999 if (entering(tcp))
1000 tprintf(", ");
1001 return 0;
1002}
1003
1004int
1005sys_sigcleanup(tcp)
1006struct tcb *tcp;
1007{
1008 return 0;
1009}
1010
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001011#endif /* SUNOS4 || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001012
1013#ifndef SVR4
1014
1015int
1016sys_sigsetmask(tcp)
1017struct tcb *tcp;
1018{
1019 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001020 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +00001021 long_to_sigset(tcp->u_arg[0], &sigm);
1022 printsigmask(&sigm, 0);
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001023#ifndef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001024 if ((tcp->u_arg[0] & sigmask(SIGTRAP))) {
1025 /* Mark attempt to block SIGTRAP */
1026 tcp->flags |= TCB_SIGTRAPPED;
1027 /* Send unblockable signal */
1028 kill(tcp->pid, SIGSTOP);
1029 }
Roland McGratha39c5a12002-12-17 05:10:37 +00001030#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001031 }
1032 else if (!syserror(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001033 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +00001034 long_to_sigset(tcp->u_rval, &sigm);
1035 tcp->auxstr = sprintsigmask("old mask ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001036
1037 return RVAL_HEX | RVAL_STR;
1038 }
1039 return 0;
1040}
1041
1042int
1043sys_sigblock(tcp)
1044struct tcb *tcp;
1045{
1046 return sys_sigsetmask(tcp);
1047}
1048
1049#endif /* !SVR4 */
1050
1051#ifdef HAVE_SIGACTION
1052
1053#ifdef LINUX
1054struct old_sigaction {
1055 __sighandler_t __sa_handler;
1056 unsigned long sa_mask;
1057 unsigned long sa_flags;
1058 void (*sa_restorer)(void);
1059};
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001060#define SA_HANDLER __sa_handler
1061#endif /* LINUX */
1062
Roland McGratha39c5a12002-12-17 05:10:37 +00001063#ifndef SA_HANDLER
1064#define SA_HANDLER sa_handler
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001065#endif
1066
1067int
1068sys_sigaction(tcp)
1069struct tcb *tcp;
1070{
1071 long addr;
Nate Sammons4a121431999-04-06 01:19:39 +00001072#ifdef LINUX
John Hughes1e4cb342001-03-06 09:25:46 +00001073 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001074 struct old_sigaction sa;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001075#else
1076 struct sigaction sa;
1077#endif
1078
1079
1080 if (entering(tcp)) {
1081 printsignal(tcp->u_arg[0]);
1082 tprintf(", ");
1083 addr = tcp->u_arg[1];
1084 } else
1085 addr = tcp->u_arg[2];
1086 if (addr == 0)
1087 tprintf("NULL");
1088 else if (!verbose(tcp))
1089 tprintf("%#lx", addr);
1090 else if (umove(tcp, addr, &sa) < 0)
1091 tprintf("{...}");
1092 else {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001093 switch ((long) sa.SA_HANDLER) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001094 case (long) SIG_ERR:
1095 tprintf("{SIG_ERR}");
1096 break;
1097 case (long) SIG_DFL:
1098 tprintf("{SIG_DFL}");
1099 break;
1100 case (long) SIG_IGN:
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001101#ifndef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001102 if (tcp->u_arg[0] == SIGTRAP) {
1103 tcp->flags |= TCB_SIGTRAPPED;
1104 kill(tcp->pid, SIGSTOP);
1105 }
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001106#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001107 tprintf("{SIG_IGN}");
1108 break;
1109 default:
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001110#ifndef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001111 if (tcp->u_arg[0] == SIGTRAP) {
1112 tcp->flags |= TCB_SIGTRAPPED;
1113 kill(tcp->pid, SIGSTOP);
1114 }
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001115#endif /* !USE_PROCFS */
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001116 tprintf("{%#lx, ", (long) sa.SA_HANDLER);
Wichert Akkerman48214be1999-11-26 09:55:42 +00001117#ifndef LINUX
1118 printsigmask (&sa.sa_mask, 0);
1119#else
Nate Sammons4a121431999-04-06 01:19:39 +00001120 long_to_sigset(sa.sa_mask, &sigset);
1121 printsigmask(&sigset, 0);
Wichert Akkerman48214be1999-11-26 09:55:42 +00001122#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001123 tprintf(", ");
1124 if (!printflags(sigact_flags, sa.sa_flags))
1125 tprintf("0");
Roland McGrath2638cb42002-12-15 23:58:41 +00001126#ifdef SA_RESTORER
1127 if (sa.sa_flags & SA_RESTORER)
1128 tprintf(", %p", sa.sa_restorer);
1129#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001130 tprintf("}");
1131 }
1132 }
1133 if (entering(tcp))
1134 tprintf(", ");
1135#ifdef LINUX
1136 else
1137 tprintf(", %#lx", (unsigned long) sa.sa_restorer);
1138#endif
1139 return 0;
1140}
1141
1142int
1143sys_signal(tcp)
1144struct tcb *tcp;
1145{
1146 if (entering(tcp)) {
1147 printsignal(tcp->u_arg[0]);
Wichert Akkerman16a03d22000-08-10 02:14:04 +00001148 tprintf(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001149 switch (tcp->u_arg[1]) {
1150 case (int) SIG_ERR:
1151 tprintf("SIG_ERR");
1152 break;
1153 case (int) SIG_DFL:
1154 tprintf("SIG_DFL");
1155 break;
1156 case (int) SIG_IGN:
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001157#ifndef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001158 if (tcp->u_arg[0] == SIGTRAP) {
1159 tcp->flags |= TCB_SIGTRAPPED;
1160 kill(tcp->pid, SIGSTOP);
1161 }
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001162#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001163 tprintf("SIG_IGN");
1164 break;
1165 default:
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001166#ifndef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001167 if (tcp->u_arg[0] == SIGTRAP) {
1168 tcp->flags |= TCB_SIGTRAPPED;
1169 kill(tcp->pid, SIGSTOP);
1170 }
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001171#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001172 tprintf("%#lx", tcp->u_arg[1]);
1173 }
Wichert Akkerman16a03d22000-08-10 02:14:04 +00001174 return 0;
1175 }
1176 else {
1177 switch (tcp->u_rval) {
1178 case (int) SIG_ERR:
1179 tcp->auxstr = "SIG_ERR"; break;
1180 case (int) SIG_DFL:
1181 tcp->auxstr = "SIG_DFL"; break;
1182 case (int) SIG_IGN:
1183 tcp->auxstr = "SIG_IGN"; break;
1184 default:
1185 tcp->auxstr = NULL;
1186 }
1187 return RVAL_HEX | RVAL_STR;
1188 }
1189}
1190
1191int
1192sys_sighold(tcp)
1193struct tcb *tcp;
1194{
1195 if (entering(tcp)) {
1196 printsignal(tcp->u_arg[0]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001197 }
1198 return 0;
1199}
1200
1201#endif /* HAVE_SIGACTION */
1202
1203#ifdef LINUX
1204
1205int
1206sys_sigreturn(tcp)
1207struct tcb *tcp;
1208{
Roland McGrath0f87c492003-06-03 23:29:04 +00001209#ifdef ARM
1210 struct pt_regs regs;
1211 struct sigcontext_struct sc;
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00001212
Roland McGrath0f87c492003-06-03 23:29:04 +00001213 if (entering(tcp)) {
1214 tcp->u_arg[0] = 0;
1215
1216 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)&regs) == -1)
1217 return 0;
1218
1219 if (umove(tcp, regs.ARM_sp, &sc) < 0)
1220 return 0;
1221
1222 tcp->u_arg[0] = 1;
1223 tcp->u_arg[1] = sc.oldmask;
1224 } else {
1225 sigset_t sigm;
1226 long_to_sigset(tcp->u_arg[1], &sigm);
1227 tcp->u_rval = tcp->u_error = 0;
1228 if (tcp->u_arg[0] == 0)
1229 return 0;
1230 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1231 return RVAL_NONE | RVAL_STR;
1232 }
1233 return 0;
1234#elif defined(S390) || defined(S390X)
1235 long usp;
1236 struct sigcontext_struct sc;
1237
1238 if (entering(tcp)) {
1239 tcp->u_arg[0] = 0;
1240 if (upeek(tcp->pid,PT_GPR15,&usp)<0)
1241 return 0;
1242 if (umove(tcp, usp+__SIGNAL_FRAMESIZE, &sc) < 0)
1243 return 0;
1244 tcp->u_arg[0] = 1;
1245 memcpy(&tcp->u_arg[1],&sc.oldmask[0],sizeof(sigset_t));
1246 } else {
1247 tcp->u_rval = tcp->u_error = 0;
1248 if (tcp->u_arg[0] == 0)
1249 return 0;
1250 tcp->auxstr = sprintsigmask("mask now ",(sigset_t *)&tcp->u_arg[1],0);
1251 return RVAL_NONE | RVAL_STR;
1252 }
1253 return 0;
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00001254#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001255#ifdef I386
1256 long esp;
1257 struct sigcontext_struct sc;
1258
1259 if (entering(tcp)) {
1260 tcp->u_arg[0] = 0;
1261 if (upeek(tcp->pid, 4*UESP, &esp) < 0)
1262 return 0;
1263 if (umove(tcp, esp, &sc) < 0)
1264 return 0;
1265 tcp->u_arg[0] = 1;
1266 tcp->u_arg[1] = sc.oldmask;
1267 }
1268 else {
1269 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +00001270 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001271 tcp->u_rval = tcp->u_error = 0;
1272 if (tcp->u_arg[0] == 0)
1273 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +00001274 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001275 return RVAL_NONE | RVAL_STR;
1276 }
1277 return 0;
1278#else /* !I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001279#ifdef IA64
1280 struct sigcontext sc;
1281 long sp;
1282
1283 if (entering(tcp)) {
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +00001284 /* offset of sigcontext in the kernel's sigframe structure: */
1285# define SIGFRAME_SC_OFFSET 0x90
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001286 tcp->u_arg[0] = 0;
1287 if (upeek(tcp->pid, PT_R12, &sp) < 0)
1288 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +00001289 if (umove(tcp, sp + 16 + SIGFRAME_SC_OFFSET, &sc) < 0)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001290 return 0;
1291 tcp->u_arg[0] = 1;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +00001292 memcpy(tcp->u_arg + 1, &sc.sc_mask, sizeof(sc.sc_mask));
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001293 }
1294 else {
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +00001295 sigset_t sigm;
1296
1297 memcpy(&sigm, tcp->u_arg + 1, sizeof (sigm));
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001298 tcp->u_rval = tcp->u_error = 0;
1299 if (tcp->u_arg[0] == 0)
1300 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +00001301 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001302 return RVAL_NONE | RVAL_STR;
1303 }
1304 return 0;
1305#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001306#ifdef POWERPC
Roland McGrath0f87c492003-06-03 23:29:04 +00001307 long esp;
1308 struct sigcontext_struct sc;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001309
Roland McGrath0f87c492003-06-03 23:29:04 +00001310 if (entering(tcp)) {
1311 tcp->u_arg[0] = 0;
1312 if (upeek(tcp->pid, sizeof(unsigned long)*PT_R1, &esp) < 0)
1313 return 0;
1314 if (umove(tcp, esp, &sc) < 0)
1315 return 0;
1316 tcp->u_arg[0] = 1;
1317 tcp->u_arg[1] = sc.oldmask;
1318 }
1319 else {
1320 sigset_t sigm;
1321 long_to_sigset(tcp->u_arg[1], &sigm);
1322 tcp->u_rval = tcp->u_error = 0;
1323 if (tcp->u_arg[0] == 0)
1324 return 0;
1325 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1326 return RVAL_NONE | RVAL_STR;
1327 }
1328 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001329#else /* !POWERPC */
1330#ifdef M68K
1331 long usp;
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001332 struct sigcontext sc;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001333
1334 if (entering(tcp)) {
Roland McGrath0f87c492003-06-03 23:29:04 +00001335 tcp->u_arg[0] = 0;
1336 if (upeek(tcp->pid, 4*PT_USP, &usp) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001337 return 0;
Roland McGrath0f87c492003-06-03 23:29:04 +00001338 if (umove(tcp, usp, &sc) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001339 return 0;
Roland McGrath0f87c492003-06-03 23:29:04 +00001340 tcp->u_arg[0] = 1;
1341 tcp->u_arg[1] = sc.sc_mask;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001342 }
1343 else {
Roland McGrath0f87c492003-06-03 23:29:04 +00001344 sigset_t sigm;
1345 long_to_sigset(tcp->u_arg[1], &sigm);
1346 tcp->u_rval = tcp->u_error = 0;
1347 if (tcp->u_arg[0] == 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001348 return 0;
Roland McGrath0f87c492003-06-03 23:29:04 +00001349 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1350 return RVAL_NONE | RVAL_STR;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001351 }
1352 return 0;
1353#else /* !M68K */
1354#ifdef ALPHA
1355 long fp;
1356 struct sigcontext_struct sc;
1357
1358 if (entering(tcp)) {
Roland McGrath0f87c492003-06-03 23:29:04 +00001359 tcp->u_arg[0] = 0;
1360 if (upeek(tcp->pid, REG_FP, &fp) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001361 return 0;
Roland McGrath0f87c492003-06-03 23:29:04 +00001362 if (umove(tcp, fp, &sc) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001363 return 0;
Roland McGrath0f87c492003-06-03 23:29:04 +00001364 tcp->u_arg[0] = 1;
1365 tcp->u_arg[1] = sc.sc_mask;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001366 }
1367 else {
Roland McGrath0f87c492003-06-03 23:29:04 +00001368 sigset_t sigm;
1369 long_to_sigset(tcp->u_arg[1], &sigm);
1370 tcp->u_rval = tcp->u_error = 0;
1371 if (tcp->u_arg[0] == 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001372 return 0;
Roland McGrath0f87c492003-06-03 23:29:04 +00001373 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1374 return RVAL_NONE | RVAL_STR;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001375 }
1376 return 0;
1377#else
1378#ifdef SPARC
1379 long i1;
Wichert Akkerman9ce1a631999-08-29 23:15:07 +00001380 struct regs regs;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001381 m_siginfo_t si;
1382
1383 if(ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
Roland McGrath0f87c492003-06-03 23:29:04 +00001384 perror("sigreturn: PTRACE_GETREGS ");
1385 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001386 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001387 if(entering(tcp)) {
1388 tcp->u_arg[0] = 0;
Wichert Akkerman9ce1a631999-08-29 23:15:07 +00001389 i1 = regs.r_o1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001390 if(umove(tcp, i1, &si) < 0) {
1391 perror("sigreturn: umove ");
1392 return 0;
1393 }
1394 tcp->u_arg[0] = 1;
1395 tcp->u_arg[1] = si.si_mask;
1396 } else {
1397 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +00001398 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001399 tcp->u_rval = tcp->u_error = 0;
1400 if(tcp->u_arg[0] == 0)
1401 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +00001402 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001403 return RVAL_NONE | RVAL_STR;
1404 }
1405 return 0;
Roland McGratha39c5a12002-12-17 05:10:37 +00001406#else
Wichert Akkermanf90da011999-10-31 21:15:38 +00001407#ifdef MIPS
1408 long sp;
1409 struct sigcontext sc;
1410
1411 if(entering(tcp)) {
1412 tcp->u_arg[0] = 0;
1413 if (upeek(tcp->pid, REG_SP, &sp) < 0)
1414 return 0;
1415 if (umove(tcp, sp, &sc) < 0)
1416 return 0;
1417 tcp->u_arg[0] = 1;
1418 tcp->u_arg[1] = sc.sc_sigset;
1419 } else {
1420 tcp->u_rval = tcp->u_error = 0;
1421 if(tcp->u_arg[0] == 0)
1422 return 0;
1423 tcp->auxstr = sprintsigmask("mask now ", tcp->u_arg[1]);
1424 return RVAL_NONE | RVAL_STR;
1425 }
1426 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +00001427#else
Michal Ludvig0e035502002-09-23 15:41:01 +00001428#warning No sys_sigreturn() for this architecture
1429#warning (no problem, just a reminder :-)
Wichert Akkermanc1652e22001-03-27 12:17:16 +00001430 return 0;
Wichert Akkermanf90da011999-10-31 21:15:38 +00001431#endif /* MIPS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001432#endif /* SPARC */
1433#endif /* ALPHA */
1434#endif /* !M68K */
1435#endif /* !POWERPC */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001436#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001437#endif /* !I386 */
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00001438#endif /* S390 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001439}
1440
1441int
1442sys_siggetmask(tcp)
1443struct tcb *tcp;
1444{
1445 if (exiting(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001446 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +00001447 long_to_sigset(tcp->u_rval, &sigm);
1448 tcp->auxstr = sprintsigmask("mask ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001449 }
1450 return RVAL_HEX | RVAL_STR;
1451}
1452
1453int
1454sys_sigsuspend(tcp)
1455struct tcb *tcp;
1456{
1457 if (entering(tcp)) {
1458 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +00001459 long_to_sigset(tcp->u_arg[2], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001460#if 0
1461 /* first two are not really arguments, but print them anyway */
1462 /* nevermind, they are an anachronism now, too bad... */
1463 tprintf("%d, %#x, ", tcp->u_arg[0], tcp->u_arg[1]);
1464#endif
Nate Sammons4a121431999-04-06 01:19:39 +00001465 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001466 }
1467 return 0;
1468}
1469
1470#endif /* LINUX */
1471
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001472#if defined(SVR4) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001473
1474int
1475sys_sigsuspend(tcp)
1476struct tcb *tcp;
1477{
1478 sigset_t sigset;
1479
1480 if (entering(tcp)) {
1481 if (umove(tcp, tcp->u_arg[0], &sigset) < 0)
1482 tprintf("[?]");
1483 else
Wichert Akkerman46956571999-11-26 10:12:59 +00001484 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001485 }
1486 return 0;
1487}
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001488#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001489static struct xlat ucontext_flags[] = {
1490 { UC_SIGMASK, "UC_SIGMASK" },
1491 { UC_STACK, "UC_STACK" },
1492 { UC_CPU, "UC_CPU" },
1493#ifdef UC_FPU
1494 { UC_FPU, "UC_FPU" },
1495#endif
1496#ifdef UC_INTR
1497 { UC_INTR, "UC_INTR" },
1498#endif
1499 { 0, NULL },
1500};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001501#endif /* !FREEBSD */
1502#endif /* SVR4 || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001503
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001504#if defined SVR4 || defined LINUX || defined FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001505#if defined LINUX && !defined SS_ONSTACK
1506#define SS_ONSTACK 1
1507#define SS_DISABLE 2
1508#if __GLIBC_MINOR__ == 0
1509typedef struct
1510{
1511 __ptr_t ss_sp;
1512 int ss_flags;
1513 size_t ss_size;
1514} stack_t;
1515#endif
1516#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001517#ifdef FREEBSD
1518#define stack_t struct sigaltstack
1519#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001520
1521static struct xlat sigaltstack_flags[] = {
1522 { SS_ONSTACK, "SS_ONSTACK" },
1523 { SS_DISABLE, "SS_DISABLE" },
1524 { 0, NULL },
1525};
1526#endif
1527
1528#ifdef SVR4
1529static void
1530printcontext(tcp, ucp)
1531struct tcb *tcp;
1532ucontext_t *ucp;
1533{
1534 tprintf("{");
1535 if (!abbrev(tcp)) {
1536 tprintf("uc_flags=");
1537 if (!printflags(ucontext_flags, ucp->uc_flags))
1538 tprintf("0");
1539 tprintf(", uc_link=%#lx, ", (unsigned long) ucp->uc_link);
1540 }
1541 tprintf("uc_sigmask=");
John Hughes70c5e7a2001-05-15 15:09:14 +00001542 printsigmask(&ucp->uc_sigmask, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001543 if (!abbrev(tcp)) {
1544 tprintf(", uc_stack={ss_sp=%#lx, ss_size=%d, ss_flags=",
1545 (unsigned long) ucp->uc_stack.ss_sp,
1546 ucp->uc_stack.ss_size);
1547 if (!printflags(sigaltstack_flags, ucp->uc_stack.ss_flags))
1548 tprintf("0");
1549 tprintf("}");
1550 }
1551 tprintf(", ...}");
1552}
1553
1554int
1555sys_getcontext(tcp)
1556struct tcb *tcp;
1557{
1558 ucontext_t uc;
1559
Wichert Akkerman16a03d22000-08-10 02:14:04 +00001560 if (exiting(tcp)) {
1561 if (tcp->u_error)
1562 tprintf("%#lx", tcp->u_arg[0]);
1563 else if (!tcp->u_arg[0])
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001564 tprintf("NULL");
1565 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
1566 tprintf("{...}");
1567 else
1568 printcontext(tcp, &uc);
1569 }
1570 return 0;
1571}
1572
1573int
1574sys_setcontext(tcp)
1575struct tcb *tcp;
1576{
1577 ucontext_t uc;
1578
1579 if (entering(tcp)) {
1580 if (!tcp->u_arg[0])
1581 tprintf("NULL");
1582 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
1583 tprintf("{...}");
1584 else
1585 printcontext(tcp, &uc);
1586 }
1587 else {
1588 tcp->u_rval = tcp->u_error = 0;
1589 if (tcp->u_arg[0] == 0)
1590 return 0;
1591 return RVAL_NONE;
1592 }
1593 return 0;
1594}
1595
1596#endif /* SVR4 */
1597
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001598#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001599
1600static int
1601print_stack_t(tcp, addr)
1602struct tcb *tcp;
1603unsigned long addr;
1604{
1605 stack_t ss;
1606 if (umove(tcp, addr, &ss) < 0)
1607 return -1;
1608 tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp);
1609 if (!printflags(sigaltstack_flags, ss.ss_flags))
1610 tprintf("0");
1611 tprintf(", ss_size=%lu}", (unsigned long) ss.ss_size);
1612 return 0;
1613}
1614
1615int
1616sys_sigaltstack(tcp)
1617 struct tcb *tcp;
1618{
1619 if (entering(tcp)) {
1620 if (tcp->u_arg[0] == 0)
1621 tprintf("NULL");
1622 else if (print_stack_t(tcp, tcp->u_arg[0]) < 0)
1623 return -1;
1624 }
1625 else {
1626 tprintf(", ");
1627 if (tcp->u_arg[1] == 0)
1628 tprintf("NULL");
1629 else if (print_stack_t(tcp, tcp->u_arg[1]) < 0)
1630 return -1;
1631 }
1632 return 0;
1633}
1634#endif
1635
1636#ifdef HAVE_SIGACTION
1637
1638int
1639sys_sigprocmask(tcp)
1640struct tcb *tcp;
1641{
1642#ifdef ALPHA
1643 if (entering(tcp)) {
1644 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1645 tprintf(", ");
Nate Sammons4a121431999-04-06 01:19:39 +00001646 printsigmask(tcp->u_arg[1], 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001647 }
1648 else if (!syserror(tcp)) {
Nate Sammons4a121431999-04-06 01:19:39 +00001649 tcp->auxstr = sprintsigmask("old mask ", tcp->u_rval, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001650 return RVAL_HEX | RVAL_STR;
1651 }
1652#else /* !ALPHA */
1653 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001654
1655 if (entering(tcp)) {
1656#ifdef SVR4
1657 if (tcp->u_arg[0] == 0)
1658 tprintf("0");
1659 else
1660#endif /* SVR4 */
1661 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1662 tprintf(", ");
1663 if (!tcp->u_arg[1])
1664 tprintf("NULL, ");
Nate Sammons4a121431999-04-06 01:19:39 +00001665 else if (copy_sigset(tcp, tcp->u_arg[1], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001666 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001667 else {
Nate Sammons4a121431999-04-06 01:19:39 +00001668 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001669 tprintf(", ");
1670 }
1671 }
1672 else {
1673 if (!tcp->u_arg[2])
1674 tprintf("NULL");
1675 else if (syserror(tcp))
1676 tprintf("%#lx", tcp->u_arg[2]);
Nate Sammons4a121431999-04-06 01:19:39 +00001677 else if (copy_sigset(tcp, tcp->u_arg[2], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001678 tprintf("[?]");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001679 else
Nate Sammons4a121431999-04-06 01:19:39 +00001680 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001681 }
1682#endif /* !ALPHA */
1683 return 0;
1684}
1685
1686#endif /* HAVE_SIGACTION */
1687
1688int
1689sys_kill(tcp)
1690struct tcb *tcp;
1691{
1692 if (entering(tcp)) {
Nate Sammonsce780fc1999-03-29 23:23:13 +00001693 tprintf("%ld, %s", tcp->u_arg[0], signame(tcp->u_arg[1]));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001694 }
1695 return 0;
1696}
1697
1698int
1699sys_killpg(tcp)
1700struct tcb *tcp;
1701{
1702 return sys_kill(tcp);
1703}
1704
Roland McGrath8ffc3522003-07-09 09:47:49 +00001705#ifdef LINUX
1706int
1707sys_tgkill(tcp)
1708 struct tcb *tcp;
1709{
1710 if (entering(tcp)) {
1711 tprintf("%ld, %ld, %s",
1712 tcp->u_arg[0], tcp->u_arg[1], signame(tcp->u_arg[2]));
1713 }
1714 return 0;
1715}
1716#endif
1717
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001718int
1719sys_sigpending(tcp)
1720struct tcb *tcp;
1721{
1722 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001723
1724 if (exiting(tcp)) {
1725 if (syserror(tcp))
1726 tprintf("%#lx", tcp->u_arg[0]);
Nate Sammons4a121431999-04-06 01:19:39 +00001727 else if (copy_sigset(tcp, tcp->u_arg[0], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001728 tprintf("[?]");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001729 else
Wichert Akkerman46956571999-11-26 10:12:59 +00001730 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001731 }
1732 return 0;
1733}
1734
John Hughes42162082001-10-18 14:48:26 +00001735int sys_sigwait(tcp)
1736struct tcb *tcp;
1737{
1738 sigset_t sigset;
1739
1740 if (entering(tcp)) {
1741 if (copy_sigset(tcp, tcp->u_arg[0], &sigset) < 0)
1742 tprintf("[?]");
1743 else
1744 printsigmask(&sigset, 0);
1745 }
1746 else {
1747 if (!syserror(tcp)) {
1748 tcp->auxstr = signalent[tcp->u_rval];
1749 return RVAL_DECIMAL | RVAL_STR;
1750 }
1751 }
1752 return 0;
1753}
1754
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001755#ifdef LINUX
1756
1757 int
1758sys_rt_sigprocmask(tcp)
1759 struct tcb *tcp;
1760{
1761 sigset_t sigset;
1762
Nate Sammons4a121431999-04-06 01:19:39 +00001763 /* Note: arg[3] is the length of the sigset. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001764 if (entering(tcp)) {
1765 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1766 tprintf(", ");
1767 if (!tcp->u_arg[1])
1768 tprintf("NULL, ");
Nate Sammons4a121431999-04-06 01:19:39 +00001769 else if (copy_sigset_len(tcp, tcp->u_arg[1], &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001770 tprintf("%#lx, ", tcp->u_arg[1]);
1771 else {
Nate Sammons4a121431999-04-06 01:19:39 +00001772 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001773 tprintf(", ");
1774 }
1775 }
1776 else {
1777 if (!tcp->u_arg[2])
1778
1779 tprintf("NULL");
1780 else if (syserror(tcp))
1781 tprintf("%#lx", tcp->u_arg[2]);
Nate Sammons4a121431999-04-06 01:19:39 +00001782 else if (copy_sigset_len(tcp, tcp->u_arg[2], &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001783 tprintf("[?]");
1784 else
Nate Sammons4a121431999-04-06 01:19:39 +00001785 printsigmask(&sigset, 1);
Nate Sammonsdab325a1999-03-29 23:33:35 +00001786 tprintf(", %lu", tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001787 }
1788 return 0;
1789}
1790
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001791
1792/* Structure describing the action to be taken when a signal arrives. */
1793struct new_sigaction
1794{
1795 union
1796 {
1797 __sighandler_t __sa_handler;
1798 void (*__sa_sigaction) (int, siginfo_t *, void *);
1799 }
1800 __sigaction_handler;
1801 unsigned long sa_flags;
1802 void (*sa_restorer) (void);
1803 unsigned long int sa_mask[2];
1804};
1805
1806
1807 int
1808sys_rt_sigaction(tcp)
1809 struct tcb *tcp;
1810{
1811 struct new_sigaction sa;
1812 sigset_t sigset;
1813 long addr;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001814
1815 if (entering(tcp)) {
1816 printsignal(tcp->u_arg[0]);
1817 tprintf(", ");
1818 addr = tcp->u_arg[1];
1819 } else
1820 addr = tcp->u_arg[2];
1821 if (addr == 0)
1822 tprintf("NULL");
1823 else if (!verbose(tcp))
1824 tprintf("%#lx", addr);
1825 else if (umove(tcp, addr, &sa) < 0)
1826 tprintf("{...}");
1827 else {
1828 switch ((long) sa.__sigaction_handler.__sa_handler) {
1829 case (long) SIG_ERR:
1830 tprintf("{SIG_ERR}");
1831 break;
1832 case (long) SIG_DFL:
1833 tprintf("{SIG_DFL}");
1834 break;
1835 case (long) SIG_IGN:
1836 tprintf("{SIG_IGN}");
1837 break;
1838 default:
1839 tprintf("{%#lx, ",
1840 (long) sa.__sigaction_handler.__sa_handler);
Nate Sammons4a121431999-04-06 01:19:39 +00001841 sigemptyset(&sigset);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001842#ifdef LINUXSPARC
1843 if (tcp->u_arg[4] <= sizeof(sigset))
1844 memcpy(&sigset, &sa.sa_mask, tcp->u_arg[4]);
1845#else
Nate Sammons4a121431999-04-06 01:19:39 +00001846 if (tcp->u_arg[3] <= sizeof(sigset))
1847 memcpy(&sigset, &sa.sa_mask, tcp->u_arg[3]);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001848#endif
Nate Sammons4a121431999-04-06 01:19:39 +00001849 else
1850 memcpy(&sigset, &sa.sa_mask, sizeof(sigset));
1851 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001852 tprintf(", ");
1853 if (!printflags(sigact_flags, sa.sa_flags))
1854 tprintf("0");
Roland McGrath2638cb42002-12-15 23:58:41 +00001855#ifdef SA_RESTORER
1856 if (sa.sa_flags & SA_RESTORER)
1857 tprintf(", %p", sa.sa_restorer);
1858#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001859 tprintf("}");
1860 }
1861 }
1862 if (entering(tcp))
1863 tprintf(", ");
1864 else
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001865#ifdef LINUXSPARC
1866 tprintf(", %#lx, %lu", tcp->u_arg[3], tcp->u_arg[4]);
1867#elif defined(ALPHA)
1868 tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]);
1869#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001870 tprintf(", %lu", addr = tcp->u_arg[3]);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001871#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001872 return 0;
1873}
1874
1875 int
1876sys_rt_sigpending(tcp)
1877 struct tcb *tcp;
1878{
1879 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001880
1881 if (exiting(tcp)) {
1882 if (syserror(tcp))
1883 tprintf("%#lx", tcp->u_arg[0]);
Nate Sammons4a121431999-04-06 01:19:39 +00001884 else if (copy_sigset_len(tcp, tcp->u_arg[0],
1885 &sigset, tcp->u_arg[1]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001886 tprintf("[?]");
1887 else
Wichert Akkerman46956571999-11-26 10:12:59 +00001888 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001889 }
1890 return 0;
1891}
1892 int
1893sys_rt_sigsuspend(tcp)
1894 struct tcb *tcp;
1895{
1896 if (entering(tcp)) {
1897 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +00001898 if (copy_sigset_len(tcp, tcp->u_arg[0], &sigm, tcp->u_arg[1]) < 0)
1899 tprintf("[?]");
1900 else
1901 printsigmask(&sigm, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001902 }
1903 return 0;
1904}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001905 int
1906sys_rt_sigqueueinfo(tcp)
1907 struct tcb *tcp;
1908{
1909 if (entering(tcp)) {
1910 siginfo_t si;
1911 tprintf("%lu, ", tcp->u_arg[0]);
1912 printsignal(tcp->u_arg[1]);
1913 tprintf(", ");
1914 if (umove(tcp, tcp->u_arg[2], &si) < 0)
1915 tprintf("%#lx", tcp->u_arg[2]);
1916 else
John Hughes58265892001-10-18 15:13:53 +00001917 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001918 }
1919 return 0;
1920}
1921
1922int sys_rt_sigtimedwait(tcp)
1923 struct tcb *tcp;
1924{
1925 if (entering(tcp)) {
1926 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001927
Roland McGratha39c5a12002-12-17 05:10:37 +00001928 if (copy_sigset_len(tcp, tcp->u_arg[0],
Nate Sammons4a121431999-04-06 01:19:39 +00001929 &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001930 tprintf("[?]");
1931 else
Wichert Akkerman46956571999-11-26 10:12:59 +00001932 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001933 tprintf(", ");
1934 }
1935 else {
1936 if (syserror(tcp))
1937 tprintf("%#lx", tcp->u_arg[0]);
1938 else {
1939 siginfo_t si;
1940 if (umove(tcp, tcp->u_arg[1], &si) < 0)
1941 tprintf("%#lx", tcp->u_arg[1]);
1942 else
John Hughes58265892001-10-18 15:13:53 +00001943 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001944 /* XXX For now */
1945 tprintf(", %#lx", tcp->u_arg[2]);
1946 tprintf(", %d", (int) tcp->u_arg[3]);
1947 }
1948 }
1949 return 0;
1950};
1951
1952#endif /* LINUX */