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