xref: /aosp_15_r20/external/strace/signal.c (revision cf84ac9a129d8ea9952db616b4e9b904c4bdde56)
1*cf84ac9aSAndroid Build Coastguard Worker /*
2*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 1991, 1992 Paul Kranenburg <[email protected]>
3*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 1993 Branko Lankester <[email protected]>
4*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <[email protected]>
5*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 1996-1999 Wichert Akkerman <[email protected]>
6*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7*cf84ac9aSAndroid Build Coastguard Worker  *                     Linux for s390 port by D.J. Barrow
8*cf84ac9aSAndroid Build Coastguard Worker  *                    <[email protected],[email protected]>
9*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 2001-2018 The strace developers.
10*cf84ac9aSAndroid Build Coastguard Worker  * All rights reserved.
11*cf84ac9aSAndroid Build Coastguard Worker  *
12*cf84ac9aSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
13*cf84ac9aSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
14*cf84ac9aSAndroid Build Coastguard Worker  * are met:
15*cf84ac9aSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
16*cf84ac9aSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
17*cf84ac9aSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
18*cf84ac9aSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
19*cf84ac9aSAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
20*cf84ac9aSAndroid Build Coastguard Worker  * 3. The name of the author may not be used to endorse or promote products
21*cf84ac9aSAndroid Build Coastguard Worker  *    derived from this software without specific prior written permission.
22*cf84ac9aSAndroid Build Coastguard Worker  *
23*cf84ac9aSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24*cf84ac9aSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25*cf84ac9aSAndroid Build Coastguard Worker  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26*cf84ac9aSAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27*cf84ac9aSAndroid Build Coastguard Worker  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28*cf84ac9aSAndroid Build Coastguard Worker  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29*cf84ac9aSAndroid Build Coastguard Worker  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30*cf84ac9aSAndroid Build Coastguard Worker  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31*cf84ac9aSAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32*cf84ac9aSAndroid Build Coastguard Worker  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*cf84ac9aSAndroid Build Coastguard Worker  */
34*cf84ac9aSAndroid Build Coastguard Worker 
35*cf84ac9aSAndroid Build Coastguard Worker #include "defs.h"
36*cf84ac9aSAndroid Build Coastguard Worker #include "nsig.h"
37*cf84ac9aSAndroid Build Coastguard Worker #include "xstring.h"
38*cf84ac9aSAndroid Build Coastguard Worker 
39*cf84ac9aSAndroid Build Coastguard Worker /* The libc headers do not define this constant since it should only be
40*cf84ac9aSAndroid Build Coastguard Worker    used by the implementation.  So we define it here.  */
41*cf84ac9aSAndroid Build Coastguard Worker #ifndef SA_RESTORER
42*cf84ac9aSAndroid Build Coastguard Worker # ifdef ASM_SA_RESTORER
43*cf84ac9aSAndroid Build Coastguard Worker #  define SA_RESTORER ASM_SA_RESTORER
44*cf84ac9aSAndroid Build Coastguard Worker # endif
45*cf84ac9aSAndroid Build Coastguard Worker #endif
46*cf84ac9aSAndroid Build Coastguard Worker 
47*cf84ac9aSAndroid Build Coastguard Worker /*
48*cf84ac9aSAndroid Build Coastguard Worker  * Some architectures define SA_RESTORER in their headers,
49*cf84ac9aSAndroid Build Coastguard Worker  * but do not actually have sa_restorer.
50*cf84ac9aSAndroid Build Coastguard Worker  *
51*cf84ac9aSAndroid Build Coastguard Worker  * Some architectures, otherwise, do not define SA_RESTORER in their headers,
52*cf84ac9aSAndroid Build Coastguard Worker  * but actually have sa_restorer.
53*cf84ac9aSAndroid Build Coastguard Worker  */
54*cf84ac9aSAndroid Build Coastguard Worker #ifdef HAVE_ARCH_SA_RESTORER
55*cf84ac9aSAndroid Build Coastguard Worker # define HAVE_SA_RESTORER HAVE_ARCH_SA_RESTORER
56*cf84ac9aSAndroid Build Coastguard Worker #else /* !HAVE_ARCH_SA_RESTORER */
57*cf84ac9aSAndroid Build Coastguard Worker # ifdef SA_RESTORER
58*cf84ac9aSAndroid Build Coastguard Worker #  define HAVE_SA_RESTORER 1
59*cf84ac9aSAndroid Build Coastguard Worker # else
60*cf84ac9aSAndroid Build Coastguard Worker #  define HAVE_SA_RESTORER 0
61*cf84ac9aSAndroid Build Coastguard Worker # endif
62*cf84ac9aSAndroid Build Coastguard Worker #endif /* HAVE_ARCH_SA_RESTORER */
63*cf84ac9aSAndroid Build Coastguard Worker 
64*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/sa_handler_values.h"
65*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/sigact_flags.h"
66*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/sigprocmaskcmds.h"
67*cf84ac9aSAndroid Build Coastguard Worker 
68*cf84ac9aSAndroid Build Coastguard Worker /* Anonymous realtime signals. */
69*cf84ac9aSAndroid Build Coastguard Worker #ifndef ASM_SIGRTMIN
70*cf84ac9aSAndroid Build Coastguard Worker /* Linux kernel >= 3.18 defines SIGRTMIN to 32 on all architectures. */
71*cf84ac9aSAndroid Build Coastguard Worker # define ASM_SIGRTMIN 32
72*cf84ac9aSAndroid Build Coastguard Worker #endif
73*cf84ac9aSAndroid Build Coastguard Worker #ifndef ASM_SIGRTMAX
74*cf84ac9aSAndroid Build Coastguard Worker /* Under glibc 2.1, SIGRTMAX et al are functions, but __SIGRTMAX is a
75*cf84ac9aSAndroid Build Coastguard Worker    constant.  This is what we want.  Otherwise, just use SIGRTMAX. */
76*cf84ac9aSAndroid Build Coastguard Worker # ifdef SIGRTMAX
77*cf84ac9aSAndroid Build Coastguard Worker #  ifndef __SIGRTMAX
78*cf84ac9aSAndroid Build Coastguard Worker #   define __SIGRTMAX SIGRTMAX
79*cf84ac9aSAndroid Build Coastguard Worker #  endif
80*cf84ac9aSAndroid Build Coastguard Worker # endif
81*cf84ac9aSAndroid Build Coastguard Worker # ifdef __SIGRTMAX
82*cf84ac9aSAndroid Build Coastguard Worker #  define ASM_SIGRTMAX __SIGRTMAX
83*cf84ac9aSAndroid Build Coastguard Worker # endif
84*cf84ac9aSAndroid Build Coastguard Worker #endif
85*cf84ac9aSAndroid Build Coastguard Worker 
86*cf84ac9aSAndroid Build Coastguard Worker /* Note on the size of sigset_t:
87*cf84ac9aSAndroid Build Coastguard Worker  *
88*cf84ac9aSAndroid Build Coastguard Worker  * In glibc, sigset_t is an array with space for 1024 bits (!),
89*cf84ac9aSAndroid Build Coastguard Worker  * even though all arches supported by Linux have only 64 signals
90*cf84ac9aSAndroid Build Coastguard Worker  * except MIPS, which has 128. IOW, it is 128 bytes long.
91*cf84ac9aSAndroid Build Coastguard Worker  *
92*cf84ac9aSAndroid Build Coastguard Worker  * In-kernel sigset_t is sized correctly (it is either 64 or 128 bit long).
93*cf84ac9aSAndroid Build Coastguard Worker  * However, some old syscall return only 32 lower bits (one word).
94*cf84ac9aSAndroid Build Coastguard Worker  * Example: sys_sigpending vs sys_rt_sigpending.
95*cf84ac9aSAndroid Build Coastguard Worker  *
96*cf84ac9aSAndroid Build Coastguard Worker  * Be aware of this fact when you try to
97*cf84ac9aSAndroid Build Coastguard Worker  *     memcpy(&tcp->u_arg[1], &something, sizeof(sigset_t))
98*cf84ac9aSAndroid Build Coastguard Worker  * - sizeof(sigset_t) is much bigger than you think,
99*cf84ac9aSAndroid Build Coastguard Worker  * it may overflow tcp->u_arg[] array, and it may try to copy more data
100*cf84ac9aSAndroid Build Coastguard Worker  * than is really available in <something>.
101*cf84ac9aSAndroid Build Coastguard Worker  * Similarly,
102*cf84ac9aSAndroid Build Coastguard Worker  *     umoven(tcp, addr, sizeof(sigset_t), &sigset)
103*cf84ac9aSAndroid Build Coastguard Worker  * may be a bad idea: it'll try to read much more data than needed
104*cf84ac9aSAndroid Build Coastguard Worker  * to fetch a sigset_t.
105*cf84ac9aSAndroid Build Coastguard Worker  * Use NSIG_BYTES as a size instead.
106*cf84ac9aSAndroid Build Coastguard Worker  */
107*cf84ac9aSAndroid Build Coastguard Worker 
108*cf84ac9aSAndroid Build Coastguard Worker static const char *
get_sa_handler_str(kernel_ulong_t handler)109*cf84ac9aSAndroid Build Coastguard Worker get_sa_handler_str(kernel_ulong_t handler)
110*cf84ac9aSAndroid Build Coastguard Worker {
111*cf84ac9aSAndroid Build Coastguard Worker 	return xlookup(sa_handler_values, handler);
112*cf84ac9aSAndroid Build Coastguard Worker }
113*cf84ac9aSAndroid Build Coastguard Worker 
114*cf84ac9aSAndroid Build Coastguard Worker static void
print_sa_handler(kernel_ulong_t handler)115*cf84ac9aSAndroid Build Coastguard Worker print_sa_handler(kernel_ulong_t handler)
116*cf84ac9aSAndroid Build Coastguard Worker {
117*cf84ac9aSAndroid Build Coastguard Worker 	const char *sa_handler_str = get_sa_handler_str(handler);
118*cf84ac9aSAndroid Build Coastguard Worker 
119*cf84ac9aSAndroid Build Coastguard Worker 	if (sa_handler_str)
120*cf84ac9aSAndroid Build Coastguard Worker 		print_xlat_ex(handler, sa_handler_str, XLAT_STYLE_DEFAULT);
121*cf84ac9aSAndroid Build Coastguard Worker 	else
122*cf84ac9aSAndroid Build Coastguard Worker 		printaddr(handler);
123*cf84ac9aSAndroid Build Coastguard Worker }
124*cf84ac9aSAndroid Build Coastguard Worker 
125*cf84ac9aSAndroid Build Coastguard Worker const char *
signame(const int sig)126*cf84ac9aSAndroid Build Coastguard Worker signame(const int sig)
127*cf84ac9aSAndroid Build Coastguard Worker {
128*cf84ac9aSAndroid Build Coastguard Worker 	static char buf[sizeof("SIGRT_%u") + sizeof(int)*3];
129*cf84ac9aSAndroid Build Coastguard Worker 
130*cf84ac9aSAndroid Build Coastguard Worker 	if (sig >= 0) {
131*cf84ac9aSAndroid Build Coastguard Worker 		const unsigned int s = sig;
132*cf84ac9aSAndroid Build Coastguard Worker 
133*cf84ac9aSAndroid Build Coastguard Worker 		if (s < nsignals)
134*cf84ac9aSAndroid Build Coastguard Worker 			return signalent[s];
135*cf84ac9aSAndroid Build Coastguard Worker #ifdef ASM_SIGRTMAX
136*cf84ac9aSAndroid Build Coastguard Worker 		if (s >= ASM_SIGRTMIN && s <= (unsigned int) ASM_SIGRTMAX) {
137*cf84ac9aSAndroid Build Coastguard Worker 			xsprintf(buf, "SIGRT_%u", s - ASM_SIGRTMIN);
138*cf84ac9aSAndroid Build Coastguard Worker 			return buf;
139*cf84ac9aSAndroid Build Coastguard Worker 		}
140*cf84ac9aSAndroid Build Coastguard Worker #endif
141*cf84ac9aSAndroid Build Coastguard Worker 	}
142*cf84ac9aSAndroid Build Coastguard Worker 	xsprintf(buf, "%d", sig);
143*cf84ac9aSAndroid Build Coastguard Worker 	return buf;
144*cf84ac9aSAndroid Build Coastguard Worker }
145*cf84ac9aSAndroid Build Coastguard Worker 
146*cf84ac9aSAndroid Build Coastguard Worker static unsigned int
popcount32(const uint32_t * a,unsigned int size)147*cf84ac9aSAndroid Build Coastguard Worker popcount32(const uint32_t *a, unsigned int size)
148*cf84ac9aSAndroid Build Coastguard Worker {
149*cf84ac9aSAndroid Build Coastguard Worker 	unsigned int count = 0;
150*cf84ac9aSAndroid Build Coastguard Worker 
151*cf84ac9aSAndroid Build Coastguard Worker 	for (; size; ++a, --size) {
152*cf84ac9aSAndroid Build Coastguard Worker 		uint32_t x = *a;
153*cf84ac9aSAndroid Build Coastguard Worker 
154*cf84ac9aSAndroid Build Coastguard Worker #ifdef HAVE___BUILTIN_POPCOUNT
155*cf84ac9aSAndroid Build Coastguard Worker 		count += __builtin_popcount(x);
156*cf84ac9aSAndroid Build Coastguard Worker #else
157*cf84ac9aSAndroid Build Coastguard Worker 		for (; x; ++count)
158*cf84ac9aSAndroid Build Coastguard Worker 			x &= x - 1;
159*cf84ac9aSAndroid Build Coastguard Worker #endif
160*cf84ac9aSAndroid Build Coastguard Worker 	}
161*cf84ac9aSAndroid Build Coastguard Worker 
162*cf84ac9aSAndroid Build Coastguard Worker 	return count;
163*cf84ac9aSAndroid Build Coastguard Worker }
164*cf84ac9aSAndroid Build Coastguard Worker 
165*cf84ac9aSAndroid Build Coastguard Worker const char *
sprintsigmask_n(const char * prefix,const void * sig_mask,unsigned int bytes)166*cf84ac9aSAndroid Build Coastguard Worker sprintsigmask_n(const char *prefix, const void *sig_mask, unsigned int bytes)
167*cf84ac9aSAndroid Build Coastguard Worker {
168*cf84ac9aSAndroid Build Coastguard Worker 	/*
169*cf84ac9aSAndroid Build Coastguard Worker 	 * The maximum number of signal names to be printed
170*cf84ac9aSAndroid Build Coastguard Worker 	 * is NSIG_BYTES * 8 * 2 / 3.
171*cf84ac9aSAndroid Build Coastguard Worker 	 * Most of signal names have length 7,
172*cf84ac9aSAndroid Build Coastguard Worker 	 * average length of signal names is less than 7.
173*cf84ac9aSAndroid Build Coastguard Worker 	 * The length of prefix string does not exceed 16.
174*cf84ac9aSAndroid Build Coastguard Worker 	 */
175*cf84ac9aSAndroid Build Coastguard Worker 	static char outstr[128 + 8 * (NSIG_BYTES * 8 * 2 / 3)];
176*cf84ac9aSAndroid Build Coastguard Worker 
177*cf84ac9aSAndroid Build Coastguard Worker 	char *s;
178*cf84ac9aSAndroid Build Coastguard Worker 	const uint32_t *mask;
179*cf84ac9aSAndroid Build Coastguard Worker 	uint32_t inverted_mask[NSIG_BYTES / 4];
180*cf84ac9aSAndroid Build Coastguard Worker 	unsigned int size;
181*cf84ac9aSAndroid Build Coastguard Worker 	int i;
182*cf84ac9aSAndroid Build Coastguard Worker 	char sep;
183*cf84ac9aSAndroid Build Coastguard Worker 
184*cf84ac9aSAndroid Build Coastguard Worker 	s = stpcpy(outstr, prefix);
185*cf84ac9aSAndroid Build Coastguard Worker 
186*cf84ac9aSAndroid Build Coastguard Worker 	mask = sig_mask;
187*cf84ac9aSAndroid Build Coastguard Worker 	/* length of signal mask in 4-byte words */
188*cf84ac9aSAndroid Build Coastguard Worker 	size = (bytes >= NSIG_BYTES) ? NSIG_BYTES / 4 : (bytes + 3) / 4;
189*cf84ac9aSAndroid Build Coastguard Worker 
190*cf84ac9aSAndroid Build Coastguard Worker 	/* check whether 2/3 or more bits are set */
191*cf84ac9aSAndroid Build Coastguard Worker 	if (popcount32(mask, size) >= size * (4 * 8) * 2 / 3) {
192*cf84ac9aSAndroid Build Coastguard Worker 		/* show those signals that are NOT in the mask */
193*cf84ac9aSAndroid Build Coastguard Worker 		unsigned int j;
194*cf84ac9aSAndroid Build Coastguard Worker 		for (j = 0; j < size; ++j)
195*cf84ac9aSAndroid Build Coastguard Worker 			inverted_mask[j] = ~mask[j];
196*cf84ac9aSAndroid Build Coastguard Worker 		mask = inverted_mask;
197*cf84ac9aSAndroid Build Coastguard Worker 		*s++ = '~';
198*cf84ac9aSAndroid Build Coastguard Worker 	}
199*cf84ac9aSAndroid Build Coastguard Worker 
200*cf84ac9aSAndroid Build Coastguard Worker 	sep = '[';
201*cf84ac9aSAndroid Build Coastguard Worker 	for (i = 0; (i = next_set_bit(mask, i, size * (4 * 8))) >= 0; ) {
202*cf84ac9aSAndroid Build Coastguard Worker 		++i;
203*cf84ac9aSAndroid Build Coastguard Worker 		*s++ = sep;
204*cf84ac9aSAndroid Build Coastguard Worker 		if ((unsigned) i < nsignals) {
205*cf84ac9aSAndroid Build Coastguard Worker 			s = stpcpy(s, signalent[i] + 3);
206*cf84ac9aSAndroid Build Coastguard Worker 		}
207*cf84ac9aSAndroid Build Coastguard Worker #ifdef ASM_SIGRTMAX
208*cf84ac9aSAndroid Build Coastguard Worker 		else if (i >= ASM_SIGRTMIN && i <= ASM_SIGRTMAX) {
209*cf84ac9aSAndroid Build Coastguard Worker 			s = xappendstr(outstr, s, "RT_%u", i - ASM_SIGRTMIN);
210*cf84ac9aSAndroid Build Coastguard Worker 		}
211*cf84ac9aSAndroid Build Coastguard Worker #endif
212*cf84ac9aSAndroid Build Coastguard Worker 		else {
213*cf84ac9aSAndroid Build Coastguard Worker 			s = xappendstr(outstr, s, "%u", i);
214*cf84ac9aSAndroid Build Coastguard Worker 		}
215*cf84ac9aSAndroid Build Coastguard Worker 		sep = ' ';
216*cf84ac9aSAndroid Build Coastguard Worker 	}
217*cf84ac9aSAndroid Build Coastguard Worker 	if (sep == '[')
218*cf84ac9aSAndroid Build Coastguard Worker 		*s++ = sep;
219*cf84ac9aSAndroid Build Coastguard Worker 	*s++ = ']';
220*cf84ac9aSAndroid Build Coastguard Worker 	*s = '\0';
221*cf84ac9aSAndroid Build Coastguard Worker 	return outstr;
222*cf84ac9aSAndroid Build Coastguard Worker }
223*cf84ac9aSAndroid Build Coastguard Worker 
224*cf84ac9aSAndroid Build Coastguard Worker #define sprintsigmask_val(prefix, mask) \
225*cf84ac9aSAndroid Build Coastguard Worker 	sprintsigmask_n((prefix), &(mask), sizeof(mask))
226*cf84ac9aSAndroid Build Coastguard Worker 
227*cf84ac9aSAndroid Build Coastguard Worker #define tprintsigmask_val(prefix, mask) \
228*cf84ac9aSAndroid Build Coastguard Worker 	tprints(sprintsigmask_n((prefix), &(mask), sizeof(mask)))
229*cf84ac9aSAndroid Build Coastguard Worker 
230*cf84ac9aSAndroid Build Coastguard Worker static const char *
sprint_old_sigmask_val(const char * const prefix,const unsigned long mask)231*cf84ac9aSAndroid Build Coastguard Worker sprint_old_sigmask_val(const char *const prefix, const unsigned long mask)
232*cf84ac9aSAndroid Build Coastguard Worker {
233*cf84ac9aSAndroid Build Coastguard Worker #if defined(current_wordsize) || !defined(WORDS_BIGENDIAN)
234*cf84ac9aSAndroid Build Coastguard Worker 	return sprintsigmask_n(prefix, &mask, current_wordsize);
235*cf84ac9aSAndroid Build Coastguard Worker #else /* !current_wordsize && WORDS_BIGENDIAN */
236*cf84ac9aSAndroid Build Coastguard Worker 	if (current_wordsize == sizeof(mask)) {
237*cf84ac9aSAndroid Build Coastguard Worker 		return sprintsigmask_val(prefix, mask);
238*cf84ac9aSAndroid Build Coastguard Worker 	} else {
239*cf84ac9aSAndroid Build Coastguard Worker 		uint32_t mask32 = mask;
240*cf84ac9aSAndroid Build Coastguard Worker 		return sprintsigmask_val(prefix, mask32);
241*cf84ac9aSAndroid Build Coastguard Worker 	}
242*cf84ac9aSAndroid Build Coastguard Worker #endif
243*cf84ac9aSAndroid Build Coastguard Worker }
244*cf84ac9aSAndroid Build Coastguard Worker 
245*cf84ac9aSAndroid Build Coastguard Worker #define tprint_old_sigmask_val(prefix, mask) \
246*cf84ac9aSAndroid Build Coastguard Worker 	tprints(sprint_old_sigmask_val((prefix), (mask)))
247*cf84ac9aSAndroid Build Coastguard Worker 
248*cf84ac9aSAndroid Build Coastguard Worker void
printsignal(int nr)249*cf84ac9aSAndroid Build Coastguard Worker printsignal(int nr)
250*cf84ac9aSAndroid Build Coastguard Worker {
251*cf84ac9aSAndroid Build Coastguard Worker 	tprints(signame(nr));
252*cf84ac9aSAndroid Build Coastguard Worker }
253*cf84ac9aSAndroid Build Coastguard Worker 
254*cf84ac9aSAndroid Build Coastguard Worker static void
print_sigset_addr_len_limit(struct tcb * const tcp,const kernel_ulong_t addr,const kernel_ulong_t len,const unsigned int min_len)255*cf84ac9aSAndroid Build Coastguard Worker print_sigset_addr_len_limit(struct tcb *const tcp, const kernel_ulong_t addr,
256*cf84ac9aSAndroid Build Coastguard Worker 			    const kernel_ulong_t len, const unsigned int min_len)
257*cf84ac9aSAndroid Build Coastguard Worker {
258*cf84ac9aSAndroid Build Coastguard Worker 	/*
259*cf84ac9aSAndroid Build Coastguard Worker 	 * Here len is usually equal to NSIG_BYTES or current_wordsize.
260*cf84ac9aSAndroid Build Coastguard Worker 	 * But we code this defensively:
261*cf84ac9aSAndroid Build Coastguard Worker 	 */
262*cf84ac9aSAndroid Build Coastguard Worker 	if (len < min_len || len > NSIG_BYTES) {
263*cf84ac9aSAndroid Build Coastguard Worker 		printaddr(addr);
264*cf84ac9aSAndroid Build Coastguard Worker 		return;
265*cf84ac9aSAndroid Build Coastguard Worker 	}
266*cf84ac9aSAndroid Build Coastguard Worker 	int mask[NSIG_BYTES / sizeof(int)] = {};
267*cf84ac9aSAndroid Build Coastguard Worker 	if (umoven_or_printaddr(tcp, addr, len, mask))
268*cf84ac9aSAndroid Build Coastguard Worker 		return;
269*cf84ac9aSAndroid Build Coastguard Worker 	tprints(sprintsigmask_n("", mask, len));
270*cf84ac9aSAndroid Build Coastguard Worker }
271*cf84ac9aSAndroid Build Coastguard Worker 
272*cf84ac9aSAndroid Build Coastguard Worker void
print_sigset_addr_len(struct tcb * const tcp,const kernel_ulong_t addr,const kernel_ulong_t len)273*cf84ac9aSAndroid Build Coastguard Worker print_sigset_addr_len(struct tcb *const tcp, const kernel_ulong_t addr,
274*cf84ac9aSAndroid Build Coastguard Worker 		      const kernel_ulong_t len)
275*cf84ac9aSAndroid Build Coastguard Worker {
276*cf84ac9aSAndroid Build Coastguard Worker 	print_sigset_addr_len_limit(tcp, addr, len, current_wordsize);
277*cf84ac9aSAndroid Build Coastguard Worker }
278*cf84ac9aSAndroid Build Coastguard Worker 
279*cf84ac9aSAndroid Build Coastguard Worker void
print_sigset_addr(struct tcb * const tcp,const kernel_ulong_t addr)280*cf84ac9aSAndroid Build Coastguard Worker print_sigset_addr(struct tcb *const tcp, const kernel_ulong_t addr)
281*cf84ac9aSAndroid Build Coastguard Worker {
282*cf84ac9aSAndroid Build Coastguard Worker 	print_sigset_addr_len_limit(tcp, addr, NSIG_BYTES, NSIG_BYTES);
283*cf84ac9aSAndroid Build Coastguard Worker }
284*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(ssetmask)285*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(ssetmask)
286*cf84ac9aSAndroid Build Coastguard Worker {
287*cf84ac9aSAndroid Build Coastguard Worker 	if (entering(tcp)) {
288*cf84ac9aSAndroid Build Coastguard Worker 		tprint_old_sigmask_val("", (unsigned) tcp->u_arg[0]);
289*cf84ac9aSAndroid Build Coastguard Worker 	} else if (!syserror(tcp)) {
290*cf84ac9aSAndroid Build Coastguard Worker 		tcp->auxstr = sprint_old_sigmask_val("old mask ",
291*cf84ac9aSAndroid Build Coastguard Worker 						     (unsigned) tcp->u_rval);
292*cf84ac9aSAndroid Build Coastguard Worker 		return RVAL_HEX | RVAL_STR;
293*cf84ac9aSAndroid Build Coastguard Worker 	}
294*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
295*cf84ac9aSAndroid Build Coastguard Worker }
296*cf84ac9aSAndroid Build Coastguard Worker 
297*cf84ac9aSAndroid Build Coastguard Worker struct old_sigaction {
298*cf84ac9aSAndroid Build Coastguard Worker 	/* sa_handler may be a libc #define, need to use other name: */
299*cf84ac9aSAndroid Build Coastguard Worker #if defined MIPS
300*cf84ac9aSAndroid Build Coastguard Worker 	unsigned int sa_flags;
301*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long sa_handler__;
302*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long sa_mask;
303*cf84ac9aSAndroid Build Coastguard Worker #elif defined ALPHA
304*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long sa_handler__;
305*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long sa_mask;
306*cf84ac9aSAndroid Build Coastguard Worker 	unsigned int sa_flags;
307*cf84ac9aSAndroid Build Coastguard Worker #else
308*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long sa_handler__;
309*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long sa_mask;
310*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long sa_flags;
311*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long sa_restorer;
312*cf84ac9aSAndroid Build Coastguard Worker #endif
313*cf84ac9aSAndroid Build Coastguard Worker }
314*cf84ac9aSAndroid Build Coastguard Worker #ifdef ALPHA
315*cf84ac9aSAndroid Build Coastguard Worker 	ATTRIBUTE_PACKED
316*cf84ac9aSAndroid Build Coastguard Worker #endif
317*cf84ac9aSAndroid Build Coastguard Worker ;
318*cf84ac9aSAndroid Build Coastguard Worker 
319*cf84ac9aSAndroid Build Coastguard Worker static void
decode_old_sigaction(struct tcb * const tcp,const kernel_ulong_t addr)320*cf84ac9aSAndroid Build Coastguard Worker decode_old_sigaction(struct tcb *const tcp, const kernel_ulong_t addr)
321*cf84ac9aSAndroid Build Coastguard Worker {
322*cf84ac9aSAndroid Build Coastguard Worker 	struct old_sigaction sa;
323*cf84ac9aSAndroid Build Coastguard Worker 
324*cf84ac9aSAndroid Build Coastguard Worker #ifndef current_wordsize
325*cf84ac9aSAndroid Build Coastguard Worker 	if (current_wordsize < sizeof(sa.sa_handler__)) {
326*cf84ac9aSAndroid Build Coastguard Worker 		struct old_sigaction32 {
327*cf84ac9aSAndroid Build Coastguard Worker 			uint32_t sa_handler__;
328*cf84ac9aSAndroid Build Coastguard Worker 			uint32_t sa_mask;
329*cf84ac9aSAndroid Build Coastguard Worker 			uint32_t sa_flags;
330*cf84ac9aSAndroid Build Coastguard Worker 			uint32_t sa_restorer;
331*cf84ac9aSAndroid Build Coastguard Worker 		} sa32;
332*cf84ac9aSAndroid Build Coastguard Worker 
333*cf84ac9aSAndroid Build Coastguard Worker 		if (umove_or_printaddr(tcp, addr, &sa32))
334*cf84ac9aSAndroid Build Coastguard Worker 			return;
335*cf84ac9aSAndroid Build Coastguard Worker 
336*cf84ac9aSAndroid Build Coastguard Worker 		memset(&sa, 0, sizeof(sa));
337*cf84ac9aSAndroid Build Coastguard Worker 		sa.sa_handler__ = sa32.sa_handler__;
338*cf84ac9aSAndroid Build Coastguard Worker 		sa.sa_flags = sa32.sa_flags;
339*cf84ac9aSAndroid Build Coastguard Worker 		sa.sa_restorer = sa32.sa_restorer;
340*cf84ac9aSAndroid Build Coastguard Worker 		sa.sa_mask = sa32.sa_mask;
341*cf84ac9aSAndroid Build Coastguard Worker 	} else
342*cf84ac9aSAndroid Build Coastguard Worker #endif
343*cf84ac9aSAndroid Build Coastguard Worker 	if (umove_or_printaddr(tcp, addr, &sa))
344*cf84ac9aSAndroid Build Coastguard Worker 		return;
345*cf84ac9aSAndroid Build Coastguard Worker 
346*cf84ac9aSAndroid Build Coastguard Worker 	tprints("{sa_handler=");
347*cf84ac9aSAndroid Build Coastguard Worker 	print_sa_handler(sa.sa_handler__);
348*cf84ac9aSAndroid Build Coastguard Worker 	tprints(", sa_mask=");
349*cf84ac9aSAndroid Build Coastguard Worker 	tprint_old_sigmask_val("", sa.sa_mask);
350*cf84ac9aSAndroid Build Coastguard Worker 	tprints(", sa_flags=");
351*cf84ac9aSAndroid Build Coastguard Worker 	printflags(sigact_flags, sa.sa_flags, "SA_???");
352*cf84ac9aSAndroid Build Coastguard Worker #if !(defined ALPHA || defined MIPS)
353*cf84ac9aSAndroid Build Coastguard Worker 	if (sa.sa_flags & 0x04000000U) {
354*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", sa_restorer=");
355*cf84ac9aSAndroid Build Coastguard Worker 		printaddr(sa.sa_restorer);
356*cf84ac9aSAndroid Build Coastguard Worker 	}
357*cf84ac9aSAndroid Build Coastguard Worker #endif
358*cf84ac9aSAndroid Build Coastguard Worker 	tprints("}");
359*cf84ac9aSAndroid Build Coastguard Worker }
360*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(sigaction)361*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(sigaction)
362*cf84ac9aSAndroid Build Coastguard Worker {
363*cf84ac9aSAndroid Build Coastguard Worker 	if (entering(tcp)) {
364*cf84ac9aSAndroid Build Coastguard Worker 		int signo = tcp->u_arg[0];
365*cf84ac9aSAndroid Build Coastguard Worker #if defined SPARC || defined SPARC64
366*cf84ac9aSAndroid Build Coastguard Worker 		if (signo < 0) {
367*cf84ac9aSAndroid Build Coastguard Worker 			tprints("-");
368*cf84ac9aSAndroid Build Coastguard Worker 			signo = -signo;
369*cf84ac9aSAndroid Build Coastguard Worker 		}
370*cf84ac9aSAndroid Build Coastguard Worker #endif
371*cf84ac9aSAndroid Build Coastguard Worker 		printsignal(signo);
372*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", ");
373*cf84ac9aSAndroid Build Coastguard Worker 		decode_old_sigaction(tcp, tcp->u_arg[1]);
374*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", ");
375*cf84ac9aSAndroid Build Coastguard Worker 	} else
376*cf84ac9aSAndroid Build Coastguard Worker 		decode_old_sigaction(tcp, tcp->u_arg[2]);
377*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
378*cf84ac9aSAndroid Build Coastguard Worker }
379*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(signal)380*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(signal)
381*cf84ac9aSAndroid Build Coastguard Worker {
382*cf84ac9aSAndroid Build Coastguard Worker 	if (entering(tcp)) {
383*cf84ac9aSAndroid Build Coastguard Worker 		printsignal(tcp->u_arg[0]);
384*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", ");
385*cf84ac9aSAndroid Build Coastguard Worker 		print_sa_handler(tcp->u_arg[1]);
386*cf84ac9aSAndroid Build Coastguard Worker 		return 0;
387*cf84ac9aSAndroid Build Coastguard Worker 	} else if (!syserror(tcp)) {
388*cf84ac9aSAndroid Build Coastguard Worker 		tcp->auxstr = get_sa_handler_str(tcp->u_rval);
389*cf84ac9aSAndroid Build Coastguard Worker 		return RVAL_HEX | RVAL_STR;
390*cf84ac9aSAndroid Build Coastguard Worker 	}
391*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
392*cf84ac9aSAndroid Build Coastguard Worker }
393*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(sgetmask)394*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(sgetmask)
395*cf84ac9aSAndroid Build Coastguard Worker {
396*cf84ac9aSAndroid Build Coastguard Worker 	if (exiting(tcp) && !syserror(tcp)) {
397*cf84ac9aSAndroid Build Coastguard Worker 		tcp->auxstr = sprint_old_sigmask_val("mask ", tcp->u_rval);
398*cf84ac9aSAndroid Build Coastguard Worker 		return RVAL_HEX | RVAL_STR;
399*cf84ac9aSAndroid Build Coastguard Worker 	}
400*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
401*cf84ac9aSAndroid Build Coastguard Worker }
402*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(sigsuspend)403*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(sigsuspend)
404*cf84ac9aSAndroid Build Coastguard Worker {
405*cf84ac9aSAndroid Build Coastguard Worker #ifdef MIPS
406*cf84ac9aSAndroid Build Coastguard Worker 	print_sigset_addr_len(tcp, tcp->u_arg[tcp->s_ent->nargs - 1],
407*cf84ac9aSAndroid Build Coastguard Worker 			      current_wordsize);
408*cf84ac9aSAndroid Build Coastguard Worker #else
409*cf84ac9aSAndroid Build Coastguard Worker 	tprint_old_sigmask_val("", tcp->u_arg[tcp->s_ent->nargs - 1]);
410*cf84ac9aSAndroid Build Coastguard Worker #endif
411*cf84ac9aSAndroid Build Coastguard Worker 
412*cf84ac9aSAndroid Build Coastguard Worker 	return RVAL_DECODED;
413*cf84ac9aSAndroid Build Coastguard Worker }
414*cf84ac9aSAndroid Build Coastguard Worker 
415*cf84ac9aSAndroid Build Coastguard Worker #ifdef ALPHA
416*cf84ac9aSAndroid Build Coastguard Worker /*
417*cf84ac9aSAndroid Build Coastguard Worker  * The OSF/1 sigprocmask is different: it doesn't pass in two pointers,
418*cf84ac9aSAndroid Build Coastguard Worker  * but rather passes in the new bitmask as an argument and then returns
419*cf84ac9aSAndroid Build Coastguard Worker  * the old bitmask.  This "works" because we only have 64 signals to worry
420*cf84ac9aSAndroid Build Coastguard Worker  * about.  If you want more, use of the rt_sigprocmask syscall is required.
421*cf84ac9aSAndroid Build Coastguard Worker  *
422*cf84ac9aSAndroid Build Coastguard Worker  * Alpha:
423*cf84ac9aSAndroid Build Coastguard Worker  *	old = osf_sigprocmask(how, new);
424*cf84ac9aSAndroid Build Coastguard Worker  * Everyone else:
425*cf84ac9aSAndroid Build Coastguard Worker  *	ret = sigprocmask(how, &new, &old, ...);
426*cf84ac9aSAndroid Build Coastguard Worker  */
SYS_FUNC(osf_sigprocmask)427*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(osf_sigprocmask)
428*cf84ac9aSAndroid Build Coastguard Worker {
429*cf84ac9aSAndroid Build Coastguard Worker 	if (entering(tcp)) {
430*cf84ac9aSAndroid Build Coastguard Worker 		printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
431*cf84ac9aSAndroid Build Coastguard Worker 		tprintsigmask_val(", ", tcp->u_arg[1]);
432*cf84ac9aSAndroid Build Coastguard Worker 	} else if (!syserror(tcp)) {
433*cf84ac9aSAndroid Build Coastguard Worker 		tcp->auxstr = sprintsigmask_val("old mask ", tcp->u_rval);
434*cf84ac9aSAndroid Build Coastguard Worker 		return RVAL_HEX | RVAL_STR;
435*cf84ac9aSAndroid Build Coastguard Worker 	}
436*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
437*cf84ac9aSAndroid Build Coastguard Worker }
438*cf84ac9aSAndroid Build Coastguard Worker 
439*cf84ac9aSAndroid Build Coastguard Worker #else /* !ALPHA */
440*cf84ac9aSAndroid Build Coastguard Worker 
441*cf84ac9aSAndroid Build Coastguard Worker /* "Old" sigprocmask, which operates with word-sized signal masks */
SYS_FUNC(sigprocmask)442*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(sigprocmask)
443*cf84ac9aSAndroid Build Coastguard Worker {
444*cf84ac9aSAndroid Build Coastguard Worker 	if (entering(tcp)) {
445*cf84ac9aSAndroid Build Coastguard Worker 		printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
446*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", ");
447*cf84ac9aSAndroid Build Coastguard Worker 		print_sigset_addr_len(tcp, tcp->u_arg[1], current_wordsize);
448*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", ");
449*cf84ac9aSAndroid Build Coastguard Worker 	} else {
450*cf84ac9aSAndroid Build Coastguard Worker 		print_sigset_addr_len(tcp, tcp->u_arg[2], current_wordsize);
451*cf84ac9aSAndroid Build Coastguard Worker 	}
452*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
453*cf84ac9aSAndroid Build Coastguard Worker }
454*cf84ac9aSAndroid Build Coastguard Worker #endif /* !ALPHA */
455*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(kill)456*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(kill)
457*cf84ac9aSAndroid Build Coastguard Worker {
458*cf84ac9aSAndroid Build Coastguard Worker 	tprintf("%d, %s",
459*cf84ac9aSAndroid Build Coastguard Worker 		(int) tcp->u_arg[0],
460*cf84ac9aSAndroid Build Coastguard Worker 		signame(tcp->u_arg[1]));
461*cf84ac9aSAndroid Build Coastguard Worker 
462*cf84ac9aSAndroid Build Coastguard Worker 	return RVAL_DECODED;
463*cf84ac9aSAndroid Build Coastguard Worker }
464*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(tgkill)465*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(tgkill)
466*cf84ac9aSAndroid Build Coastguard Worker {
467*cf84ac9aSAndroid Build Coastguard Worker 	tprintf("%d, %d, %s",
468*cf84ac9aSAndroid Build Coastguard Worker 		(int) tcp->u_arg[0],
469*cf84ac9aSAndroid Build Coastguard Worker 		(int) tcp->u_arg[1],
470*cf84ac9aSAndroid Build Coastguard Worker 		signame(tcp->u_arg[2]));
471*cf84ac9aSAndroid Build Coastguard Worker 
472*cf84ac9aSAndroid Build Coastguard Worker 	return RVAL_DECODED;
473*cf84ac9aSAndroid Build Coastguard Worker }
474*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(sigpending)475*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(sigpending)
476*cf84ac9aSAndroid Build Coastguard Worker {
477*cf84ac9aSAndroid Build Coastguard Worker 	if (exiting(tcp))
478*cf84ac9aSAndroid Build Coastguard Worker 		print_sigset_addr_len(tcp, tcp->u_arg[0], current_wordsize);
479*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
480*cf84ac9aSAndroid Build Coastguard Worker }
481*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(rt_sigprocmask)482*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(rt_sigprocmask)
483*cf84ac9aSAndroid Build Coastguard Worker {
484*cf84ac9aSAndroid Build Coastguard Worker 	/* Note: arg[3] is the length of the sigset. Kernel requires NSIG_BYTES */
485*cf84ac9aSAndroid Build Coastguard Worker 	if (entering(tcp)) {
486*cf84ac9aSAndroid Build Coastguard Worker 		printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
487*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", ");
488*cf84ac9aSAndroid Build Coastguard Worker 		print_sigset_addr_len(tcp, tcp->u_arg[1], tcp->u_arg[3]);
489*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", ");
490*cf84ac9aSAndroid Build Coastguard Worker 	} else {
491*cf84ac9aSAndroid Build Coastguard Worker 		print_sigset_addr_len(tcp, tcp->u_arg[2], tcp->u_arg[3]);
492*cf84ac9aSAndroid Build Coastguard Worker 		tprintf(", %" PRI_klu, tcp->u_arg[3]);
493*cf84ac9aSAndroid Build Coastguard Worker 	}
494*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
495*cf84ac9aSAndroid Build Coastguard Worker }
496*cf84ac9aSAndroid Build Coastguard Worker 
497*cf84ac9aSAndroid Build Coastguard Worker /* Structure describing the action to be taken when a signal arrives.  */
498*cf84ac9aSAndroid Build Coastguard Worker struct new_sigaction {
499*cf84ac9aSAndroid Build Coastguard Worker 	/* sa_handler may be a libc #define, need to use other name: */
500*cf84ac9aSAndroid Build Coastguard Worker #ifdef MIPS
501*cf84ac9aSAndroid Build Coastguard Worker 	unsigned int sa_flags;
502*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long sa_handler__;
503*cf84ac9aSAndroid Build Coastguard Worker #else
504*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long sa_handler__;
505*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long sa_flags;
506*cf84ac9aSAndroid Build Coastguard Worker #endif /* !MIPS */
507*cf84ac9aSAndroid Build Coastguard Worker #if HAVE_SA_RESTORER
508*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long sa_restorer;
509*cf84ac9aSAndroid Build Coastguard Worker #endif
510*cf84ac9aSAndroid Build Coastguard Worker 	/* Kernel treats sa_mask as an array of longs. */
511*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long sa_mask[NSIG / sizeof(long)];
512*cf84ac9aSAndroid Build Coastguard Worker };
513*cf84ac9aSAndroid Build Coastguard Worker /* Same for i386-on-x86_64 and similar cases */
514*cf84ac9aSAndroid Build Coastguard Worker struct new_sigaction32 {
515*cf84ac9aSAndroid Build Coastguard Worker 	uint32_t sa_handler__;
516*cf84ac9aSAndroid Build Coastguard Worker 	uint32_t sa_flags;
517*cf84ac9aSAndroid Build Coastguard Worker #if HAVE_SA_RESTORER
518*cf84ac9aSAndroid Build Coastguard Worker 	uint32_t sa_restorer;
519*cf84ac9aSAndroid Build Coastguard Worker #endif
520*cf84ac9aSAndroid Build Coastguard Worker 	uint32_t sa_mask[2 * (NSIG / sizeof(long))];
521*cf84ac9aSAndroid Build Coastguard Worker };
522*cf84ac9aSAndroid Build Coastguard Worker 
523*cf84ac9aSAndroid Build Coastguard Worker static void
decode_new_sigaction(struct tcb * const tcp,const kernel_ulong_t addr)524*cf84ac9aSAndroid Build Coastguard Worker decode_new_sigaction(struct tcb *const tcp, const kernel_ulong_t addr)
525*cf84ac9aSAndroid Build Coastguard Worker {
526*cf84ac9aSAndroid Build Coastguard Worker 	struct new_sigaction sa;
527*cf84ac9aSAndroid Build Coastguard Worker 
528*cf84ac9aSAndroid Build Coastguard Worker #ifndef current_wordsize
529*cf84ac9aSAndroid Build Coastguard Worker 	if (current_wordsize < sizeof(sa.sa_handler__)) {
530*cf84ac9aSAndroid Build Coastguard Worker 		struct new_sigaction32 sa32;
531*cf84ac9aSAndroid Build Coastguard Worker 
532*cf84ac9aSAndroid Build Coastguard Worker 		if (umove_or_printaddr(tcp, addr, &sa32))
533*cf84ac9aSAndroid Build Coastguard Worker 			return;
534*cf84ac9aSAndroid Build Coastguard Worker 
535*cf84ac9aSAndroid Build Coastguard Worker 		memset(&sa, 0, sizeof(sa));
536*cf84ac9aSAndroid Build Coastguard Worker 		sa.sa_handler__ = sa32.sa_handler__;
537*cf84ac9aSAndroid Build Coastguard Worker 		sa.sa_flags     = sa32.sa_flags;
538*cf84ac9aSAndroid Build Coastguard Worker #if HAVE_SA_RESTORER && defined SA_RESTORER
539*cf84ac9aSAndroid Build Coastguard Worker 		sa.sa_restorer  = sa32.sa_restorer;
540*cf84ac9aSAndroid Build Coastguard Worker #endif
541*cf84ac9aSAndroid Build Coastguard Worker 		/* Kernel treats sa_mask as an array of longs.
542*cf84ac9aSAndroid Build Coastguard Worker 		 * For 32-bit process, "long" is uint32_t, thus, for example,
543*cf84ac9aSAndroid Build Coastguard Worker 		 * 32th bit in sa_mask will end up as bit 0 in sa_mask[1].
544*cf84ac9aSAndroid Build Coastguard Worker 		 * But for (64-bit) kernel, 32th bit in sa_mask is
545*cf84ac9aSAndroid Build Coastguard Worker 		 * 32th bit in 0th (64-bit) long!
546*cf84ac9aSAndroid Build Coastguard Worker 		 * For little-endian, it's the same.
547*cf84ac9aSAndroid Build Coastguard Worker 		 * For big-endian, we swap 32-bit words.
548*cf84ac9aSAndroid Build Coastguard Worker 		 */
549*cf84ac9aSAndroid Build Coastguard Worker 		sa.sa_mask[0] = ULONG_LONG(sa32.sa_mask[0], sa32.sa_mask[1]);
550*cf84ac9aSAndroid Build Coastguard Worker 	} else
551*cf84ac9aSAndroid Build Coastguard Worker #endif
552*cf84ac9aSAndroid Build Coastguard Worker 	if (umove_or_printaddr(tcp, addr, &sa))
553*cf84ac9aSAndroid Build Coastguard Worker 		return;
554*cf84ac9aSAndroid Build Coastguard Worker 
555*cf84ac9aSAndroid Build Coastguard Worker 	tprints("{sa_handler=");
556*cf84ac9aSAndroid Build Coastguard Worker 	print_sa_handler(sa.sa_handler__);
557*cf84ac9aSAndroid Build Coastguard Worker 	tprints(", sa_mask=");
558*cf84ac9aSAndroid Build Coastguard Worker 	/*
559*cf84ac9aSAndroid Build Coastguard Worker 	 * Sigset size is in tcp->u_arg[4] (SPARC)
560*cf84ac9aSAndroid Build Coastguard Worker 	 * or in tcp->u_arg[3] (all other),
561*cf84ac9aSAndroid Build Coastguard Worker 	 * but kernel won't handle sys_rt_sigaction
562*cf84ac9aSAndroid Build Coastguard Worker 	 * with wrong sigset size (just returns EINVAL instead).
563*cf84ac9aSAndroid Build Coastguard Worker 	 * We just fetch the right size, which is NSIG_BYTES.
564*cf84ac9aSAndroid Build Coastguard Worker 	 */
565*cf84ac9aSAndroid Build Coastguard Worker 	tprintsigmask_val("", sa.sa_mask);
566*cf84ac9aSAndroid Build Coastguard Worker 	tprints(", sa_flags=");
567*cf84ac9aSAndroid Build Coastguard Worker 
568*cf84ac9aSAndroid Build Coastguard Worker 	printflags(sigact_flags, sa.sa_flags, "SA_???");
569*cf84ac9aSAndroid Build Coastguard Worker #if HAVE_SA_RESTORER && defined SA_RESTORER
570*cf84ac9aSAndroid Build Coastguard Worker 	if (sa.sa_flags & SA_RESTORER) {
571*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", sa_restorer=");
572*cf84ac9aSAndroid Build Coastguard Worker 		printaddr(sa.sa_restorer);
573*cf84ac9aSAndroid Build Coastguard Worker 	}
574*cf84ac9aSAndroid Build Coastguard Worker #endif
575*cf84ac9aSAndroid Build Coastguard Worker 	tprints("}");
576*cf84ac9aSAndroid Build Coastguard Worker }
577*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(rt_sigaction)578*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(rt_sigaction)
579*cf84ac9aSAndroid Build Coastguard Worker {
580*cf84ac9aSAndroid Build Coastguard Worker 	if (entering(tcp)) {
581*cf84ac9aSAndroid Build Coastguard Worker 		printsignal(tcp->u_arg[0]);
582*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", ");
583*cf84ac9aSAndroid Build Coastguard Worker 		decode_new_sigaction(tcp, tcp->u_arg[1]);
584*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", ");
585*cf84ac9aSAndroid Build Coastguard Worker 	} else {
586*cf84ac9aSAndroid Build Coastguard Worker 		decode_new_sigaction(tcp, tcp->u_arg[2]);
587*cf84ac9aSAndroid Build Coastguard Worker #if defined(SPARC) || defined(SPARC64)
588*cf84ac9aSAndroid Build Coastguard Worker 		tprintf(", %#" PRI_klx ", %" PRI_klu, tcp->u_arg[3], tcp->u_arg[4]);
589*cf84ac9aSAndroid Build Coastguard Worker #elif defined(ALPHA)
590*cf84ac9aSAndroid Build Coastguard Worker 		tprintf(", %" PRI_klu ", %#" PRI_klx, tcp->u_arg[3], tcp->u_arg[4]);
591*cf84ac9aSAndroid Build Coastguard Worker #else
592*cf84ac9aSAndroid Build Coastguard Worker 		tprintf(", %" PRI_klu, tcp->u_arg[3]);
593*cf84ac9aSAndroid Build Coastguard Worker #endif
594*cf84ac9aSAndroid Build Coastguard Worker 	}
595*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
596*cf84ac9aSAndroid Build Coastguard Worker }
597*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(rt_sigpending)598*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(rt_sigpending)
599*cf84ac9aSAndroid Build Coastguard Worker {
600*cf84ac9aSAndroid Build Coastguard Worker 	if (exiting(tcp)) {
601*cf84ac9aSAndroid Build Coastguard Worker 		/*
602*cf84ac9aSAndroid Build Coastguard Worker 		 * One of the few syscalls where sigset size (arg[1])
603*cf84ac9aSAndroid Build Coastguard Worker 		 * is allowed to be <= NSIG_BYTES, not strictly ==.
604*cf84ac9aSAndroid Build Coastguard Worker 		 * This allows non-rt sigpending() syscall
605*cf84ac9aSAndroid Build Coastguard Worker 		 * to reuse rt_sigpending() code in kernel.
606*cf84ac9aSAndroid Build Coastguard Worker 		 */
607*cf84ac9aSAndroid Build Coastguard Worker 		print_sigset_addr_len_limit(tcp, tcp->u_arg[0],
608*cf84ac9aSAndroid Build Coastguard Worker 					    tcp->u_arg[1], 1);
609*cf84ac9aSAndroid Build Coastguard Worker 		tprintf(", %" PRI_klu, tcp->u_arg[1]);
610*cf84ac9aSAndroid Build Coastguard Worker 	}
611*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
612*cf84ac9aSAndroid Build Coastguard Worker }
613*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(rt_sigsuspend)614*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(rt_sigsuspend)
615*cf84ac9aSAndroid Build Coastguard Worker {
616*cf84ac9aSAndroid Build Coastguard Worker 	/* NB: kernel requires arg[1] == NSIG_BYTES */
617*cf84ac9aSAndroid Build Coastguard Worker 	print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[1]);
618*cf84ac9aSAndroid Build Coastguard Worker 	tprintf(", %" PRI_klu, tcp->u_arg[1]);
619*cf84ac9aSAndroid Build Coastguard Worker 
620*cf84ac9aSAndroid Build Coastguard Worker 	return RVAL_DECODED;
621*cf84ac9aSAndroid Build Coastguard Worker }
622*cf84ac9aSAndroid Build Coastguard Worker 
623*cf84ac9aSAndroid Build Coastguard Worker static void
print_sigqueueinfo(struct tcb * const tcp,const int sig,const kernel_ulong_t addr)624*cf84ac9aSAndroid Build Coastguard Worker print_sigqueueinfo(struct tcb *const tcp, const int sig,
625*cf84ac9aSAndroid Build Coastguard Worker 		   const kernel_ulong_t addr)
626*cf84ac9aSAndroid Build Coastguard Worker {
627*cf84ac9aSAndroid Build Coastguard Worker 	printsignal(sig);
628*cf84ac9aSAndroid Build Coastguard Worker 	tprints(", ");
629*cf84ac9aSAndroid Build Coastguard Worker 	printsiginfo_at(tcp, addr);
630*cf84ac9aSAndroid Build Coastguard Worker }
631*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(rt_sigqueueinfo)632*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(rt_sigqueueinfo)
633*cf84ac9aSAndroid Build Coastguard Worker {
634*cf84ac9aSAndroid Build Coastguard Worker 	tprintf("%d, ", (int) tcp->u_arg[0]);
635*cf84ac9aSAndroid Build Coastguard Worker 	print_sigqueueinfo(tcp, tcp->u_arg[1], tcp->u_arg[2]);
636*cf84ac9aSAndroid Build Coastguard Worker 
637*cf84ac9aSAndroid Build Coastguard Worker 	return RVAL_DECODED;
638*cf84ac9aSAndroid Build Coastguard Worker }
639*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(rt_tgsigqueueinfo)640*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(rt_tgsigqueueinfo)
641*cf84ac9aSAndroid Build Coastguard Worker {
642*cf84ac9aSAndroid Build Coastguard Worker 	tprintf("%d, %d, ", (int) tcp->u_arg[0], (int) tcp->u_arg[1]);
643*cf84ac9aSAndroid Build Coastguard Worker 	print_sigqueueinfo(tcp, tcp->u_arg[2], tcp->u_arg[3]);
644*cf84ac9aSAndroid Build Coastguard Worker 
645*cf84ac9aSAndroid Build Coastguard Worker 	return RVAL_DECODED;
646*cf84ac9aSAndroid Build Coastguard Worker }
647*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(rt_sigtimedwait)648*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(rt_sigtimedwait)
649*cf84ac9aSAndroid Build Coastguard Worker {
650*cf84ac9aSAndroid Build Coastguard Worker 	/* NB: kernel requires arg[3] == NSIG_BYTES */
651*cf84ac9aSAndroid Build Coastguard Worker 	if (entering(tcp)) {
652*cf84ac9aSAndroid Build Coastguard Worker 		print_sigset_addr_len(tcp, tcp->u_arg[0], tcp->u_arg[3]);
653*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", ");
654*cf84ac9aSAndroid Build Coastguard Worker 		if (!(tcp->u_arg[1] && verbose(tcp))) {
655*cf84ac9aSAndroid Build Coastguard Worker 			/*
656*cf84ac9aSAndroid Build Coastguard Worker 			 * This is the only "return" parameter,
657*cf84ac9aSAndroid Build Coastguard Worker 			 * if we are not going to fetch it on exit,
658*cf84ac9aSAndroid Build Coastguard Worker 			 * decode all parameters on entry.
659*cf84ac9aSAndroid Build Coastguard Worker 			 */
660*cf84ac9aSAndroid Build Coastguard Worker 			printaddr(tcp->u_arg[1]);
661*cf84ac9aSAndroid Build Coastguard Worker 			tprints(", ");
662*cf84ac9aSAndroid Build Coastguard Worker 			print_timespec(tcp, tcp->u_arg[2]);
663*cf84ac9aSAndroid Build Coastguard Worker 			tprintf(", %" PRI_klu, tcp->u_arg[3]);
664*cf84ac9aSAndroid Build Coastguard Worker 		} else {
665*cf84ac9aSAndroid Build Coastguard Worker 			char *sts = xstrdup(sprint_timespec(tcp, tcp->u_arg[2]));
666*cf84ac9aSAndroid Build Coastguard Worker 			set_tcb_priv_data(tcp, sts, free);
667*cf84ac9aSAndroid Build Coastguard Worker 		}
668*cf84ac9aSAndroid Build Coastguard Worker 	} else {
669*cf84ac9aSAndroid Build Coastguard Worker 		if (tcp->u_arg[1] && verbose(tcp)) {
670*cf84ac9aSAndroid Build Coastguard Worker 			printsiginfo_at(tcp, tcp->u_arg[1]);
671*cf84ac9aSAndroid Build Coastguard Worker 			tprints(", ");
672*cf84ac9aSAndroid Build Coastguard Worker 			tprints(get_tcb_priv_data(tcp));
673*cf84ac9aSAndroid Build Coastguard Worker 			tprintf(", %" PRI_klu, tcp->u_arg[3]);
674*cf84ac9aSAndroid Build Coastguard Worker 		}
675*cf84ac9aSAndroid Build Coastguard Worker 
676*cf84ac9aSAndroid Build Coastguard Worker 		if (!syserror(tcp) && tcp->u_rval) {
677*cf84ac9aSAndroid Build Coastguard Worker 			tcp->auxstr = signame(tcp->u_rval);
678*cf84ac9aSAndroid Build Coastguard Worker 			return RVAL_STR;
679*cf84ac9aSAndroid Build Coastguard Worker 		}
680*cf84ac9aSAndroid Build Coastguard Worker 	}
681*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
682*cf84ac9aSAndroid Build Coastguard Worker }
683*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(restart_syscall)684*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(restart_syscall)
685*cf84ac9aSAndroid Build Coastguard Worker {
686*cf84ac9aSAndroid Build Coastguard Worker 	tprintf("<... resuming interrupted %s ...>",
687*cf84ac9aSAndroid Build Coastguard Worker 		tcp->s_prev_ent ? tcp->s_prev_ent->sys_name : "system call");
688*cf84ac9aSAndroid Build Coastguard Worker 
689*cf84ac9aSAndroid Build Coastguard Worker 	return RVAL_DECODED;
690*cf84ac9aSAndroid Build Coastguard Worker }
691