blob: 8c9433d69e9969543cbbe4f9d23da58753a2d876 [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
Denys Vlasenko7a862d72009-04-15 13:22:59 +000038#include <stdint.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000039#include <signal.h>
40#include <sys/user.h>
41#include <fcntl.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000042
43#ifdef SVR4
44#include <sys/ucontext.h>
45#endif /* SVR4 */
46
Wichert Akkerman36915a11999-07-13 15:45:02 +000047#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 Akkermanfaf72222000-02-19 23:59:03 +000055#elif defined(HAVE_LINUX_PTRACE_H)
56#undef PTRACE_SYSCALL
Roland McGrathb0acdfd2004-03-01 21:31:02 +000057# ifdef HAVE_STRUCT_IA64_FPREG
58# define ia64_fpreg XXX_ia64_fpreg
59# endif
60# ifdef HAVE_STRUCT_PT_ALL_USER_REGS
61# define pt_all_user_regs XXX_pt_all_user_regs
62# endif
Wichert Akkermanfaf72222000-02-19 23:59:03 +000063#include <linux/ptrace.h>
Roland McGrathb0acdfd2004-03-01 21:31:02 +000064# undef ia64_fpreg
65# undef pt_all_user_regs
Wichert Akkerman15dea971999-10-06 13:06:34 +000066#endif
Wichert Akkerman36915a11999-07-13 15:45:02 +000067
Wichert Akkermanfaf72222000-02-19 23:59:03 +000068
Wichert Akkerman36915a11999-07-13 15:45:02 +000069#ifdef LINUX
70
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +000071#ifdef IA64
72# include <asm/ptrace_offsets.h>
Denys Vlasenko041b3ee2011-08-18 12:48:56 +020073#endif
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +000074
Roland McGrath6d1a65c2004-07-12 07:44:08 +000075#if defined (LINUX) && defined (SPARC64)
Roland McGrath6d1a65c2004-07-12 07:44:08 +000076# undef PTRACE_GETREGS
77# define PTRACE_GETREGS PTRACE_GETREGS64
78# undef PTRACE_SETREGS
79# define PTRACE_SETREGS PTRACE_SETREGS64
80#endif /* LINUX && SPARC64 */
Roland McGrath30ff45e2003-01-30 20:15:23 +000081
Mike Frysinger8566c502009-10-12 11:05:14 -040082#if defined (SPARC) || defined (SPARC64) || defined (MIPS)
Roland McGrath576b7842007-11-04 00:00:00 +000083typedef struct {
84 struct pt_regs si_regs;
85 int si_mask;
86} m_siginfo_t;
Roland McGrath30ff45e2003-01-30 20:15:23 +000087#elif defined HAVE_ASM_SIGCONTEXT_H
88#if !defined(IA64) && !defined(X86_64)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000089#include <asm/sigcontext.h>
Roland McGrath30ff45e2003-01-30 20:15:23 +000090#endif /* !IA64 && !X86_64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000091#else /* !HAVE_ASM_SIGCONTEXT_H */
Roland McGrath0cbb4e42008-05-20 01:26:21 +000092#if defined I386 && !defined HAVE_STRUCT_SIGCONTEXT_STRUCT
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000093struct sigcontext_struct {
94 unsigned short gs, __gsh;
95 unsigned short fs, __fsh;
96 unsigned short es, __esh;
97 unsigned short ds, __dsh;
98 unsigned long edi;
99 unsigned long esi;
100 unsigned long ebp;
101 unsigned long esp;
102 unsigned long ebx;
103 unsigned long edx;
104 unsigned long ecx;
105 unsigned long eax;
106 unsigned long trapno;
107 unsigned long err;
108 unsigned long eip;
109 unsigned short cs, __csh;
110 unsigned long eflags;
111 unsigned long esp_at_signal;
112 unsigned short ss, __ssh;
113 unsigned long i387;
114 unsigned long oldmask;
115 unsigned long cr2;
116};
117#else /* !I386 */
Roland McGrath587c7b52009-02-11 03:03:28 +0000118#if defined M68K && !defined HAVE_STRUCT_SIGCONTEXT
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000119struct sigcontext
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000120{
121 unsigned long sc_mask;
122 unsigned long sc_usp;
123 unsigned long sc_d0;
124 unsigned long sc_d1;
125 unsigned long sc_a0;
126 unsigned long sc_a1;
127 unsigned short sc_sr;
128 unsigned long sc_pc;
129 unsigned short sc_formatvec;
130};
131#endif /* M68K */
132#endif /* !I386 */
133#endif /* !HAVE_ASM_SIGCONTEXT_H */
Denys Vlasenko041b3ee2011-08-18 12:48:56 +0200134
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000135#ifndef NSIG
Denys Vlasenko041b3ee2011-08-18 12:48:56 +0200136#warning: NSIG is not defined, using 32
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000137#define NSIG 32
138#endif
139#ifdef ARM
Denys Vlasenko041b3ee2011-08-18 12:48:56 +0200140/* Ugh. Is this really correct? ARM has no RT signals?! */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000141#undef NSIG
142#define NSIG 32
143#endif
Denys Vlasenko041b3ee2011-08-18 12:48:56 +0200144
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000145#endif /* LINUX */
146
Roland McGrathee36ce12004-09-04 03:53:10 +0000147const char *const signalent0[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000148#include "signalent.h"
149};
Dmitry V. Levinfcda7a52011-06-13 21:58:43 +0000150const int nsignals0 = ARRAY_SIZE(signalent0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000151
152#if SUPPORTED_PERSONALITIES >= 2
Roland McGrathee36ce12004-09-04 03:53:10 +0000153const char *const signalent1[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000154#include "signalent1.h"
155};
Dmitry V. Levinfcda7a52011-06-13 21:58:43 +0000156const int nsignals1 = ARRAY_SIZE(signalent1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000157#endif /* SUPPORTED_PERSONALITIES >= 2 */
158
159#if SUPPORTED_PERSONALITIES >= 3
Roland McGrathee36ce12004-09-04 03:53:10 +0000160const char *const signalent2[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000161#include "signalent2.h"
162};
Dmitry V. Levinfcda7a52011-06-13 21:58:43 +0000163const int nsignals2 = ARRAY_SIZE(signalent2);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000164#endif /* SUPPORTED_PERSONALITIES >= 3 */
165
Roland McGrathee36ce12004-09-04 03:53:10 +0000166const char *const *signalent;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000167int nsignals;
168
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000169#if defined(SUNOS4) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000170
Roland McGrathd9f816f2004-09-04 03:39:20 +0000171static const struct xlat sigvec_flags[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000172 { SV_ONSTACK, "SV_ONSTACK" },
173 { SV_INTERRUPT, "SV_INTERRUPT" },
174 { SV_RESETHAND, "SV_RESETHAND" },
175 { SA_NOCLDSTOP, "SA_NOCLDSTOP" },
176 { 0, NULL },
177};
178
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000179#endif /* SUNOS4 || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000180
181#ifdef HAVE_SIGACTION
182
Roland McGrath063ae2d2005-02-02 04:16:54 +0000183#if defined LINUX && (defined I386 || defined X86_64)
Roland McGrath2638cb42002-12-15 23:58:41 +0000184/* The libc headers do not define this constant since it should only be
Denys Vlasenko041b3ee2011-08-18 12:48:56 +0200185 used by the implementation. So we define it here. */
Roland McGrath2638cb42002-12-15 23:58:41 +0000186# ifndef SA_RESTORER
187# define SA_RESTORER 0x04000000
188# endif
189#endif
190
Roland McGrathd9f816f2004-09-04 03:39:20 +0000191static const struct xlat sigact_flags[] = {
Wichert Akkermanc7926982000-04-10 22:22:31 +0000192#ifdef SA_RESTORER
193 { SA_RESTORER, "SA_RESTORER" },
194#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000195#ifdef SA_STACK
196 { SA_STACK, "SA_STACK" },
197#endif
198#ifdef SA_RESTART
199 { SA_RESTART, "SA_RESTART" },
200#endif
201#ifdef SA_INTERRUPT
202 { SA_INTERRUPT, "SA_INTERRUPT" },
203#endif
Roland McGrath4fef51d2008-07-18 01:02:41 +0000204#ifdef SA_NODEFER
205 { SA_NODEFER, "SA_NODEFER" },
206#endif
207#if defined SA_NOMASK && SA_NODEFER != SA_NOMASK
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000208 { SA_NOMASK, "SA_NOMASK" },
209#endif
Roland McGrath4fef51d2008-07-18 01:02:41 +0000210#ifdef SA_RESETHAND
211 { SA_RESETHAND, "SA_RESETHAND" },
212#endif
213#if defined SA_ONESHOT && SA_ONESHOT != SA_RESETHAND
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000214 { SA_ONESHOT, "SA_ONESHOT" },
215#endif
216#ifdef SA_SIGINFO
217 { SA_SIGINFO, "SA_SIGINFO" },
218#endif
219#ifdef SA_RESETHAND
220 { SA_RESETHAND, "SA_RESETHAND" },
221#endif
222#ifdef SA_ONSTACK
223 { SA_ONSTACK, "SA_ONSTACK" },
224#endif
225#ifdef SA_NODEFER
226 { SA_NODEFER, "SA_NODEFER" },
227#endif
228#ifdef SA_NOCLDSTOP
229 { SA_NOCLDSTOP, "SA_NOCLDSTOP" },
230#endif
231#ifdef SA_NOCLDWAIT
232 { SA_NOCLDWAIT, "SA_NOCLDWAIT" },
233#endif
234#ifdef _SA_BSDCALL
235 { _SA_BSDCALL, "_SA_BSDCALL" },
236#endif
Chris Metcalfc8c66982009-12-28 10:00:15 -0500237#ifdef SA_NOPTRACE
238 { SA_NOPTRACE, "SA_NOPTRACE" },
239#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000240 { 0, NULL },
241};
242
Roland McGrathd9f816f2004-09-04 03:39:20 +0000243static const struct xlat sigprocmaskcmds[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000244 { SIG_BLOCK, "SIG_BLOCK" },
245 { SIG_UNBLOCK, "SIG_UNBLOCK" },
246 { SIG_SETMASK, "SIG_SETMASK" },
247#ifdef SIG_SETMASK32
248 { SIG_SETMASK32,"SIG_SETMASK32" },
249#endif
250 { 0, NULL },
251};
252
253#endif /* HAVE_SIGACTION */
254
Nate Sammonsce780fc1999-03-29 23:23:13 +0000255/* Anonymous realtime signals. */
256/* Under glibc 2.1, SIGRTMIN et al are functions, but __SIGRTMIN is a
257 constant. This is what we want. Otherwise, just use SIGRTMIN. */
258#ifdef SIGRTMIN
259#ifndef __SIGRTMIN
260#define __SIGRTMIN SIGRTMIN
261#define __SIGRTMAX SIGRTMAX /* likewise */
262#endif
263#endif
264
Denys Vlasenkod9560c12011-08-19 17:41:28 +0200265/* Note on the size of sigset_t:
266 *
267 * In glibc, sigset_t is an array with space for 1024 bits (!),
268 * even though all arches supported by Linux have only 64 signals
269 * except MIPS, which has 128. IOW, it is 128 bytes long.
270 *
271 * In-kernel sigset_t is sized correctly (it is either 64 or 128 bit long).
272 * However, some old syscall return only 32 lower bits (one word).
273 * Example: sys_sigpending vs sys_rt_sigpending.
274 *
275 * Be aware of this fact when you try to
276 * memcpy(&tcp->u_arg[1], &something, sizeof(sigset_t))
277 * - sizeof(sigset_t) is much bigger than you think,
278 * it may overflow tcp->u_arg[] array, and it may try to copy more data
279 * than is really available in <something>.
280 * Similarly,
281 * umoven(tcp, addr, sizeof(sigset_t), &sigset)
282 * may be a bad idea: it'll try to read much more data than needed
283 * to fetch a sigset_t.
284 * Use (NSIG / 8) as a size instead.
285 */
286
Roland McGrathee36ce12004-09-04 03:53:10 +0000287const char *
Denys Vlasenkoeccc48c2011-06-09 01:28:11 +0200288signame(int sig)
Nate Sammonsce780fc1999-03-29 23:23:13 +0000289{
Denys Vlasenko041b3ee2011-08-18 12:48:56 +0200290 static char buf[sizeof("SIGRT_%d") + sizeof(int)*3];
291
292 if (sig >= 0 && sig < nsignals)
Nate Sammonsce780fc1999-03-29 23:23:13 +0000293 return signalent[sig];
294#ifdef SIGRTMIN
Denys Vlasenko041b3ee2011-08-18 12:48:56 +0200295 if (sig >= __SIGRTMIN && sig <= __SIGRTMAX) {
296 sprintf(buf, "SIGRT_%d", (int)(sig - __SIGRTMIN));
Nate Sammonsce780fc1999-03-29 23:23:13 +0000297 return buf;
298 }
Denys Vlasenko041b3ee2011-08-18 12:48:56 +0200299#endif
300 sprintf(buf, "%d", sig);
301 return buf;
Nate Sammonsce780fc1999-03-29 23:23:13 +0000302}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000303
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000304#ifndef UNIXWARE
Nate Sammons4a121431999-04-06 01:19:39 +0000305static void
Denys Vlasenkoeccc48c2011-06-09 01:28:11 +0200306long_to_sigset(long l, sigset_t *s)
Nate Sammons4a121431999-04-06 01:19:39 +0000307{
308 sigemptyset(s);
309 *(long *)s = l;
310}
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000311#endif
Nate Sammons4a121431999-04-06 01:19:39 +0000312
313static int
Denys Vlasenko12014262011-05-30 14:00:14 +0200314copy_sigset_len(struct tcb *tcp, long addr, sigset_t *s, int len)
Nate Sammons4a121431999-04-06 01:19:39 +0000315{
316 if (len > sizeof(*s))
317 len = sizeof(*s);
318 sigemptyset(s);
319 if (umoven(tcp, addr, len, (char *)s) < 0)
320 return -1;
321 return 0;
322}
323
324#ifdef LINUX
325/* Original sigset is unsigned long */
326#define copy_sigset(tcp, addr, s) copy_sigset_len(tcp, addr, s, sizeof(long))
327#else
328#define copy_sigset(tcp, addr, s) copy_sigset_len(tcp, addr, s, sizeof(sigset_t))
329#endif
330
Dmitry V. Levinab9008b2007-01-11 22:05:04 +0000331static const char *
332sprintsigmask(const char *str, sigset_t *mask, int rt)
333/* set might include realtime sigs */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000334{
Denys Vlasenkod9560c12011-08-19 17:41:28 +0200335 /* Was [8 * sizeof(sigset_t) * 8], but
336 * glibc sigset_t is huge (1024 bits = 128 *bytes*),
337 * and we were ending up with 8k (!) buffer here.
338 *
339 * No Unix system can have sig > 255
340 * (waitpid API won't be able to indicate death from one)
341 * and sig 0 doesn't exist either.
342 * Therefore max possible no of sigs is 255: 1..255
343 */
344 static char outstr[8 * 255];
345
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000346 int i, nsigs;
Nate Sammons4a121431999-04-06 01:19:39 +0000347 int maxsigs;
Dmitry V. Levin30145dd2010-09-06 22:08:24 +0000348 const char *format;
349 char *s;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000350
Dmitry V. Levinab9008b2007-01-11 22:05:04 +0000351 strcpy(outstr, str);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000352 s = outstr + strlen(outstr);
353 nsigs = 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000354 maxsigs = nsignals;
355#ifdef __SIGRTMAX
356 if (rt)
357 maxsigs = __SIGRTMAX; /* instead */
358#endif
359 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000360 if (sigismember(mask, i) == 1)
361 nsigs++;
362 }
363 if (nsigs >= nsignals * 2 / 3) {
364 *s++ = '~';
Nate Sammons4a121431999-04-06 01:19:39 +0000365 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000366 switch (sigismember(mask, i)) {
367 case 1:
368 sigdelset(mask, i);
369 break;
370 case 0:
371 sigaddset(mask, i);
372 break;
373 }
374 }
375 }
376 format = "%s";
377 *s++ = '[';
Nate Sammons4a121431999-04-06 01:19:39 +0000378 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000379 if (sigismember(mask, i) == 1) {
John Hughesbdf48f52001-03-06 15:08:09 +0000380 /* real-time signals on solaris don't have
381 * signalent entries
382 */
383 if (i < nsignals) {
384 sprintf(s, format, signalent[i] + 3);
385 }
Roland McGrath90b4cb52003-09-23 22:19:32 +0000386#ifdef SIGRTMIN
387 else if (i >= __SIGRTMIN && i <= __SIGRTMAX) {
388 char tsig[40];
389 sprintf(tsig, "RT_%u", i - __SIGRTMIN);
390 sprintf(s, format, tsig);
391 }
392#endif /* SIGRTMIN */
John Hughesbdf48f52001-03-06 15:08:09 +0000393 else {
394 char tsig[32];
395 sprintf(tsig, "%u", i);
396 sprintf(s, format, tsig);
397 }
398 s += strlen(s);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000399 format = " %s";
400 }
401 }
402 *s++ = ']';
403 *s = '\0';
404 return outstr;
405}
406
407static void
Denys Vlasenkoeccc48c2011-06-09 01:28:11 +0200408printsigmask(sigset_t *mask, int rt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000409{
Nate Sammons4a121431999-04-06 01:19:39 +0000410 tprintf("%s", sprintsigmask("", mask, rt));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000411}
412
413void
Denys Vlasenkoeccc48c2011-06-09 01:28:11 +0200414printsignal(int nr)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000415{
Dmitry V. Levin4bcd5ef2009-06-01 10:32:27 +0000416 tprintf("%s", signame(nr));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000417}
418
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000419void
420print_sigset(struct tcb *tcp, long addr, int rt)
421{
422 sigset_t ss;
423
424 if (!addr)
425 tprintf("NULL");
426 else if (copy_sigset(tcp, addr, &ss) < 0)
427 tprintf("%#lx", addr);
428 else
429 printsigmask(&ss, rt);
430}
431
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000432#ifdef LINUX
433
John Hughes58265892001-10-18 15:13:53 +0000434#ifndef ILL_ILLOPC
435#define ILL_ILLOPC 1 /* illegal opcode */
436#define ILL_ILLOPN 2 /* illegal operand */
437#define ILL_ILLADR 3 /* illegal addressing mode */
438#define ILL_ILLTRP 4 /* illegal trap */
439#define ILL_PRVOPC 5 /* privileged opcode */
440#define ILL_PRVREG 6 /* privileged register */
441#define ILL_COPROC 7 /* coprocessor error */
442#define ILL_BADSTK 8 /* internal stack error */
443#define FPE_INTDIV 1 /* integer divide by zero */
444#define FPE_INTOVF 2 /* integer overflow */
445#define FPE_FLTDIV 3 /* floating point divide by zero */
446#define FPE_FLTOVF 4 /* floating point overflow */
447#define FPE_FLTUND 5 /* floating point underflow */
448#define FPE_FLTRES 6 /* floating point inexact result */
449#define FPE_FLTINV 7 /* floating point invalid operation */
450#define FPE_FLTSUB 8 /* subscript out of range */
451#define SEGV_MAPERR 1 /* address not mapped to object */
452#define SEGV_ACCERR 2 /* invalid permissions for mapped object */
453#define BUS_ADRALN 1 /* invalid address alignment */
454#define BUS_ADRERR 2 /* non-existant physical address */
455#define BUS_OBJERR 3 /* object specific hardware error */
456#define TRAP_BRKPT 1 /* process breakpoint */
457#define TRAP_TRACE 2 /* process trace trap */
458#define CLD_EXITED 1 /* child has exited */
459#define CLD_KILLED 2 /* child was killed */
460#define CLD_DUMPED 3 /* child terminated abnormally */
461#define CLD_TRAPPED 4 /* traced child has trapped */
462#define CLD_STOPPED 5 /* child has stopped */
463#define CLD_CONTINUED 6 /* stopped child has continued */
464#define POLL_IN 1 /* data input available */
465#define POLL_OUT 2 /* output buffers available */
466#define POLL_MSG 3 /* input message available */
467#define POLL_ERR 4 /* i/o error */
468#define POLL_PRI 5 /* high priority input available */
469#define POLL_HUP 6 /* device disconnected */
Dmitry V. Levin7d4bff12011-03-10 21:41:34 +0000470#define SI_KERNEL 0x80 /* sent by kernel */
John Hughes58265892001-10-18 15:13:53 +0000471#define SI_USER 0 /* sent by kill, sigsend, raise */
472#define SI_QUEUE -1 /* sent by sigqueue */
473#define SI_TIMER -2 /* sent by timer expiration */
474#define SI_MESGQ -3 /* sent by real time mesq state change */
475#define SI_ASYNCIO -4 /* sent by AIO completion */
Dmitry V. Levin7d4bff12011-03-10 21:41:34 +0000476#define SI_SIGIO -5 /* sent by SIGIO */
477#define SI_TKILL -6 /* sent by tkill */
478#define SI_ASYNCNL -60 /* sent by asynch name lookup completion */
479
Dmitry V. Levin6d9e8e82011-03-10 22:18:56 +0000480#define SI_FROMUSER(sip) ((sip)->si_code <= 0)
481
Dmitry V. Levin7d4bff12011-03-10 21:41:34 +0000482#endif /* LINUX */
John Hughes58265892001-10-18 15:13:53 +0000483
484#if __GLIBC_MINOR__ < 1
485/* Type for data associated with a signal. */
486typedef union sigval
487{
488 int sival_int;
489 void *sival_ptr;
490} sigval_t;
491
492# define __SI_MAX_SIZE 128
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200493# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof(int)) - 3)
John Hughes58265892001-10-18 15:13:53 +0000494
495typedef struct siginfo
496{
497 int si_signo; /* Signal number. */
498 int si_errno; /* If non-zero, an errno value associated with
499 this signal, as defined in <errno.h>. */
500 int si_code; /* Signal code. */
501
502 union
503 {
504 int _pad[__SI_PAD_SIZE];
505
506 /* kill(). */
507 struct
508 {
509 __pid_t si_pid; /* Sending process ID. */
510 __uid_t si_uid; /* Real user ID of sending process. */
511 } _kill;
512
513 /* POSIX.1b timers. */
514 struct
515 {
516 unsigned int _timer1;
517 unsigned int _timer2;
518 } _timer;
519
520 /* POSIX.1b signals. */
521 struct
522 {
523 __pid_t si_pid; /* Sending process ID. */
524 __uid_t si_uid; /* Real user ID of sending process. */
525 sigval_t si_sigval; /* Signal value. */
526 } _rt;
527
528 /* SIGCHLD. */
529 struct
530 {
531 __pid_t si_pid; /* Which child. */
532 int si_status; /* Exit value or signal. */
533 __clock_t si_utime;
534 __clock_t si_stime;
535 } _sigchld;
536
537 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
538 struct
539 {
540 void *si_addr; /* Faulting insn/memory ref. */
541 } _sigfault;
542
543 /* SIGPOLL. */
544 struct
545 {
546 int si_band; /* Band event for SIGPOLL. */
547 int si_fd;
548 } _sigpoll;
549 } _sifields;
550} siginfo_t;
551
552#define si_pid _sifields._kill.si_pid
553#define si_uid _sifields._kill.si_uid
554#define si_status _sifields._sigchld.si_status
555#define si_utime _sifields._sigchld.si_utime
556#define si_stime _sifields._sigchld.si_stime
557#define si_value _sifields._rt.si_sigval
558#define si_int _sifields._rt.si_sigval.sival_int
559#define si_ptr _sifields._rt.si_sigval.sival_ptr
560#define si_addr _sifields._sigfault.si_addr
561#define si_band _sifields._sigpoll.si_band
562#define si_fd _sifields._sigpoll.si_fd
563
564#endif
565
566#endif
567
568#if defined (SVR4) || defined (LINUX)
569
Roland McGrathd9f816f2004-09-04 03:39:20 +0000570static const struct xlat siginfo_codes[] = {
Dmitry V. Levin7d4bff12011-03-10 21:41:34 +0000571#ifdef SI_KERNEL
572 { SI_KERNEL, "SI_KERNEL" },
John Hughes58265892001-10-18 15:13:53 +0000573#endif
574#ifdef SI_USER
575 { SI_USER, "SI_USER" },
576#endif
John Hughes58265892001-10-18 15:13:53 +0000577#ifdef SI_QUEUE
578 { SI_QUEUE, "SI_QUEUE" },
579#endif
580#ifdef SI_TIMER
581 { SI_TIMER, "SI_TIMER" },
582#endif
John Hughes58265892001-10-18 15:13:53 +0000583#ifdef SI_MESGQ
584 { SI_MESGQ, "SI_MESGQ" },
585#endif
Dmitry V. Levin7d4bff12011-03-10 21:41:34 +0000586#ifdef SI_ASYNCIO
587 { SI_ASYNCIO, "SI_ASYNCIO" },
588#endif
Roland McGrath941b7402003-05-23 00:29:02 +0000589#ifdef SI_SIGIO
590 { SI_SIGIO, "SI_SIGIO" },
591#endif
592#ifdef SI_TKILL
593 { SI_TKILL, "SI_TKILL" },
594#endif
Dmitry V. Levin7d4bff12011-03-10 21:41:34 +0000595#ifdef SI_ASYNCNL
596 { SI_ASYNCNL, "SI_ASYNCNL" },
597#endif
598#ifdef SI_NOINFO
599 { SI_NOINFO, "SI_NOINFO" },
600#endif
601#ifdef SI_LWP
602 { SI_LWP, "SI_LWP" },
603#endif
John Hughes58265892001-10-18 15:13:53 +0000604 { 0, NULL },
605};
606
Roland McGrathd9f816f2004-09-04 03:39:20 +0000607static const struct xlat sigill_codes[] = {
John Hughes58265892001-10-18 15:13:53 +0000608 { ILL_ILLOPC, "ILL_ILLOPC" },
609 { ILL_ILLOPN, "ILL_ILLOPN" },
610 { ILL_ILLADR, "ILL_ILLADR" },
611 { ILL_ILLTRP, "ILL_ILLTRP" },
612 { ILL_PRVOPC, "ILL_PRVOPC" },
613 { ILL_PRVREG, "ILL_PRVREG" },
614 { ILL_COPROC, "ILL_COPROC" },
615 { ILL_BADSTK, "ILL_BADSTK" },
616 { 0, NULL },
617};
618
Roland McGrathd9f816f2004-09-04 03:39:20 +0000619static const struct xlat sigfpe_codes[] = {
John Hughes58265892001-10-18 15:13:53 +0000620 { FPE_INTDIV, "FPE_INTDIV" },
621 { FPE_INTOVF, "FPE_INTOVF" },
622 { FPE_FLTDIV, "FPE_FLTDIV" },
623 { FPE_FLTOVF, "FPE_FLTOVF" },
624 { FPE_FLTUND, "FPE_FLTUND" },
625 { FPE_FLTRES, "FPE_FLTRES" },
626 { FPE_FLTINV, "FPE_FLTINV" },
627 { FPE_FLTSUB, "FPE_FLTSUB" },
628 { 0, NULL },
629};
630
Roland McGrathd9f816f2004-09-04 03:39:20 +0000631static const struct xlat sigtrap_codes[] = {
John Hughes58265892001-10-18 15:13:53 +0000632 { TRAP_BRKPT, "TRAP_BRKPT" },
633 { TRAP_TRACE, "TRAP_TRACE" },
634 { 0, NULL },
635};
636
Roland McGrathd9f816f2004-09-04 03:39:20 +0000637static const struct xlat sigchld_codes[] = {
John Hughes58265892001-10-18 15:13:53 +0000638 { CLD_EXITED, "CLD_EXITED" },
639 { CLD_KILLED, "CLD_KILLED" },
640 { CLD_DUMPED, "CLD_DUMPED" },
641 { CLD_TRAPPED, "CLD_TRAPPED" },
642 { CLD_STOPPED, "CLD_STOPPED" },
643 { CLD_CONTINUED,"CLD_CONTINUED" },
644 { 0, NULL },
645};
646
Roland McGrathd9f816f2004-09-04 03:39:20 +0000647static const struct xlat sigpoll_codes[] = {
John Hughes58265892001-10-18 15:13:53 +0000648 { POLL_IN, "POLL_IN" },
649 { POLL_OUT, "POLL_OUT" },
650 { POLL_MSG, "POLL_MSG" },
651 { POLL_ERR, "POLL_ERR" },
652 { POLL_PRI, "POLL_PRI" },
653 { POLL_HUP, "POLL_HUP" },
654 { 0, NULL },
655};
656
Roland McGrathd9f816f2004-09-04 03:39:20 +0000657static const struct xlat sigprof_codes[] = {
John Hughes58265892001-10-18 15:13:53 +0000658#ifdef PROF_SIG
659 { PROF_SIG, "PROF_SIG" },
660#endif
661 { 0, NULL },
662};
663
664#ifdef SIGEMT
Roland McGrathd9f816f2004-09-04 03:39:20 +0000665static const struct xlat sigemt_codes[] = {
John Hughes58265892001-10-18 15:13:53 +0000666#ifdef EMT_TAGOVF
667 { EMT_TAGOVF, "EMT_TAGOVF" },
668#endif
669 { 0, NULL },
670};
671#endif
672
Roland McGrathd9f816f2004-09-04 03:39:20 +0000673static const struct xlat sigsegv_codes[] = {
John Hughes58265892001-10-18 15:13:53 +0000674 { SEGV_MAPERR, "SEGV_MAPERR" },
675 { SEGV_ACCERR, "SEGV_ACCERR" },
676 { 0, NULL },
677};
678
Roland McGrathd9f816f2004-09-04 03:39:20 +0000679static const struct xlat sigbus_codes[] = {
John Hughes58265892001-10-18 15:13:53 +0000680 { BUS_ADRALN, "BUS_ADRALN" },
681 { BUS_ADRERR, "BUS_ADRERR" },
682 { BUS_OBJERR, "BUS_OBJERR" },
683 { 0, NULL },
684};
685
686void
Dmitry V. Levin6d9e8e82011-03-10 22:18:56 +0000687printsiginfo(siginfo_t *sip, int verbose)
John Hughes58265892001-10-18 15:13:53 +0000688{
Roland McGrathf9c49b22004-10-06 22:11:54 +0000689 const char *code;
John Hughes58265892001-10-18 15:13:53 +0000690
691 if (sip->si_signo == 0) {
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200692 tprintf("{}");
John Hughes58265892001-10-18 15:13:53 +0000693 return;
694 }
695 tprintf("{si_signo=");
696 printsignal(sip->si_signo);
697 code = xlookup(siginfo_codes, sip->si_code);
698 if (!code) {
699 switch (sip->si_signo) {
700 case SIGTRAP:
701 code = xlookup(sigtrap_codes, sip->si_code);
702 break;
703 case SIGCHLD:
704 code = xlookup(sigchld_codes, sip->si_code);
705 break;
706 case SIGPOLL:
707 code = xlookup(sigpoll_codes, sip->si_code);
708 break;
709 case SIGPROF:
710 code = xlookup(sigprof_codes, sip->si_code);
711 break;
712 case SIGILL:
713 code = xlookup(sigill_codes, sip->si_code);
714 break;
715#ifdef SIGEMT
716 case SIGEMT:
717 code = xlookup(sigemt_codes, sip->si_code);
718 break;
719#endif
720 case SIGFPE:
721 code = xlookup(sigfpe_codes, sip->si_code);
722 break;
723 case SIGSEGV:
724 code = xlookup(sigsegv_codes, sip->si_code);
725 break;
726 case SIGBUS:
727 code = xlookup(sigbus_codes, sip->si_code);
728 break;
729 }
730 }
731 if (code)
732 tprintf(", si_code=%s", code);
733 else
734 tprintf(", si_code=%#x", sip->si_code);
735#ifdef SI_NOINFO
736 if (sip->si_code != SI_NOINFO)
737#endif
738 {
739 if (sip->si_errno) {
740 if (sip->si_errno < 0 || sip->si_errno >= nerrnos)
741 tprintf(", si_errno=%d", sip->si_errno);
742 else
743 tprintf(", si_errno=%s",
744 errnoent[sip->si_errno]);
745 }
746#ifdef SI_FROMUSER
747 if (SI_FROMUSER(sip)) {
Dmitry V. Levin6d9e8e82011-03-10 22:18:56 +0000748 tprintf(", si_pid=%lu, si_uid=%lu",
749 (unsigned long) sip->si_pid,
750 (unsigned long) sip->si_uid);
John Hughes58265892001-10-18 15:13:53 +0000751 switch (sip->si_code) {
Dmitry V. Levin6d9e8e82011-03-10 22:18:56 +0000752#ifdef SI_USER
753 case SI_USER:
754 break;
755#endif
756#ifdef SI_TKILL
757 case SI_TKILL:
758 break;
759#endif
John Hughes58265892001-10-18 15:13:53 +0000760#ifdef SI_TIMER
761 case SI_TIMER:
Dmitry V. Levin6d9e8e82011-03-10 22:18:56 +0000762 tprintf(", si_value=%d", sip->si_int);
John Hughes58265892001-10-18 15:13:53 +0000763 break;
Dmitry V. Levin6d9e8e82011-03-10 22:18:56 +0000764#endif
765#ifdef LINUX
766 default:
Dmitry V. Levinb41e1c92011-03-10 23:14:47 +0000767 if (!sip->si_ptr)
768 break;
Dmitry V. Levin6d9e8e82011-03-10 22:18:56 +0000769 if (!verbose)
770 tprintf(", ...");
771 else
772 tprintf(", si_value={int=%u, ptr=%#lx}",
773 sip->si_int,
774 (unsigned long) sip->si_ptr);
775 break;
776#endif
John Hughes58265892001-10-18 15:13:53 +0000777 }
John Hughes58265892001-10-18 15:13:53 +0000778 }
779 else
780#endif /* SI_FROMUSER */
781 {
782 switch (sip->si_signo) {
783 case SIGCHLD:
784 tprintf(", si_pid=%ld, si_status=",
785 (long) sip->si_pid);
786 if (sip->si_code == CLD_EXITED)
787 tprintf("%d", sip->si_status);
788 else
789 printsignal(sip->si_status);
790#if LINUX
791 if (!verbose)
792 tprintf(", ...");
793 else
794 tprintf(", si_utime=%lu, si_stime=%lu",
795 sip->si_utime,
796 sip->si_stime);
797#endif
798 break;
799 case SIGILL: case SIGFPE:
800 case SIGSEGV: case SIGBUS:
801 tprintf(", si_addr=%#lx",
802 (unsigned long) sip->si_addr);
803 break;
804 case SIGPOLL:
805 switch (sip->si_code) {
806 case POLL_IN: case POLL_OUT: case POLL_MSG:
807 tprintf(", si_band=%ld",
808 (long) sip->si_band);
809 break;
810 }
811 break;
812#ifdef LINUX
813 default:
Dmitry V. Levinb41e1c92011-03-10 23:14:47 +0000814 if (sip->si_pid || sip->si_uid)
815 tprintf(", si_pid=%lu, si_uid=%lu",
816 (unsigned long) sip->si_pid,
817 (unsigned long) sip->si_uid);
818 if (!sip->si_ptr)
819 break;
John Hughes58265892001-10-18 15:13:53 +0000820 if (!verbose)
Dmitry V. Levinb41e1c92011-03-10 23:14:47 +0000821 tprintf(", ...");
John Hughes58265892001-10-18 15:13:53 +0000822 else {
Dmitry V. Levinb41e1c92011-03-10 23:14:47 +0000823 tprintf(", si_value={int=%u, ptr=%#lx}",
John Hughes58265892001-10-18 15:13:53 +0000824 sip->si_int,
825 (unsigned long) sip->si_ptr);
826 }
827#endif
Roland McGratha39c5a12002-12-17 05:10:37 +0000828
John Hughes58265892001-10-18 15:13:53 +0000829 }
830 }
831 }
832 tprintf("}");
833}
834
835#endif /* SVR4 || LINUX */
836
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000837#if defined(SUNOS4) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000838
839int
Denys Vlasenko12014262011-05-30 14:00:14 +0200840sys_sigvec(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000841{
842 struct sigvec sv;
843 long addr;
844
845 if (entering(tcp)) {
846 printsignal(tcp->u_arg[0]);
847 tprintf(", ");
848 addr = tcp->u_arg[1];
849 } else {
850 addr = tcp->u_arg[2];
851 }
852 if (addr == 0)
853 tprintf("NULL");
854 else if (!verbose(tcp))
855 tprintf("%#lx", addr);
856 else if (umove(tcp, addr, &sv) < 0)
857 tprintf("{...}");
858 else {
859 switch ((int) sv.sv_handler) {
860 case (int) SIG_ERR:
861 tprintf("{SIG_ERR}");
862 break;
863 case (int) SIG_DFL:
864 tprintf("{SIG_DFL}");
865 break;
866 case (int) SIG_IGN:
867 if (tcp->u_arg[0] == SIGTRAP) {
868 tcp->flags |= TCB_SIGTRAPPED;
869 kill(tcp->pid, SIGSTOP);
870 }
871 tprintf("{SIG_IGN}");
872 break;
873 case (int) SIG_HOLD:
874 if (tcp->u_arg[0] == SIGTRAP) {
875 tcp->flags |= TCB_SIGTRAPPED;
876 kill(tcp->pid, SIGSTOP);
877 }
878 tprintf("SIG_HOLD");
879 break;
880 default:
881 if (tcp->u_arg[0] == SIGTRAP) {
882 tcp->flags |= TCB_SIGTRAPPED;
883 kill(tcp->pid, SIGSTOP);
884 }
885 tprintf("{%#lx, ", (unsigned long) sv.sv_handler);
Nate Sammons4a121431999-04-06 01:19:39 +0000886 printsigmask(&sv.sv_mask, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000887 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +0000888 printflags(sigvec_flags, sv.sv_flags, "SV_???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000889 tprintf("}");
890 }
891 }
892 if (entering(tcp))
893 tprintf(", ");
894 return 0;
895}
896
897int
Denys Vlasenko12014262011-05-30 14:00:14 +0200898sys_sigpause(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000899{
900 if (entering(tcp)) { /* WTA: UD had a bug here: he forgot the braces */
Nate Sammons4a121431999-04-06 01:19:39 +0000901 sigset_t sigm;
902 long_to_sigset(tcp->u_arg[0], &sigm);
903 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000904 }
905 return 0;
906}
907
908int
Denys Vlasenko12014262011-05-30 14:00:14 +0200909sys_sigstack(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000910{
911 struct sigstack ss;
912 long addr;
913
914 if (entering(tcp))
915 addr = tcp->u_arg[0];
916 else
917 addr = tcp->u_arg[1];
918 if (addr == 0)
919 tprintf("NULL");
920 else if (umove(tcp, addr, &ss) < 0)
921 tprintf("%#lx", addr);
922 else {
923 tprintf("{ss_sp %#lx ", (unsigned long) ss.ss_sp);
924 tprintf("ss_onstack %s}", ss.ss_onstack ? "YES" : "NO");
925 }
926 if (entering(tcp))
927 tprintf(", ");
928 return 0;
929}
930
931int
Denys Vlasenko12014262011-05-30 14:00:14 +0200932sys_sigcleanup(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000933{
934 return 0;
935}
936
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000937#endif /* SUNOS4 || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000938
939#ifndef SVR4
940
941int
Denys Vlasenko12014262011-05-30 14:00:14 +0200942sys_sigsetmask(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000943{
944 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000945 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000946 long_to_sigset(tcp->u_arg[0], &sigm);
947 printsigmask(&sigm, 0);
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000948#ifndef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000949 if ((tcp->u_arg[0] & sigmask(SIGTRAP))) {
950 /* Mark attempt to block SIGTRAP */
951 tcp->flags |= TCB_SIGTRAPPED;
952 /* Send unblockable signal */
953 kill(tcp->pid, SIGSTOP);
954 }
Roland McGratha39c5a12002-12-17 05:10:37 +0000955#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000956 }
957 else if (!syserror(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000958 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000959 long_to_sigset(tcp->u_rval, &sigm);
960 tcp->auxstr = sprintsigmask("old mask ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000961
962 return RVAL_HEX | RVAL_STR;
963 }
964 return 0;
965}
966
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000967#if defined(SUNOS4) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000968int
Denys Vlasenko12014262011-05-30 14:00:14 +0200969sys_sigblock(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000970{
971 return sys_sigsetmask(tcp);
972}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000973#endif /* SUNOS4 || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000974
975#endif /* !SVR4 */
976
977#ifdef HAVE_SIGACTION
978
979#ifdef LINUX
980struct old_sigaction {
981 __sighandler_t __sa_handler;
982 unsigned long sa_mask;
983 unsigned long sa_flags;
984 void (*sa_restorer)(void);
985};
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000986#define SA_HANDLER __sa_handler
987#endif /* LINUX */
988
Roland McGratha39c5a12002-12-17 05:10:37 +0000989#ifndef SA_HANDLER
990#define SA_HANDLER sa_handler
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000991#endif
992
993int
Denys Vlasenko12014262011-05-30 14:00:14 +0200994sys_sigaction(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000995{
996 long addr;
Nate Sammons4a121431999-04-06 01:19:39 +0000997#ifdef LINUX
John Hughes1e4cb342001-03-06 09:25:46 +0000998 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000999 struct old_sigaction sa;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001000#else
1001 struct sigaction sa;
1002#endif
1003
1004
1005 if (entering(tcp)) {
1006 printsignal(tcp->u_arg[0]);
1007 tprintf(", ");
1008 addr = tcp->u_arg[1];
1009 } else
1010 addr = tcp->u_arg[2];
1011 if (addr == 0)
1012 tprintf("NULL");
1013 else if (!verbose(tcp))
1014 tprintf("%#lx", addr);
1015 else if (umove(tcp, addr, &sa) < 0)
1016 tprintf("{...}");
1017 else {
Carlos O'Donell4677c8a2009-09-09 18:13:19 +00001018 /* Architectures using function pointers, like
1019 * hppa, may need to manipulate the function pointer
1020 * to compute the result of a comparison. However,
1021 * the SA_HANDLER function pointer exists only in
1022 * the address space of the traced process, and can't
1023 * be manipulated by strace. In order to prevent the
1024 * compiler from generating code to manipulate
1025 * SA_HANDLER we cast the function pointers to long. */
1026 if ((long)sa.SA_HANDLER == (long)SIG_ERR)
Roland McGrath5f206812008-08-20 01:59:40 +00001027 tprintf("{SIG_ERR, ");
Carlos O'Donell4677c8a2009-09-09 18:13:19 +00001028 else if ((long)sa.SA_HANDLER == (long)SIG_DFL)
Roland McGrath5f206812008-08-20 01:59:40 +00001029 tprintf("{SIG_DFL, ");
Carlos O'Donell4677c8a2009-09-09 18:13:19 +00001030 else if ((long)sa.SA_HANDLER == (long)SIG_IGN) {
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001031#ifndef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001032 if (tcp->u_arg[0] == SIGTRAP) {
1033 tcp->flags |= TCB_SIGTRAPPED;
1034 kill(tcp->pid, SIGSTOP);
1035 }
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001036#endif /* !USE_PROCFS */
Roland McGrath5f206812008-08-20 01:59:40 +00001037 tprintf("{SIG_IGN, ");
1038 }
1039 else {
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001040#ifndef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001041 if (tcp->u_arg[0] == SIGTRAP) {
1042 tcp->flags |= TCB_SIGTRAPPED;
1043 kill(tcp->pid, SIGSTOP);
1044 }
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001045#endif /* !USE_PROCFS */
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001046 tprintf("{%#lx, ", (long) sa.SA_HANDLER);
Wichert Akkerman48214be1999-11-26 09:55:42 +00001047#ifndef LINUX
Denys Vlasenkob63256e2011-06-07 12:13:24 +02001048 printsigmask(&sa.sa_mask, 0);
Wichert Akkerman48214be1999-11-26 09:55:42 +00001049#else
Nate Sammons4a121431999-04-06 01:19:39 +00001050 long_to_sigset(sa.sa_mask, &sigset);
1051 printsigmask(&sigset, 0);
Wichert Akkerman48214be1999-11-26 09:55:42 +00001052#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001053 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00001054 printflags(sigact_flags, sa.sa_flags, "SA_???");
Roland McGrath2638cb42002-12-15 23:58:41 +00001055#ifdef SA_RESTORER
1056 if (sa.sa_flags & SA_RESTORER)
1057 tprintf(", %p", sa.sa_restorer);
1058#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001059 tprintf("}");
1060 }
1061 }
1062 if (entering(tcp))
1063 tprintf(", ");
1064#ifdef LINUX
1065 else
1066 tprintf(", %#lx", (unsigned long) sa.sa_restorer);
1067#endif
1068 return 0;
1069}
1070
1071int
Denys Vlasenko12014262011-05-30 14:00:14 +02001072sys_signal(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001073{
1074 if (entering(tcp)) {
1075 printsignal(tcp->u_arg[0]);
Wichert Akkerman16a03d22000-08-10 02:14:04 +00001076 tprintf(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001077 switch (tcp->u_arg[1]) {
Jan Kratochvil1f942712008-08-06 21:38:52 +00001078 case (long) SIG_ERR:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001079 tprintf("SIG_ERR");
1080 break;
Jan Kratochvil1f942712008-08-06 21:38:52 +00001081 case (long) SIG_DFL:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001082 tprintf("SIG_DFL");
1083 break;
Jan Kratochvil1f942712008-08-06 21:38:52 +00001084 case (long) SIG_IGN:
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001085#ifndef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001086 if (tcp->u_arg[0] == SIGTRAP) {
1087 tcp->flags |= TCB_SIGTRAPPED;
1088 kill(tcp->pid, SIGSTOP);
1089 }
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001090#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001091 tprintf("SIG_IGN");
1092 break;
1093 default:
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001094#ifndef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001095 if (tcp->u_arg[0] == SIGTRAP) {
1096 tcp->flags |= TCB_SIGTRAPPED;
1097 kill(tcp->pid, SIGSTOP);
1098 }
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001099#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001100 tprintf("%#lx", tcp->u_arg[1]);
1101 }
Wichert Akkerman16a03d22000-08-10 02:14:04 +00001102 return 0;
1103 }
Dmitry V. Levin21a75342008-09-03 01:22:18 +00001104 else if (!syserror(tcp)) {
Wichert Akkerman16a03d22000-08-10 02:14:04 +00001105 switch (tcp->u_rval) {
Jan Kratochvil1f942712008-08-06 21:38:52 +00001106 case (long) SIG_ERR:
Wichert Akkerman16a03d22000-08-10 02:14:04 +00001107 tcp->auxstr = "SIG_ERR"; break;
Jan Kratochvil1f942712008-08-06 21:38:52 +00001108 case (long) SIG_DFL:
Wichert Akkerman16a03d22000-08-10 02:14:04 +00001109 tcp->auxstr = "SIG_DFL"; break;
Jan Kratochvil1f942712008-08-06 21:38:52 +00001110 case (long) SIG_IGN:
Wichert Akkerman16a03d22000-08-10 02:14:04 +00001111 tcp->auxstr = "SIG_IGN"; break;
1112 default:
1113 tcp->auxstr = NULL;
1114 }
1115 return RVAL_HEX | RVAL_STR;
1116 }
Dmitry V. Levin21a75342008-09-03 01:22:18 +00001117 return 0;
Wichert Akkerman16a03d22000-08-10 02:14:04 +00001118}
1119
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001120#ifdef SVR4
Wichert Akkerman16a03d22000-08-10 02:14:04 +00001121int
Denys Vlasenko12014262011-05-30 14:00:14 +02001122sys_sighold(struct tcb *tcp)
Wichert Akkerman16a03d22000-08-10 02:14:04 +00001123{
1124 if (entering(tcp)) {
1125 printsignal(tcp->u_arg[0]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001126 }
1127 return 0;
1128}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001129#endif /* SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001130
1131#endif /* HAVE_SIGACTION */
1132
1133#ifdef LINUX
1134
1135int
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001136sys_sigreturn(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001137{
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001138#if defined(ARM)
Roland McGrath0f87c492003-06-03 23:29:04 +00001139 if (entering(tcp)) {
Denys Vlasenko56a52982011-06-09 01:36:29 +02001140 struct pt_regs regs;
1141 struct sigcontext_struct sc;
Roland McGrath0f87c492003-06-03 23:29:04 +00001142 tcp->u_arg[0] = 0;
Roland McGrath0f87c492003-06-03 23:29:04 +00001143 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)&regs) == -1)
1144 return 0;
Roland McGrath0f87c492003-06-03 23:29:04 +00001145 if (umove(tcp, regs.ARM_sp, &sc) < 0)
1146 return 0;
Roland McGrath0f87c492003-06-03 23:29:04 +00001147 tcp->u_arg[0] = 1;
1148 tcp->u_arg[1] = sc.oldmask;
1149 } else {
1150 sigset_t sigm;
Roland McGrath0f87c492003-06-03 23:29:04 +00001151 tcp->u_rval = tcp->u_error = 0;
1152 if (tcp->u_arg[0] == 0)
1153 return 0;
Denys Vlasenko56a52982011-06-09 01:36:29 +02001154 long_to_sigset(tcp->u_arg[1], &sigm);
Roland McGrath0f87c492003-06-03 23:29:04 +00001155 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1156 return RVAL_NONE | RVAL_STR;
1157 }
1158 return 0;
1159#elif defined(S390) || defined(S390X)
Roland McGrath0f87c492003-06-03 23:29:04 +00001160 if (entering(tcp)) {
Denys Vlasenko56a52982011-06-09 01:36:29 +02001161 long usp;
1162 struct sigcontext_struct sc;
Roland McGrath0f87c492003-06-03 23:29:04 +00001163 tcp->u_arg[0] = 0;
Denys Vlasenkob63256e2011-06-07 12:13:24 +02001164 if (upeek(tcp, PT_GPR15, &usp) < 0)
Roland McGrath0f87c492003-06-03 23:29:04 +00001165 return 0;
1166 if (umove(tcp, usp+__SIGNAL_FRAMESIZE, &sc) < 0)
1167 return 0;
1168 tcp->u_arg[0] = 1;
Denys Vlasenkod9560c12011-08-19 17:41:28 +02001169 memcpy(&tcp->u_arg[1], &sc.oldmask[0], NSIG / 8);
Roland McGrath0f87c492003-06-03 23:29:04 +00001170 } else {
1171 tcp->u_rval = tcp->u_error = 0;
1172 if (tcp->u_arg[0] == 0)
1173 return 0;
Denys Vlasenkob63256e2011-06-07 12:13:24 +02001174 tcp->auxstr = sprintsigmask("mask now ", (sigset_t *)&tcp->u_arg[1], 0);
Roland McGrath0f87c492003-06-03 23:29:04 +00001175 return RVAL_NONE | RVAL_STR;
1176 }
1177 return 0;
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001178#elif defined(I386)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001179 if (entering(tcp)) {
Denys Vlasenko56a52982011-06-09 01:36:29 +02001180 long esp;
1181 struct sigcontext_struct sc;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001182 tcp->u_arg[0] = 0;
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00001183 if (upeek(tcp, 4*UESP, &esp) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001184 return 0;
1185 if (umove(tcp, esp, &sc) < 0)
1186 return 0;
1187 tcp->u_arg[0] = 1;
1188 tcp->u_arg[1] = sc.oldmask;
1189 }
1190 else {
1191 sigset_t sigm;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001192 tcp->u_rval = tcp->u_error = 0;
1193 if (tcp->u_arg[0] == 0)
1194 return 0;
Denys Vlasenko56a52982011-06-09 01:36:29 +02001195 long_to_sigset(tcp->u_arg[1], &sigm);
Nate Sammons4a121431999-04-06 01:19:39 +00001196 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001197 return RVAL_NONE | RVAL_STR;
1198 }
1199 return 0;
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001200#elif defined(IA64)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001201 if (entering(tcp)) {
Denys Vlasenko56a52982011-06-09 01:36:29 +02001202 struct sigcontext sc;
1203 long sp;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +00001204 /* offset of sigcontext in the kernel's sigframe structure: */
1205# define SIGFRAME_SC_OFFSET 0x90
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001206 tcp->u_arg[0] = 0;
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00001207 if (upeek(tcp, PT_R12, &sp) < 0)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001208 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +00001209 if (umove(tcp, sp + 16 + SIGFRAME_SC_OFFSET, &sc) < 0)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001210 return 0;
1211 tcp->u_arg[0] = 1;
Denys Vlasenkod9560c12011-08-19 17:41:28 +02001212 memcpy(tcp->u_arg + 1, &sc.sc_mask, NSIG / 8);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001213 }
1214 else {
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +00001215 sigset_t sigm;
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001216 tcp->u_rval = tcp->u_error = 0;
1217 if (tcp->u_arg[0] == 0)
1218 return 0;
Denys Vlasenkod9560c12011-08-19 17:41:28 +02001219 sigemptyset(&sigm);
1220 memcpy(&sigm, tcp->u_arg + 1, NSIG / 8);
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +00001221 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001222 return RVAL_NONE | RVAL_STR;
1223 }
1224 return 0;
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001225#elif defined(POWERPC)
Roland McGrath0f87c492003-06-03 23:29:04 +00001226 if (entering(tcp)) {
Denys Vlasenko56a52982011-06-09 01:36:29 +02001227 long esp;
1228 struct sigcontext_struct sc;
Roland McGrath0f87c492003-06-03 23:29:04 +00001229 tcp->u_arg[0] = 0;
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00001230 if (upeek(tcp, sizeof(unsigned long)*PT_R1, &esp) < 0)
Roland McGrath0f87c492003-06-03 23:29:04 +00001231 return 0;
Andreas Schwabedb39342010-02-23 00:18:51 +01001232 /* Skip dummy stack frame. */
Andreas Schwabd69fa492010-07-12 21:39:57 +02001233#ifdef POWERPC64
1234 if (current_personality == 0)
1235 esp += 128;
1236 else
1237 esp += 64;
Andreas Schwabedb39342010-02-23 00:18:51 +01001238#else
1239 esp += 64;
1240#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00001241 if (umove(tcp, esp, &sc) < 0)
1242 return 0;
1243 tcp->u_arg[0] = 1;
1244 tcp->u_arg[1] = sc.oldmask;
1245 }
1246 else {
1247 sigset_t sigm;
Roland McGrath0f87c492003-06-03 23:29:04 +00001248 tcp->u_rval = tcp->u_error = 0;
1249 if (tcp->u_arg[0] == 0)
1250 return 0;
Denys Vlasenko56a52982011-06-09 01:36:29 +02001251 long_to_sigset(tcp->u_arg[1], &sigm);
Roland McGrath0f87c492003-06-03 23:29:04 +00001252 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1253 return RVAL_NONE | RVAL_STR;
1254 }
1255 return 0;
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001256#elif defined(M68K)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001257 if (entering(tcp)) {
Denys Vlasenko56a52982011-06-09 01:36:29 +02001258 long usp;
1259 struct sigcontext sc;
Roland McGrath0f87c492003-06-03 23:29:04 +00001260 tcp->u_arg[0] = 0;
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00001261 if (upeek(tcp, 4*PT_USP, &usp) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001262 return 0;
Roland McGrath0f87c492003-06-03 23:29:04 +00001263 if (umove(tcp, usp, &sc) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001264 return 0;
Roland McGrath0f87c492003-06-03 23:29:04 +00001265 tcp->u_arg[0] = 1;
1266 tcp->u_arg[1] = sc.sc_mask;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001267 }
1268 else {
Roland McGrath0f87c492003-06-03 23:29:04 +00001269 sigset_t sigm;
Roland McGrath0f87c492003-06-03 23:29:04 +00001270 tcp->u_rval = tcp->u_error = 0;
1271 if (tcp->u_arg[0] == 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001272 return 0;
Denys Vlasenko56a52982011-06-09 01:36:29 +02001273 long_to_sigset(tcp->u_arg[1], &sigm);
Roland McGrath0f87c492003-06-03 23:29:04 +00001274 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1275 return RVAL_NONE | RVAL_STR;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001276 }
1277 return 0;
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001278#elif defined(ALPHA)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001279 if (entering(tcp)) {
Denys Vlasenko56a52982011-06-09 01:36:29 +02001280 long fp;
1281 struct sigcontext_struct sc;
Roland McGrath0f87c492003-06-03 23:29:04 +00001282 tcp->u_arg[0] = 0;
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00001283 if (upeek(tcp, REG_FP, &fp) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001284 return 0;
Roland McGrath0f87c492003-06-03 23:29:04 +00001285 if (umove(tcp, fp, &sc) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001286 return 0;
Roland McGrath0f87c492003-06-03 23:29:04 +00001287 tcp->u_arg[0] = 1;
1288 tcp->u_arg[1] = sc.sc_mask;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001289 }
1290 else {
Roland McGrath0f87c492003-06-03 23:29:04 +00001291 sigset_t sigm;
Roland McGrath0f87c492003-06-03 23:29:04 +00001292 tcp->u_rval = tcp->u_error = 0;
1293 if (tcp->u_arg[0] == 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001294 return 0;
Denys Vlasenko56a52982011-06-09 01:36:29 +02001295 long_to_sigset(tcp->u_arg[1], &sigm);
Roland McGrath0f87c492003-06-03 23:29:04 +00001296 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1297 return RVAL_NONE | RVAL_STR;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001298 }
1299 return 0;
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001300#elif defined (SPARC) || defined (SPARC64)
Denys Vlasenkob63256e2011-06-07 12:13:24 +02001301 if (entering(tcp)) {
Denys Vlasenko56a52982011-06-09 01:36:29 +02001302 long i1;
1303 struct pt_regs regs;
1304 m_siginfo_t si;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001305 tcp->u_arg[0] = 0;
Denys Vlasenko56a52982011-06-09 01:36:29 +02001306 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1307 perror("sigreturn: PTRACE_GETREGS");
1308 return 0;
1309 }
Mike Frysinger8566c502009-10-12 11:05:14 -04001310 i1 = regs.u_regs[U_REG_O1];
Denys Vlasenkob63256e2011-06-07 12:13:24 +02001311 if (umove(tcp, i1, &si) < 0) {
Denys Vlasenko56a52982011-06-09 01:36:29 +02001312 perror("sigreturn: umove");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001313 return 0;
1314 }
1315 tcp->u_arg[0] = 1;
1316 tcp->u_arg[1] = si.si_mask;
1317 } else {
1318 sigset_t sigm;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001319 tcp->u_rval = tcp->u_error = 0;
Denys Vlasenkob63256e2011-06-07 12:13:24 +02001320 if (tcp->u_arg[0] == 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001321 return 0;
Denys Vlasenko56a52982011-06-09 01:36:29 +02001322 long_to_sigset(tcp->u_arg[1], &sigm);
Nate Sammons4a121431999-04-06 01:19:39 +00001323 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001324 return RVAL_NONE | RVAL_STR;
1325 }
1326 return 0;
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001327#elif defined (LINUX_MIPSN32) || defined (LINUX_MIPSN64)
Roland McGrath542c2c62008-05-20 01:11:56 +00001328 /* This decodes rt_sigreturn. The 64-bit ABIs do not have
1329 sigreturn. */
Denys Vlasenkob63256e2011-06-07 12:13:24 +02001330 if (entering(tcp)) {
Denys Vlasenko56a52982011-06-09 01:36:29 +02001331 long sp;
1332 struct ucontext uc;
Denys Vlasenko5ae2b7c2009-02-27 20:32:52 +00001333 tcp->u_arg[0] = 0;
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00001334 if (upeek(tcp, REG_SP, &sp) < 0)
Denys Vlasenko5ae2b7c2009-02-27 20:32:52 +00001335 return 0;
Roland McGrath542c2c62008-05-20 01:11:56 +00001336 /* There are six words followed by a 128-byte siginfo. */
1337 sp = sp + 6 * 4 + 128;
1338 if (umove(tcp, sp, &uc) < 0)
Denys Vlasenko5ae2b7c2009-02-27 20:32:52 +00001339 return 0;
Roland McGrath542c2c62008-05-20 01:11:56 +00001340 tcp->u_arg[0] = 1;
1341 tcp->u_arg[1] = *(long *) &uc.uc_sigmask;
1342 } else {
1343 sigset_t sigm;
Denys Vlasenko5ae2b7c2009-02-27 20:32:52 +00001344 tcp->u_rval = tcp->u_error = 0;
Denys Vlasenkob63256e2011-06-07 12:13:24 +02001345 if (tcp->u_arg[0] == 0)
Denys Vlasenko5ae2b7c2009-02-27 20:32:52 +00001346 return 0;
Denys Vlasenko56a52982011-06-09 01:36:29 +02001347 long_to_sigset(tcp->u_arg[1], &sigm);
Roland McGrath542c2c62008-05-20 01:11:56 +00001348 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1349 return RVAL_NONE | RVAL_STR;
1350 }
1351 return 0;
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001352#elif defined(MIPS)
Denys Vlasenkob63256e2011-06-07 12:13:24 +02001353 if (entering(tcp)) {
Denys Vlasenko56a52982011-06-09 01:36:29 +02001354 long sp;
1355 struct pt_regs regs;
1356 m_siginfo_t si;
Denys Vlasenko5ae2b7c2009-02-27 20:32:52 +00001357 tcp->u_arg[0] = 0;
Denys Vlasenko56a52982011-06-09 01:36:29 +02001358 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1359 perror("sigreturn: PTRACE_GETREGS");
1360 return 0;
1361 }
Roland McGrath576b7842007-11-04 00:00:00 +00001362 sp = regs.regs[29];
1363 if (umove(tcp, sp, &si) < 0)
Denys Vlasenkofacd45b2011-06-09 01:22:10 +02001364 return 0;
Wichert Akkermanf90da011999-10-31 21:15:38 +00001365 tcp->u_arg[0] = 1;
Roland McGrath576b7842007-11-04 00:00:00 +00001366 tcp->u_arg[1] = si.si_mask;
Wichert Akkermanf90da011999-10-31 21:15:38 +00001367 } else {
Roland McGrath576b7842007-11-04 00:00:00 +00001368 sigset_t sigm;
Denys Vlasenko5ae2b7c2009-02-27 20:32:52 +00001369 tcp->u_rval = tcp->u_error = 0;
Denys Vlasenkob63256e2011-06-07 12:13:24 +02001370 if (tcp->u_arg[0] == 0)
Roland McGrath576b7842007-11-04 00:00:00 +00001371 return 0;
Denys Vlasenko56a52982011-06-09 01:36:29 +02001372 long_to_sigset(tcp->u_arg[1], &sigm);
Roland McGrath576b7842007-11-04 00:00:00 +00001373 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkermanf90da011999-10-31 21:15:38 +00001374 return RVAL_NONE | RVAL_STR;
1375 }
1376 return 0;
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001377#elif defined(CRISV10) || defined(CRISV32)
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001378 if (entering(tcp)) {
Denys Vlasenko56a52982011-06-09 01:36:29 +02001379 struct sigcontext sc;
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001380 long regs[PT_MAX+1];
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001381 tcp->u_arg[0] = 0;
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001382 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long)regs) < 0) {
1383 perror("sigreturn: PTRACE_GETREGS");
1384 return 0;
1385 }
1386 if (umove(tcp, regs[PT_USP], &sc) < 0)
1387 return 0;
1388 tcp->u_arg[0] = 1;
1389 tcp->u_arg[1] = sc.oldmask;
1390 } else {
1391 sigset_t sigm;
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001392 tcp->u_rval = tcp->u_error = 0;
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001393 if (tcp->u_arg[0] == 0)
1394 return 0;
Denys Vlasenko56a52982011-06-09 01:36:29 +02001395 long_to_sigset(tcp->u_arg[1], &sigm);
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001396 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1397 return RVAL_NONE | RVAL_STR;
1398 }
1399 return 0;
Chris Metcalfc8c66982009-12-28 10:00:15 -05001400#elif defined(TILE)
Chris Metcalfc8c66982009-12-28 10:00:15 -05001401 if (entering(tcp)) {
Denys Vlasenko56a52982011-06-09 01:36:29 +02001402 struct ucontext uc;
1403 long sp;
1404
1405 /* offset of ucontext in the kernel's sigframe structure */
1406# define SIGFRAME_UC_OFFSET C_ABI_SAVE_AREA_SIZE + sizeof(struct siginfo)
Chris Metcalfc8c66982009-12-28 10:00:15 -05001407 tcp->u_arg[0] = 0;
1408 if (upeek(tcp, PTREGS_OFFSET_SP, &sp) < 0)
1409 return 0;
1410 if (umove(tcp, sp + SIGFRAME_UC_OFFSET, &uc) < 0)
1411 return 0;
1412 tcp->u_arg[0] = 1;
Denys Vlasenkod9560c12011-08-19 17:41:28 +02001413 memcpy(tcp->u_arg + 1, &uc.uc_sigmask, NSIG / 8);
Chris Metcalfc8c66982009-12-28 10:00:15 -05001414 }
1415 else {
1416 sigset_t sigm;
Chris Metcalfc8c66982009-12-28 10:00:15 -05001417 tcp->u_rval = tcp->u_error = 0;
1418 if (tcp->u_arg[0] == 0)
1419 return 0;
Denys Vlasenkod9560c12011-08-19 17:41:28 +02001420 sigemptyset(&sigm);
1421 memcpy(&sigm, tcp->u_arg + 1, NSIG / 8);
Chris Metcalfc8c66982009-12-28 10:00:15 -05001422 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1423 return RVAL_NONE | RVAL_STR;
1424 }
1425 return 0;
Edgar E. Iglesias939caba2010-07-06 14:21:07 +02001426#elif defined(MICROBLAZE)
Edgar E. Iglesias939caba2010-07-06 14:21:07 +02001427 /* TODO: Verify that this is correct... */
1428 if (entering(tcp)) {
Denys Vlasenko56a52982011-06-09 01:36:29 +02001429 struct sigcontext sc;
Edgar E. Iglesias939caba2010-07-06 14:21:07 +02001430 long sp;
Edgar E. Iglesias939caba2010-07-06 14:21:07 +02001431 tcp->u_arg[0] = 0;
Edgar E. Iglesias939caba2010-07-06 14:21:07 +02001432 /* Read r1, the stack pointer. */
1433 if (upeek(tcp, 1 * 4, &sp) < 0)
1434 return 0;
1435 if (umove(tcp, sp, &sc) < 0)
1436 return 0;
1437 tcp->u_arg[0] = 1;
1438 tcp->u_arg[1] = sc.oldmask;
1439 } else {
1440 sigset_t sigm;
Edgar E. Iglesias939caba2010-07-06 14:21:07 +02001441 tcp->u_rval = tcp->u_error = 0;
1442 if (tcp->u_arg[0] == 0)
1443 return 0;
Denys Vlasenko56a52982011-06-09 01:36:29 +02001444 long_to_sigset(tcp->u_arg[1], &sigm);
Edgar E. Iglesias939caba2010-07-06 14:21:07 +02001445 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
1446 return RVAL_NONE | RVAL_STR;
1447 }
1448 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +00001449#else
Michal Ludvig0e035502002-09-23 15:41:01 +00001450#warning No sys_sigreturn() for this architecture
1451#warning (no problem, just a reminder :-)
Wichert Akkermanc1652e22001-03-27 12:17:16 +00001452 return 0;
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001453#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001454}
1455
1456int
Denys Vlasenko12014262011-05-30 14:00:14 +02001457sys_siggetmask(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001458{
1459 if (exiting(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001460 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +00001461 long_to_sigset(tcp->u_rval, &sigm);
1462 tcp->auxstr = sprintsigmask("mask ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001463 }
1464 return RVAL_HEX | RVAL_STR;
1465}
1466
1467int
Dmitry V. Levine5e60852009-12-31 22:50:49 +00001468sys_sigsuspend(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001469{
1470 if (entering(tcp)) {
1471 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +00001472 long_to_sigset(tcp->u_arg[2], &sigm);
Nate Sammons4a121431999-04-06 01:19:39 +00001473 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001474 }
1475 return 0;
1476}
1477
1478#endif /* LINUX */
1479
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001480#if defined(SVR4) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001481
1482int
Denys Vlasenko12014262011-05-30 14:00:14 +02001483sys_sigsuspend(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001484{
1485 sigset_t sigset;
1486
1487 if (entering(tcp)) {
1488 if (umove(tcp, tcp->u_arg[0], &sigset) < 0)
1489 tprintf("[?]");
1490 else
Wichert Akkerman46956571999-11-26 10:12:59 +00001491 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001492 }
1493 return 0;
1494}
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001495#ifndef FREEBSD
Roland McGrathd9f816f2004-09-04 03:39:20 +00001496static const struct xlat ucontext_flags[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001497 { UC_SIGMASK, "UC_SIGMASK" },
1498 { UC_STACK, "UC_STACK" },
1499 { UC_CPU, "UC_CPU" },
1500#ifdef UC_FPU
1501 { UC_FPU, "UC_FPU" },
1502#endif
1503#ifdef UC_INTR
1504 { UC_INTR, "UC_INTR" },
1505#endif
1506 { 0, NULL },
1507};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001508#endif /* !FREEBSD */
1509#endif /* SVR4 || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001510
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001511#if defined SVR4 || defined LINUX || defined FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001512#if defined LINUX && !defined SS_ONSTACK
1513#define SS_ONSTACK 1
1514#define SS_DISABLE 2
1515#if __GLIBC_MINOR__ == 0
1516typedef struct
1517{
1518 __ptr_t ss_sp;
1519 int ss_flags;
1520 size_t ss_size;
1521} stack_t;
1522#endif
1523#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001524#ifdef FREEBSD
1525#define stack_t struct sigaltstack
1526#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001527
Roland McGrathd9f816f2004-09-04 03:39:20 +00001528static const struct xlat sigaltstack_flags[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001529 { SS_ONSTACK, "SS_ONSTACK" },
1530 { SS_DISABLE, "SS_DISABLE" },
1531 { 0, NULL },
1532};
1533#endif
1534
1535#ifdef SVR4
1536static void
Denys Vlasenko12014262011-05-30 14:00:14 +02001537printcontext(struct tcb *tcp, ucontext_t *ucp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001538{
1539 tprintf("{");
1540 if (!abbrev(tcp)) {
1541 tprintf("uc_flags=");
Roland McGrathb2dee132005-06-01 19:02:36 +00001542 printflags(ucontext_flags, ucp->uc_flags, "UC_???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001543 tprintf(", uc_link=%#lx, ", (unsigned long) ucp->uc_link);
1544 }
1545 tprintf("uc_sigmask=");
John Hughes70c5e7a2001-05-15 15:09:14 +00001546 printsigmask(&ucp->uc_sigmask, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001547 if (!abbrev(tcp)) {
1548 tprintf(", uc_stack={ss_sp=%#lx, ss_size=%d, ss_flags=",
1549 (unsigned long) ucp->uc_stack.ss_sp,
1550 ucp->uc_stack.ss_size);
Roland McGrathb2dee132005-06-01 19:02:36 +00001551 printflags(sigaltstack_flags, ucp->uc_stack.ss_flags, "SS_???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001552 tprintf("}");
1553 }
1554 tprintf(", ...}");
1555}
1556
1557int
Denys Vlasenko12014262011-05-30 14:00:14 +02001558sys_getcontext(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001559{
1560 ucontext_t uc;
1561
Wichert Akkerman16a03d22000-08-10 02:14:04 +00001562 if (exiting(tcp)) {
1563 if (tcp->u_error)
1564 tprintf("%#lx", tcp->u_arg[0]);
1565 else if (!tcp->u_arg[0])
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001566 tprintf("NULL");
1567 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
1568 tprintf("{...}");
1569 else
1570 printcontext(tcp, &uc);
1571 }
1572 return 0;
1573}
1574
1575int
Denys Vlasenko12014262011-05-30 14:00:14 +02001576sys_setcontext(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001577{
1578 ucontext_t uc;
1579
1580 if (entering(tcp)) {
1581 if (!tcp->u_arg[0])
1582 tprintf("NULL");
1583 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
1584 tprintf("{...}");
1585 else
1586 printcontext(tcp, &uc);
1587 }
1588 else {
1589 tcp->u_rval = tcp->u_error = 0;
1590 if (tcp->u_arg[0] == 0)
1591 return 0;
1592 return RVAL_NONE;
1593 }
1594 return 0;
1595}
1596
1597#endif /* SVR4 */
1598
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001599#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001600
1601static int
Denys Vlasenko12014262011-05-30 14:00:14 +02001602print_stack_t(struct tcb *tcp, unsigned long addr)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001603{
1604 stack_t ss;
1605 if (umove(tcp, addr, &ss) < 0)
1606 return -1;
1607 tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp);
Roland McGrathb2dee132005-06-01 19:02:36 +00001608 printflags(sigaltstack_flags, ss.ss_flags, "SS_???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001609 tprintf(", ss_size=%lu}", (unsigned long) ss.ss_size);
1610 return 0;
1611}
1612
1613int
Denys Vlasenko12014262011-05-30 14:00:14 +02001614sys_sigaltstack(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001615{
1616 if (entering(tcp)) {
1617 if (tcp->u_arg[0] == 0)
1618 tprintf("NULL");
1619 else if (print_stack_t(tcp, tcp->u_arg[0]) < 0)
1620 return -1;
1621 }
1622 else {
1623 tprintf(", ");
1624 if (tcp->u_arg[1] == 0)
1625 tprintf("NULL");
1626 else if (print_stack_t(tcp, tcp->u_arg[1]) < 0)
1627 return -1;
1628 }
1629 return 0;
1630}
1631#endif
1632
1633#ifdef HAVE_SIGACTION
1634
1635int
Denys Vlasenko12014262011-05-30 14:00:14 +02001636sys_sigprocmask(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001637{
1638#ifdef ALPHA
1639 if (entering(tcp)) {
1640 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1641 tprintf(", ");
Nate Sammons4a121431999-04-06 01:19:39 +00001642 printsigmask(tcp->u_arg[1], 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001643 }
1644 else if (!syserror(tcp)) {
Nate Sammons4a121431999-04-06 01:19:39 +00001645 tcp->auxstr = sprintsigmask("old mask ", tcp->u_rval, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001646 return RVAL_HEX | RVAL_STR;
1647 }
1648#else /* !ALPHA */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001649 if (entering(tcp)) {
1650#ifdef SVR4
1651 if (tcp->u_arg[0] == 0)
1652 tprintf("0");
1653 else
1654#endif /* SVR4 */
1655 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1656 tprintf(", ");
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001657 print_sigset(tcp, tcp->u_arg[1], 0);
1658 tprintf(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001659 }
1660 else {
1661 if (!tcp->u_arg[2])
1662 tprintf("NULL");
1663 else if (syserror(tcp))
1664 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001665 else
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001666 print_sigset(tcp, tcp->u_arg[2], 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001667 }
1668#endif /* !ALPHA */
1669 return 0;
1670}
1671
1672#endif /* HAVE_SIGACTION */
1673
1674int
Denys Vlasenko12014262011-05-30 14:00:14 +02001675sys_kill(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001676{
1677 if (entering(tcp)) {
Roland McGrath4d7ed022008-05-20 01:43:09 +00001678 /*
1679 * Sign-extend a 32-bit value when that's what it is.
1680 */
1681 long pid = tcp->u_arg[0];
1682 if (personality_wordsize[current_personality] < sizeof pid)
1683 pid = (long) (int) pid;
1684 tprintf("%ld, %s", pid, signame(tcp->u_arg[1]));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001685 }
1686 return 0;
1687}
1688
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001689#if defined(FREEBSD) || defined(SUNOS4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001690int
Denys Vlasenko12014262011-05-30 14:00:14 +02001691sys_killpg(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001692{
1693 return sys_kill(tcp);
1694}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001695#endif /* FREEBSD || SUNOS4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001696
Roland McGrath8ffc3522003-07-09 09:47:49 +00001697#ifdef LINUX
1698int
Denys Vlasenko12014262011-05-30 14:00:14 +02001699sys_tgkill(struct tcb *tcp)
Roland McGrath8ffc3522003-07-09 09:47:49 +00001700{
1701 if (entering(tcp)) {
1702 tprintf("%ld, %ld, %s",
1703 tcp->u_arg[0], tcp->u_arg[1], signame(tcp->u_arg[2]));
1704 }
1705 return 0;
1706}
1707#endif
1708
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001709int
Denys Vlasenko12014262011-05-30 14:00:14 +02001710sys_sigpending(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001711{
1712 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001713
1714 if (exiting(tcp)) {
1715 if (syserror(tcp))
1716 tprintf("%#lx", tcp->u_arg[0]);
Nate Sammons4a121431999-04-06 01:19:39 +00001717 else if (copy_sigset(tcp, tcp->u_arg[0], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001718 tprintf("[?]");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001719 else
Wichert Akkerman46956571999-11-26 10:12:59 +00001720 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001721 }
1722 return 0;
1723}
1724
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001725#ifdef SVR4
Denys Vlasenko12014262011-05-30 14:00:14 +02001726int sys_sigwait(struct tcb *tcp)
John Hughes42162082001-10-18 14:48:26 +00001727{
1728 sigset_t sigset;
1729
1730 if (entering(tcp)) {
1731 if (copy_sigset(tcp, tcp->u_arg[0], &sigset) < 0)
1732 tprintf("[?]");
1733 else
1734 printsigmask(&sigset, 0);
1735 }
1736 else {
1737 if (!syserror(tcp)) {
1738 tcp->auxstr = signalent[tcp->u_rval];
1739 return RVAL_DECIMAL | RVAL_STR;
1740 }
1741 }
1742 return 0;
1743}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001744#endif /* SVR4 */
John Hughes42162082001-10-18 14:48:26 +00001745
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001746#ifdef LINUX
1747
Denys Vlasenko12014262011-05-30 14:00:14 +02001748int
1749sys_rt_sigprocmask(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001750{
1751 sigset_t sigset;
1752
Nate Sammons4a121431999-04-06 01:19:39 +00001753 /* Note: arg[3] is the length of the sigset. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001754 if (entering(tcp)) {
1755 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1756 tprintf(", ");
1757 if (!tcp->u_arg[1])
1758 tprintf("NULL, ");
Nate Sammons4a121431999-04-06 01:19:39 +00001759 else if (copy_sigset_len(tcp, tcp->u_arg[1], &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001760 tprintf("%#lx, ", tcp->u_arg[1]);
1761 else {
Nate Sammons4a121431999-04-06 01:19:39 +00001762 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001763 tprintf(", ");
1764 }
1765 }
1766 else {
1767 if (!tcp->u_arg[2])
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001768 tprintf("NULL");
1769 else if (syserror(tcp))
1770 tprintf("%#lx", tcp->u_arg[2]);
Nate Sammons4a121431999-04-06 01:19:39 +00001771 else if (copy_sigset_len(tcp, tcp->u_arg[2], &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001772 tprintf("[?]");
1773 else
Nate Sammons4a121431999-04-06 01:19:39 +00001774 printsigmask(&sigset, 1);
Nate Sammonsdab325a1999-03-29 23:33:35 +00001775 tprintf(", %lu", tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001776 }
1777 return 0;
1778}
1779
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001780
1781/* Structure describing the action to be taken when a signal arrives. */
1782struct new_sigaction
1783{
Denys Vlasenko7a862d72009-04-15 13:22:59 +00001784 __sighandler_t __sa_handler;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001785 unsigned long sa_flags;
1786 void (*sa_restorer) (void);
Denys Vlasenko7a862d72009-04-15 13:22:59 +00001787 /* Kernel treats sa_mask as an array of longs. */
1788 unsigned long sa_mask[NSIG / sizeof(long) ? NSIG / sizeof(long) : 1];
1789};
1790/* Same for i386-on-x86_64 and similar cases */
1791struct new_sigaction32
1792{
1793 uint32_t __sa_handler;
1794 uint32_t sa_flags;
1795 uint32_t sa_restorer;
1796 uint32_t sa_mask[2 * (NSIG / sizeof(long) ? NSIG / sizeof(long) : 1)];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001797};
1798
1799
Roland McGrath5f206812008-08-20 01:59:40 +00001800int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001801sys_rt_sigaction(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001802{
1803 struct new_sigaction sa;
1804 sigset_t sigset;
1805 long addr;
Denys Vlasenko7a862d72009-04-15 13:22:59 +00001806 int r;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001807
1808 if (entering(tcp)) {
1809 printsignal(tcp->u_arg[0]);
1810 tprintf(", ");
1811 addr = tcp->u_arg[1];
1812 } else
1813 addr = tcp->u_arg[2];
Denys Vlasenko7a862d72009-04-15 13:22:59 +00001814
1815 if (addr == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001816 tprintf("NULL");
Denys Vlasenko7a862d72009-04-15 13:22:59 +00001817 goto after_sa;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001818 }
Denys Vlasenko7a862d72009-04-15 13:22:59 +00001819 if (!verbose(tcp)) {
1820 tprintf("%#lx", addr);
1821 goto after_sa;
1822 }
1823#if SUPPORTED_PERSONALITIES > 1
1824 if (personality_wordsize[current_personality] != sizeof(sa.sa_flags)
1825 && personality_wordsize[current_personality] == 4
1826 ) {
1827 struct new_sigaction32 sa32;
1828 r = umove(tcp, addr, &sa32);
1829 if (r >= 0) {
1830 memset(&sa, 0, sizeof(sa));
1831 sa.__sa_handler = (void*)(unsigned long)sa32.__sa_handler;
1832 sa.sa_flags = sa32.sa_flags;
1833 sa.sa_restorer = (void*)(unsigned long)sa32.sa_restorer;
1834 /* Kernel treats sa_mask as an array of longs.
1835 * For 32-bit process, "long" is uint32_t, thus, for example,
1836 * 32th bit in sa_mask will end up as bit 0 in sa_mask[1].
1837 * But for (64-bit) kernel, 32th bit in sa_mask is
1838 * 32th bit in 0th (64-bit) long!
1839 * For little-endian, it's the same.
1840 * For big-endian, we swap 32-bit words.
1841 */
1842 sa.sa_mask[0] = sa32.sa_mask[0] + ((long)(sa32.sa_mask[1]) << 32);
1843 }
1844 } else
1845#endif
1846 {
1847 r = umove(tcp, addr, &sa);
1848 }
1849 if (r < 0) {
1850 tprintf("{...}");
1851 goto after_sa;
1852 }
Carlos O'Donell4677c8a2009-09-09 18:13:19 +00001853 /* Architectures using function pointers, like
1854 * hppa, may need to manipulate the function pointer
1855 * to compute the result of a comparison. However,
1856 * the SA_HANDLER function pointer exists only in
1857 * the address space of the traced process, and can't
1858 * be manipulated by strace. In order to prevent the
1859 * compiler from generating code to manipulate
1860 * SA_HANDLER we cast the function pointers to long. */
1861 if ((long)sa.__sa_handler == (long)SIG_ERR)
Denys Vlasenko7a862d72009-04-15 13:22:59 +00001862 tprintf("{SIG_ERR, ");
Carlos O'Donell4677c8a2009-09-09 18:13:19 +00001863 else if ((long)sa.__sa_handler == (long)SIG_DFL)
Denys Vlasenko7a862d72009-04-15 13:22:59 +00001864 tprintf("{SIG_DFL, ");
Carlos O'Donell4677c8a2009-09-09 18:13:19 +00001865 else if ((long)sa.__sa_handler == (long)SIG_IGN)
Denys Vlasenko7a862d72009-04-15 13:22:59 +00001866 tprintf("{SIG_IGN, ");
1867 else
1868 tprintf("{%#lx, ", (long) sa.__sa_handler);
1869 /* Questionable code below.
1870 * Kernel won't handle sys_rt_sigaction
1871 * with wrong sigset size (just returns EINVAL)
1872 * therefore tcp->u_arg[3(4)] _must_ be NSIG / 8 here,
1873 * and we always use smaller memcpy. */
1874 sigemptyset(&sigset);
1875#ifdef LINUXSPARC
1876 if (tcp->u_arg[4] <= sizeof(sigset))
1877 memcpy(&sigset, &sa.sa_mask, tcp->u_arg[4]);
1878#else
1879 if (tcp->u_arg[3] <= sizeof(sigset))
1880 memcpy(&sigset, &sa.sa_mask, tcp->u_arg[3]);
1881#endif
1882 else
1883 memcpy(&sigset, &sa.sa_mask, sizeof(sigset));
1884 printsigmask(&sigset, 1);
1885 tprintf(", ");
1886 printflags(sigact_flags, sa.sa_flags, "SA_???");
1887#ifdef SA_RESTORER
1888 if (sa.sa_flags & SA_RESTORER)
1889 tprintf(", %p", sa.sa_restorer);
1890#endif
1891 tprintf("}");
1892
1893 after_sa:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001894 if (entering(tcp))
1895 tprintf(", ");
1896 else
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001897#ifdef LINUXSPARC
1898 tprintf(", %#lx, %lu", tcp->u_arg[3], tcp->u_arg[4]);
1899#elif defined(ALPHA)
1900 tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]);
1901#else
Denys Vlasenko7a862d72009-04-15 13:22:59 +00001902 tprintf(", %lu", tcp->u_arg[3]);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001903#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001904 return 0;
1905}
1906
Denys Vlasenko1d632462009-04-14 12:51:00 +00001907int
1908sys_rt_sigpending(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001909{
1910 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001911
1912 if (exiting(tcp)) {
1913 if (syserror(tcp))
1914 tprintf("%#lx", tcp->u_arg[0]);
Nate Sammons4a121431999-04-06 01:19:39 +00001915 else if (copy_sigset_len(tcp, tcp->u_arg[0],
1916 &sigset, tcp->u_arg[1]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001917 tprintf("[?]");
1918 else
Wichert Akkerman46956571999-11-26 10:12:59 +00001919 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001920 }
1921 return 0;
1922}
Denys Vlasenko1d632462009-04-14 12:51:00 +00001923
1924int
1925sys_rt_sigsuspend(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001926{
1927 if (entering(tcp)) {
1928 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +00001929 if (copy_sigset_len(tcp, tcp->u_arg[0], &sigm, tcp->u_arg[1]) < 0)
1930 tprintf("[?]");
1931 else
1932 printsigmask(&sigm, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001933 }
1934 return 0;
1935}
Denys Vlasenko1d632462009-04-14 12:51:00 +00001936
1937int
1938sys_rt_sigqueueinfo(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001939{
1940 if (entering(tcp)) {
1941 siginfo_t si;
1942 tprintf("%lu, ", tcp->u_arg[0]);
1943 printsignal(tcp->u_arg[1]);
1944 tprintf(", ");
1945 if (umove(tcp, tcp->u_arg[2], &si) < 0)
1946 tprintf("%#lx", tcp->u_arg[2]);
1947 else
Denys Vlasenkof535b542009-01-13 18:30:55 +00001948 printsiginfo(&si, verbose(tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001949 }
1950 return 0;
1951}
1952
Denys Vlasenko1d632462009-04-14 12:51:00 +00001953int sys_rt_sigtimedwait(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001954{
1955 if (entering(tcp)) {
1956 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001957
Roland McGratha39c5a12002-12-17 05:10:37 +00001958 if (copy_sigset_len(tcp, tcp->u_arg[0],
Nate Sammons4a121431999-04-06 01:19:39 +00001959 &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001960 tprintf("[?]");
1961 else
Wichert Akkerman46956571999-11-26 10:12:59 +00001962 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001963 tprintf(", ");
Denys Vlasenkob1a78cf2009-04-15 13:31:59 +00001964 /* This is the only "return" parameter, */
1965 if (tcp->u_arg[1] != 0)
1966 return 0;
1967 /* ... if it's NULL, can decode all on entry */
1968 tprintf("NULL, ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001969 }
Denys Vlasenkob1a78cf2009-04-15 13:31:59 +00001970 else if (tcp->u_arg[1] != 0) {
1971 /* syscall exit, and u_arg[1] wasn't NULL */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001972 if (syserror(tcp))
Denys Vlasenkob1a78cf2009-04-15 13:31:59 +00001973 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001974 else {
1975 siginfo_t si;
1976 if (umove(tcp, tcp->u_arg[1], &si) < 0)
Denys Vlasenkob1a78cf2009-04-15 13:31:59 +00001977 tprintf("%#lx, ", tcp->u_arg[1]);
1978 else {
Denys Vlasenkof535b542009-01-13 18:30:55 +00001979 printsiginfo(&si, verbose(tcp));
Denys Vlasenkob1a78cf2009-04-15 13:31:59 +00001980 tprintf(", ");
1981 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001982 }
1983 }
Denys Vlasenkob1a78cf2009-04-15 13:31:59 +00001984 else {
1985 /* syscall exit, and u_arg[1] was NULL */
1986 return 0;
1987 }
1988 print_timespec(tcp, tcp->u_arg[2]);
1989 tprintf(", %d", (int) tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001990 return 0;
1991};
1992
Roland McGrath79dcd7a2006-01-12 22:34:50 +00001993int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001994sys_restart_syscall(struct tcb *tcp)
Roland McGrath79dcd7a2006-01-12 22:34:50 +00001995{
1996 if (entering(tcp))
1997 tprintf("<... resuming interrupted call ...>");
1998 return 0;
1999}
2000
Dmitry V. Levin4371b102008-11-10 22:53:02 +00002001static int
2002do_signalfd(struct tcb *tcp, int flags_arg)
Roland McGrathf46ccd32007-08-02 01:15:59 +00002003{
2004 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +03002005 printfd(tcp, tcp->u_arg[0]);
2006 tprintf(", ");
Roland McGrathf46ccd32007-08-02 01:15:59 +00002007 print_sigset(tcp, tcp->u_arg[1], 1);
Dmitry V. Levin9d2ee3d2009-10-05 13:45:19 +00002008 tprintf(", %lu", tcp->u_arg[2]);
Dmitry V. Levin4371b102008-11-10 22:53:02 +00002009 if (flags_arg >= 0) {
2010 tprintf(", ");
2011 printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
2012 }
Roland McGrathf46ccd32007-08-02 01:15:59 +00002013 }
2014 return 0;
2015}
Dmitry V. Levin4371b102008-11-10 22:53:02 +00002016
2017int
2018sys_signalfd(struct tcb *tcp)
2019{
2020 return do_signalfd(tcp, -1);
2021}
2022
2023int
2024sys_signalfd4(struct tcb *tcp)
2025{
2026 return do_signalfd(tcp, 3);
2027}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002028#endif /* LINUX */