blob: 0b52ddb61d24160248ffae4bf6f224e88d61b38b [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"
Denys Vlasenko041b3ee2011-08-18 12:48:56 +020035
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000036#ifndef NSIG
Dmitry V. Levin74219ea2015-03-06 01:47:18 +000037# warning NSIG is not defined, using 32
Denys Vlasenko84703742012-02-25 02:38:52 +010038# define NSIG 32
Dmitry V. Levin38593e92014-02-26 16:51:28 +000039#elif NSIG < 32
Dmitry V. Levin74219ea2015-03-06 01:47:18 +000040# error NSIG < 32
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000041#endif
Denys Vlasenko041b3ee2011-08-18 12:48:56 +020042
Roland McGrath2638cb42002-12-15 23:58:41 +000043/* The libc headers do not define this constant since it should only be
Denys Vlasenko041b3ee2011-08-18 12:48:56 +020044 used by the implementation. So we define it here. */
Dmitry V. Levin5c7f6272014-02-08 00:26:06 +000045#ifndef SA_RESTORER
46# ifdef ASM_SA_RESTORER
47# define SA_RESTORER ASM_SA_RESTORER
Roland McGrath2638cb42002-12-15 23:58:41 +000048# endif
49#endif
50
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +000051/*
52 * Some architectures define SA_RESTORER in their headers,
53 * but do not actually have sa_restorer.
54 *
55 * Some architectures, otherwise, do not define SA_RESTORER in their headers,
56 * but actually have sa_restorer.
57 */
58#ifdef SA_RESTORER
59# if defined HPPA || defined IA64
60# define HAVE_SA_RESTORER 0
61# else
62# define HAVE_SA_RESTORER 1
63# endif
64#else /* !SA_RESTORER */
Andreas Schwaba8971362015-03-11 14:15:34 +010065# if defined SPARC || defined SPARC64 || defined M68K
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +000066# define HAVE_SA_RESTORER 1
67# else
68# define HAVE_SA_RESTORER 0
69# endif
Mike Frysingerd632e102014-08-09 09:04:18 -040070#endif
71
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000072#include "xlat/sigact_flags.h"
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000073#include "xlat/sigprocmaskcmds.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000074
Nate Sammonsce780fc1999-03-29 23:23:13 +000075/* Anonymous realtime signals. */
Dmitry V. Levin59f63d32015-03-05 05:03:41 +000076#ifndef ASM_SIGRTMIN
77/* Linux kernel >= 3.18 defines SIGRTMIN to 32 on all architectures. */
78# define ASM_SIGRTMIN 32
Nate Sammonsce780fc1999-03-29 23:23:13 +000079#endif
Dmitry V. Levin59f63d32015-03-05 05:03:41 +000080#ifndef ASM_SIGRTMAX
81/* Under glibc 2.1, SIGRTMAX et al are functions, but __SIGRTMAX is a
82 constant. This is what we want. Otherwise, just use SIGRTMAX. */
83# ifdef SIGRTMAX
84# ifndef __SIGRTMAX
85# define __SIGRTMAX SIGRTMAX
86# endif
87# endif
88# ifdef __SIGRTMAX
89# define ASM_SIGRTMAX __SIGRTMAX
90# endif
Nate Sammonsce780fc1999-03-29 23:23:13 +000091#endif
92
Denys Vlasenkod9560c12011-08-19 17:41:28 +020093/* Note on the size of sigset_t:
94 *
95 * In glibc, sigset_t is an array with space for 1024 bits (!),
96 * even though all arches supported by Linux have only 64 signals
97 * except MIPS, which has 128. IOW, it is 128 bytes long.
98 *
99 * In-kernel sigset_t is sized correctly (it is either 64 or 128 bit long).
100 * However, some old syscall return only 32 lower bits (one word).
101 * Example: sys_sigpending vs sys_rt_sigpending.
102 *
103 * Be aware of this fact when you try to
104 * memcpy(&tcp->u_arg[1], &something, sizeof(sigset_t))
105 * - sizeof(sigset_t) is much bigger than you think,
106 * it may overflow tcp->u_arg[] array, and it may try to copy more data
107 * than is really available in <something>.
108 * Similarly,
109 * umoven(tcp, addr, sizeof(sigset_t), &sigset)
110 * may be a bad idea: it'll try to read much more data than needed
111 * to fetch a sigset_t.
112 * Use (NSIG / 8) as a size instead.
113 */
114
Roland McGrathee36ce12004-09-04 03:53:10 +0000115const char *
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000116signame(const int sig)
Nate Sammonsce780fc1999-03-29 23:23:13 +0000117{
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000118 static char buf[sizeof("SIGRT_%u") + sizeof(int)*3];
Denys Vlasenko041b3ee2011-08-18 12:48:56 +0200119
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000120 if (sig >= 0) {
121 const unsigned int s = sig;
122
123 if (s < nsignals)
124 return signalent[s];
Dmitry V. Levin59f63d32015-03-05 05:03:41 +0000125#ifdef ASM_SIGRTMAX
126 if (s >= ASM_SIGRTMIN && s <= ASM_SIGRTMAX) {
127 sprintf(buf, "SIGRT_%u", s - ASM_SIGRTMIN);
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000128 return buf;
129 }
Denys Vlasenko041b3ee2011-08-18 12:48:56 +0200130#endif
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000131 }
Denys Vlasenko041b3ee2011-08-18 12:48:56 +0200132 sprintf(buf, "%d", sig);
133 return buf;
Nate Sammonsce780fc1999-03-29 23:23:13 +0000134}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000135
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000136static unsigned int
137popcount32(const uint32_t *a, unsigned int size)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000138{
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000139 unsigned int count = 0;
Denys Vlasenkod9560c12011-08-19 17:41:28 +0200140
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000141 for (; size; ++a, --size) {
142 uint32_t x = *a;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000143
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000144#ifdef HAVE___BUILTIN_POPCOUNT
145 count += __builtin_popcount(x);
Denys Vlasenkoa8773792013-07-18 20:42:41 +0200146#else
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000147 for (; x; ++count)
148 x &= x - 1;
Nate Sammons4a121431999-04-06 01:19:39 +0000149#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000150 }
Denys Vlasenko4f3df072012-01-29 22:38:35 +0100151
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000152 return count;
153}
154
Dmitry V. Levin74219ea2015-03-06 01:47:18 +0000155const char *
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000156sprintsigmask_n(const char *prefix, const void *sig_mask, unsigned int bytes)
157{
158 /*
159 * The maximum number of signal names to be printed is NSIG * 2 / 3.
160 * Most of signal names have length 7,
161 * average length of signal names is less than 7.
162 * The length of prefix string does not exceed 16.
163 */
164 static char outstr[128 + 8 * (NSIG * 2 / 3)];
165
166 char *s;
167 const uint32_t *mask;
168 uint32_t inverted_mask[NSIG / 32];
169 unsigned int size;
170 int i;
171 char sep;
172
173 s = stpcpy(outstr, prefix);
174
175 mask = sig_mask;
176 /* length of signal mask in 4-byte words */
177 size = (bytes >= NSIG / 8) ? NSIG / 32 : (bytes + 3) / 4;
178
179 /* check whether 2/3 or more bits are set */
180 if (popcount32(mask, size) >= size * 32 * 2 / 3) {
181 /* show those signals that are NOT in the mask */
182 unsigned int j;
183 for (j = 0; j < size; ++j)
184 inverted_mask[j] = ~mask[j];
185 mask = inverted_mask;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000186 *s++ = '~';
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000187 }
Denys Vlasenko4f3df072012-01-29 22:38:35 +0100188
189 sep = '[';
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000190 for (i = 0; (i = next_set_bit(mask, i, size * 32)) >= 0; ) {
191 ++i;
192 *s++ = sep;
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000193 if ((unsigned) i < nsignals) {
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000194 s = stpcpy(s, signalent[i] + 3);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000195 }
Dmitry V. Levin59f63d32015-03-05 05:03:41 +0000196#ifdef ASM_SIGRTMAX
197 else if (i >= ASM_SIGRTMIN && i <= ASM_SIGRTMAX) {
198 s += sprintf(s, "RT_%u", i - ASM_SIGRTMIN);
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000199 }
200#endif
201 else {
202 s += sprintf(s, "%u", i);
203 }
204 sep = ' ';
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000205 }
Denys Vlasenko4f3df072012-01-29 22:38:35 +0100206 if (sep == '[')
207 *s++ = sep;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000208 *s++ = ']';
209 *s = '\0';
210 return outstr;
211}
212
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000213#define sprintsigmask_val(prefix, mask) \
214 sprintsigmask_n((prefix), &(mask), sizeof(mask))
215
216#define tprintsigmask_val(prefix, mask) \
217 tprints(sprintsigmask_n((prefix), &(mask), sizeof(mask)))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000218
219void
Denys Vlasenkoeccc48c2011-06-09 01:28:11 +0200220printsignal(int nr)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000221{
Denys Vlasenko5940e652011-09-01 09:55:05 +0200222 tprints(signame(nr));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000223}
224
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000225void
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200226print_sigset_addr_len(struct tcb *tcp, long addr, long len)
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000227{
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000228 char mask[NSIG / 8];
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000229
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200230 if (!addr) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200231 tprints("NULL");
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200232 return;
233 }
234 /* Here len is usually equals NSIG / 8 or current_wordsize.
235 * But we code this defensively:
236 */
237 if (len < 0) {
238 bad:
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000239 tprintf("%#lx", addr);
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200240 return;
241 }
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000242 if (len >= NSIG / 8)
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200243 len = NSIG / 8;
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000244 else
245 len = (len + 3) & ~3;
246
247 if (umoven(tcp, addr, len, mask) < 0)
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200248 goto bad;
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000249 tprints(sprintsigmask_n("", mask, len));
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000250}
251
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000252int
Denys Vlasenko12014262011-05-30 14:00:14 +0200253sys_sigsetmask(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000254{
255 if (entering(tcp)) {
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000256 tprintsigmask_val("", tcp->u_arg[0]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000257 }
258 else if (!syserror(tcp)) {
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000259 tcp->auxstr = sprintsigmask_val("old mask ", tcp->u_rval);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000260 return RVAL_HEX | RVAL_STR;
261 }
262 return 0;
263}
264
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000265#ifdef HAVE_SIGACTION
266
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000267struct old_sigaction {
Denys Vlasenko86d94842013-02-08 12:59:13 +0100268 /* sa_handler may be a libc #define, need to use other name: */
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800269#ifdef MIPS
270 unsigned int sa_flags;
271 void (*__sa_handler)(int);
272 /* Kernel treats sa_mask as an array of longs. */
273 unsigned long sa_mask[NSIG / sizeof(long) ? NSIG / sizeof(long) : 1];
274#else
Denys Vlasenko86d94842013-02-08 12:59:13 +0100275 void (*__sa_handler)(int);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000276 unsigned long sa_mask;
277 unsigned long sa_flags;
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800278#endif /* !MIPS */
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000279#if HAVE_SA_RESTORER
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100280 void (*sa_restorer)(void);
281#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000282};
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000283
Elliott Hughes458b3f22014-02-28 23:21:35 +0000284struct old_sigaction32 {
285 /* sa_handler may be a libc #define, need to use other name: */
286 uint32_t __sa_handler;
287 uint32_t sa_mask;
288 uint32_t sa_flags;
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000289#if HAVE_SA_RESTORER
Elliott Hughes458b3f22014-02-28 23:21:35 +0000290 uint32_t sa_restorer;
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100291#endif
Elliott Hughes458b3f22014-02-28 23:21:35 +0000292};
293
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000294static void
295decode_old_sigaction(struct tcb *tcp, long addr)
296{
297 struct old_sigaction sa;
Elliott Hughes458b3f22014-02-28 23:21:35 +0000298 int r;
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000299
300 if (!addr) {
301 tprints("NULL");
302 return;
303 }
304 if (!verbose(tcp) || (exiting(tcp) && syserror(tcp))) {
305 tprintf("%#lx", addr);
306 return;
307 }
Elliott Hughes458b3f22014-02-28 23:21:35 +0000308
309#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
310 if (current_wordsize != sizeof(sa.__sa_handler) && current_wordsize == 4) {
311 struct old_sigaction32 sa32;
312 r = umove(tcp, addr, &sa32);
313 if (r >= 0) {
314 memset(&sa, 0, sizeof(sa));
315 sa.__sa_handler = (void*)(uintptr_t)sa32.__sa_handler;
316 sa.sa_flags = sa32.sa_flags;
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000317#if HAVE_SA_RESTORER && defined SA_RESTORER
Elliott Hughes458b3f22014-02-28 23:21:35 +0000318 sa.sa_restorer = (void*)(uintptr_t)sa32.sa_restorer;
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100319#endif
Elliott Hughes458b3f22014-02-28 23:21:35 +0000320 sa.sa_mask = sa32.sa_mask;
321 }
322 } else
323#endif
324 {
325 r = umove(tcp, addr, &sa);
326 }
327 if (r < 0) {
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000328 tprints("{...}");
329 return;
330 }
331
332 /* Architectures using function pointers, like
333 * hppa, may need to manipulate the function pointer
334 * to compute the result of a comparison. However,
335 * the __sa_handler function pointer exists only in
336 * the address space of the traced process, and can't
337 * be manipulated by strace. In order to prevent the
338 * compiler from generating code to manipulate
339 * __sa_handler we cast the function pointers to long. */
340 if ((long)sa.__sa_handler == (long)SIG_ERR)
341 tprints("{SIG_ERR, ");
342 else if ((long)sa.__sa_handler == (long)SIG_DFL)
343 tprints("{SIG_DFL, ");
344 else if ((long)sa.__sa_handler == (long)SIG_IGN)
345 tprints("{SIG_IGN, ");
346 else
347 tprintf("{%#lx, ", (long) sa.__sa_handler);
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800348#ifdef MIPS
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000349 tprintsigmask_addr("", sa.sa_mask);
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800350#else
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000351 tprintsigmask_val("", sa.sa_mask);
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800352#endif
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000353 tprints(", ");
354 printflags(sigact_flags, sa.sa_flags, "SA_???");
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000355#if HAVE_SA_RESTORER && defined SA_RESTORER
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000356 if (sa.sa_flags & SA_RESTORER)
357 tprintf(", %p", sa.sa_restorer);
358#endif
359 tprints("}");
360}
361
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000362int
Denys Vlasenko12014262011-05-30 14:00:14 +0200363sys_sigaction(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000364{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000365 if (entering(tcp)) {
366 printsignal(tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200367 tprints(", ");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000368 decode_old_sigaction(tcp, tcp->u_arg[1]);
369 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000370 } else
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000371 decode_old_sigaction(tcp, tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000372 return 0;
373}
374
375int
Denys Vlasenko12014262011-05-30 14:00:14 +0200376sys_signal(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000377{
378 if (entering(tcp)) {
379 printsignal(tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200380 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000381 switch (tcp->u_arg[1]) {
Jan Kratochvil1f942712008-08-06 21:38:52 +0000382 case (long) SIG_ERR:
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200383 tprints("SIG_ERR");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000384 break;
Jan Kratochvil1f942712008-08-06 21:38:52 +0000385 case (long) SIG_DFL:
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200386 tprints("SIG_DFL");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000387 break;
Jan Kratochvil1f942712008-08-06 21:38:52 +0000388 case (long) SIG_IGN:
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200389 tprints("SIG_IGN");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000390 break;
391 default:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000392 tprintf("%#lx", tcp->u_arg[1]);
393 }
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000394 return 0;
395 }
Dmitry V. Levin21a75342008-09-03 01:22:18 +0000396 else if (!syserror(tcp)) {
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000397 switch (tcp->u_rval) {
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100398 case (long) SIG_ERR:
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000399 tcp->auxstr = "SIG_ERR"; break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100400 case (long) SIG_DFL:
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000401 tcp->auxstr = "SIG_DFL"; break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100402 case (long) SIG_IGN:
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000403 tcp->auxstr = "SIG_IGN"; break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100404 default:
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000405 tcp->auxstr = NULL;
406 }
407 return RVAL_HEX | RVAL_STR;
408 }
Dmitry V. Levin21a75342008-09-03 01:22:18 +0000409 return 0;
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000410}
411
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000412#endif /* HAVE_SIGACTION */
413
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000414int
Denys Vlasenko12014262011-05-30 14:00:14 +0200415sys_siggetmask(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000416{
417 if (exiting(tcp)) {
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000418 tcp->auxstr = sprintsigmask_val("mask ", tcp->u_rval);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000419 }
420 return RVAL_HEX | RVAL_STR;
421}
422
423int
Dmitry V. Levine5e60852009-12-31 22:50:49 +0000424sys_sigsuspend(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000425{
426 if (entering(tcp)) {
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000427 tprintsigmask_val("", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000428 }
429 return 0;
430}
431
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000432#ifdef HAVE_SIGACTION
433
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200434/* "Old" sigprocmask, which operates with word-sized signal masks */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000435int
Denys Vlasenko12014262011-05-30 14:00:14 +0200436sys_sigprocmask(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000437{
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200438# ifdef ALPHA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000439 if (entering(tcp)) {
Mike Frysingerdde045c2012-03-15 00:45:33 -0400440 /*
441 * Alpha/OSF is different: it doesn't pass in two pointers,
442 * but rather passes in the new bitmask as an argument and
443 * then returns the old bitmask. This "works" because we
444 * only have 64 signals to worry about. If you want more,
445 * use of the rt_sigprocmask syscall is required.
446 * Alpha:
447 * old = osf_sigprocmask(how, new);
448 * Everyone else:
449 * ret = sigprocmask(how, &new, &old, ...);
450 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000451 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000452 tprintsigmask_val(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000453 }
454 else if (!syserror(tcp)) {
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000455 tcp->auxstr = sprintsigmask_val("old mask ", tcp->u_rval);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000456 return RVAL_HEX | RVAL_STR;
457 }
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200458# else /* !ALPHA */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000459 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000460 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200461 tprints(", ");
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200462 print_sigset_addr_len(tcp, tcp->u_arg[1], current_wordsize);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200463 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000464 }
465 else {
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200466 if (syserror(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000467 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000468 else
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200469 print_sigset_addr_len(tcp, tcp->u_arg[2], current_wordsize);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000470 }
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200471# endif /* !ALPHA */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000472 return 0;
473}
474
475#endif /* HAVE_SIGACTION */
476
477int
Denys Vlasenko12014262011-05-30 14:00:14 +0200478sys_kill(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000479{
480 if (entering(tcp)) {
Denys Vlasenkoe015d2d2013-02-15 14:58:52 +0100481 tprintf("%ld, %s",
482 widen_to_long(tcp->u_arg[0]),
483 signame(tcp->u_arg[1])
484 );
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000485 }
486 return 0;
487}
488
Roland McGrath8ffc3522003-07-09 09:47:49 +0000489int
Denys Vlasenko12014262011-05-30 14:00:14 +0200490sys_tgkill(struct tcb *tcp)
Roland McGrath8ffc3522003-07-09 09:47:49 +0000491{
492 if (entering(tcp)) {
493 tprintf("%ld, %ld, %s",
Denys Vlasenkoe015d2d2013-02-15 14:58:52 +0100494 widen_to_long(tcp->u_arg[0]),
495 widen_to_long(tcp->u_arg[1]),
496 signame(tcp->u_arg[2])
497 );
Roland McGrath8ffc3522003-07-09 09:47:49 +0000498 }
499 return 0;
500}
Roland McGrath8ffc3522003-07-09 09:47:49 +0000501
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000502int
Denys Vlasenko12014262011-05-30 14:00:14 +0200503sys_sigpending(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000504{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000505 if (exiting(tcp)) {
506 if (syserror(tcp))
507 tprintf("%#lx", tcp->u_arg[0]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000508 else
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200509 print_sigset_addr_len(tcp, tcp->u_arg[0], current_wordsize);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000510 }
511 return 0;
512}
513
Denys Vlasenko12014262011-05-30 14:00:14 +0200514int
515sys_rt_sigprocmask(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000516{
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200517 /* Note: arg[3] is the length of the sigset. Kernel requires NSIG / 8 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000518 if (entering(tcp)) {
519 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200520 tprints(", ");
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200521 print_sigset_addr_len(tcp, tcp->u_arg[1], tcp->u_arg[3]);
522 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000523 }
524 else {
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200525 if (syserror(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000526 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000527 else
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200528 print_sigset_addr_len(tcp, tcp->u_arg[2], tcp->u_arg[3]);
Nate Sammonsdab325a1999-03-29 23:33:35 +0000529 tprintf(", %lu", tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000530 }
531 return 0;
532}
533
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000534/* Structure describing the action to be taken when a signal arrives. */
535struct new_sigaction
536{
Denys Vlasenko86d94842013-02-08 12:59:13 +0100537 /* sa_handler may be a libc #define, need to use other name: */
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800538#ifdef MIPS
539 unsigned int sa_flags;
540 void (*__sa_handler)(int);
541#else
Denys Vlasenko86d94842013-02-08 12:59:13 +0100542 void (*__sa_handler)(int);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000543 unsigned long sa_flags;
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800544#endif /* !MIPS */
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000545#if HAVE_SA_RESTORER
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100546 void (*sa_restorer)(void);
547#endif
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000548 /* Kernel treats sa_mask as an array of longs. */
549 unsigned long sa_mask[NSIG / sizeof(long) ? NSIG / sizeof(long) : 1];
550};
551/* Same for i386-on-x86_64 and similar cases */
552struct new_sigaction32
553{
554 uint32_t __sa_handler;
555 uint32_t sa_flags;
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000556#if HAVE_SA_RESTORER
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000557 uint32_t sa_restorer;
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100558#endif
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000559 uint32_t sa_mask[2 * (NSIG / sizeof(long) ? NSIG / sizeof(long) : 1)];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000560};
561
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000562static void
563decode_new_sigaction(struct tcb *tcp, long addr)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000564{
565 struct new_sigaction sa;
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000566 int r;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000567
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000568 if (!addr) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200569 tprints("NULL");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000570 return;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000571 }
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000572 if (!verbose(tcp) || (exiting(tcp) && syserror(tcp))) {
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000573 tprintf("%#lx", addr);
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000574 return;
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000575 }
Denys Vlasenkod4d3ede2013-02-13 16:31:32 +0100576#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
Denys Vlasenko9fd4f962012-03-19 09:36:42 +0100577 if (current_wordsize != sizeof(sa.sa_flags) && current_wordsize == 4) {
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000578 struct new_sigaction32 sa32;
579 r = umove(tcp, addr, &sa32);
580 if (r >= 0) {
581 memset(&sa, 0, sizeof(sa));
582 sa.__sa_handler = (void*)(unsigned long)sa32.__sa_handler;
583 sa.sa_flags = sa32.sa_flags;
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000584#if HAVE_SA_RESTORER && defined SA_RESTORER
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000585 sa.sa_restorer = (void*)(unsigned long)sa32.sa_restorer;
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100586#endif
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000587 /* Kernel treats sa_mask as an array of longs.
588 * For 32-bit process, "long" is uint32_t, thus, for example,
589 * 32th bit in sa_mask will end up as bit 0 in sa_mask[1].
590 * But for (64-bit) kernel, 32th bit in sa_mask is
591 * 32th bit in 0th (64-bit) long!
592 * For little-endian, it's the same.
593 * For big-endian, we swap 32-bit words.
594 */
595 sa.sa_mask[0] = sa32.sa_mask[0] + ((long)(sa32.sa_mask[1]) << 32);
596 }
597 } else
598#endif
599 {
600 r = umove(tcp, addr, &sa);
601 }
602 if (r < 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200603 tprints("{...}");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000604 return;
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000605 }
Carlos O'Donell4677c8a2009-09-09 18:13:19 +0000606 /* Architectures using function pointers, like
607 * hppa, may need to manipulate the function pointer
608 * to compute the result of a comparison. However,
Denys Vlasenko86d94842013-02-08 12:59:13 +0100609 * the __sa_handler function pointer exists only in
Carlos O'Donell4677c8a2009-09-09 18:13:19 +0000610 * the address space of the traced process, and can't
611 * be manipulated by strace. In order to prevent the
612 * compiler from generating code to manipulate
Denys Vlasenko86d94842013-02-08 12:59:13 +0100613 * __sa_handler we cast the function pointers to long. */
Carlos O'Donell4677c8a2009-09-09 18:13:19 +0000614 if ((long)sa.__sa_handler == (long)SIG_ERR)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200615 tprints("{SIG_ERR, ");
Carlos O'Donell4677c8a2009-09-09 18:13:19 +0000616 else if ((long)sa.__sa_handler == (long)SIG_DFL)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200617 tprints("{SIG_DFL, ");
Carlos O'Donell4677c8a2009-09-09 18:13:19 +0000618 else if ((long)sa.__sa_handler == (long)SIG_IGN)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200619 tprints("{SIG_IGN, ");
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000620 else
621 tprintf("{%#lx, ", (long) sa.__sa_handler);
Denys Vlasenko80b73a22013-07-18 10:10:46 +0200622 /*
623 * Sigset size is in tcp->u_arg[4] (SPARC)
624 * or in tcp->u_arg[3] (all other),
625 * but kernel won't handle sys_rt_sigaction
626 * with wrong sigset size (just returns EINVAL instead).
627 * We just fetch the right size, which is NSIG / 8.
628 */
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000629 tprintsigmask_val("", sa.sa_mask);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200630 tprints(", ");
Denys Vlasenko80b73a22013-07-18 10:10:46 +0200631
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000632 printflags(sigact_flags, sa.sa_flags, "SA_???");
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000633#if HAVE_SA_RESTORER && defined SA_RESTORER
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000634 if (sa.sa_flags & SA_RESTORER)
635 tprintf(", %p", sa.sa_restorer);
636#endif
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200637 tprints("}");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000638}
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000639
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000640int
641sys_rt_sigaction(struct tcb *tcp)
642{
643 if (entering(tcp)) {
644 printsignal(tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200645 tprints(", ");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000646 decode_new_sigaction(tcp, tcp->u_arg[1]);
647 tprints(", ");
648 } else {
649 decode_new_sigaction(tcp, tcp->u_arg[2]);
Denys Vlasenko9472a272013-02-12 11:43:46 +0100650#if defined(SPARC) || defined(SPARC64)
Wichert Akkermandacfb6e1999-06-03 14:21:07 +0000651 tprintf(", %#lx, %lu", tcp->u_arg[3], tcp->u_arg[4]);
652#elif defined(ALPHA)
653 tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]);
654#else
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000655 tprintf(", %lu", tcp->u_arg[3]);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +0000656#endif
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000657 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000658 return 0;
659}
660
Denys Vlasenko1d632462009-04-14 12:51:00 +0000661int
662sys_rt_sigpending(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000663{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000664 if (exiting(tcp)) {
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200665 /*
666 * One of the few syscalls where sigset size (arg[1])
667 * is allowed to be <= NSIG / 8, not strictly ==.
668 * This allows non-rt sigpending() syscall
669 * to reuse rt_sigpending() code in kernel.
670 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000671 if (syserror(tcp))
672 tprintf("%#lx", tcp->u_arg[0]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000673 else
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200674 print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[1]);
675 tprintf(", %lu", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000676 }
677 return 0;
678}
Denys Vlasenko1d632462009-04-14 12:51:00 +0000679
680int
681sys_rt_sigsuspend(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000682{
683 if (entering(tcp)) {
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200684 /* NB: kernel requires arg[1] == NSIG / 8 */
685 print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[1]);
686 tprintf(", %lu", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000687 }
688 return 0;
689}
Denys Vlasenko1d632462009-04-14 12:51:00 +0000690
Dmitry V. Levin297632b2012-03-13 15:51:13 +0000691static void
692print_sigqueueinfo(struct tcb *tcp, int sig, unsigned long uinfo)
693{
Dmitry V. Levin297632b2012-03-13 15:51:13 +0000694 printsignal(sig);
695 tprints(", ");
Denys Vlasenkod4d3ede2013-02-13 16:31:32 +0100696 printsiginfo_at(tcp, uinfo);
Dmitry V. Levin297632b2012-03-13 15:51:13 +0000697}
698
Denys Vlasenko1d632462009-04-14 12:51:00 +0000699int
700sys_rt_sigqueueinfo(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000701{
702 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000703 tprintf("%lu, ", tcp->u_arg[0]);
Dmitry V. Levin297632b2012-03-13 15:51:13 +0000704 print_sigqueueinfo(tcp, tcp->u_arg[1], tcp->u_arg[2]);
705 }
706 return 0;
707}
708
709int
710sys_rt_tgsigqueueinfo(struct tcb *tcp)
711{
712 if (entering(tcp)) {
713 tprintf("%lu, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
714 print_sigqueueinfo(tcp, tcp->u_arg[2], tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000715 }
716 return 0;
717}
718
Denys Vlasenko1d632462009-04-14 12:51:00 +0000719int sys_rt_sigtimedwait(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000720{
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200721 /* NB: kernel requires arg[3] == NSIG / 8 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000722 if (entering(tcp)) {
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200723 print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[3]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200724 tprints(", ");
Denys Vlasenkob1a78cf2009-04-15 13:31:59 +0000725 /* This is the only "return" parameter, */
726 if (tcp->u_arg[1] != 0)
727 return 0;
728 /* ... if it's NULL, can decode all on entry */
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200729 tprints("NULL, ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000730 }
Denys Vlasenkob1a78cf2009-04-15 13:31:59 +0000731 else if (tcp->u_arg[1] != 0) {
732 /* syscall exit, and u_arg[1] wasn't NULL */
Denys Vlasenkod4d3ede2013-02-13 16:31:32 +0100733 printsiginfo_at(tcp, tcp->u_arg[1]);
734 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000735 }
Denys Vlasenkob1a78cf2009-04-15 13:31:59 +0000736 else {
737 /* syscall exit, and u_arg[1] was NULL */
738 return 0;
739 }
740 print_timespec(tcp, tcp->u_arg[2]);
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200741 tprintf(", %lu", tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000742 return 0;
743};
744
Roland McGrath79dcd7a2006-01-12 22:34:50 +0000745int
Denys Vlasenko1d632462009-04-14 12:51:00 +0000746sys_restart_syscall(struct tcb *tcp)
Roland McGrath79dcd7a2006-01-12 22:34:50 +0000747{
Denys Vlasenko8497b622015-03-21 17:51:52 +0100748 if (entering(tcp)) {
749 tprintf("<... resuming interrupted %s ...>",
750 tcp->s_prev_ent
751 ? tcp->s_prev_ent->sys_name
752 : "system call"
753 );
754 }
Roland McGrath79dcd7a2006-01-12 22:34:50 +0000755 return 0;
756}
757
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000758static int
759do_signalfd(struct tcb *tcp, int flags_arg)
Roland McGrathf46ccd32007-08-02 01:15:59 +0000760{
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200761 /* NB: kernel requires arg[2] == NSIG / 8 */
Roland McGrathf46ccd32007-08-02 01:15:59 +0000762 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +0300763 printfd(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200764 tprints(", ");
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200765 print_sigset_addr_len(tcp, tcp->u_arg[1], tcp->u_arg[2]);
Dmitry V. Levin9d2ee3d2009-10-05 13:45:19 +0000766 tprintf(", %lu", tcp->u_arg[2]);
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000767 if (flags_arg >= 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200768 tprints(", ");
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000769 printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
770 }
Roland McGrathf46ccd32007-08-02 01:15:59 +0000771 }
772 return 0;
773}
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000774
775int
776sys_signalfd(struct tcb *tcp)
777{
778 return do_signalfd(tcp, -1);
779}
780
781int
782sys_signalfd4(struct tcb *tcp)
783{
784 return do_signalfd(tcp, 3);
785}