blob: c9e7518f92f28efacac3c17962a74593f356846b [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
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000252SYS_FUNC(sigsetmask)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000253{
254 if (entering(tcp)) {
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000255 tprintsigmask_val("", tcp->u_arg[0]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000256 }
257 else if (!syserror(tcp)) {
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000258 tcp->auxstr = sprintsigmask_val("old mask ", tcp->u_rval);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000259 return RVAL_HEX | RVAL_STR;
260 }
261 return 0;
262}
263
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000264#ifdef HAVE_SIGACTION
265
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000266struct old_sigaction {
Denys Vlasenko86d94842013-02-08 12:59:13 +0100267 /* sa_handler may be a libc #define, need to use other name: */
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800268#ifdef MIPS
269 unsigned int sa_flags;
270 void (*__sa_handler)(int);
271 /* Kernel treats sa_mask as an array of longs. */
272 unsigned long sa_mask[NSIG / sizeof(long) ? NSIG / sizeof(long) : 1];
273#else
Denys Vlasenko86d94842013-02-08 12:59:13 +0100274 void (*__sa_handler)(int);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000275 unsigned long sa_mask;
276 unsigned long sa_flags;
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800277#endif /* !MIPS */
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000278#if HAVE_SA_RESTORER
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100279 void (*sa_restorer)(void);
280#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000281};
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000282
Elliott Hughes458b3f22014-02-28 23:21:35 +0000283struct old_sigaction32 {
284 /* sa_handler may be a libc #define, need to use other name: */
285 uint32_t __sa_handler;
286 uint32_t sa_mask;
287 uint32_t sa_flags;
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000288#if HAVE_SA_RESTORER
Elliott Hughes458b3f22014-02-28 23:21:35 +0000289 uint32_t sa_restorer;
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100290#endif
Elliott Hughes458b3f22014-02-28 23:21:35 +0000291};
292
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000293static void
294decode_old_sigaction(struct tcb *tcp, long addr)
295{
296 struct old_sigaction sa;
Elliott Hughes458b3f22014-02-28 23:21:35 +0000297 int r;
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000298
299 if (!addr) {
300 tprints("NULL");
301 return;
302 }
303 if (!verbose(tcp) || (exiting(tcp) && syserror(tcp))) {
304 tprintf("%#lx", addr);
305 return;
306 }
Elliott Hughes458b3f22014-02-28 23:21:35 +0000307
308#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
309 if (current_wordsize != sizeof(sa.__sa_handler) && current_wordsize == 4) {
310 struct old_sigaction32 sa32;
311 r = umove(tcp, addr, &sa32);
312 if (r >= 0) {
313 memset(&sa, 0, sizeof(sa));
314 sa.__sa_handler = (void*)(uintptr_t)sa32.__sa_handler;
315 sa.sa_flags = sa32.sa_flags;
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000316#if HAVE_SA_RESTORER && defined SA_RESTORER
Elliott Hughes458b3f22014-02-28 23:21:35 +0000317 sa.sa_restorer = (void*)(uintptr_t)sa32.sa_restorer;
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100318#endif
Elliott Hughes458b3f22014-02-28 23:21:35 +0000319 sa.sa_mask = sa32.sa_mask;
320 }
321 } else
322#endif
323 {
324 r = umove(tcp, addr, &sa);
325 }
326 if (r < 0) {
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000327 tprints("{...}");
328 return;
329 }
330
331 /* Architectures using function pointers, like
332 * hppa, may need to manipulate the function pointer
333 * to compute the result of a comparison. However,
334 * the __sa_handler function pointer exists only in
335 * the address space of the traced process, and can't
336 * be manipulated by strace. In order to prevent the
337 * compiler from generating code to manipulate
338 * __sa_handler we cast the function pointers to long. */
339 if ((long)sa.__sa_handler == (long)SIG_ERR)
340 tprints("{SIG_ERR, ");
341 else if ((long)sa.__sa_handler == (long)SIG_DFL)
342 tprints("{SIG_DFL, ");
343 else if ((long)sa.__sa_handler == (long)SIG_IGN)
344 tprints("{SIG_IGN, ");
345 else
346 tprintf("{%#lx, ", (long) sa.__sa_handler);
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800347#ifdef MIPS
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000348 tprintsigmask_addr("", sa.sa_mask);
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800349#else
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000350 tprintsigmask_val("", sa.sa_mask);
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800351#endif
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000352 tprints(", ");
353 printflags(sigact_flags, sa.sa_flags, "SA_???");
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000354#if HAVE_SA_RESTORER && defined SA_RESTORER
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000355 if (sa.sa_flags & SA_RESTORER)
356 tprintf(", %p", sa.sa_restorer);
357#endif
358 tprints("}");
359}
360
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000361SYS_FUNC(sigaction)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000362{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000363 if (entering(tcp)) {
364 printsignal(tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200365 tprints(", ");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000366 decode_old_sigaction(tcp, tcp->u_arg[1]);
367 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000368 } else
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000369 decode_old_sigaction(tcp, tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000370 return 0;
371}
372
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000373SYS_FUNC(signal)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000374{
375 if (entering(tcp)) {
376 printsignal(tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200377 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000378 switch (tcp->u_arg[1]) {
Jan Kratochvil1f942712008-08-06 21:38:52 +0000379 case (long) SIG_ERR:
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200380 tprints("SIG_ERR");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000381 break;
Jan Kratochvil1f942712008-08-06 21:38:52 +0000382 case (long) SIG_DFL:
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200383 tprints("SIG_DFL");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000384 break;
Jan Kratochvil1f942712008-08-06 21:38:52 +0000385 case (long) SIG_IGN:
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200386 tprints("SIG_IGN");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000387 break;
388 default:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000389 tprintf("%#lx", tcp->u_arg[1]);
390 }
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000391 return 0;
392 }
Dmitry V. Levin21a75342008-09-03 01:22:18 +0000393 else if (!syserror(tcp)) {
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000394 switch (tcp->u_rval) {
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100395 case (long) SIG_ERR:
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000396 tcp->auxstr = "SIG_ERR"; break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100397 case (long) SIG_DFL:
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000398 tcp->auxstr = "SIG_DFL"; break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100399 case (long) SIG_IGN:
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000400 tcp->auxstr = "SIG_IGN"; break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100401 default:
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000402 tcp->auxstr = NULL;
403 }
404 return RVAL_HEX | RVAL_STR;
405 }
Dmitry V. Levin21a75342008-09-03 01:22:18 +0000406 return 0;
Wichert Akkerman16a03d22000-08-10 02:14:04 +0000407}
408
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000409#endif /* HAVE_SIGACTION */
410
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000411SYS_FUNC(siggetmask)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000412{
413 if (exiting(tcp)) {
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000414 tcp->auxstr = sprintsigmask_val("mask ", tcp->u_rval);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000415 }
416 return RVAL_HEX | RVAL_STR;
417}
418
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000419SYS_FUNC(sigsuspend)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000420{
421 if (entering(tcp)) {
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000422 tprintsigmask_val("", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000423 }
424 return 0;
425}
426
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000427#ifdef HAVE_SIGACTION
428
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200429/* "Old" sigprocmask, which operates with word-sized signal masks */
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000430SYS_FUNC(sigprocmask)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000431{
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200432# ifdef ALPHA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000433 if (entering(tcp)) {
Mike Frysingerdde045c2012-03-15 00:45:33 -0400434 /*
435 * Alpha/OSF is different: it doesn't pass in two pointers,
436 * but rather passes in the new bitmask as an argument and
437 * then returns the old bitmask. This "works" because we
438 * only have 64 signals to worry about. If you want more,
439 * use of the rt_sigprocmask syscall is required.
440 * Alpha:
441 * old = osf_sigprocmask(how, new);
442 * Everyone else:
443 * ret = sigprocmask(how, &new, &old, ...);
444 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000445 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000446 tprintsigmask_val(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000447 }
448 else if (!syserror(tcp)) {
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000449 tcp->auxstr = sprintsigmask_val("old mask ", tcp->u_rval);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000450 return RVAL_HEX | RVAL_STR;
451 }
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200452# else /* !ALPHA */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000453 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000454 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200455 tprints(", ");
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200456 print_sigset_addr_len(tcp, tcp->u_arg[1], current_wordsize);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200457 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000458 }
459 else {
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200460 if (syserror(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000461 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000462 else
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200463 print_sigset_addr_len(tcp, tcp->u_arg[2], current_wordsize);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000464 }
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200465# endif /* !ALPHA */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000466 return 0;
467}
468
469#endif /* HAVE_SIGACTION */
470
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000471SYS_FUNC(kill)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000472{
473 if (entering(tcp)) {
Denys Vlasenkoe015d2d2013-02-15 14:58:52 +0100474 tprintf("%ld, %s",
475 widen_to_long(tcp->u_arg[0]),
476 signame(tcp->u_arg[1])
477 );
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000478 }
479 return 0;
480}
481
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000482SYS_FUNC(tgkill)
Roland McGrath8ffc3522003-07-09 09:47:49 +0000483{
484 if (entering(tcp)) {
485 tprintf("%ld, %ld, %s",
Denys Vlasenkoe015d2d2013-02-15 14:58:52 +0100486 widen_to_long(tcp->u_arg[0]),
487 widen_to_long(tcp->u_arg[1]),
488 signame(tcp->u_arg[2])
489 );
Roland McGrath8ffc3522003-07-09 09:47:49 +0000490 }
491 return 0;
492}
Roland McGrath8ffc3522003-07-09 09:47:49 +0000493
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000494SYS_FUNC(sigpending)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000495{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000496 if (exiting(tcp)) {
497 if (syserror(tcp))
498 tprintf("%#lx", tcp->u_arg[0]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000499 else
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200500 print_sigset_addr_len(tcp, tcp->u_arg[0], current_wordsize);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000501 }
502 return 0;
503}
504
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000505SYS_FUNC(rt_sigprocmask)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000506{
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200507 /* Note: arg[3] is the length of the sigset. Kernel requires NSIG / 8 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000508 if (entering(tcp)) {
509 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200510 tprints(", ");
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200511 print_sigset_addr_len(tcp, tcp->u_arg[1], tcp->u_arg[3]);
512 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000513 }
514 else {
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200515 if (syserror(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000516 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000517 else
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200518 print_sigset_addr_len(tcp, tcp->u_arg[2], tcp->u_arg[3]);
Nate Sammonsdab325a1999-03-29 23:33:35 +0000519 tprintf(", %lu", tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000520 }
521 return 0;
522}
523
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000524/* Structure describing the action to be taken when a signal arrives. */
525struct new_sigaction
526{
Denys Vlasenko86d94842013-02-08 12:59:13 +0100527 /* sa_handler may be a libc #define, need to use other name: */
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800528#ifdef MIPS
529 unsigned int sa_flags;
530 void (*__sa_handler)(int);
531#else
Denys Vlasenko86d94842013-02-08 12:59:13 +0100532 void (*__sa_handler)(int);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000533 unsigned long sa_flags;
Chris Dearman2b4bb1c2013-12-09 19:58:42 -0800534#endif /* !MIPS */
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000535#if HAVE_SA_RESTORER
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100536 void (*sa_restorer)(void);
537#endif
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000538 /* Kernel treats sa_mask as an array of longs. */
539 unsigned long sa_mask[NSIG / sizeof(long) ? NSIG / sizeof(long) : 1];
540};
541/* Same for i386-on-x86_64 and similar cases */
542struct new_sigaction32
543{
544 uint32_t __sa_handler;
545 uint32_t sa_flags;
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000546#if HAVE_SA_RESTORER
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000547 uint32_t sa_restorer;
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100548#endif
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000549 uint32_t sa_mask[2 * (NSIG / sizeof(long) ? NSIG / sizeof(long) : 1)];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000550};
551
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000552static void
553decode_new_sigaction(struct tcb *tcp, long addr)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000554{
555 struct new_sigaction sa;
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000556 int r;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000557
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000558 if (!addr) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200559 tprints("NULL");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000560 return;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000561 }
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000562 if (!verbose(tcp) || (exiting(tcp) && syserror(tcp))) {
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000563 tprintf("%#lx", addr);
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000564 return;
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000565 }
Denys Vlasenkod4d3ede2013-02-13 16:31:32 +0100566#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
Denys Vlasenko9fd4f962012-03-19 09:36:42 +0100567 if (current_wordsize != sizeof(sa.sa_flags) && current_wordsize == 4) {
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000568 struct new_sigaction32 sa32;
569 r = umove(tcp, addr, &sa32);
570 if (r >= 0) {
571 memset(&sa, 0, sizeof(sa));
572 sa.__sa_handler = (void*)(unsigned long)sa32.__sa_handler;
573 sa.sa_flags = sa32.sa_flags;
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000574#if HAVE_SA_RESTORER && defined SA_RESTORER
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000575 sa.sa_restorer = (void*)(unsigned long)sa32.sa_restorer;
Vicente Olivert Rierac3a5c012014-09-11 20:05:18 +0100576#endif
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000577 /* Kernel treats sa_mask as an array of longs.
578 * For 32-bit process, "long" is uint32_t, thus, for example,
579 * 32th bit in sa_mask will end up as bit 0 in sa_mask[1].
580 * But for (64-bit) kernel, 32th bit in sa_mask is
581 * 32th bit in 0th (64-bit) long!
582 * For little-endian, it's the same.
583 * For big-endian, we swap 32-bit words.
584 */
585 sa.sa_mask[0] = sa32.sa_mask[0] + ((long)(sa32.sa_mask[1]) << 32);
586 }
587 } else
588#endif
589 {
590 r = umove(tcp, addr, &sa);
591 }
592 if (r < 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200593 tprints("{...}");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000594 return;
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000595 }
Carlos O'Donell4677c8a2009-09-09 18:13:19 +0000596 /* Architectures using function pointers, like
597 * hppa, may need to manipulate the function pointer
598 * to compute the result of a comparison. However,
Denys Vlasenko86d94842013-02-08 12:59:13 +0100599 * the __sa_handler function pointer exists only in
Carlos O'Donell4677c8a2009-09-09 18:13:19 +0000600 * the address space of the traced process, and can't
601 * be manipulated by strace. In order to prevent the
602 * compiler from generating code to manipulate
Denys Vlasenko86d94842013-02-08 12:59:13 +0100603 * __sa_handler we cast the function pointers to long. */
Carlos O'Donell4677c8a2009-09-09 18:13:19 +0000604 if ((long)sa.__sa_handler == (long)SIG_ERR)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200605 tprints("{SIG_ERR, ");
Carlos O'Donell4677c8a2009-09-09 18:13:19 +0000606 else if ((long)sa.__sa_handler == (long)SIG_DFL)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200607 tprints("{SIG_DFL, ");
Carlos O'Donell4677c8a2009-09-09 18:13:19 +0000608 else if ((long)sa.__sa_handler == (long)SIG_IGN)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200609 tprints("{SIG_IGN, ");
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000610 else
611 tprintf("{%#lx, ", (long) sa.__sa_handler);
Denys Vlasenko80b73a22013-07-18 10:10:46 +0200612 /*
613 * Sigset size is in tcp->u_arg[4] (SPARC)
614 * or in tcp->u_arg[3] (all other),
615 * but kernel won't handle sys_rt_sigaction
616 * with wrong sigset size (just returns EINVAL instead).
617 * We just fetch the right size, which is NSIG / 8.
618 */
Dmitry V. Levin38593e92014-02-26 16:51:28 +0000619 tprintsigmask_val("", sa.sa_mask);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200620 tprints(", ");
Denys Vlasenko80b73a22013-07-18 10:10:46 +0200621
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000622 printflags(sigact_flags, sa.sa_flags, "SA_???");
Dmitry V. Levin24b8eb02015-02-28 17:17:09 +0000623#if HAVE_SA_RESTORER && defined SA_RESTORER
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000624 if (sa.sa_flags & SA_RESTORER)
625 tprintf(", %p", sa.sa_restorer);
626#endif
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200627 tprints("}");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000628}
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000629
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000630SYS_FUNC(rt_sigaction)
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000631{
632 if (entering(tcp)) {
633 printsignal(tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200634 tprints(", ");
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000635 decode_new_sigaction(tcp, tcp->u_arg[1]);
636 tprints(", ");
637 } else {
638 decode_new_sigaction(tcp, tcp->u_arg[2]);
Denys Vlasenko9472a272013-02-12 11:43:46 +0100639#if defined(SPARC) || defined(SPARC64)
Wichert Akkermandacfb6e1999-06-03 14:21:07 +0000640 tprintf(", %#lx, %lu", tcp->u_arg[3], tcp->u_arg[4]);
641#elif defined(ALPHA)
642 tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]);
643#else
Denys Vlasenko7a862d72009-04-15 13:22:59 +0000644 tprintf(", %lu", tcp->u_arg[3]);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +0000645#endif
Dmitry V. Levinac655a82014-01-07 22:41:30 +0000646 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000647 return 0;
648}
649
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000650SYS_FUNC(rt_sigpending)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000651{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000652 if (exiting(tcp)) {
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200653 /*
654 * One of the few syscalls where sigset size (arg[1])
655 * is allowed to be <= NSIG / 8, not strictly ==.
656 * This allows non-rt sigpending() syscall
657 * to reuse rt_sigpending() code in kernel.
658 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000659 if (syserror(tcp))
660 tprintf("%#lx", tcp->u_arg[0]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000661 else
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200662 print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[1]);
663 tprintf(", %lu", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000664 }
665 return 0;
666}
Denys Vlasenko1d632462009-04-14 12:51:00 +0000667
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000668SYS_FUNC(rt_sigsuspend)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000669{
670 if (entering(tcp)) {
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200671 /* NB: kernel requires arg[1] == NSIG / 8 */
672 print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[1]);
673 tprintf(", %lu", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000674 }
675 return 0;
676}
Denys Vlasenko1d632462009-04-14 12:51:00 +0000677
Dmitry V. Levin297632b2012-03-13 15:51:13 +0000678static void
679print_sigqueueinfo(struct tcb *tcp, int sig, unsigned long uinfo)
680{
Dmitry V. Levin297632b2012-03-13 15:51:13 +0000681 printsignal(sig);
682 tprints(", ");
Denys Vlasenkod4d3ede2013-02-13 16:31:32 +0100683 printsiginfo_at(tcp, uinfo);
Dmitry V. Levin297632b2012-03-13 15:51:13 +0000684}
685
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000686SYS_FUNC(rt_sigqueueinfo)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000687{
688 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000689 tprintf("%lu, ", tcp->u_arg[0]);
Dmitry V. Levin297632b2012-03-13 15:51:13 +0000690 print_sigqueueinfo(tcp, tcp->u_arg[1], tcp->u_arg[2]);
691 }
692 return 0;
693}
694
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000695SYS_FUNC(rt_tgsigqueueinfo)
Dmitry V. Levin297632b2012-03-13 15:51:13 +0000696{
697 if (entering(tcp)) {
698 tprintf("%lu, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
699 print_sigqueueinfo(tcp, tcp->u_arg[2], tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000700 }
701 return 0;
702}
703
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000704SYS_FUNC(rt_sigtimedwait)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000705{
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200706 /* NB: kernel requires arg[3] == NSIG / 8 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000707 if (entering(tcp)) {
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200708 print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[3]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200709 tprints(", ");
Denys Vlasenkob1a78cf2009-04-15 13:31:59 +0000710 /* This is the only "return" parameter, */
711 if (tcp->u_arg[1] != 0)
712 return 0;
713 /* ... if it's NULL, can decode all on entry */
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200714 tprints("NULL, ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000715 }
Denys Vlasenkob1a78cf2009-04-15 13:31:59 +0000716 else if (tcp->u_arg[1] != 0) {
717 /* syscall exit, and u_arg[1] wasn't NULL */
Denys Vlasenkod4d3ede2013-02-13 16:31:32 +0100718 printsiginfo_at(tcp, tcp->u_arg[1]);
719 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000720 }
Denys Vlasenkob1a78cf2009-04-15 13:31:59 +0000721 else {
722 /* syscall exit, and u_arg[1] was NULL */
723 return 0;
724 }
725 print_timespec(tcp, tcp->u_arg[2]);
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200726 tprintf(", %lu", tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000727 return 0;
728};
729
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000730SYS_FUNC(restart_syscall)
Roland McGrath79dcd7a2006-01-12 22:34:50 +0000731{
Denys Vlasenko8497b622015-03-21 17:51:52 +0100732 if (entering(tcp)) {
733 tprintf("<... resuming interrupted %s ...>",
734 tcp->s_prev_ent
735 ? tcp->s_prev_ent->sys_name
736 : "system call"
737 );
738 }
Roland McGrath79dcd7a2006-01-12 22:34:50 +0000739 return 0;
740}
741
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000742static int
743do_signalfd(struct tcb *tcp, int flags_arg)
Roland McGrathf46ccd32007-08-02 01:15:59 +0000744{
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200745 /* NB: kernel requires arg[2] == NSIG / 8 */
Roland McGrathf46ccd32007-08-02 01:15:59 +0000746 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +0300747 printfd(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200748 tprints(", ");
Denys Vlasenko5e133aa2013-07-18 17:02:21 +0200749 print_sigset_addr_len(tcp, tcp->u_arg[1], tcp->u_arg[2]);
Dmitry V. Levin9d2ee3d2009-10-05 13:45:19 +0000750 tprintf(", %lu", tcp->u_arg[2]);
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000751 if (flags_arg >= 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200752 tprints(", ");
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000753 printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
754 }
Roland McGrathf46ccd32007-08-02 01:15:59 +0000755 }
756 return 0;
757}
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000758
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000759SYS_FUNC(signalfd)
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000760{
761 return do_signalfd(tcp, -1);
762}
763
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000764SYS_FUNC(signalfd4)
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000765{
766 return do_signalfd(tcp, 3);
767}