blob: 3d4b7c1bf6285bd6408dd11c1e061b899f645938 [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>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * $Id$
30 */
31
32#include "defs.h"
33
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000034#include <signal.h>
35#include <sys/user.h>
36#include <fcntl.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000037
38#ifdef SVR4
39#include <sys/ucontext.h>
40#endif /* SVR4 */
41
Wichert Akkerman15dea971999-10-06 13:06:34 +000042#if HAVE_LINUX_PTRACE_H
43#undef PTRACE_SYSCALL
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000044#include <linux/ptrace.h>
Wichert Akkerman36915a11999-07-13 15:45:02 +000045#endif
46
47#ifdef HAVE_SYS_REG_H
48# include <sys/reg.h>
Wichert Akkerman15dea971999-10-06 13:06:34 +000049#ifndef PTRACE_PEEKUSR
Wichert Akkerman36915a11999-07-13 15:45:02 +000050# define PTRACE_PEEKUSR PTRACE_PEEKUSER
Wichert Akkerman15dea971999-10-06 13:06:34 +000051#endif
52#ifndef PTRACE_POKEUSR
Wichert Akkerman36915a11999-07-13 15:45:02 +000053# define PTRACE_POKEUSR PTRACE_POKEUSER
Wichert Akkerman2e2553a1999-05-09 00:29:58 +000054#endif
Wichert Akkerman15dea971999-10-06 13:06:34 +000055#endif
Wichert Akkerman36915a11999-07-13 15:45:02 +000056
57#ifdef LINUX
58
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000059#ifdef HAVE_ASM_SIGCONTEXT_H
60#include <asm/sigcontext.h>
61#ifdef SPARC
Wichert Akkerman9ce1a631999-08-29 23:15:07 +000062#include <asm/reg.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000063typedef struct {
Wichert Akkerman9ce1a631999-08-29 23:15:07 +000064 struct regs si_regs;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000065 int si_mask;
66} m_siginfo_t;
67#endif
68#else /* !HAVE_ASM_SIGCONTEXT_H */
69#ifdef I386
70struct sigcontext_struct {
71 unsigned short gs, __gsh;
72 unsigned short fs, __fsh;
73 unsigned short es, __esh;
74 unsigned short ds, __dsh;
75 unsigned long edi;
76 unsigned long esi;
77 unsigned long ebp;
78 unsigned long esp;
79 unsigned long ebx;
80 unsigned long edx;
81 unsigned long ecx;
82 unsigned long eax;
83 unsigned long trapno;
84 unsigned long err;
85 unsigned long eip;
86 unsigned short cs, __csh;
87 unsigned long eflags;
88 unsigned long esp_at_signal;
89 unsigned short ss, __ssh;
90 unsigned long i387;
91 unsigned long oldmask;
92 unsigned long cr2;
93};
94#else /* !I386 */
95#ifdef M68K
Wichert Akkerman2e2553a1999-05-09 00:29:58 +000096struct sigcontext
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000097{
98 unsigned long sc_mask;
99 unsigned long sc_usp;
100 unsigned long sc_d0;
101 unsigned long sc_d1;
102 unsigned long sc_a0;
103 unsigned long sc_a1;
104 unsigned short sc_sr;
105 unsigned long sc_pc;
106 unsigned short sc_formatvec;
107};
108#endif /* M68K */
109#endif /* !I386 */
110#endif /* !HAVE_ASM_SIGCONTEXT_H */
111#ifndef NSIG
112#define NSIG 32
113#endif
114#ifdef ARM
115#undef NSIG
116#define NSIG 32
117#endif
118#endif /* LINUX */
119
120char *signalent0[] = {
121#include "signalent.h"
122};
123int nsignals0 = sizeof signalent0 / sizeof signalent0[0];
124
125#if SUPPORTED_PERSONALITIES >= 2
126char *signalent1[] = {
127#include "signalent1.h"
128};
129int nsignals1 = sizeof signalent1 / sizeof signalent1[0];
130#endif /* SUPPORTED_PERSONALITIES >= 2 */
131
132#if SUPPORTED_PERSONALITIES >= 3
133char *signalent2[] = {
134#include "signalent2.h"
135};
136int nsignals2 = sizeof signalent2 / sizeof signalent2[0];
137#endif /* SUPPORTED_PERSONALITIES >= 3 */
138
139char **signalent;
140int nsignals;
141
142#ifdef SUNOS4
143
144static struct xlat sigvec_flags[] = {
145 { SV_ONSTACK, "SV_ONSTACK" },
146 { SV_INTERRUPT, "SV_INTERRUPT" },
147 { SV_RESETHAND, "SV_RESETHAND" },
148 { SA_NOCLDSTOP, "SA_NOCLDSTOP" },
149 { 0, NULL },
150};
151
152#endif /* SUNOS4 */
153
154#ifdef HAVE_SIGACTION
155
156static struct xlat sigact_flags[] = {
157#ifdef SA_STACK
158 { SA_STACK, "SA_STACK" },
159#endif
160#ifdef SA_RESTART
161 { SA_RESTART, "SA_RESTART" },
162#endif
163#ifdef SA_INTERRUPT
164 { SA_INTERRUPT, "SA_INTERRUPT" },
165#endif
166#ifdef SA_NOMASK
167 { SA_NOMASK, "SA_NOMASK" },
168#endif
169#ifdef SA_ONESHOT
170 { SA_ONESHOT, "SA_ONESHOT" },
171#endif
172#ifdef SA_SIGINFO
173 { SA_SIGINFO, "SA_SIGINFO" },
174#endif
175#ifdef SA_RESETHAND
176 { SA_RESETHAND, "SA_RESETHAND" },
177#endif
178#ifdef SA_ONSTACK
179 { SA_ONSTACK, "SA_ONSTACK" },
180#endif
181#ifdef SA_NODEFER
182 { SA_NODEFER, "SA_NODEFER" },
183#endif
184#ifdef SA_NOCLDSTOP
185 { SA_NOCLDSTOP, "SA_NOCLDSTOP" },
186#endif
187#ifdef SA_NOCLDWAIT
188 { SA_NOCLDWAIT, "SA_NOCLDWAIT" },
189#endif
190#ifdef _SA_BSDCALL
191 { _SA_BSDCALL, "_SA_BSDCALL" },
192#endif
193 { 0, NULL },
194};
195
196static struct xlat sigprocmaskcmds[] = {
197 { SIG_BLOCK, "SIG_BLOCK" },
198 { SIG_UNBLOCK, "SIG_UNBLOCK" },
199 { SIG_SETMASK, "SIG_SETMASK" },
200#ifdef SIG_SETMASK32
201 { SIG_SETMASK32,"SIG_SETMASK32" },
202#endif
203 { 0, NULL },
204};
205
206#endif /* HAVE_SIGACTION */
207
Nate Sammonsce780fc1999-03-29 23:23:13 +0000208/* Anonymous realtime signals. */
209/* Under glibc 2.1, SIGRTMIN et al are functions, but __SIGRTMIN is a
210 constant. This is what we want. Otherwise, just use SIGRTMIN. */
211#ifdef SIGRTMIN
212#ifndef __SIGRTMIN
213#define __SIGRTMIN SIGRTMIN
214#define __SIGRTMAX SIGRTMAX /* likewise */
215#endif
216#endif
217
218char *
219signame(sig)
220int sig;
221{
222 static char buf[30];
223 if (sig < nsignals) {
224 return signalent[sig];
225#ifdef SIGRTMIN
Nate Sammons3080aa41999-03-30 00:16:41 +0000226 } else if (sig >= __SIGRTMIN && sig <= __SIGRTMAX) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000227 sprintf(buf, "SIGRT_%ld", (long)(sig - __SIGRTMIN));
Nate Sammonsce780fc1999-03-29 23:23:13 +0000228 return buf;
229#endif /* SIGRTMIN */
230 } else {
231 sprintf(buf, "%d", sig);
232 return buf;
233 }
234}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000235
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000236#ifndef UNIXWARE
Nate Sammons4a121431999-04-06 01:19:39 +0000237static void
238long_to_sigset(l, s)
239long l;
240sigset_t *s;
241{
242 sigemptyset(s);
243 *(long *)s = l;
244}
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000245#endif
Nate Sammons4a121431999-04-06 01:19:39 +0000246
247static int
248copy_sigset_len(tcp, addr, s, len)
249struct tcb *tcp;
250int addr;
251sigset_t *s;
252int len;
253{
254 if (len > sizeof(*s))
255 len = sizeof(*s);
256 sigemptyset(s);
257 if (umoven(tcp, addr, len, (char *)s) < 0)
258 return -1;
259 return 0;
260}
261
262#ifdef LINUX
263/* Original sigset is unsigned long */
264#define copy_sigset(tcp, addr, s) copy_sigset_len(tcp, addr, s, sizeof(long))
265#else
266#define copy_sigset(tcp, addr, s) copy_sigset_len(tcp, addr, s, sizeof(sigset_t))
267#endif
268
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000269static char *
Nate Sammons4a121431999-04-06 01:19:39 +0000270sprintsigmask(s, mask, rt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000271char *s;
272sigset_t *mask;
Nate Sammons4a121431999-04-06 01:19:39 +0000273int rt; /* set might include realtime sigs */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000274{
275 int i, nsigs;
Nate Sammons4a121431999-04-06 01:19:39 +0000276 int maxsigs;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000277 char *format;
278 static char outstr[256];
279
280 strcpy(outstr, s);
281 s = outstr + strlen(outstr);
282 nsigs = 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000283 maxsigs = nsignals;
284#ifdef __SIGRTMAX
285 if (rt)
286 maxsigs = __SIGRTMAX; /* instead */
287#endif
288 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000289 if (sigismember(mask, i) == 1)
290 nsigs++;
291 }
292 if (nsigs >= nsignals * 2 / 3) {
293 *s++ = '~';
Nate Sammons4a121431999-04-06 01:19:39 +0000294 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000295 switch (sigismember(mask, i)) {
296 case 1:
297 sigdelset(mask, i);
298 break;
299 case 0:
300 sigaddset(mask, i);
301 break;
302 }
303 }
304 }
305 format = "%s";
306 *s++ = '[';
Nate Sammons4a121431999-04-06 01:19:39 +0000307 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000308 if (sigismember(mask, i) == 1) {
Nate Sammonsce780fc1999-03-29 23:23:13 +0000309 sprintf(s, format, signame(i) + 3); s += strlen(s);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000310 format = " %s";
311 }
312 }
313 *s++ = ']';
314 *s = '\0';
315 return outstr;
316}
317
318static void
Nate Sammons4a121431999-04-06 01:19:39 +0000319printsigmask(mask, rt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000320sigset_t *mask;
Nate Sammons4a121431999-04-06 01:19:39 +0000321int rt;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000322{
Nate Sammons4a121431999-04-06 01:19:39 +0000323 tprintf("%s", sprintsigmask("", mask, rt));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000324}
325
326void
327printsignal(nr)
328int nr;
329{
Nate Sammonsce780fc1999-03-29 23:23:13 +0000330 tprintf(signame(nr));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000331}
332
333/*
334 * Check process TCP for the disposition of signal SIG.
335 * Return 1 if the process would somehow manage to survive signal SIG,
336 * else return 0. This routine will never be called with SIGKILL.
337 */
338int
339sigishandled(tcp, sig)
340struct tcb *tcp;
341int sig;
342{
343#ifdef LINUX
344 int sfd;
345 char sname[32];
346 char buf[1024];
347 char *s;
348 int i;
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000349 unsigned int signalled, blocked, ignored, caught;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000350
351 /* This is incredibly costly but it's worth it. */
352 sprintf(sname, "/proc/%d/stat", tcp->pid);
353 if ((sfd = open(sname, O_RDONLY)) == -1) {
354 perror(sname);
355 return 1;
356 }
357 i = read(sfd, buf, 1024);
358 buf[i] = '\0';
359 close(sfd);
360 /*
361 * Skip the extraneous fields. This loses if the
362 * command name has any spaces in it. So be it.
363 */
364 for (i = 0, s = buf; i < 30; i++) {
365 while (*++s != ' ') {
366 if (!*s)
367 break;
368 }
369 }
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000370 if (sscanf(s, "%u%u%u%u",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000371 &signalled, &blocked, &ignored, &caught) != 4) {
372 fprintf(stderr, "/proc/pid/stat format error\n");
373 return 1;
374 }
375#ifdef DEBUG
376 fprintf(stderr, "sigs: %08x %08x %08x %08x\n",
377 signalled, blocked, ignored, caught);
378#endif
379 if ((ignored & sigmask(sig)) || (caught & sigmask(sig)))
380 return 1;
381#endif /* LINUX */
382
383#ifdef SUNOS4
384 void (*u_signal)();
385
386 if (upeek(tcp->pid, uoff(u_signal[0]) + sig*sizeof(u_signal),
387 (long *) &u_signal) < 0) {
388 return 0;
389 }
390 if (u_signal != SIG_DFL)
391 return 1;
392#endif /* SUNOS4 */
393
394#ifdef SVR4
395 /*
396 * Since procfs doesn't interfere with wait I think it is safe
397 * to punt on this question. If not, the information is there.
398 */
399 return 1;
400#else /* !SVR4 */
401 switch (sig) {
402 case SIGCONT:
403 case SIGSTOP:
404 case SIGTSTP:
405 case SIGTTIN:
406 case SIGTTOU:
407 case SIGCHLD:
408 case SIGIO:
409#if defined(SIGURG) && SIGURG != SIGIO
410 case SIGURG:
411#endif
412 case SIGWINCH:
413 /* Gloria Gaynor says ... */
414 return 1;
415 default:
416 break;
417 }
418 return 0;
419#endif /* !SVR4 */
420}
421
422#if defined(SUNOS4)
423
424int
425sys_sigvec(tcp)
426struct tcb *tcp;
427{
428 struct sigvec sv;
429 long addr;
430
431 if (entering(tcp)) {
432 printsignal(tcp->u_arg[0]);
433 tprintf(", ");
434 addr = tcp->u_arg[1];
435 } else {
436 addr = tcp->u_arg[2];
437 }
438 if (addr == 0)
439 tprintf("NULL");
440 else if (!verbose(tcp))
441 tprintf("%#lx", addr);
442 else if (umove(tcp, addr, &sv) < 0)
443 tprintf("{...}");
444 else {
445 switch ((int) sv.sv_handler) {
446 case (int) SIG_ERR:
447 tprintf("{SIG_ERR}");
448 break;
449 case (int) SIG_DFL:
450 tprintf("{SIG_DFL}");
451 break;
452 case (int) SIG_IGN:
453 if (tcp->u_arg[0] == SIGTRAP) {
454 tcp->flags |= TCB_SIGTRAPPED;
455 kill(tcp->pid, SIGSTOP);
456 }
457 tprintf("{SIG_IGN}");
458 break;
459 case (int) SIG_HOLD:
460 if (tcp->u_arg[0] == SIGTRAP) {
461 tcp->flags |= TCB_SIGTRAPPED;
462 kill(tcp->pid, SIGSTOP);
463 }
464 tprintf("SIG_HOLD");
465 break;
466 default:
467 if (tcp->u_arg[0] == SIGTRAP) {
468 tcp->flags |= TCB_SIGTRAPPED;
469 kill(tcp->pid, SIGSTOP);
470 }
471 tprintf("{%#lx, ", (unsigned long) sv.sv_handler);
Nate Sammons4a121431999-04-06 01:19:39 +0000472 printsigmask(&sv.sv_mask, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000473 tprintf(", ");
474 if (!printflags(sigvec_flags, sv.sv_flags))
475 tprintf("0");
476 tprintf("}");
477 }
478 }
479 if (entering(tcp))
480 tprintf(", ");
481 return 0;
482}
483
484int
485sys_sigpause(tcp)
486struct tcb *tcp;
487{
488 if (entering(tcp)) { /* WTA: UD had a bug here: he forgot the braces */
Nate Sammons4a121431999-04-06 01:19:39 +0000489 sigset_t sigm;
490 long_to_sigset(tcp->u_arg[0], &sigm);
491 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000492 }
493 return 0;
494}
495
496int
497sys_sigstack(tcp)
498struct tcb *tcp;
499{
500 struct sigstack ss;
501 long addr;
502
503 if (entering(tcp))
504 addr = tcp->u_arg[0];
505 else
506 addr = tcp->u_arg[1];
507 if (addr == 0)
508 tprintf("NULL");
509 else if (umove(tcp, addr, &ss) < 0)
510 tprintf("%#lx", addr);
511 else {
512 tprintf("{ss_sp %#lx ", (unsigned long) ss.ss_sp);
513 tprintf("ss_onstack %s}", ss.ss_onstack ? "YES" : "NO");
514 }
515 if (entering(tcp))
516 tprintf(", ");
517 return 0;
518}
519
520int
521sys_sigcleanup(tcp)
522struct tcb *tcp;
523{
524 return 0;
525}
526
527#endif /* SUNOS4 */
528
529#ifndef SVR4
530
531int
532sys_sigsetmask(tcp)
533struct tcb *tcp;
534{
535 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000536 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000537 long_to_sigset(tcp->u_arg[0], &sigm);
538 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000539 if ((tcp->u_arg[0] & sigmask(SIGTRAP))) {
540 /* Mark attempt to block SIGTRAP */
541 tcp->flags |= TCB_SIGTRAPPED;
542 /* Send unblockable signal */
543 kill(tcp->pid, SIGSTOP);
544 }
545 }
546 else if (!syserror(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000547 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000548 long_to_sigset(tcp->u_rval, &sigm);
549 tcp->auxstr = sprintsigmask("old mask ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000550
551 return RVAL_HEX | RVAL_STR;
552 }
553 return 0;
554}
555
556int
557sys_sigblock(tcp)
558struct tcb *tcp;
559{
560 return sys_sigsetmask(tcp);
561}
562
563#endif /* !SVR4 */
564
565#ifdef HAVE_SIGACTION
566
567#ifdef LINUX
568struct old_sigaction {
569 __sighandler_t __sa_handler;
570 unsigned long sa_mask;
571 unsigned long sa_flags;
572 void (*sa_restorer)(void);
573};
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000574#define SA_HANDLER __sa_handler
575#endif /* LINUX */
576
577#ifndef SA_HANDLER
578#define SA_HANDLER sa_handler
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000579#endif
580
581int
582sys_sigaction(tcp)
583struct tcb *tcp;
584{
585 long addr;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000586 sigset_t sigset;
Nate Sammons4a121431999-04-06 01:19:39 +0000587#ifdef LINUX
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000588 struct old_sigaction sa;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000589#else
590 struct sigaction sa;
591#endif
592
593
594 if (entering(tcp)) {
595 printsignal(tcp->u_arg[0]);
596 tprintf(", ");
597 addr = tcp->u_arg[1];
598 } else
599 addr = tcp->u_arg[2];
600 if (addr == 0)
601 tprintf("NULL");
602 else if (!verbose(tcp))
603 tprintf("%#lx", addr);
604 else if (umove(tcp, addr, &sa) < 0)
605 tprintf("{...}");
606 else {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000607 switch ((long) sa.SA_HANDLER) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000608 case (long) SIG_ERR:
609 tprintf("{SIG_ERR}");
610 break;
611 case (long) SIG_DFL:
612 tprintf("{SIG_DFL}");
613 break;
614 case (long) SIG_IGN:
615#ifndef SVR4
616 if (tcp->u_arg[0] == SIGTRAP) {
617 tcp->flags |= TCB_SIGTRAPPED;
618 kill(tcp->pid, SIGSTOP);
619 }
620#endif /* !SVR4 */
621 tprintf("{SIG_IGN}");
622 break;
623 default:
624#ifndef SVR4
625 if (tcp->u_arg[0] == SIGTRAP) {
626 tcp->flags |= TCB_SIGTRAPPED;
627 kill(tcp->pid, SIGSTOP);
628 }
629#endif /* !SVR4 */
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000630 tprintf("{%#lx, ", (long) sa.SA_HANDLER);
Nate Sammons4a121431999-04-06 01:19:39 +0000631 long_to_sigset(sa.sa_mask, &sigset);
632 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000633 tprintf(", ");
634 if (!printflags(sigact_flags, sa.sa_flags))
635 tprintf("0");
636 tprintf("}");
637 }
638 }
639 if (entering(tcp))
640 tprintf(", ");
641#ifdef LINUX
642 else
643 tprintf(", %#lx", (unsigned long) sa.sa_restorer);
644#endif
645 return 0;
646}
647
648int
649sys_signal(tcp)
650struct tcb *tcp;
651{
652 if (entering(tcp)) {
653 printsignal(tcp->u_arg[0]);
654 switch (tcp->u_arg[1]) {
655 case (int) SIG_ERR:
656 tprintf("SIG_ERR");
657 break;
658 case (int) SIG_DFL:
659 tprintf("SIG_DFL");
660 break;
661 case (int) SIG_IGN:
662#ifndef SVR4
663 if (tcp->u_arg[0] == SIGTRAP) {
664 tcp->flags |= TCB_SIGTRAPPED;
665 kill(tcp->pid, SIGSTOP);
666 }
667#endif /* !SVR4 */
668 tprintf("SIG_IGN");
669 break;
670 default:
671#ifndef SVR4
672 if (tcp->u_arg[0] == SIGTRAP) {
673 tcp->flags |= TCB_SIGTRAPPED;
674 kill(tcp->pid, SIGSTOP);
675 }
676#endif /* !SVR4 */
677 tprintf("%#lx", tcp->u_arg[1]);
678 }
679 }
680 return 0;
681}
682
683#endif /* HAVE_SIGACTION */
684
685#ifdef LINUX
686
687int
688sys_sigreturn(tcp)
689struct tcb *tcp;
690{
691#ifdef I386
692 long esp;
693 struct sigcontext_struct sc;
694
695 if (entering(tcp)) {
696 tcp->u_arg[0] = 0;
697 if (upeek(tcp->pid, 4*UESP, &esp) < 0)
698 return 0;
699 if (umove(tcp, esp, &sc) < 0)
700 return 0;
701 tcp->u_arg[0] = 1;
702 tcp->u_arg[1] = sc.oldmask;
703 }
704 else {
705 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000706 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000707 tcp->u_rval = tcp->u_error = 0;
708 if (tcp->u_arg[0] == 0)
709 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000710 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000711 return RVAL_NONE | RVAL_STR;
712 }
713 return 0;
714#else /* !I386 */
715#ifdef POWERPC
716 long esp;
717 struct sigcontext_struct sc;
718
719 if (entering(tcp)) {
720 tcp->u_arg[0] = 0;
721 if (upeek(tcp->pid, 4*PT_R1, &esp) < 0)
722 return 0;
723 if (umove(tcp, esp, &sc) < 0)
724 return 0;
725 tcp->u_arg[0] = 1;
726 tcp->u_arg[1] = sc.oldmask;
727 }
728 else {
729 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000730 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000731 tcp->u_rval = tcp->u_error = 0;
732 if (tcp->u_arg[0] == 0)
733 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000734 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000735 return RVAL_NONE | RVAL_STR;
736 }
737 return 0;
738#else /* !POWERPC */
739#ifdef M68K
740 long usp;
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000741 struct sigcontext sc;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000742
743 if (entering(tcp)) {
744 tcp->u_arg[0] = 0;
745 if (upeek(tcp->pid, 4*PT_USP, &usp) < 0)
746 return 0;
747 if (umove(tcp, usp, &sc) < 0)
748 return 0;
749 tcp->u_arg[0] = 1;
750 tcp->u_arg[1] = sc.sc_mask;
751 }
752 else {
753 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000754 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000755 tcp->u_rval = tcp->u_error = 0;
756 if (tcp->u_arg[0] == 0)
757 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000758 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000759 return RVAL_NONE | RVAL_STR;
760 }
761 return 0;
762#else /* !M68K */
763#ifdef ALPHA
764 long fp;
765 struct sigcontext_struct sc;
766
767 if (entering(tcp)) {
768 tcp->u_arg[0] = 0;
769 if (upeek(tcp->pid, REG_FP, &fp) < 0)
770 return 0;
771 if (umove(tcp, fp, &sc) < 0)
772 return 0;
773 tcp->u_arg[0] = 1;
774 tcp->u_arg[1] = sc.sc_mask;
775 }
776 else {
777 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000778 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000779 tcp->u_rval = tcp->u_error = 0;
780 if (tcp->u_arg[0] == 0)
781 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000782 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000783 return RVAL_NONE | RVAL_STR;
784 }
785 return 0;
786#else
787#ifdef SPARC
788 long i1;
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000789 struct regs regs;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000790 m_siginfo_t si;
791
792 if(ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
793 perror("sigreturn: PTRACE_GETREGS ");
794 return 0;
795 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000796 if(entering(tcp)) {
797 tcp->u_arg[0] = 0;
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000798 i1 = regs.r_o1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000799 if(umove(tcp, i1, &si) < 0) {
800 perror("sigreturn: umove ");
801 return 0;
802 }
803 tcp->u_arg[0] = 1;
804 tcp->u_arg[1] = si.si_mask;
805 } else {
806 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000807 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000808 tcp->u_rval = tcp->u_error = 0;
809 if(tcp->u_arg[0] == 0)
810 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000811 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000812 return RVAL_NONE | RVAL_STR;
813 }
814 return 0;
815#endif /* SPARC */
816#endif /* ALPHA */
817#endif /* !M68K */
818#endif /* !POWERPC */
819#endif /* !I386 */
820}
821
822int
823sys_siggetmask(tcp)
824struct tcb *tcp;
825{
826 if (exiting(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000827 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000828 long_to_sigset(tcp->u_rval, &sigm);
829 tcp->auxstr = sprintsigmask("mask ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000830 }
831 return RVAL_HEX | RVAL_STR;
832}
833
834int
835sys_sigsuspend(tcp)
836struct tcb *tcp;
837{
838 if (entering(tcp)) {
839 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000840 long_to_sigset(tcp->u_arg[2], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000841#if 0
842 /* first two are not really arguments, but print them anyway */
843 /* nevermind, they are an anachronism now, too bad... */
844 tprintf("%d, %#x, ", tcp->u_arg[0], tcp->u_arg[1]);
845#endif
Nate Sammons4a121431999-04-06 01:19:39 +0000846 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000847 }
848 return 0;
849}
850
851#endif /* LINUX */
852
853#ifdef SVR4
854
855int
856sys_sigsuspend(tcp)
857struct tcb *tcp;
858{
859 sigset_t sigset;
860
861 if (entering(tcp)) {
862 if (umove(tcp, tcp->u_arg[0], &sigset) < 0)
863 tprintf("[?]");
864 else
Nate Sammons4a121431999-04-06 01:19:39 +0000865 printsigmask(sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000866 }
867 return 0;
868}
869static struct xlat ucontext_flags[] = {
870 { UC_SIGMASK, "UC_SIGMASK" },
871 { UC_STACK, "UC_STACK" },
872 { UC_CPU, "UC_CPU" },
873#ifdef UC_FPU
874 { UC_FPU, "UC_FPU" },
875#endif
876#ifdef UC_INTR
877 { UC_INTR, "UC_INTR" },
878#endif
879 { 0, NULL },
880};
881
882#endif
883
884#if defined SVR4 || defined LINUX
885#if defined LINUX && !defined SS_ONSTACK
886#define SS_ONSTACK 1
887#define SS_DISABLE 2
888#if __GLIBC_MINOR__ == 0
889typedef struct
890{
891 __ptr_t ss_sp;
892 int ss_flags;
893 size_t ss_size;
894} stack_t;
895#endif
896#endif
897
898static struct xlat sigaltstack_flags[] = {
899 { SS_ONSTACK, "SS_ONSTACK" },
900 { SS_DISABLE, "SS_DISABLE" },
901 { 0, NULL },
902};
903#endif
904
905#ifdef SVR4
906static void
907printcontext(tcp, ucp)
908struct tcb *tcp;
909ucontext_t *ucp;
910{
911 tprintf("{");
912 if (!abbrev(tcp)) {
913 tprintf("uc_flags=");
914 if (!printflags(ucontext_flags, ucp->uc_flags))
915 tprintf("0");
916 tprintf(", uc_link=%#lx, ", (unsigned long) ucp->uc_link);
917 }
918 tprintf("uc_sigmask=");
Nate Sammons4a121431999-04-06 01:19:39 +0000919 printsigmask(ucp->uc_sigmask, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000920 if (!abbrev(tcp)) {
921 tprintf(", uc_stack={ss_sp=%#lx, ss_size=%d, ss_flags=",
922 (unsigned long) ucp->uc_stack.ss_sp,
923 ucp->uc_stack.ss_size);
924 if (!printflags(sigaltstack_flags, ucp->uc_stack.ss_flags))
925 tprintf("0");
926 tprintf("}");
927 }
928 tprintf(", ...}");
929}
930
931int
932sys_getcontext(tcp)
933struct tcb *tcp;
934{
935 ucontext_t uc;
936
937 if (entering(tcp)) {
938 if (!tcp->u_arg[0])
939 tprintf("NULL");
940 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
941 tprintf("{...}");
942 else
943 printcontext(tcp, &uc);
944 }
945 return 0;
946}
947
948int
949sys_setcontext(tcp)
950struct tcb *tcp;
951{
952 ucontext_t uc;
953
954 if (entering(tcp)) {
955 if (!tcp->u_arg[0])
956 tprintf("NULL");
957 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
958 tprintf("{...}");
959 else
960 printcontext(tcp, &uc);
961 }
962 else {
963 tcp->u_rval = tcp->u_error = 0;
964 if (tcp->u_arg[0] == 0)
965 return 0;
966 return RVAL_NONE;
967 }
968 return 0;
969}
970
971#endif /* SVR4 */
972
973#ifdef LINUX
974
975static int
976print_stack_t(tcp, addr)
977struct tcb *tcp;
978unsigned long addr;
979{
980 stack_t ss;
981 if (umove(tcp, addr, &ss) < 0)
982 return -1;
983 tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp);
984 if (!printflags(sigaltstack_flags, ss.ss_flags))
985 tprintf("0");
986 tprintf(", ss_size=%lu}", (unsigned long) ss.ss_size);
987 return 0;
988}
989
990int
991sys_sigaltstack(tcp)
992 struct tcb *tcp;
993{
994 if (entering(tcp)) {
995 if (tcp->u_arg[0] == 0)
996 tprintf("NULL");
997 else if (print_stack_t(tcp, tcp->u_arg[0]) < 0)
998 return -1;
999 }
1000 else {
1001 tprintf(", ");
1002 if (tcp->u_arg[1] == 0)
1003 tprintf("NULL");
1004 else if (print_stack_t(tcp, tcp->u_arg[1]) < 0)
1005 return -1;
1006 }
1007 return 0;
1008}
1009#endif
1010
1011#ifdef HAVE_SIGACTION
1012
1013int
1014sys_sigprocmask(tcp)
1015struct tcb *tcp;
1016{
1017#ifdef ALPHA
1018 if (entering(tcp)) {
1019 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1020 tprintf(", ");
Nate Sammons4a121431999-04-06 01:19:39 +00001021 printsigmask(tcp->u_arg[1], 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001022 }
1023 else if (!syserror(tcp)) {
Nate Sammons4a121431999-04-06 01:19:39 +00001024 tcp->auxstr = sprintsigmask("old mask ", tcp->u_rval, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001025 return RVAL_HEX | RVAL_STR;
1026 }
1027#else /* !ALPHA */
1028 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001029
1030 if (entering(tcp)) {
1031#ifdef SVR4
1032 if (tcp->u_arg[0] == 0)
1033 tprintf("0");
1034 else
1035#endif /* SVR4 */
1036 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1037 tprintf(", ");
1038 if (!tcp->u_arg[1])
1039 tprintf("NULL, ");
Nate Sammons4a121431999-04-06 01:19:39 +00001040 else if (copy_sigset(tcp, tcp->u_arg[1], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001041 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001042 else {
Nate Sammons4a121431999-04-06 01:19:39 +00001043 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001044 tprintf(", ");
1045 }
1046 }
1047 else {
1048 if (!tcp->u_arg[2])
1049 tprintf("NULL");
1050 else if (syserror(tcp))
1051 tprintf("%#lx", tcp->u_arg[2]);
Nate Sammons4a121431999-04-06 01:19:39 +00001052 else if (copy_sigset(tcp, tcp->u_arg[2], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001053 tprintf("[?]");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001054 else
Nate Sammons4a121431999-04-06 01:19:39 +00001055 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001056 }
1057#endif /* !ALPHA */
1058 return 0;
1059}
1060
1061#endif /* HAVE_SIGACTION */
1062
1063int
1064sys_kill(tcp)
1065struct tcb *tcp;
1066{
1067 if (entering(tcp)) {
Nate Sammonsce780fc1999-03-29 23:23:13 +00001068 tprintf("%ld, %s", tcp->u_arg[0], signame(tcp->u_arg[1]));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001069 }
1070 return 0;
1071}
1072
1073int
1074sys_killpg(tcp)
1075struct tcb *tcp;
1076{
1077 return sys_kill(tcp);
1078}
1079
1080int
1081sys_sigpending(tcp)
1082struct tcb *tcp;
1083{
1084 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001085
1086 if (exiting(tcp)) {
1087 if (syserror(tcp))
1088 tprintf("%#lx", tcp->u_arg[0]);
Nate Sammons4a121431999-04-06 01:19:39 +00001089 else if (copy_sigset(tcp, tcp->u_arg[0], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001090 tprintf("[?]");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001091 else
Nate Sammons4a121431999-04-06 01:19:39 +00001092 printsigmask(sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001093 }
1094 return 0;
1095}
1096
1097#ifdef LINUX
1098
1099 int
1100sys_rt_sigprocmask(tcp)
1101 struct tcb *tcp;
1102{
1103 sigset_t sigset;
1104
Nate Sammons4a121431999-04-06 01:19:39 +00001105 /* Note: arg[3] is the length of the sigset. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001106 if (entering(tcp)) {
1107 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1108 tprintf(", ");
1109 if (!tcp->u_arg[1])
1110 tprintf("NULL, ");
Nate Sammons4a121431999-04-06 01:19:39 +00001111 else if (copy_sigset_len(tcp, tcp->u_arg[1], &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001112 tprintf("%#lx, ", tcp->u_arg[1]);
1113 else {
Nate Sammons4a121431999-04-06 01:19:39 +00001114 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001115 tprintf(", ");
1116 }
1117 }
1118 else {
1119 if (!tcp->u_arg[2])
1120
1121 tprintf("NULL");
1122 else if (syserror(tcp))
1123 tprintf("%#lx", tcp->u_arg[2]);
Nate Sammons4a121431999-04-06 01:19:39 +00001124 else if (copy_sigset_len(tcp, tcp->u_arg[2], &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001125 tprintf("[?]");
1126 else
Nate Sammons4a121431999-04-06 01:19:39 +00001127 printsigmask(&sigset, 1);
Nate Sammonsdab325a1999-03-29 23:33:35 +00001128 tprintf(", %lu", tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001129 }
1130 return 0;
1131}
1132
1133#if __GLIBC_MINOR__ < 1
1134/* Type for data associated with a signal. */
1135typedef union sigval
1136{
1137 int sival_int;
1138 void *sival_ptr;
1139} sigval_t;
1140
1141# define __SI_MAX_SIZE 128
1142# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
1143
1144typedef struct siginfo
1145{
1146 int si_signo; /* Signal number. */
1147 int si_errno; /* If non-zero, an errno value associated with
1148 this signal, as defined in <errno.h>. */
1149 int si_code; /* Signal code. */
1150
1151 union
1152 {
1153 int _pad[__SI_PAD_SIZE];
1154
1155 /* kill(). */
1156 struct
1157 {
1158 __pid_t si_pid; /* Sending process ID. */
1159 __uid_t si_uid; /* Real user ID of sending process. */
1160 } _kill;
1161
1162 /* POSIX.1b timers. */
1163 struct
1164 {
1165 unsigned int _timer1;
1166 unsigned int _timer2;
1167 } _timer;
1168
1169 /* POSIX.1b signals. */
1170 struct
1171 {
1172 __pid_t si_pid; /* Sending process ID. */
1173 __uid_t si_uid; /* Real user ID of sending process. */
1174 sigval_t si_sigval; /* Signal value. */
1175 } _rt;
1176
1177 /* SIGCHLD. */
1178 struct
1179 {
1180 __pid_t si_pid; /* Which child. */
1181 int si_status; /* Exit value or signal. */
1182 __clock_t si_utime;
1183 __clock_t si_stime;
1184 } _sigchld;
1185
1186 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
1187 struct
1188 {
1189 void *si_addr; /* Faulting insn/memory ref. */
1190 } _sigfault;
1191
1192 /* SIGPOLL. */
1193 struct
1194 {
1195 int si_band; /* Band event for SIGPOLL. */
1196 int si_fd;
1197 } _sigpoll;
1198 } _sifields;
1199} siginfo_t;
1200#endif
1201
1202/* Structure describing the action to be taken when a signal arrives. */
1203struct new_sigaction
1204{
1205 union
1206 {
1207 __sighandler_t __sa_handler;
1208 void (*__sa_sigaction) (int, siginfo_t *, void *);
1209 }
1210 __sigaction_handler;
1211 unsigned long sa_flags;
1212 void (*sa_restorer) (void);
1213 unsigned long int sa_mask[2];
1214};
1215
1216
1217 int
1218sys_rt_sigaction(tcp)
1219 struct tcb *tcp;
1220{
1221 struct new_sigaction sa;
1222 sigset_t sigset;
1223 long addr;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001224
1225 if (entering(tcp)) {
1226 printsignal(tcp->u_arg[0]);
1227 tprintf(", ");
1228 addr = tcp->u_arg[1];
1229 } else
1230 addr = tcp->u_arg[2];
1231 if (addr == 0)
1232 tprintf("NULL");
1233 else if (!verbose(tcp))
1234 tprintf("%#lx", addr);
1235 else if (umove(tcp, addr, &sa) < 0)
1236 tprintf("{...}");
1237 else {
1238 switch ((long) sa.__sigaction_handler.__sa_handler) {
1239 case (long) SIG_ERR:
1240 tprintf("{SIG_ERR}");
1241 break;
1242 case (long) SIG_DFL:
1243 tprintf("{SIG_DFL}");
1244 break;
1245 case (long) SIG_IGN:
1246 tprintf("{SIG_IGN}");
1247 break;
1248 default:
1249 tprintf("{%#lx, ",
1250 (long) sa.__sigaction_handler.__sa_handler);
Nate Sammons4a121431999-04-06 01:19:39 +00001251 sigemptyset(&sigset);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001252#ifdef LINUXSPARC
1253 if (tcp->u_arg[4] <= sizeof(sigset))
1254 memcpy(&sigset, &sa.sa_mask, tcp->u_arg[4]);
1255#else
Nate Sammons4a121431999-04-06 01:19:39 +00001256 if (tcp->u_arg[3] <= sizeof(sigset))
1257 memcpy(&sigset, &sa.sa_mask, tcp->u_arg[3]);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001258#endif
Nate Sammons4a121431999-04-06 01:19:39 +00001259 else
1260 memcpy(&sigset, &sa.sa_mask, sizeof(sigset));
1261 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001262 tprintf(", ");
1263 if (!printflags(sigact_flags, sa.sa_flags))
1264 tprintf("0");
1265 tprintf("}");
1266 }
1267 }
1268 if (entering(tcp))
1269 tprintf(", ");
1270 else
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001271#ifdef LINUXSPARC
1272 tprintf(", %#lx, %lu", tcp->u_arg[3], tcp->u_arg[4]);
1273#elif defined(ALPHA)
1274 tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]);
1275#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001276 tprintf(", %lu", addr = tcp->u_arg[3]);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001277#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001278 return 0;
1279}
1280
1281 int
1282sys_rt_sigpending(tcp)
1283 struct tcb *tcp;
1284{
1285 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001286
1287 if (exiting(tcp)) {
1288 if (syserror(tcp))
1289 tprintf("%#lx", tcp->u_arg[0]);
Nate Sammons4a121431999-04-06 01:19:39 +00001290 else if (copy_sigset_len(tcp, tcp->u_arg[0],
1291 &sigset, tcp->u_arg[1]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001292 tprintf("[?]");
1293 else
Nate Sammons4a121431999-04-06 01:19:39 +00001294 printsigmask(sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001295 }
1296 return 0;
1297}
1298 int
1299sys_rt_sigsuspend(tcp)
1300 struct tcb *tcp;
1301{
1302 if (entering(tcp)) {
1303 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +00001304 if (copy_sigset_len(tcp, tcp->u_arg[0], &sigm, tcp->u_arg[1]) < 0)
1305 tprintf("[?]");
1306 else
1307 printsigmask(&sigm, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001308 }
1309 return 0;
1310}
1311#ifndef ILL_ILLOPC
1312#define ILL_ILLOPC 1 /* illegal opcode */
1313#define ILL_ILLOPN 2 /* illegal operand */
1314#define ILL_ILLADR 3 /* illegal addressing mode */
1315#define ILL_ILLTRP 4 /* illegal trap */
1316#define ILL_PRVOPC 5 /* privileged opcode */
1317#define ILL_PRVREG 6 /* privileged register */
1318#define ILL_COPROC 7 /* coprocessor error */
1319#define ILL_BADSTK 8 /* internal stack error */
1320#define FPE_INTDIV 1 /* integer divide by zero */
1321#define FPE_INTOVF 2 /* integer overflow */
1322#define FPE_FLTDIV 3 /* floating point divide by zero */
1323#define FPE_FLTOVF 4 /* floating point overflow */
1324#define FPE_FLTUND 5 /* floating point underflow */
1325#define FPE_FLTRES 6 /* floating point inexact result */
1326#define FPE_FLTINV 7 /* floating point invalid operation */
1327#define FPE_FLTSUB 8 /* subscript out of range */
1328#define SEGV_MAPERR 1 /* address not mapped to object */
1329#define SEGV_ACCERR 2 /* invalid permissions for mapped object */
1330#define BUS_ADRALN 1 /* invalid address alignment */
1331#define BUS_ADRERR 2 /* non-existant physical address */
1332#define BUS_OBJERR 3 /* object specific hardware error */
1333#define TRAP_BRKPT 1 /* process breakpoint */
1334#define TRAP_TRACE 2 /* process trace trap */
1335#define CLD_EXITED 1 /* child has exited */
1336#define CLD_KILLED 2 /* child was killed */
1337#define CLD_DUMPED 3 /* child terminated abnormally */
1338#define CLD_TRAPPED 4 /* traced child has trapped */
1339#define CLD_STOPPED 5 /* child has stopped */
1340#define CLD_CONTINUED 6 /* stopped child has continued */
1341#define POLL_IN 1 /* data input available */
1342#define POLL_OUT 2 /* output buffers available */
1343#define POLL_MSG 3 /* input message available */
1344#define POLL_ERR 4 /* i/o error */
1345#define POLL_PRI 5 /* high priority input available */
1346#define POLL_HUP 6 /* device disconnected */
1347#define SI_USER 0 /* sent by kill, sigsend, raise */
1348#define SI_QUEUE -1 /* sent by sigqueue */
1349#define SI_TIMER -2 /* sent by timer expiration */
1350#define SI_MESGQ -3 /* sent by real time mesq state change */
1351#define SI_ASYNCIO -4 /* sent by AIO completion */
1352#else
1353#undef si_pid
1354#undef si_uid
1355#undef si_status
1356#undef si_utime
1357#undef si_stime
1358#undef si_value
1359#undef si_int
1360#undef si_ptr
1361#undef si_addr
1362#undef si_band
1363#undef si_fd
1364#endif
1365
1366static struct xlat sigill_flags[] = {
1367 {ILL_ILLOPC, "ILL_ILLOPC"},
1368 {ILL_ILLOPN, "ILL_ILLOPN"},
1369 {ILL_ILLADR, "ILL_ILLADR"},
1370 {ILL_ILLTRP, "ILL_ILLTRP"},
1371 {ILL_PRVOPC, "ILL_PRVOPC"},
1372 {ILL_PRVREG, "ILL_PRVREG"},
1373 {ILL_COPROC, "ILL_COPROC"},
1374 {ILL_BADSTK, "ILL_BADSTK"},
1375 {0, NULL}
1376};
1377
1378static struct xlat sigfpe_flags[] = {
1379 {FPE_INTDIV, "FPE_INTDIV"},
1380 {FPE_INTOVF, "FPE_INTOVF"},
1381 {FPE_FLTDIV, "FPE_FLTDIV"},
1382 {FPE_FLTOVF, "FPE_FLTOVF"},
1383 {FPE_FLTUND, "FPE_FLTUND"},
1384 {FPE_FLTRES, "FPE_FLTRES"},
1385 {FPE_FLTINV, "FPE_FLTINV"},
1386 {FPE_FLTSUB, "FPE_FLTSUB"},
1387 {0, NULL}
1388};
1389
1390static struct xlat sigsegv_flags[] = {
1391 {SEGV_MAPERR, "SEGV_MAPERR"},
1392 {SEGV_ACCERR, "SEGV_ACCERR"},
1393 {0, NULL}
1394};
1395
1396static struct xlat sigbus_flags[] = {
1397 {BUS_ADRALN, "BUS_ADRALN"},
1398 {BUS_ADRERR, "BUS_ADRERR"},
1399 {BUS_OBJERR, "BUS_OBJERR"},
1400 {0, NULL}
1401};
1402
1403static struct xlat sigtrap_flags[] = {
1404 {TRAP_BRKPT, "TRAP_BRKPT"},
1405 {TRAP_TRACE, "TRAP_TRACE"},
1406 {0, NULL}
1407};
1408
1409static struct xlat sigchld_flags[] = {
1410 {CLD_EXITED, "CLD_EXITED"},
1411 {CLD_KILLED, "CLD_KILLED"},
1412 {CLD_DUMPED, "CLD_DUMPED"},
1413 {CLD_TRAPPED, "CLD_TRAPPED"},
1414 {CLD_STOPPED, "CLD_STOPPED"},
1415 {CLD_CONTINUED, "CLD_CONTINUED"},
1416 {0, NULL}
1417};
1418
1419static struct xlat sigpoll_flags[] = {
1420 {POLL_IN, "POLL_IN"},
1421 {POLL_OUT, "POLL_OUT"},
1422 {POLL_MSG, "POLL_MSG"},
1423 {POLL_ERR, "POLL_ERR"},
1424 {POLL_PRI, "POLL_PRI"},
1425 {POLL_HUP, "POLL_HUP"},
1426 {0, NULL}
1427};
1428
1429static struct xlat siginfo_flags[] = {
1430 {SI_USER, "SI_USER"},
1431 {SI_QUEUE, "SI_QUEUE"},
1432 {SI_TIMER, "SI_TIMER"},
1433 {SI_MESGQ, "SI_MESGQ"},
1434 {SI_ASYNCIO, "SI_ASYNCIO"},
1435 {0, NULL}
1436};
1437
1438 static void
1439printsiginfo(tcp, si)
1440 struct tcb *tcp;
1441 siginfo_t *si;
1442{
1443 tprintf("{si_signo=");
1444 printsignal(si->si_signo);
1445 tprintf(", si_errno=%d, si_code=", si->si_errno);
1446 switch(si->si_signo)
1447 {
1448 case SIGILL:
1449 if (!printflags(sigill_flags, si->si_code))
1450 tprintf("%d /* ILL_??? */", si->si_code);
1451 tprintf(", si_addr=%lx",
1452 (unsigned long) si->_sifields._sigfault.si_addr);
1453 break;
1454 case SIGFPE:
1455 if (!printflags(sigfpe_flags, si->si_code))
1456 tprintf("%d /* FPE_??? */", si->si_code);
1457 tprintf(", si_addr=%lx",
1458 (unsigned long) si->_sifields._sigfault.si_addr);
1459 break;
1460 case SIGSEGV:
1461 if (!printflags(sigsegv_flags, si->si_code))
1462 tprintf("%d /* SEGV_??? */", si->si_code);
1463 tprintf(", si_addr=%lx",
1464 (unsigned long) si->_sifields._sigfault.si_addr);
1465 break;
1466 case SIGBUS:
1467 if (!printflags(sigbus_flags, si->si_code))
1468 tprintf("%d /* BUS_??? */", si->si_code);
1469 tprintf(", si_addr=%lx",
1470 (unsigned long) si->_sifields._sigfault.si_addr);
1471 break;
1472 case SIGTRAP:
1473 if (!printflags(sigtrap_flags, si->si_code))
1474 tprintf("%d /* TRAP_??? */", si->si_code);
1475 break;
1476 case SIGCHLD:
1477 if (!printflags(sigchld_flags, si->si_code))
1478 tprintf("%d /* CLD_??? */", si->si_code);
1479 if (!verbose(tcp))
1480 tprintf(", ...");
1481 else
1482 tprintf(", si_pid=%d, si_uid=%d, si_status=%d, si_utime=%lu, si_stime=%lu",
1483 si->_sifields._kill.si_pid,
1484 si->_sifields._kill.si_uid,
1485 si->_sifields._sigchld.si_status,
1486 si->_sifields._sigchld.si_utime,
1487 si->_sifields._sigchld.si_stime);
1488 break;
1489 case SIGPOLL:
1490 if (!printflags(sigpoll_flags, si->si_code))
1491 tprintf("%d /* POLL_??? */", si->si_code);
1492 if (si->si_code == POLL_IN
1493 || si->si_code == POLL_OUT
1494 || si->si_code == POLL_MSG)
1495 tprintf(", si_bind=%lu, si_fd=%d",
1496 (unsigned long) si->_sifields._sigpoll.si_band,
1497 si->_sifields._sigpoll.si_fd);
1498 break;
1499 default:
1500 if (!printflags(siginfo_flags, si->si_code))
1501 tprintf("%d /* SI_??? */", si->si_code);
1502 tprintf(", si_pid=%lu, si_uid=%lu, si_value={",
1503 (unsigned long) si->_sifields._rt.si_pid,
1504 (unsigned long) si->_sifields._rt.si_uid);
1505 if (!verbose(tcp))
1506 tprintf("...");
1507 else {
1508 tprintf("sival_int=%u, sival_ptr=%#lx",
1509 si->_sifields._rt.si_sigval.sival_int,
1510 (unsigned long) si->_sifields._rt.si_sigval.sival_ptr);
1511 }
1512 tprintf("}");
1513 break;
1514 }
1515 tprintf("}");
1516}
1517
1518 int
1519sys_rt_sigqueueinfo(tcp)
1520 struct tcb *tcp;
1521{
1522 if (entering(tcp)) {
1523 siginfo_t si;
1524 tprintf("%lu, ", tcp->u_arg[0]);
1525 printsignal(tcp->u_arg[1]);
1526 tprintf(", ");
1527 if (umove(tcp, tcp->u_arg[2], &si) < 0)
1528 tprintf("%#lx", tcp->u_arg[2]);
1529 else
1530 printsiginfo(&si);
1531 }
1532 return 0;
1533}
1534
1535int sys_rt_sigtimedwait(tcp)
1536 struct tcb *tcp;
1537{
1538 if (entering(tcp)) {
1539 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001540
Nate Sammons4a121431999-04-06 01:19:39 +00001541 if (copy_sigset_len(tcp, tcp->u_arg[0],
1542 &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001543 tprintf("[?]");
1544 else
Nate Sammons4a121431999-04-06 01:19:39 +00001545 printsigmask(sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001546 tprintf(", ");
1547 }
1548 else {
1549 if (syserror(tcp))
1550 tprintf("%#lx", tcp->u_arg[0]);
1551 else {
1552 siginfo_t si;
1553 if (umove(tcp, tcp->u_arg[1], &si) < 0)
1554 tprintf("%#lx", tcp->u_arg[1]);
1555 else
1556 printsiginfo(&si);
1557 /* XXX For now */
1558 tprintf(", %#lx", tcp->u_arg[2]);
1559 tprintf(", %d", (int) tcp->u_arg[3]);
1560 }
1561 }
1562 return 0;
1563};
1564
1565#endif /* LINUX */
1566