blob: ad1d967f058d66fd17120ea6a2192f024864cce2 [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.
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000032 */
33
34#include "defs.h"
Dmitry V. Levin0e946ab2015-07-17 23:56:54 +000035#include <signal.h>
Denys Vlasenko041b3ee2011-08-18 12:48:56 +020036
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000037#ifndef NSIG
Dmitry V. Levin74219ea2015-03-06 01:47:18 +000038# warning NSIG is not defined, using 32
Denys Vlasenko84703742012-02-25 02:38:52 +010039# define NSIG 32
Dmitry V. Levin38593e92014-02-26 16:51:28 +000040#elif NSIG < 32
Dmitry V. Levin74219ea2015-03-06 01:47:18 +000041# error NSIG < 32
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000042#endif
Denys Vlasenko041b3ee2011-08-18 12:48:56 +020043
Roland McGrath2638cb42002-12-15 23:58:41 +000044/* The libc headers do not define this constant since it should only be
Denys Vlasenko041b3ee2011-08-18 12:48:56 +020045 used by the implementation. So we define it here. */
Dmitry V. Levin5c7f6272014-02-08 00:26:06 +000046#ifndef SA_RESTORER
47# ifdef ASM_SA_RESTORER
48# define SA_RESTORER ASM_SA_RESTORER
Roland McGrath2638cb42002-12-15 23:58:41 +000049# endif
50#endif
51
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +000052/*
53 * Some architectures define SA_RESTORER in their headers,
54 * but do not actually have sa_restorer.
55 *
56 * Some architectures, otherwise, do not define SA_RESTORER in their headers,
57 * but actually have sa_restorer.
58 */
59#ifdef SA_RESTORER
60# if defined HPPA || defined IA64
61# define HAVE_SA_RESTORER 0
62# else
63# define HAVE_SA_RESTORER 1
64# endif
65#else /* !SA_RESTORER */
Andreas Schwaba8971362015-03-11 14:15:34 +010066# if defined SPARC || defined SPARC64 || defined M68K
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +000067# define HAVE_SA_RESTORER 1
68# else
69# define HAVE_SA_RESTORER 0
70# endif
Mike Frysingerd632e102014-08-09 09:04:18 -040071#endif
72
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000073#include "xlat/sigact_flags.h"
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000074#include "xlat/sigprocmaskcmds.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000075
Nate Sammonsce780fc1999-03-29 23:23:13 +000076/* Anonymous realtime signals. */
Dmitry V. Levin59f63d32015-03-05 05:03:41 +000077#ifndef ASM_SIGRTMIN
78/* Linux kernel >= 3.18 defines SIGRTMIN to 32 on all architectures. */
79# define ASM_SIGRTMIN 32
Nate Sammonsce780fc1999-03-29 23:23:13 +000080#endif
Dmitry V. Levin59f63d32015-03-05 05:03:41 +000081#ifndef ASM_SIGRTMAX
82/* Under glibc 2.1, SIGRTMAX et al are functions, but __SIGRTMAX is a
83 constant. This is what we want. Otherwise, just use SIGRTMAX. */
84# ifdef SIGRTMAX
85# ifndef __SIGRTMAX
86# define __SIGRTMAX SIGRTMAX
87# endif
88# endif
89# ifdef __SIGRTMAX
90# define ASM_SIGRTMAX __SIGRTMAX
91# endif
Nate Sammonsce780fc1999-03-29 23:23:13 +000092#endif
93
Denys Vlasenkod9560c12011-08-19 17:41:28 +020094/* Note on the size of sigset_t:
95 *
96 * In glibc, sigset_t is an array with space for 1024 bits (!),
97 * even though all arches supported by Linux have only 64 signals
98 * except MIPS, which has 128. IOW, it is 128 bytes long.
99 *
100 * In-kernel sigset_t is sized correctly (it is either 64 or 128 bit long).
101 * However, some old syscall return only 32 lower bits (one word).
102 * Example: sys_sigpending vs sys_rt_sigpending.
103 *
104 * Be aware of this fact when you try to
105 * memcpy(&tcp->u_arg[1], &something, sizeof(sigset_t))
106 * - sizeof(sigset_t) is much bigger than you think,
107 * it may overflow tcp->u_arg[] array, and it may try to copy more data
108 * than is really available in <something>.
109 * Similarly,
110 * umoven(tcp, addr, sizeof(sigset_t), &sigset)
111 * may be a bad idea: it'll try to read much more data than needed
112 * to fetch a sigset_t.
113 * Use (NSIG / 8) as a size instead.
114 */
115
Roland McGrathee36ce12004-09-04 03:53:10 +0000116const char *
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000117signame(const int sig)
Nate Sammonsce780fc1999-03-29 23:23:13 +0000118{
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000119 static char buf[sizeof("SIGRT_%u") + sizeof(int)*3];
Denys Vlasenko041b3ee2011-08-18 12:48:56 +0200120
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000121 if (sig >= 0) {
122 const unsigned int s = sig;
123
124 if (s < nsignals)
125 return signalent[s];
Dmitry V. Levin59f63d32015-03-05 05:03:41 +0000126#ifdef ASM_SIGRTMAX
Dmitry V. Levin07572c62016-01-12 00:04:15 +0000127 if (s >= ASM_SIGRTMIN && s <= (unsigned int) ASM_SIGRTMAX) {
Dmitry V. Levin59f63d32015-03-05 05:03:41 +0000128 sprintf(buf, "SIGRT_%u", s - ASM_SIGRTMIN);
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000129 return buf;
130 }
Denys Vlasenko041b3ee2011-08-18 12:48:56 +0200131#endif
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000132 }
Denys Vlasenko041b3ee2011-08-18 12:48:56 +0200133 sprintf(buf, "%d", sig);
134 return buf;
Nate Sammonsce780fc1999-03-29 23:23:13 +0000135}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000136
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000137static unsigned int
138popcount32(const uint32_t *a, unsigned int size)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000139{
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000140 unsigned int count = 0;
Denys Vlasenkod9560c12011-08-19 17:41:28 +0200141
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000142 for (; size; ++a, --size) {
143 uint32_t x = *a;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000144
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000145#ifdef HAVE___BUILTIN_POPCOUNT
146 count += __builtin_popcount(x);
Denys Vlasenkoa8773792013-07-18 20:42:41 +0200147#else
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000148 for (; x; ++count)
149 x &= x - 1;
Nate Sammons4a121431999-04-06 01:19:39 +0000150#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000151 }
Denys Vlasenko4f3df072012-01-29 22:38:35 +0100152
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000153 return count;
154}
155
Dmitry V. Levin74219ea2015-03-06 01:47:18 +0000156const char *
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000157sprintsigmask_n(const char *prefix, const void *sig_mask, unsigned int bytes)
158{
159 /*
160 * The maximum number of signal names to be printed is NSIG * 2 / 3.
161 * Most of signal names have length 7,
162 * average length of signal names is less than 7.
163 * The length of prefix string does not exceed 16.
164 */
165 static char outstr[128 + 8 * (NSIG * 2 / 3)];
166
167 char *s;
168 const uint32_t *mask;
169 uint32_t inverted_mask[NSIG / 32];
170 unsigned int size;
171 int i;
172 char sep;
173
174 s = stpcpy(outstr, prefix);
175
176 mask = sig_mask;
177 /* length of signal mask in 4-byte words */
178 size = (bytes >= NSIG / 8) ? NSIG / 32 : (bytes + 3) / 4;
179
180 /* check whether 2/3 or more bits are set */
181 if (popcount32(mask, size) >= size * 32 * 2 / 3) {
182 /* show those signals that are NOT in the mask */
183 unsigned int j;
184 for (j = 0; j < size; ++j)
185 inverted_mask[j] = ~mask[j];
186 mask = inverted_mask;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000187 *s++ = '~';
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000188 }
Denys Vlasenko4f3df072012-01-29 22:38:35 +0100189
190 sep = '[';
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000191 for (i = 0; (i = next_set_bit(mask, i, size * 32)) >= 0; ) {
192 ++i;
193 *s++ = sep;
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000194 if ((unsigned) i < nsignals) {
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000195 s = stpcpy(s, signalent[i] + 3);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000196 }
Dmitry V. Levin59f63d32015-03-05 05:03:41 +0000197#ifdef ASM_SIGRTMAX
198 else if (i >= ASM_SIGRTMIN && i <= ASM_SIGRTMAX) {
199 s += sprintf(s, "RT_%u", i - ASM_SIGRTMIN);
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000200 }
201#endif
202 else {
203 s += sprintf(s, "%u", i);
204 }
205 sep = ' ';
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000206 }
Denys Vlasenko4f3df072012-01-29 22:38:35 +0100207 if (sep == '[')
208 *s++ = sep;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000209 *s++ = ']';
210 *s = '\0';
211 return outstr;
212}
213
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000214#define sprintsigmask_val(prefix, mask) \
215 sprintsigmask_n((prefix), &(mask), sizeof(mask))
216
217#define tprintsigmask_val(prefix, mask) \
218 tprints(sprintsigmask_n((prefix), &(mask), sizeof(mask)))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000219
220void
Denys Vlasenkoeccc48c2011-06-09 01:28:11 +0200221printsignal(int nr)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000222{
Denys Vlasenko5940e652011-09-01 09:55:05 +0200223 tprints(signame(nr));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000224}
225
Dmitry V. Levin11656202016-02-18 00:08:30 +0000226static void
227print_sigset_addr_len_limit(struct tcb *tcp, long addr, long len, long min_len)
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000228{
Dmitry V. Levin11656202016-02-18 00:08:30 +0000229 /*
230 * Here len is usually equal to NSIG / 8 or current_wordsize.
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200231 * But we code this defensively:
232 */
Dmitry V. Levin11656202016-02-18 00:08:30 +0000233 if (len < min_len || len > NSIG / 8) {
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000234 printaddr(addr);
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200235 return;
236 }
Dmitry V. Levin11656202016-02-18 00:08:30 +0000237 int mask[NSIG / 8 / sizeof(int)] = {};
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000238 if (umoven_or_printaddr(tcp, addr, len, mask))
239 return;
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000240 tprints(sprintsigmask_n("", mask, len));
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000241}
242
Dmitry V. Levin11656202016-02-18 00:08:30 +0000243void
244print_sigset_addr_len(struct tcb *tcp, long addr, long len)
245{
246 print_sigset_addr_len_limit(tcp, addr, len, current_wordsize);
247}
248
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000249SYS_FUNC(sigsetmask)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000250{
251 if (entering(tcp)) {
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000252 tprintsigmask_val("", tcp->u_arg[0]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000253 }
254 else if (!syserror(tcp)) {
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000255 tcp->auxstr = sprintsigmask_val("old mask ", tcp->u_rval);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000256 return RVAL_HEX | RVAL_STR;
257 }
258 return 0;
259}
260
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000261#ifdef HAVE_SIGACTION
262
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000263struct old_sigaction {
Denys Vlasenko86d94842013-02-08 12:59:13 +0100264 /* sa_handler may be a libc #define, need to use other name: */
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800265#ifdef MIPS
266 unsigned int sa_flags;
267 void (*__sa_handler)(int);
268 /* Kernel treats sa_mask as an array of longs. */
269 unsigned long sa_mask[NSIG / sizeof(long) ? NSIG / sizeof(long) : 1];
270#else
Denys Vlasenko86d94842013-02-08 12:59:13 +0100271 void (*__sa_handler)(int);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000272 unsigned long sa_mask;
273 unsigned long sa_flags;
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800274#endif /* !MIPS */
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000275#if HAVE_SA_RESTORER
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100276 void (*sa_restorer)(void);
277#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000278};
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000279
Elliott Hughes458b3f22014-02-28 23:21:35 +0000280struct old_sigaction32 {
281 /* sa_handler may be a libc #define, need to use other name: */
282 uint32_t __sa_handler;
283 uint32_t sa_mask;
284 uint32_t sa_flags;
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000285#if HAVE_SA_RESTORER
Elliott Hughes458b3f22014-02-28 23:21:35 +0000286 uint32_t sa_restorer;
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100287#endif
Elliott Hughes458b3f22014-02-28 23:21:35 +0000288};
289
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000290static void
291decode_old_sigaction(struct tcb *tcp, long addr)
292{
293 struct old_sigaction sa;
Elliott Hughes458b3f22014-02-28 23:21:35 +0000294
295#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
296 if (current_wordsize != sizeof(sa.__sa_handler) && current_wordsize == 4) {
297 struct old_sigaction32 sa32;
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000298
299 if (umove_or_printaddr(tcp, addr, &sa32))
300 return;
301
302 memset(&sa, 0, sizeof(sa));
303 sa.__sa_handler = (void*)(uintptr_t)sa32.__sa_handler;
304 sa.sa_flags = sa32.sa_flags;
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000305#if HAVE_SA_RESTORER && defined SA_RESTORER
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000306 sa.sa_restorer = (void*)(uintptr_t)sa32.sa_restorer;
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100307#endif
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000308 sa.sa_mask = sa32.sa_mask;
Elliott Hughes458b3f22014-02-28 23:21:35 +0000309 } else
310#endif
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000311 if (umove_or_printaddr(tcp, addr, &sa))
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000312 return;
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000313
314 /* Architectures using function pointers, like
315 * hppa, may need to manipulate the function pointer
316 * to compute the result of a comparison. However,
317 * the __sa_handler function pointer exists only in
318 * the address space of the traced process, and can't
319 * be manipulated by strace. In order to prevent the
320 * compiler from generating code to manipulate
321 * __sa_handler we cast the function pointers to long. */
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000322 tprints("{");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000323 if ((long)sa.__sa_handler == (long)SIG_ERR)
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000324 tprints("SIG_ERR");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000325 else if ((long)sa.__sa_handler == (long)SIG_DFL)
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000326 tprints("SIG_DFL");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000327 else if ((long)sa.__sa_handler == (long)SIG_IGN)
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000328 tprints("SIG_IGN");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000329 else
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000330 printaddr((long) sa.__sa_handler);
331 tprints(", ");
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800332#ifdef MIPS
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000333 tprintsigmask_addr("", sa.sa_mask);
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800334#else
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000335 tprintsigmask_val("", sa.sa_mask);
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800336#endif
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000337 tprints(", ");
338 printflags(sigact_flags, sa.sa_flags, "SA_???");
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000339#if HAVE_SA_RESTORER && defined SA_RESTORER
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000340 if (sa.sa_flags & SA_RESTORER)
341 tprintf(", %p", sa.sa_restorer);
342#endif
343 tprints("}");
344}
345
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000346SYS_FUNC(sigaction)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000347{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000348 if (entering(tcp)) {
349 printsignal(tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200350 tprints(", ");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000351 decode_old_sigaction(tcp, tcp->u_arg[1]);
352 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000353 } else
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000354 decode_old_sigaction(tcp, tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000355 return 0;
356}
357
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000358SYS_FUNC(signal)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000359{
360 if (entering(tcp)) {
361 printsignal(tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200362 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000363 switch (tcp->u_arg[1]) {
Jan Kratochvil1f942712008-08-06 21:38:52 +0000364 case (long) SIG_ERR:
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200365 tprints("SIG_ERR");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000366 break;
Jan Kratochvil1f942712008-08-06 21:38:52 +0000367 case (long) SIG_DFL:
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200368 tprints("SIG_DFL");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000369 break;
Jan Kratochvil1f942712008-08-06 21:38:52 +0000370 case (long) SIG_IGN:
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200371 tprints("SIG_IGN");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000372 break;
373 default:
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000374 printaddr(tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000375 }
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000376 return 0;
377 }
Dmitry V. Levin21a75342008-09-03 01:22:18 +0000378 else if (!syserror(tcp)) {
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000379 switch (tcp->u_rval) {
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100380 case (long) SIG_ERR:
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000381 tcp->auxstr = "SIG_ERR"; break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100382 case (long) SIG_DFL:
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000383 tcp->auxstr = "SIG_DFL"; break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100384 case (long) SIG_IGN:
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000385 tcp->auxstr = "SIG_IGN"; break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100386 default:
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000387 tcp->auxstr = NULL;
388 }
389 return RVAL_HEX | RVAL_STR;
390 }
Dmitry V. Levin21a75342008-09-03 01:22:18 +0000391 return 0;
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000392}
393
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000394#endif /* HAVE_SIGACTION */
395
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000396SYS_FUNC(siggetmask)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000397{
398 if (exiting(tcp)) {
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000399 tcp->auxstr = sprintsigmask_val("mask ", tcp->u_rval);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000400 }
401 return RVAL_HEX | RVAL_STR;
402}
403
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000404SYS_FUNC(sigsuspend)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000405{
Dmitry V. Levin0e45b502015-07-17 00:51:45 +0000406 tprintsigmask_val("", tcp->u_arg[2]);
407
408 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000409}
410
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000411#ifdef HAVE_SIGACTION
412
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200413/* "Old" sigprocmask, which operates with word-sized signal masks */
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000414SYS_FUNC(sigprocmask)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000415{
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200416# ifdef ALPHA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000417 if (entering(tcp)) {
Mike Frysingerdde045c2012-03-15 00:45:33 -0400418 /*
419 * Alpha/OSF is different: it doesn't pass in two pointers,
420 * but rather passes in the new bitmask as an argument and
421 * then returns the old bitmask. This "works" because we
422 * only have 64 signals to worry about. If you want more,
423 * use of the rt_sigprocmask syscall is required.
424 * Alpha:
425 * old = osf_sigprocmask(how, new);
426 * Everyone else:
427 * ret = sigprocmask(how, &new, &old, ...);
428 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000429 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000430 tprintsigmask_val(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000431 }
432 else if (!syserror(tcp)) {
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000433 tcp->auxstr = sprintsigmask_val("old mask ", tcp->u_rval);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000434 return RVAL_HEX | RVAL_STR;
435 }
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200436# else /* !ALPHA */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000437 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000438 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200439 tprints(", ");
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200440 print_sigset_addr_len(tcp, tcp->u_arg[1], current_wordsize);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200441 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000442 }
443 else {
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000444 print_sigset_addr_len(tcp, tcp->u_arg[2], current_wordsize);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000445 }
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200446# endif /* !ALPHA */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000447 return 0;
448}
449
450#endif /* HAVE_SIGACTION */
451
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000452SYS_FUNC(kill)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000453{
Dmitry V. Levin0e45b502015-07-17 00:51:45 +0000454 tprintf("%ld, %s",
455 widen_to_long(tcp->u_arg[0]),
456 signame(tcp->u_arg[1]));
457
458 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000459}
460
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000461SYS_FUNC(tgkill)
Roland McGrath8ffc3522003-07-09 09:47:49 +0000462{
Dmitry V. Levin0e45b502015-07-17 00:51:45 +0000463 tprintf("%ld, %ld, %s",
464 widen_to_long(tcp->u_arg[0]),
465 widen_to_long(tcp->u_arg[1]),
466 signame(tcp->u_arg[2]));
467
468 return RVAL_DECODED;
Roland McGrath8ffc3522003-07-09 09:47:49 +0000469}
Roland McGrath8ffc3522003-07-09 09:47:49 +0000470
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000471SYS_FUNC(sigpending)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000472{
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000473 if (exiting(tcp))
474 print_sigset_addr_len(tcp, tcp->u_arg[0], current_wordsize);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000475 return 0;
476}
477
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000478SYS_FUNC(rt_sigprocmask)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000479{
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200480 /* Note: arg[3] is the length of the sigset. Kernel requires NSIG / 8 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000481 if (entering(tcp)) {
482 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200483 tprints(", ");
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200484 print_sigset_addr_len(tcp, tcp->u_arg[1], tcp->u_arg[3]);
485 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000486 }
487 else {
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000488 print_sigset_addr_len(tcp, tcp->u_arg[2], tcp->u_arg[3]);
Nate Sammonsdab325a1999-03-29 23:33:35 +0000489 tprintf(", %lu", tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000490 }
491 return 0;
492}
493
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000494/* Structure describing the action to be taken when a signal arrives. */
495struct new_sigaction
496{
Denys Vlasenko86d94842013-02-08 12:59:13 +0100497 /* sa_handler may be a libc #define, need to use other name: */
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800498#ifdef MIPS
499 unsigned int sa_flags;
500 void (*__sa_handler)(int);
501#else
Denys Vlasenko86d94842013-02-08 12:59:13 +0100502 void (*__sa_handler)(int);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000503 unsigned long sa_flags;
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800504#endif /* !MIPS */
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000505#if HAVE_SA_RESTORER
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100506 void (*sa_restorer)(void);
507#endif
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000508 /* Kernel treats sa_mask as an array of longs. */
509 unsigned long sa_mask[NSIG / sizeof(long) ? NSIG / sizeof(long) : 1];
510};
511/* Same for i386-on-x86_64 and similar cases */
512struct new_sigaction32
513{
514 uint32_t __sa_handler;
515 uint32_t sa_flags;
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000516#if HAVE_SA_RESTORER
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000517 uint32_t sa_restorer;
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100518#endif
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000519 uint32_t sa_mask[2 * (NSIG / sizeof(long) ? NSIG / sizeof(long) : 1)];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000520};
521
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000522static void
523decode_new_sigaction(struct tcb *tcp, long addr)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000524{
525 struct new_sigaction sa;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000526
Denys Vlasenkod4d3ede2013-02-13 16:31:32 +0100527#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
Denys Vlasenko9fd4f962012-03-19 09:36:42 +0100528 if (current_wordsize != sizeof(sa.sa_flags) && current_wordsize == 4) {
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000529 struct new_sigaction32 sa32;
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000530
531 if (umove_or_printaddr(tcp, addr, &sa32))
532 return;
533
534 memset(&sa, 0, sizeof(sa));
535 sa.__sa_handler = (void*)(unsigned long)sa32.__sa_handler;
536 sa.sa_flags = sa32.sa_flags;
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000537#if HAVE_SA_RESTORER && defined SA_RESTORER
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000538 sa.sa_restorer = (void*)(unsigned long)sa32.sa_restorer;
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100539#endif
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000540 /* Kernel treats sa_mask as an array of longs.
541 * For 32-bit process, "long" is uint32_t, thus, for example,
542 * 32th bit in sa_mask will end up as bit 0 in sa_mask[1].
543 * But for (64-bit) kernel, 32th bit in sa_mask is
544 * 32th bit in 0th (64-bit) long!
545 * For little-endian, it's the same.
546 * For big-endian, we swap 32-bit words.
547 */
548 sa.sa_mask[0] = sa32.sa_mask[0] + ((long)(sa32.sa_mask[1]) << 32);
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000549 } else
550#endif
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000551 if (umove_or_printaddr(tcp, addr, &sa))
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000552 return;
Dmitry V. Levin735843e2015-07-17 00:37:39 +0000553
Carlos O'Donell4677c8a2009-09-09 18:13:19 +0000554 /* Architectures using function pointers, like
555 * hppa, may need to manipulate the function pointer
556 * to compute the result of a comparison. However,
Denys Vlasenko86d94842013-02-08 12:59:13 +0100557 * the __sa_handler function pointer exists only in
Carlos O'Donell4677c8a2009-09-09 18:13:19 +0000558 * the address space of the traced process, and can't
559 * be manipulated by strace. In order to prevent the
560 * compiler from generating code to manipulate
Denys Vlasenko86d94842013-02-08 12:59:13 +0100561 * __sa_handler we cast the function pointers to long. */
Carlos O'Donell4677c8a2009-09-09 18:13:19 +0000562 if ((long)sa.__sa_handler == (long)SIG_ERR)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200563 tprints("{SIG_ERR, ");
Carlos O'Donell4677c8a2009-09-09 18:13:19 +0000564 else if ((long)sa.__sa_handler == (long)SIG_DFL)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200565 tprints("{SIG_DFL, ");
Carlos O'Donell4677c8a2009-09-09 18:13:19 +0000566 else if ((long)sa.__sa_handler == (long)SIG_IGN)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200567 tprints("{SIG_IGN, ");
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000568 else
569 tprintf("{%#lx, ", (long) sa.__sa_handler);
Denys Vlasenko80b73a22013-07-18 10:10:46 +0200570 /*
571 * Sigset size is in tcp->u_arg[4] (SPARC)
572 * or in tcp->u_arg[3] (all other),
573 * but kernel won't handle sys_rt_sigaction
574 * with wrong sigset size (just returns EINVAL instead).
575 * We just fetch the right size, which is NSIG / 8.
576 */
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000577 tprintsigmask_val("", sa.sa_mask);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200578 tprints(", ");
Denys Vlasenko80b73a22013-07-18 10:10:46 +0200579
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000580 printflags(sigact_flags, sa.sa_flags, "SA_???");
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000581#if HAVE_SA_RESTORER && defined SA_RESTORER
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000582 if (sa.sa_flags & SA_RESTORER)
583 tprintf(", %p", sa.sa_restorer);
584#endif
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200585 tprints("}");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000586}
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000587
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000588SYS_FUNC(rt_sigaction)
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000589{
590 if (entering(tcp)) {
591 printsignal(tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200592 tprints(", ");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000593 decode_new_sigaction(tcp, tcp->u_arg[1]);
594 tprints(", ");
595 } else {
596 decode_new_sigaction(tcp, tcp->u_arg[2]);
Denys Vlasenko9472a272013-02-12 11:43:46 +0100597#if defined(SPARC) || defined(SPARC64)
Wichert Akkermandacfb6e1999-06-03 14:21:07 +0000598 tprintf(", %#lx, %lu", tcp->u_arg[3], tcp->u_arg[4]);
599#elif defined(ALPHA)
600 tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]);
601#else
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000602 tprintf(", %lu", tcp->u_arg[3]);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +0000603#endif
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000604 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000605 return 0;
606}
607
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000608SYS_FUNC(rt_sigpending)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000609{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000610 if (exiting(tcp)) {
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200611 /*
612 * One of the few syscalls where sigset size (arg[1])
613 * is allowed to be <= NSIG / 8, not strictly ==.
614 * This allows non-rt sigpending() syscall
615 * to reuse rt_sigpending() code in kernel.
616 */
Dmitry V. Levin11656202016-02-18 00:08:30 +0000617 print_sigset_addr_len_limit(tcp, tcp->u_arg[0],
618 tcp->u_arg[1], 1);
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200619 tprintf(", %lu", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000620 }
621 return 0;
622}
Denys Vlasenko1d632462009-04-14 12:51:00 +0000623
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000624SYS_FUNC(rt_sigsuspend)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000625{
Dmitry V. Levin0e45b502015-07-17 00:51:45 +0000626 /* NB: kernel requires arg[1] == NSIG / 8 */
627 print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[1]);
628 tprintf(", %lu", tcp->u_arg[1]);
629
630 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000631}
Denys Vlasenko1d632462009-04-14 12:51:00 +0000632
Dmitry V. Levin297632b2012-03-13 15:51:13 +0000633static void
634print_sigqueueinfo(struct tcb *tcp, int sig, unsigned long uinfo)
635{
Dmitry V. Levin297632b2012-03-13 15:51:13 +0000636 printsignal(sig);
637 tprints(", ");
Dmitry V. Levine2fb0bb2015-09-15 21:51:15 +0000638 printsiginfo_at(tcp, uinfo);
Dmitry V. Levin297632b2012-03-13 15:51:13 +0000639}
640
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000641SYS_FUNC(rt_sigqueueinfo)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000642{
Dmitry V. Levin11d623f2016-02-17 05:24:43 +0000643 tprintf("%d, ", (int) tcp->u_arg[0]);
Dmitry V. Levin0e45b502015-07-17 00:51:45 +0000644 print_sigqueueinfo(tcp, tcp->u_arg[1], tcp->u_arg[2]);
645
646 return RVAL_DECODED;
Dmitry V. Levin297632b2012-03-13 15:51:13 +0000647}
648
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000649SYS_FUNC(rt_tgsigqueueinfo)
Dmitry V. Levin297632b2012-03-13 15:51:13 +0000650{
Dmitry V. Levin11d623f2016-02-17 05:24:43 +0000651 tprintf("%d, %d, ", (int) tcp->u_arg[0], (int) tcp->u_arg[1]);
Dmitry V. Levin0e45b502015-07-17 00:51:45 +0000652 print_sigqueueinfo(tcp, tcp->u_arg[2], tcp->u_arg[3]);
653
654 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000655}
656
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000657SYS_FUNC(rt_sigtimedwait)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000658{
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200659 /* NB: kernel requires arg[3] == NSIG / 8 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000660 if (entering(tcp)) {
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200661 print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[3]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200662 tprints(", ");
Dmitry V. Levin49faae92016-02-19 03:27:09 +0000663 if (!tcp->u_arg[1]) {
664 /*
665 * This is the only "return" parameter,
666 * if it's NULL, decode all parameters on entry.
667 */
668 tprints("NULL, ");
669 print_timespec(tcp, tcp->u_arg[2]);
670 tprintf(", %lu", tcp->u_arg[3]);
671 tcp->auxstr = NULL;
672 } else {
673 tcp->auxstr = sprint_timespec(tcp, tcp->u_arg[2]);
674 }
675 } else {
676 if (tcp->auxstr) {
677 printsiginfo_at(tcp, tcp->u_arg[1]);
678 tprintf(", %s, %lu", tcp->auxstr, tcp->u_arg[3]);
679 tcp->auxstr = NULL;
680 }
Dmitry V. Levin3858b932015-09-18 01:54:59 +0000681
Dmitry V. Levin49faae92016-02-19 03:27:09 +0000682 if (!syserror(tcp) && tcp->u_rval) {
683 tcp->auxstr = signame(tcp->u_rval);
684 return RVAL_STR;
685 }
686 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000687 return 0;
688};
689
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000690SYS_FUNC(restart_syscall)
Roland McGrath79dcd7a2006-01-12 22:34:50 +0000691{
Dmitry V. Levin0e45b502015-07-17 00:51:45 +0000692 tprintf("<... resuming interrupted %s ...>",
693 tcp->s_prev_ent ? tcp->s_prev_ent->sys_name : "system call");
694
695 return RVAL_DECODED;
Roland McGrath79dcd7a2006-01-12 22:34:50 +0000696}