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) 1999-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 <limits.h>
37*cf84ac9aSAndroid Build Coastguard Worker #include <fcntl.h>
38*cf84ac9aSAndroid Build Coastguard Worker #include <stdarg.h>
39*cf84ac9aSAndroid Build Coastguard Worker #include <sys/stat.h>
40*cf84ac9aSAndroid Build Coastguard Worker #include <sys/sysmacros.h>
41*cf84ac9aSAndroid Build Coastguard Worker #ifdef HAVE_SYS_XATTR_H
42*cf84ac9aSAndroid Build Coastguard Worker # include <sys/xattr.h>
43*cf84ac9aSAndroid Build Coastguard Worker #endif
44*cf84ac9aSAndroid Build Coastguard Worker #include <sys/uio.h>
45*cf84ac9aSAndroid Build Coastguard Worker
46*cf84ac9aSAndroid Build Coastguard Worker #include "largefile_wrappers.h"
47*cf84ac9aSAndroid Build Coastguard Worker #include "xlat.h"
48*cf84ac9aSAndroid Build Coastguard Worker #include "xstring.h"
49*cf84ac9aSAndroid Build Coastguard Worker
50*cf84ac9aSAndroid Build Coastguard Worker int
ts_nz(const struct timespec * a)51*cf84ac9aSAndroid Build Coastguard Worker ts_nz(const struct timespec *a)
52*cf84ac9aSAndroid Build Coastguard Worker {
53*cf84ac9aSAndroid Build Coastguard Worker return a->tv_sec || a->tv_nsec;
54*cf84ac9aSAndroid Build Coastguard Worker }
55*cf84ac9aSAndroid Build Coastguard Worker
56*cf84ac9aSAndroid Build Coastguard Worker int
ts_cmp(const struct timespec * a,const struct timespec * b)57*cf84ac9aSAndroid Build Coastguard Worker ts_cmp(const struct timespec *a, const struct timespec *b)
58*cf84ac9aSAndroid Build Coastguard Worker {
59*cf84ac9aSAndroid Build Coastguard Worker if (a->tv_sec < b->tv_sec
60*cf84ac9aSAndroid Build Coastguard Worker || (a->tv_sec == b->tv_sec && a->tv_nsec < b->tv_nsec))
61*cf84ac9aSAndroid Build Coastguard Worker return -1;
62*cf84ac9aSAndroid Build Coastguard Worker if (a->tv_sec > b->tv_sec
63*cf84ac9aSAndroid Build Coastguard Worker || (a->tv_sec == b->tv_sec && a->tv_nsec > b->tv_nsec))
64*cf84ac9aSAndroid Build Coastguard Worker return 1;
65*cf84ac9aSAndroid Build Coastguard Worker return 0;
66*cf84ac9aSAndroid Build Coastguard Worker }
67*cf84ac9aSAndroid Build Coastguard Worker
68*cf84ac9aSAndroid Build Coastguard Worker double
ts_float(const struct timespec * tv)69*cf84ac9aSAndroid Build Coastguard Worker ts_float(const struct timespec *tv)
70*cf84ac9aSAndroid Build Coastguard Worker {
71*cf84ac9aSAndroid Build Coastguard Worker return tv->tv_sec + tv->tv_nsec/1000000000.0;
72*cf84ac9aSAndroid Build Coastguard Worker }
73*cf84ac9aSAndroid Build Coastguard Worker
74*cf84ac9aSAndroid Build Coastguard Worker void
ts_add(struct timespec * tv,const struct timespec * a,const struct timespec * b)75*cf84ac9aSAndroid Build Coastguard Worker ts_add(struct timespec *tv, const struct timespec *a, const struct timespec *b)
76*cf84ac9aSAndroid Build Coastguard Worker {
77*cf84ac9aSAndroid Build Coastguard Worker tv->tv_sec = a->tv_sec + b->tv_sec;
78*cf84ac9aSAndroid Build Coastguard Worker tv->tv_nsec = a->tv_nsec + b->tv_nsec;
79*cf84ac9aSAndroid Build Coastguard Worker if (tv->tv_nsec >= 1000000000) {
80*cf84ac9aSAndroid Build Coastguard Worker tv->tv_sec++;
81*cf84ac9aSAndroid Build Coastguard Worker tv->tv_nsec -= 1000000000;
82*cf84ac9aSAndroid Build Coastguard Worker }
83*cf84ac9aSAndroid Build Coastguard Worker }
84*cf84ac9aSAndroid Build Coastguard Worker
85*cf84ac9aSAndroid Build Coastguard Worker void
ts_sub(struct timespec * tv,const struct timespec * a,const struct timespec * b)86*cf84ac9aSAndroid Build Coastguard Worker ts_sub(struct timespec *tv, const struct timespec *a, const struct timespec *b)
87*cf84ac9aSAndroid Build Coastguard Worker {
88*cf84ac9aSAndroid Build Coastguard Worker tv->tv_sec = a->tv_sec - b->tv_sec;
89*cf84ac9aSAndroid Build Coastguard Worker tv->tv_nsec = a->tv_nsec - b->tv_nsec;
90*cf84ac9aSAndroid Build Coastguard Worker if (tv->tv_nsec < 0) {
91*cf84ac9aSAndroid Build Coastguard Worker tv->tv_sec--;
92*cf84ac9aSAndroid Build Coastguard Worker tv->tv_nsec += 1000000000;
93*cf84ac9aSAndroid Build Coastguard Worker }
94*cf84ac9aSAndroid Build Coastguard Worker }
95*cf84ac9aSAndroid Build Coastguard Worker
96*cf84ac9aSAndroid Build Coastguard Worker void
ts_div(struct timespec * tv,const struct timespec * a,int n)97*cf84ac9aSAndroid Build Coastguard Worker ts_div(struct timespec *tv, const struct timespec *a, int n)
98*cf84ac9aSAndroid Build Coastguard Worker {
99*cf84ac9aSAndroid Build Coastguard Worker long long nsec = (a->tv_sec % n * 1000000000LL + a->tv_nsec + n / 2) / n;
100*cf84ac9aSAndroid Build Coastguard Worker tv->tv_sec = a->tv_sec / n + nsec / 1000000000;
101*cf84ac9aSAndroid Build Coastguard Worker tv->tv_nsec = nsec % 1000000000;
102*cf84ac9aSAndroid Build Coastguard Worker }
103*cf84ac9aSAndroid Build Coastguard Worker
104*cf84ac9aSAndroid Build Coastguard Worker void
ts_mul(struct timespec * tv,const struct timespec * a,int n)105*cf84ac9aSAndroid Build Coastguard Worker ts_mul(struct timespec *tv, const struct timespec *a, int n)
106*cf84ac9aSAndroid Build Coastguard Worker {
107*cf84ac9aSAndroid Build Coastguard Worker long long nsec = a->tv_nsec * n;
108*cf84ac9aSAndroid Build Coastguard Worker tv->tv_sec = a->tv_sec * n + nsec / 1000000000;
109*cf84ac9aSAndroid Build Coastguard Worker tv->tv_nsec = nsec % 1000000000;
110*cf84ac9aSAndroid Build Coastguard Worker }
111*cf84ac9aSAndroid Build Coastguard Worker
112*cf84ac9aSAndroid Build Coastguard Worker #if !defined HAVE_STPCPY
113*cf84ac9aSAndroid Build Coastguard Worker char *
stpcpy(char * dst,const char * src)114*cf84ac9aSAndroid Build Coastguard Worker stpcpy(char *dst, const char *src)
115*cf84ac9aSAndroid Build Coastguard Worker {
116*cf84ac9aSAndroid Build Coastguard Worker while ((*dst = *src++) != '\0')
117*cf84ac9aSAndroid Build Coastguard Worker dst++;
118*cf84ac9aSAndroid Build Coastguard Worker return dst;
119*cf84ac9aSAndroid Build Coastguard Worker }
120*cf84ac9aSAndroid Build Coastguard Worker #endif
121*cf84ac9aSAndroid Build Coastguard Worker
122*cf84ac9aSAndroid Build Coastguard Worker /* Find a next bit which is set.
123*cf84ac9aSAndroid Build Coastguard Worker * Starts testing at cur_bit.
124*cf84ac9aSAndroid Build Coastguard Worker * Returns -1 if no more bits are set.
125*cf84ac9aSAndroid Build Coastguard Worker *
126*cf84ac9aSAndroid Build Coastguard Worker * We never touch bytes we don't need to.
127*cf84ac9aSAndroid Build Coastguard Worker * On big-endian, array is assumed to consist of
128*cf84ac9aSAndroid Build Coastguard Worker * current_wordsize wide words: for example, is current_wordsize is 4,
129*cf84ac9aSAndroid Build Coastguard Worker * the bytes are walked in 3,2,1,0, 7,6,5,4, 11,10,9,8 ... sequence.
130*cf84ac9aSAndroid Build Coastguard Worker * On little-endian machines, word size is immaterial.
131*cf84ac9aSAndroid Build Coastguard Worker */
132*cf84ac9aSAndroid Build Coastguard Worker int
next_set_bit(const void * bit_array,unsigned cur_bit,unsigned size_bits)133*cf84ac9aSAndroid Build Coastguard Worker next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_bits)
134*cf84ac9aSAndroid Build Coastguard Worker {
135*cf84ac9aSAndroid Build Coastguard Worker const unsigned endian = 1;
136*cf84ac9aSAndroid Build Coastguard Worker int little_endian = *(char *) (void *) &endian;
137*cf84ac9aSAndroid Build Coastguard Worker
138*cf84ac9aSAndroid Build Coastguard Worker const uint8_t *array = bit_array;
139*cf84ac9aSAndroid Build Coastguard Worker unsigned pos = cur_bit / 8;
140*cf84ac9aSAndroid Build Coastguard Worker unsigned pos_xor_mask = little_endian ? 0 : current_wordsize-1;
141*cf84ac9aSAndroid Build Coastguard Worker
142*cf84ac9aSAndroid Build Coastguard Worker for (;;) {
143*cf84ac9aSAndroid Build Coastguard Worker uint8_t bitmask;
144*cf84ac9aSAndroid Build Coastguard Worker uint8_t cur_byte;
145*cf84ac9aSAndroid Build Coastguard Worker
146*cf84ac9aSAndroid Build Coastguard Worker if (cur_bit >= size_bits)
147*cf84ac9aSAndroid Build Coastguard Worker return -1;
148*cf84ac9aSAndroid Build Coastguard Worker cur_byte = array[pos ^ pos_xor_mask];
149*cf84ac9aSAndroid Build Coastguard Worker if (cur_byte == 0) {
150*cf84ac9aSAndroid Build Coastguard Worker cur_bit = (cur_bit + 8) & (-8);
151*cf84ac9aSAndroid Build Coastguard Worker pos++;
152*cf84ac9aSAndroid Build Coastguard Worker continue;
153*cf84ac9aSAndroid Build Coastguard Worker }
154*cf84ac9aSAndroid Build Coastguard Worker bitmask = 1 << (cur_bit & 7);
155*cf84ac9aSAndroid Build Coastguard Worker for (;;) {
156*cf84ac9aSAndroid Build Coastguard Worker if (cur_byte & bitmask)
157*cf84ac9aSAndroid Build Coastguard Worker return cur_bit;
158*cf84ac9aSAndroid Build Coastguard Worker cur_bit++;
159*cf84ac9aSAndroid Build Coastguard Worker if (cur_bit >= size_bits)
160*cf84ac9aSAndroid Build Coastguard Worker return -1;
161*cf84ac9aSAndroid Build Coastguard Worker bitmask <<= 1;
162*cf84ac9aSAndroid Build Coastguard Worker /* This check *can't be* optimized out: */
163*cf84ac9aSAndroid Build Coastguard Worker if (bitmask == 0)
164*cf84ac9aSAndroid Build Coastguard Worker break;
165*cf84ac9aSAndroid Build Coastguard Worker }
166*cf84ac9aSAndroid Build Coastguard Worker pos++;
167*cf84ac9aSAndroid Build Coastguard Worker }
168*cf84ac9aSAndroid Build Coastguard Worker }
169*cf84ac9aSAndroid Build Coastguard Worker
170*cf84ac9aSAndroid Build Coastguard Worker /*
171*cf84ac9aSAndroid Build Coastguard Worker * Fetch 64bit argument at position arg_no and
172*cf84ac9aSAndroid Build Coastguard Worker * return the index of the next argument.
173*cf84ac9aSAndroid Build Coastguard Worker */
174*cf84ac9aSAndroid Build Coastguard Worker int
getllval(struct tcb * tcp,unsigned long long * val,int arg_no)175*cf84ac9aSAndroid Build Coastguard Worker getllval(struct tcb *tcp, unsigned long long *val, int arg_no)
176*cf84ac9aSAndroid Build Coastguard Worker {
177*cf84ac9aSAndroid Build Coastguard Worker #if SIZEOF_KERNEL_LONG_T > 4
178*cf84ac9aSAndroid Build Coastguard Worker # ifndef current_klongsize
179*cf84ac9aSAndroid Build Coastguard Worker if (current_klongsize < SIZEOF_KERNEL_LONG_T) {
180*cf84ac9aSAndroid Build Coastguard Worker # if defined(AARCH64) || defined(POWERPC64)
181*cf84ac9aSAndroid Build Coastguard Worker /* Align arg_no to the next even number. */
182*cf84ac9aSAndroid Build Coastguard Worker arg_no = (arg_no + 1) & 0xe;
183*cf84ac9aSAndroid Build Coastguard Worker # endif /* AARCH64 || POWERPC64 */
184*cf84ac9aSAndroid Build Coastguard Worker *val = ULONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
185*cf84ac9aSAndroid Build Coastguard Worker arg_no += 2;
186*cf84ac9aSAndroid Build Coastguard Worker } else
187*cf84ac9aSAndroid Build Coastguard Worker # endif /* !current_klongsize */
188*cf84ac9aSAndroid Build Coastguard Worker {
189*cf84ac9aSAndroid Build Coastguard Worker *val = tcp->u_arg[arg_no];
190*cf84ac9aSAndroid Build Coastguard Worker arg_no++;
191*cf84ac9aSAndroid Build Coastguard Worker }
192*cf84ac9aSAndroid Build Coastguard Worker #else /* SIZEOF_KERNEL_LONG_T == 4 */
193*cf84ac9aSAndroid Build Coastguard Worker # if defined __ARM_EABI__ \
194*cf84ac9aSAndroid Build Coastguard Worker || defined LINUX_MIPSO32 \
195*cf84ac9aSAndroid Build Coastguard Worker || defined POWERPC \
196*cf84ac9aSAndroid Build Coastguard Worker || defined XTENSA
197*cf84ac9aSAndroid Build Coastguard Worker /* Align arg_no to the next even number. */
198*cf84ac9aSAndroid Build Coastguard Worker arg_no = (arg_no + 1) & 0xe;
199*cf84ac9aSAndroid Build Coastguard Worker # elif defined SH
200*cf84ac9aSAndroid Build Coastguard Worker /*
201*cf84ac9aSAndroid Build Coastguard Worker * The SH4 ABI does allow long longs in odd-numbered registers, but
202*cf84ac9aSAndroid Build Coastguard Worker * does not allow them to be split between registers and memory - and
203*cf84ac9aSAndroid Build Coastguard Worker * there are only four argument registers for normal functions. As a
204*cf84ac9aSAndroid Build Coastguard Worker * result, pread, for example, takes an extra padding argument before
205*cf84ac9aSAndroid Build Coastguard Worker * the offset. This was changed late in the 2.4 series (around 2.4.20).
206*cf84ac9aSAndroid Build Coastguard Worker */
207*cf84ac9aSAndroid Build Coastguard Worker if (arg_no == 3)
208*cf84ac9aSAndroid Build Coastguard Worker arg_no++;
209*cf84ac9aSAndroid Build Coastguard Worker # endif /* __ARM_EABI__ || LINUX_MIPSO32 || POWERPC || XTENSA || SH */
210*cf84ac9aSAndroid Build Coastguard Worker *val = ULONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
211*cf84ac9aSAndroid Build Coastguard Worker arg_no += 2;
212*cf84ac9aSAndroid Build Coastguard Worker #endif
213*cf84ac9aSAndroid Build Coastguard Worker
214*cf84ac9aSAndroid Build Coastguard Worker return arg_no;
215*cf84ac9aSAndroid Build Coastguard Worker }
216*cf84ac9aSAndroid Build Coastguard Worker
217*cf84ac9aSAndroid Build Coastguard Worker /*
218*cf84ac9aSAndroid Build Coastguard Worker * Print 64bit argument at position arg_no and
219*cf84ac9aSAndroid Build Coastguard Worker * return the index of the next argument.
220*cf84ac9aSAndroid Build Coastguard Worker */
221*cf84ac9aSAndroid Build Coastguard Worker int
printllval(struct tcb * tcp,const char * format,int arg_no)222*cf84ac9aSAndroid Build Coastguard Worker printllval(struct tcb *tcp, const char *format, int arg_no)
223*cf84ac9aSAndroid Build Coastguard Worker {
224*cf84ac9aSAndroid Build Coastguard Worker unsigned long long val = 0;
225*cf84ac9aSAndroid Build Coastguard Worker
226*cf84ac9aSAndroid Build Coastguard Worker arg_no = getllval(tcp, &val, arg_no);
227*cf84ac9aSAndroid Build Coastguard Worker tprintf(format, val);
228*cf84ac9aSAndroid Build Coastguard Worker return arg_no;
229*cf84ac9aSAndroid Build Coastguard Worker }
230*cf84ac9aSAndroid Build Coastguard Worker
231*cf84ac9aSAndroid Build Coastguard Worker void
printaddr64(const uint64_t addr)232*cf84ac9aSAndroid Build Coastguard Worker printaddr64(const uint64_t addr)
233*cf84ac9aSAndroid Build Coastguard Worker {
234*cf84ac9aSAndroid Build Coastguard Worker if (!addr)
235*cf84ac9aSAndroid Build Coastguard Worker tprints("NULL");
236*cf84ac9aSAndroid Build Coastguard Worker else
237*cf84ac9aSAndroid Build Coastguard Worker tprintf("%#" PRIx64, addr);
238*cf84ac9aSAndroid Build Coastguard Worker }
239*cf84ac9aSAndroid Build Coastguard Worker
240*cf84ac9aSAndroid Build Coastguard Worker #define DEF_PRINTNUM(name, type) \
241*cf84ac9aSAndroid Build Coastguard Worker bool \
242*cf84ac9aSAndroid Build Coastguard Worker printnum_ ## name(struct tcb *const tcp, const kernel_ulong_t addr, \
243*cf84ac9aSAndroid Build Coastguard Worker const char *const fmt) \
244*cf84ac9aSAndroid Build Coastguard Worker { \
245*cf84ac9aSAndroid Build Coastguard Worker type num; \
246*cf84ac9aSAndroid Build Coastguard Worker if (umove_or_printaddr(tcp, addr, &num)) \
247*cf84ac9aSAndroid Build Coastguard Worker return false; \
248*cf84ac9aSAndroid Build Coastguard Worker tprints("["); \
249*cf84ac9aSAndroid Build Coastguard Worker tprintf(fmt, num); \
250*cf84ac9aSAndroid Build Coastguard Worker tprints("]"); \
251*cf84ac9aSAndroid Build Coastguard Worker return true; \
252*cf84ac9aSAndroid Build Coastguard Worker }
253*cf84ac9aSAndroid Build Coastguard Worker
254*cf84ac9aSAndroid Build Coastguard Worker #define DEF_PRINTNUM_ADDR(name, type) \
255*cf84ac9aSAndroid Build Coastguard Worker bool \
256*cf84ac9aSAndroid Build Coastguard Worker printnum_addr_ ## name(struct tcb *tcp, const kernel_ulong_t addr) \
257*cf84ac9aSAndroid Build Coastguard Worker { \
258*cf84ac9aSAndroid Build Coastguard Worker type num; \
259*cf84ac9aSAndroid Build Coastguard Worker if (umove_or_printaddr(tcp, addr, &num)) \
260*cf84ac9aSAndroid Build Coastguard Worker return false; \
261*cf84ac9aSAndroid Build Coastguard Worker tprints("["); \
262*cf84ac9aSAndroid Build Coastguard Worker printaddr64(num); \
263*cf84ac9aSAndroid Build Coastguard Worker tprints("]"); \
264*cf84ac9aSAndroid Build Coastguard Worker return true; \
265*cf84ac9aSAndroid Build Coastguard Worker }
266*cf84ac9aSAndroid Build Coastguard Worker
267*cf84ac9aSAndroid Build Coastguard Worker #define DEF_PRINTPAIR(name, type) \
268*cf84ac9aSAndroid Build Coastguard Worker bool \
269*cf84ac9aSAndroid Build Coastguard Worker printpair_ ## name(struct tcb *const tcp, const kernel_ulong_t addr, \
270*cf84ac9aSAndroid Build Coastguard Worker const char *const fmt) \
271*cf84ac9aSAndroid Build Coastguard Worker { \
272*cf84ac9aSAndroid Build Coastguard Worker type pair[2]; \
273*cf84ac9aSAndroid Build Coastguard Worker if (umove_or_printaddr(tcp, addr, &pair)) \
274*cf84ac9aSAndroid Build Coastguard Worker return false; \
275*cf84ac9aSAndroid Build Coastguard Worker tprints("["); \
276*cf84ac9aSAndroid Build Coastguard Worker tprintf(fmt, pair[0]); \
277*cf84ac9aSAndroid Build Coastguard Worker tprints(", "); \
278*cf84ac9aSAndroid Build Coastguard Worker tprintf(fmt, pair[1]); \
279*cf84ac9aSAndroid Build Coastguard Worker tprints("]"); \
280*cf84ac9aSAndroid Build Coastguard Worker return true; \
281*cf84ac9aSAndroid Build Coastguard Worker }
282*cf84ac9aSAndroid Build Coastguard Worker
DEF_PRINTNUM(int,int)283*cf84ac9aSAndroid Build Coastguard Worker DEF_PRINTNUM(int, int)
284*cf84ac9aSAndroid Build Coastguard Worker DEF_PRINTNUM_ADDR(int, unsigned int)
285*cf84ac9aSAndroid Build Coastguard Worker DEF_PRINTPAIR(int, int)
286*cf84ac9aSAndroid Build Coastguard Worker DEF_PRINTNUM(short, short)
287*cf84ac9aSAndroid Build Coastguard Worker DEF_PRINTNUM(int64, uint64_t)
288*cf84ac9aSAndroid Build Coastguard Worker DEF_PRINTNUM_ADDR(int64, uint64_t)
289*cf84ac9aSAndroid Build Coastguard Worker DEF_PRINTPAIR(int64, uint64_t)
290*cf84ac9aSAndroid Build Coastguard Worker
291*cf84ac9aSAndroid Build Coastguard Worker #ifndef current_wordsize
292*cf84ac9aSAndroid Build Coastguard Worker bool
293*cf84ac9aSAndroid Build Coastguard Worker printnum_long_int(struct tcb *const tcp, const kernel_ulong_t addr,
294*cf84ac9aSAndroid Build Coastguard Worker const char *const fmt_long, const char *const fmt_int)
295*cf84ac9aSAndroid Build Coastguard Worker {
296*cf84ac9aSAndroid Build Coastguard Worker if (current_wordsize > sizeof(int)) {
297*cf84ac9aSAndroid Build Coastguard Worker return printnum_int64(tcp, addr, fmt_long);
298*cf84ac9aSAndroid Build Coastguard Worker } else {
299*cf84ac9aSAndroid Build Coastguard Worker return printnum_int(tcp, addr, fmt_int);
300*cf84ac9aSAndroid Build Coastguard Worker }
301*cf84ac9aSAndroid Build Coastguard Worker }
302*cf84ac9aSAndroid Build Coastguard Worker
303*cf84ac9aSAndroid Build Coastguard Worker bool
printnum_addr_long_int(struct tcb * tcp,const kernel_ulong_t addr)304*cf84ac9aSAndroid Build Coastguard Worker printnum_addr_long_int(struct tcb *tcp, const kernel_ulong_t addr)
305*cf84ac9aSAndroid Build Coastguard Worker {
306*cf84ac9aSAndroid Build Coastguard Worker if (current_wordsize > sizeof(int)) {
307*cf84ac9aSAndroid Build Coastguard Worker return printnum_addr_int64(tcp, addr);
308*cf84ac9aSAndroid Build Coastguard Worker } else {
309*cf84ac9aSAndroid Build Coastguard Worker return printnum_addr_int(tcp, addr);
310*cf84ac9aSAndroid Build Coastguard Worker }
311*cf84ac9aSAndroid Build Coastguard Worker }
312*cf84ac9aSAndroid Build Coastguard Worker #endif /* !current_wordsize */
313*cf84ac9aSAndroid Build Coastguard Worker
314*cf84ac9aSAndroid Build Coastguard Worker #ifndef current_klongsize
315*cf84ac9aSAndroid Build Coastguard Worker bool
printnum_addr_klong_int(struct tcb * tcp,const kernel_ulong_t addr)316*cf84ac9aSAndroid Build Coastguard Worker printnum_addr_klong_int(struct tcb *tcp, const kernel_ulong_t addr)
317*cf84ac9aSAndroid Build Coastguard Worker {
318*cf84ac9aSAndroid Build Coastguard Worker if (current_klongsize > sizeof(int)) {
319*cf84ac9aSAndroid Build Coastguard Worker return printnum_addr_int64(tcp, addr);
320*cf84ac9aSAndroid Build Coastguard Worker } else {
321*cf84ac9aSAndroid Build Coastguard Worker return printnum_addr_int(tcp, addr);
322*cf84ac9aSAndroid Build Coastguard Worker }
323*cf84ac9aSAndroid Build Coastguard Worker }
324*cf84ac9aSAndroid Build Coastguard Worker #endif /* !current_klongsize */
325*cf84ac9aSAndroid Build Coastguard Worker
326*cf84ac9aSAndroid Build Coastguard Worker /**
327*cf84ac9aSAndroid Build Coastguard Worker * Prints time to a (static internal) buffer and returns pointer to it.
328*cf84ac9aSAndroid Build Coastguard Worker * Returns NULL if the provided time specification is not correct.
329*cf84ac9aSAndroid Build Coastguard Worker *
330*cf84ac9aSAndroid Build Coastguard Worker * @param sec Seconds since epoch.
331*cf84ac9aSAndroid Build Coastguard Worker * @param part_sec Amount of second parts since the start of a second.
332*cf84ac9aSAndroid Build Coastguard Worker * @param max_part_sec Maximum value of a valid part_sec.
333*cf84ac9aSAndroid Build Coastguard Worker * @param width 1 + floor(log10(max_part_sec)).
334*cf84ac9aSAndroid Build Coastguard Worker * @return Pointer to a statically allocated string on success,
335*cf84ac9aSAndroid Build Coastguard Worker * NULL on error.
336*cf84ac9aSAndroid Build Coastguard Worker */
337*cf84ac9aSAndroid Build Coastguard Worker static const char *
sprinttime_ex(const long long sec,const unsigned long long part_sec,const unsigned int max_part_sec,const int width)338*cf84ac9aSAndroid Build Coastguard Worker sprinttime_ex(const long long sec, const unsigned long long part_sec,
339*cf84ac9aSAndroid Build Coastguard Worker const unsigned int max_part_sec, const int width)
340*cf84ac9aSAndroid Build Coastguard Worker {
341*cf84ac9aSAndroid Build Coastguard Worker static char buf[sizeof(int) * 3 * 6 + sizeof(part_sec) * 3
342*cf84ac9aSAndroid Build Coastguard Worker + sizeof("+0000")];
343*cf84ac9aSAndroid Build Coastguard Worker
344*cf84ac9aSAndroid Build Coastguard Worker if ((sec == 0 && part_sec == 0) || part_sec > max_part_sec)
345*cf84ac9aSAndroid Build Coastguard Worker return NULL;
346*cf84ac9aSAndroid Build Coastguard Worker
347*cf84ac9aSAndroid Build Coastguard Worker time_t t = (time_t) sec;
348*cf84ac9aSAndroid Build Coastguard Worker struct tm *tmp = (sec == t) ? localtime(&t) : NULL;
349*cf84ac9aSAndroid Build Coastguard Worker if (!tmp)
350*cf84ac9aSAndroid Build Coastguard Worker return NULL;
351*cf84ac9aSAndroid Build Coastguard Worker
352*cf84ac9aSAndroid Build Coastguard Worker size_t pos = strftime(buf, sizeof(buf), "%FT%T", tmp);
353*cf84ac9aSAndroid Build Coastguard Worker if (!pos)
354*cf84ac9aSAndroid Build Coastguard Worker return NULL;
355*cf84ac9aSAndroid Build Coastguard Worker
356*cf84ac9aSAndroid Build Coastguard Worker if (part_sec > 0)
357*cf84ac9aSAndroid Build Coastguard Worker pos += xsnprintf(buf + pos, sizeof(buf) - pos, ".%0*llu",
358*cf84ac9aSAndroid Build Coastguard Worker width, part_sec);
359*cf84ac9aSAndroid Build Coastguard Worker
360*cf84ac9aSAndroid Build Coastguard Worker return strftime(buf + pos, sizeof(buf) - pos, "%z", tmp) ? buf : NULL;
361*cf84ac9aSAndroid Build Coastguard Worker }
362*cf84ac9aSAndroid Build Coastguard Worker
363*cf84ac9aSAndroid Build Coastguard Worker const char *
sprinttime(long long sec)364*cf84ac9aSAndroid Build Coastguard Worker sprinttime(long long sec)
365*cf84ac9aSAndroid Build Coastguard Worker {
366*cf84ac9aSAndroid Build Coastguard Worker return sprinttime_ex(sec, 0, 0, 0);
367*cf84ac9aSAndroid Build Coastguard Worker }
368*cf84ac9aSAndroid Build Coastguard Worker
369*cf84ac9aSAndroid Build Coastguard Worker const char *
sprinttime_usec(long long sec,unsigned long long usec)370*cf84ac9aSAndroid Build Coastguard Worker sprinttime_usec(long long sec, unsigned long long usec)
371*cf84ac9aSAndroid Build Coastguard Worker {
372*cf84ac9aSAndroid Build Coastguard Worker return sprinttime_ex(sec, usec, 999999, 6);
373*cf84ac9aSAndroid Build Coastguard Worker }
374*cf84ac9aSAndroid Build Coastguard Worker
375*cf84ac9aSAndroid Build Coastguard Worker const char *
sprinttime_nsec(long long sec,unsigned long long nsec)376*cf84ac9aSAndroid Build Coastguard Worker sprinttime_nsec(long long sec, unsigned long long nsec)
377*cf84ac9aSAndroid Build Coastguard Worker {
378*cf84ac9aSAndroid Build Coastguard Worker return sprinttime_ex(sec, nsec, 999999999, 9);
379*cf84ac9aSAndroid Build Coastguard Worker }
380*cf84ac9aSAndroid Build Coastguard Worker
381*cf84ac9aSAndroid Build Coastguard Worker enum sock_proto
getfdproto(struct tcb * tcp,int fd)382*cf84ac9aSAndroid Build Coastguard Worker getfdproto(struct tcb *tcp, int fd)
383*cf84ac9aSAndroid Build Coastguard Worker {
384*cf84ac9aSAndroid Build Coastguard Worker #ifdef HAVE_SYS_XATTR_H
385*cf84ac9aSAndroid Build Coastguard Worker size_t bufsize = 256;
386*cf84ac9aSAndroid Build Coastguard Worker char buf[bufsize];
387*cf84ac9aSAndroid Build Coastguard Worker ssize_t r;
388*cf84ac9aSAndroid Build Coastguard Worker char path[sizeof("/proc/%u/fd/%u") + 2 * sizeof(int)*3];
389*cf84ac9aSAndroid Build Coastguard Worker
390*cf84ac9aSAndroid Build Coastguard Worker if (fd < 0)
391*cf84ac9aSAndroid Build Coastguard Worker return SOCK_PROTO_UNKNOWN;
392*cf84ac9aSAndroid Build Coastguard Worker
393*cf84ac9aSAndroid Build Coastguard Worker xsprintf(path, "/proc/%u/fd/%u", tcp->pid, fd);
394*cf84ac9aSAndroid Build Coastguard Worker r = getxattr(path, "system.sockprotoname", buf, bufsize - 1);
395*cf84ac9aSAndroid Build Coastguard Worker if (r <= 0)
396*cf84ac9aSAndroid Build Coastguard Worker return SOCK_PROTO_UNKNOWN;
397*cf84ac9aSAndroid Build Coastguard Worker else {
398*cf84ac9aSAndroid Build Coastguard Worker /*
399*cf84ac9aSAndroid Build Coastguard Worker * This is a protection for the case when the kernel
400*cf84ac9aSAndroid Build Coastguard Worker * side does not append a null byte to the buffer.
401*cf84ac9aSAndroid Build Coastguard Worker */
402*cf84ac9aSAndroid Build Coastguard Worker buf[r] = '\0';
403*cf84ac9aSAndroid Build Coastguard Worker
404*cf84ac9aSAndroid Build Coastguard Worker return get_proto_by_name(buf);
405*cf84ac9aSAndroid Build Coastguard Worker }
406*cf84ac9aSAndroid Build Coastguard Worker #else
407*cf84ac9aSAndroid Build Coastguard Worker return SOCK_PROTO_UNKNOWN;
408*cf84ac9aSAndroid Build Coastguard Worker #endif
409*cf84ac9aSAndroid Build Coastguard Worker }
410*cf84ac9aSAndroid Build Coastguard Worker
411*cf84ac9aSAndroid Build Coastguard Worker unsigned long
getfdinode(struct tcb * tcp,int fd)412*cf84ac9aSAndroid Build Coastguard Worker getfdinode(struct tcb *tcp, int fd)
413*cf84ac9aSAndroid Build Coastguard Worker {
414*cf84ac9aSAndroid Build Coastguard Worker char path[PATH_MAX + 1];
415*cf84ac9aSAndroid Build Coastguard Worker
416*cf84ac9aSAndroid Build Coastguard Worker if (getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
417*cf84ac9aSAndroid Build Coastguard Worker const char *str = STR_STRIP_PREFIX(path, "socket:[");
418*cf84ac9aSAndroid Build Coastguard Worker
419*cf84ac9aSAndroid Build Coastguard Worker if (str != path) {
420*cf84ac9aSAndroid Build Coastguard Worker const size_t str_len = strlen(str);
421*cf84ac9aSAndroid Build Coastguard Worker if (str_len && str[str_len - 1] == ']')
422*cf84ac9aSAndroid Build Coastguard Worker return strtoul(str, NULL, 10);
423*cf84ac9aSAndroid Build Coastguard Worker }
424*cf84ac9aSAndroid Build Coastguard Worker }
425*cf84ac9aSAndroid Build Coastguard Worker
426*cf84ac9aSAndroid Build Coastguard Worker return 0;
427*cf84ac9aSAndroid Build Coastguard Worker }
428*cf84ac9aSAndroid Build Coastguard Worker
429*cf84ac9aSAndroid Build Coastguard Worker static bool
printsocket(struct tcb * tcp,int fd,const char * path)430*cf84ac9aSAndroid Build Coastguard Worker printsocket(struct tcb *tcp, int fd, const char *path)
431*cf84ac9aSAndroid Build Coastguard Worker {
432*cf84ac9aSAndroid Build Coastguard Worker const char *str = STR_STRIP_PREFIX(path, "socket:[");
433*cf84ac9aSAndroid Build Coastguard Worker size_t len;
434*cf84ac9aSAndroid Build Coastguard Worker unsigned long inode;
435*cf84ac9aSAndroid Build Coastguard Worker
436*cf84ac9aSAndroid Build Coastguard Worker return (str != path)
437*cf84ac9aSAndroid Build Coastguard Worker && (len = strlen(str))
438*cf84ac9aSAndroid Build Coastguard Worker && (str[len - 1] == ']')
439*cf84ac9aSAndroid Build Coastguard Worker && (inode = strtoul(str, NULL, 10))
440*cf84ac9aSAndroid Build Coastguard Worker && print_sockaddr_by_inode(tcp, fd, inode);
441*cf84ac9aSAndroid Build Coastguard Worker }
442*cf84ac9aSAndroid Build Coastguard Worker
443*cf84ac9aSAndroid Build Coastguard Worker static bool
printdev(struct tcb * tcp,int fd,const char * path)444*cf84ac9aSAndroid Build Coastguard Worker printdev(struct tcb *tcp, int fd, const char *path)
445*cf84ac9aSAndroid Build Coastguard Worker {
446*cf84ac9aSAndroid Build Coastguard Worker struct_stat st;
447*cf84ac9aSAndroid Build Coastguard Worker
448*cf84ac9aSAndroid Build Coastguard Worker if (path[0] != '/')
449*cf84ac9aSAndroid Build Coastguard Worker return false;
450*cf84ac9aSAndroid Build Coastguard Worker
451*cf84ac9aSAndroid Build Coastguard Worker if (stat_file(path, &st)) {
452*cf84ac9aSAndroid Build Coastguard Worker debug_func_perror_msg("stat(\"%s\")", path);
453*cf84ac9aSAndroid Build Coastguard Worker return false;
454*cf84ac9aSAndroid Build Coastguard Worker }
455*cf84ac9aSAndroid Build Coastguard Worker
456*cf84ac9aSAndroid Build Coastguard Worker switch (st.st_mode & S_IFMT) {
457*cf84ac9aSAndroid Build Coastguard Worker case S_IFBLK:
458*cf84ac9aSAndroid Build Coastguard Worker case S_IFCHR:
459*cf84ac9aSAndroid Build Coastguard Worker print_quoted_string_ex(path, strlen(path),
460*cf84ac9aSAndroid Build Coastguard Worker QUOTE_OMIT_LEADING_TRAILING_QUOTES,
461*cf84ac9aSAndroid Build Coastguard Worker "<>");
462*cf84ac9aSAndroid Build Coastguard Worker tprintf("<%s %u:%u>",
463*cf84ac9aSAndroid Build Coastguard Worker S_ISBLK(st.st_mode)? "block" : "char",
464*cf84ac9aSAndroid Build Coastguard Worker major(st.st_rdev), minor(st.st_rdev));
465*cf84ac9aSAndroid Build Coastguard Worker return true;
466*cf84ac9aSAndroid Build Coastguard Worker }
467*cf84ac9aSAndroid Build Coastguard Worker
468*cf84ac9aSAndroid Build Coastguard Worker return false;
469*cf84ac9aSAndroid Build Coastguard Worker }
470*cf84ac9aSAndroid Build Coastguard Worker
471*cf84ac9aSAndroid Build Coastguard Worker void
printfd(struct tcb * tcp,int fd)472*cf84ac9aSAndroid Build Coastguard Worker printfd(struct tcb *tcp, int fd)
473*cf84ac9aSAndroid Build Coastguard Worker {
474*cf84ac9aSAndroid Build Coastguard Worker char path[PATH_MAX + 1];
475*cf84ac9aSAndroid Build Coastguard Worker if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
476*cf84ac9aSAndroid Build Coastguard Worker tprintf("%d<", fd);
477*cf84ac9aSAndroid Build Coastguard Worker if (show_fd_path <= 1
478*cf84ac9aSAndroid Build Coastguard Worker || (!printsocket(tcp, fd, path)
479*cf84ac9aSAndroid Build Coastguard Worker && !printdev(tcp, fd, path))) {
480*cf84ac9aSAndroid Build Coastguard Worker print_quoted_string_ex(path, strlen(path),
481*cf84ac9aSAndroid Build Coastguard Worker QUOTE_OMIT_LEADING_TRAILING_QUOTES, "<>");
482*cf84ac9aSAndroid Build Coastguard Worker }
483*cf84ac9aSAndroid Build Coastguard Worker tprints(">");
484*cf84ac9aSAndroid Build Coastguard Worker } else
485*cf84ac9aSAndroid Build Coastguard Worker tprintf("%d", fd);
486*cf84ac9aSAndroid Build Coastguard Worker }
487*cf84ac9aSAndroid Build Coastguard Worker
488*cf84ac9aSAndroid Build Coastguard Worker /*
489*cf84ac9aSAndroid Build Coastguard Worker * Quote string `instr' of length `size'
490*cf84ac9aSAndroid Build Coastguard Worker * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
491*cf84ac9aSAndroid Build Coastguard Worker *
492*cf84ac9aSAndroid Build Coastguard Worker * `escape_chars' specifies characters (in addition to characters with
493*cf84ac9aSAndroid Build Coastguard Worker * codes 0..31, 127..255, single and double quotes) that should be escaped.
494*cf84ac9aSAndroid Build Coastguard Worker *
495*cf84ac9aSAndroid Build Coastguard Worker * If QUOTE_0_TERMINATED `style' flag is set,
496*cf84ac9aSAndroid Build Coastguard Worker * treat `instr' as a NUL-terminated string,
497*cf84ac9aSAndroid Build Coastguard Worker * checking up to (`size' + 1) bytes of `instr'.
498*cf84ac9aSAndroid Build Coastguard Worker *
499*cf84ac9aSAndroid Build Coastguard Worker * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
500*cf84ac9aSAndroid Build Coastguard Worker * do not add leading and trailing quoting symbols.
501*cf84ac9aSAndroid Build Coastguard Worker *
502*cf84ac9aSAndroid Build Coastguard Worker * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
503*cf84ac9aSAndroid Build Coastguard Worker * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
504*cf84ac9aSAndroid Build Coastguard Worker */
505*cf84ac9aSAndroid Build Coastguard Worker int
string_quote(const char * instr,char * outstr,const unsigned int size,const unsigned int style,const char * escape_chars)506*cf84ac9aSAndroid Build Coastguard Worker string_quote(const char *instr, char *outstr, const unsigned int size,
507*cf84ac9aSAndroid Build Coastguard Worker const unsigned int style, const char *escape_chars)
508*cf84ac9aSAndroid Build Coastguard Worker {
509*cf84ac9aSAndroid Build Coastguard Worker const unsigned char *ustr = (const unsigned char *) instr;
510*cf84ac9aSAndroid Build Coastguard Worker char *s = outstr;
511*cf84ac9aSAndroid Build Coastguard Worker unsigned int i;
512*cf84ac9aSAndroid Build Coastguard Worker int usehex, c, eol;
513*cf84ac9aSAndroid Build Coastguard Worker bool escape;
514*cf84ac9aSAndroid Build Coastguard Worker
515*cf84ac9aSAndroid Build Coastguard Worker if (style & QUOTE_0_TERMINATED)
516*cf84ac9aSAndroid Build Coastguard Worker eol = '\0';
517*cf84ac9aSAndroid Build Coastguard Worker else
518*cf84ac9aSAndroid Build Coastguard Worker eol = 0x100; /* this can never match a char */
519*cf84ac9aSAndroid Build Coastguard Worker
520*cf84ac9aSAndroid Build Coastguard Worker usehex = 0;
521*cf84ac9aSAndroid Build Coastguard Worker if ((xflag > 1) || (style & QUOTE_FORCE_HEX)) {
522*cf84ac9aSAndroid Build Coastguard Worker usehex = 1;
523*cf84ac9aSAndroid Build Coastguard Worker } else if (xflag) {
524*cf84ac9aSAndroid Build Coastguard Worker /* Check for presence of symbol which require
525*cf84ac9aSAndroid Build Coastguard Worker to hex-quote the whole string. */
526*cf84ac9aSAndroid Build Coastguard Worker for (i = 0; i < size; ++i) {
527*cf84ac9aSAndroid Build Coastguard Worker c = ustr[i];
528*cf84ac9aSAndroid Build Coastguard Worker /* Check for NUL-terminated string. */
529*cf84ac9aSAndroid Build Coastguard Worker if (c == eol)
530*cf84ac9aSAndroid Build Coastguard Worker break;
531*cf84ac9aSAndroid Build Coastguard Worker
532*cf84ac9aSAndroid Build Coastguard Worker /* Force hex unless c is printable or whitespace */
533*cf84ac9aSAndroid Build Coastguard Worker if (c > 0x7e) {
534*cf84ac9aSAndroid Build Coastguard Worker usehex = 1;
535*cf84ac9aSAndroid Build Coastguard Worker break;
536*cf84ac9aSAndroid Build Coastguard Worker }
537*cf84ac9aSAndroid Build Coastguard Worker /* In ASCII isspace is only these chars: "\t\n\v\f\r".
538*cf84ac9aSAndroid Build Coastguard Worker * They happen to have ASCII codes 9,10,11,12,13.
539*cf84ac9aSAndroid Build Coastguard Worker */
540*cf84ac9aSAndroid Build Coastguard Worker if (c < ' ' && (unsigned)(c - 9) >= 5) {
541*cf84ac9aSAndroid Build Coastguard Worker usehex = 1;
542*cf84ac9aSAndroid Build Coastguard Worker break;
543*cf84ac9aSAndroid Build Coastguard Worker }
544*cf84ac9aSAndroid Build Coastguard Worker }
545*cf84ac9aSAndroid Build Coastguard Worker }
546*cf84ac9aSAndroid Build Coastguard Worker
547*cf84ac9aSAndroid Build Coastguard Worker if (style & QUOTE_EMIT_COMMENT)
548*cf84ac9aSAndroid Build Coastguard Worker s = stpcpy(s, " /* ");
549*cf84ac9aSAndroid Build Coastguard Worker if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
550*cf84ac9aSAndroid Build Coastguard Worker *s++ = '\"';
551*cf84ac9aSAndroid Build Coastguard Worker
552*cf84ac9aSAndroid Build Coastguard Worker if (usehex) {
553*cf84ac9aSAndroid Build Coastguard Worker /* Hex-quote the whole string. */
554*cf84ac9aSAndroid Build Coastguard Worker for (i = 0; i < size; ++i) {
555*cf84ac9aSAndroid Build Coastguard Worker c = ustr[i];
556*cf84ac9aSAndroid Build Coastguard Worker /* Check for NUL-terminated string. */
557*cf84ac9aSAndroid Build Coastguard Worker if (c == eol)
558*cf84ac9aSAndroid Build Coastguard Worker goto asciz_ended;
559*cf84ac9aSAndroid Build Coastguard Worker *s++ = '\\';
560*cf84ac9aSAndroid Build Coastguard Worker *s++ = 'x';
561*cf84ac9aSAndroid Build Coastguard Worker *s++ = "0123456789abcdef"[c >> 4];
562*cf84ac9aSAndroid Build Coastguard Worker *s++ = "0123456789abcdef"[c & 0xf];
563*cf84ac9aSAndroid Build Coastguard Worker }
564*cf84ac9aSAndroid Build Coastguard Worker
565*cf84ac9aSAndroid Build Coastguard Worker goto string_ended;
566*cf84ac9aSAndroid Build Coastguard Worker }
567*cf84ac9aSAndroid Build Coastguard Worker
568*cf84ac9aSAndroid Build Coastguard Worker for (i = 0; i < size; ++i) {
569*cf84ac9aSAndroid Build Coastguard Worker c = ustr[i];
570*cf84ac9aSAndroid Build Coastguard Worker /* Check for NUL-terminated string. */
571*cf84ac9aSAndroid Build Coastguard Worker if (c == eol)
572*cf84ac9aSAndroid Build Coastguard Worker goto asciz_ended;
573*cf84ac9aSAndroid Build Coastguard Worker if ((i == (size - 1)) &&
574*cf84ac9aSAndroid Build Coastguard Worker (style & QUOTE_OMIT_TRAILING_0) && (c == '\0'))
575*cf84ac9aSAndroid Build Coastguard Worker goto asciz_ended;
576*cf84ac9aSAndroid Build Coastguard Worker switch (c) {
577*cf84ac9aSAndroid Build Coastguard Worker case '\"': case '\\':
578*cf84ac9aSAndroid Build Coastguard Worker *s++ = '\\';
579*cf84ac9aSAndroid Build Coastguard Worker *s++ = c;
580*cf84ac9aSAndroid Build Coastguard Worker break;
581*cf84ac9aSAndroid Build Coastguard Worker case '\f':
582*cf84ac9aSAndroid Build Coastguard Worker *s++ = '\\';
583*cf84ac9aSAndroid Build Coastguard Worker *s++ = 'f';
584*cf84ac9aSAndroid Build Coastguard Worker break;
585*cf84ac9aSAndroid Build Coastguard Worker case '\n':
586*cf84ac9aSAndroid Build Coastguard Worker *s++ = '\\';
587*cf84ac9aSAndroid Build Coastguard Worker *s++ = 'n';
588*cf84ac9aSAndroid Build Coastguard Worker break;
589*cf84ac9aSAndroid Build Coastguard Worker case '\r':
590*cf84ac9aSAndroid Build Coastguard Worker *s++ = '\\';
591*cf84ac9aSAndroid Build Coastguard Worker *s++ = 'r';
592*cf84ac9aSAndroid Build Coastguard Worker break;
593*cf84ac9aSAndroid Build Coastguard Worker case '\t':
594*cf84ac9aSAndroid Build Coastguard Worker *s++ = '\\';
595*cf84ac9aSAndroid Build Coastguard Worker *s++ = 't';
596*cf84ac9aSAndroid Build Coastguard Worker break;
597*cf84ac9aSAndroid Build Coastguard Worker case '\v':
598*cf84ac9aSAndroid Build Coastguard Worker *s++ = '\\';
599*cf84ac9aSAndroid Build Coastguard Worker *s++ = 'v';
600*cf84ac9aSAndroid Build Coastguard Worker break;
601*cf84ac9aSAndroid Build Coastguard Worker default:
602*cf84ac9aSAndroid Build Coastguard Worker escape = (c < ' ') || (c > 0x7e);
603*cf84ac9aSAndroid Build Coastguard Worker
604*cf84ac9aSAndroid Build Coastguard Worker if (!escape && escape_chars)
605*cf84ac9aSAndroid Build Coastguard Worker escape = !!strchr(escape_chars, c);
606*cf84ac9aSAndroid Build Coastguard Worker
607*cf84ac9aSAndroid Build Coastguard Worker if (!escape) {
608*cf84ac9aSAndroid Build Coastguard Worker *s++ = c;
609*cf84ac9aSAndroid Build Coastguard Worker } else {
610*cf84ac9aSAndroid Build Coastguard Worker /* Print \octal */
611*cf84ac9aSAndroid Build Coastguard Worker *s++ = '\\';
612*cf84ac9aSAndroid Build Coastguard Worker if (i + 1 < size
613*cf84ac9aSAndroid Build Coastguard Worker && ustr[i + 1] >= '0'
614*cf84ac9aSAndroid Build Coastguard Worker && ustr[i + 1] <= '7'
615*cf84ac9aSAndroid Build Coastguard Worker ) {
616*cf84ac9aSAndroid Build Coastguard Worker /* Print \ooo */
617*cf84ac9aSAndroid Build Coastguard Worker *s++ = '0' + (c >> 6);
618*cf84ac9aSAndroid Build Coastguard Worker *s++ = '0' + ((c >> 3) & 0x7);
619*cf84ac9aSAndroid Build Coastguard Worker } else {
620*cf84ac9aSAndroid Build Coastguard Worker /* Print \[[o]o]o */
621*cf84ac9aSAndroid Build Coastguard Worker if ((c >> 3) != 0) {
622*cf84ac9aSAndroid Build Coastguard Worker if ((c >> 6) != 0)
623*cf84ac9aSAndroid Build Coastguard Worker *s++ = '0' + (c >> 6);
624*cf84ac9aSAndroid Build Coastguard Worker *s++ = '0' + ((c >> 3) & 0x7);
625*cf84ac9aSAndroid Build Coastguard Worker }
626*cf84ac9aSAndroid Build Coastguard Worker }
627*cf84ac9aSAndroid Build Coastguard Worker *s++ = '0' + (c & 0x7);
628*cf84ac9aSAndroid Build Coastguard Worker }
629*cf84ac9aSAndroid Build Coastguard Worker }
630*cf84ac9aSAndroid Build Coastguard Worker }
631*cf84ac9aSAndroid Build Coastguard Worker
632*cf84ac9aSAndroid Build Coastguard Worker string_ended:
633*cf84ac9aSAndroid Build Coastguard Worker if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
634*cf84ac9aSAndroid Build Coastguard Worker *s++ = '\"';
635*cf84ac9aSAndroid Build Coastguard Worker if (style & QUOTE_EMIT_COMMENT)
636*cf84ac9aSAndroid Build Coastguard Worker s = stpcpy(s, " */");
637*cf84ac9aSAndroid Build Coastguard Worker *s = '\0';
638*cf84ac9aSAndroid Build Coastguard Worker
639*cf84ac9aSAndroid Build Coastguard Worker /* Return zero if we printed entire ASCIZ string (didn't truncate it) */
640*cf84ac9aSAndroid Build Coastguard Worker if (style & QUOTE_0_TERMINATED && ustr[i] == '\0') {
641*cf84ac9aSAndroid Build Coastguard Worker /* We didn't see NUL yet (otherwise we'd jump to 'asciz_ended')
642*cf84ac9aSAndroid Build Coastguard Worker * but next char is NUL.
643*cf84ac9aSAndroid Build Coastguard Worker */
644*cf84ac9aSAndroid Build Coastguard Worker return 0;
645*cf84ac9aSAndroid Build Coastguard Worker }
646*cf84ac9aSAndroid Build Coastguard Worker
647*cf84ac9aSAndroid Build Coastguard Worker return 1;
648*cf84ac9aSAndroid Build Coastguard Worker
649*cf84ac9aSAndroid Build Coastguard Worker asciz_ended:
650*cf84ac9aSAndroid Build Coastguard Worker if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
651*cf84ac9aSAndroid Build Coastguard Worker *s++ = '\"';
652*cf84ac9aSAndroid Build Coastguard Worker if (style & QUOTE_EMIT_COMMENT)
653*cf84ac9aSAndroid Build Coastguard Worker s = stpcpy(s, " */");
654*cf84ac9aSAndroid Build Coastguard Worker *s = '\0';
655*cf84ac9aSAndroid Build Coastguard Worker /* Return zero: we printed entire ASCIZ string (didn't truncate it) */
656*cf84ac9aSAndroid Build Coastguard Worker return 0;
657*cf84ac9aSAndroid Build Coastguard Worker }
658*cf84ac9aSAndroid Build Coastguard Worker
659*cf84ac9aSAndroid Build Coastguard Worker #ifndef ALLOCA_CUTOFF
660*cf84ac9aSAndroid Build Coastguard Worker # define ALLOCA_CUTOFF 4032
661*cf84ac9aSAndroid Build Coastguard Worker #endif
662*cf84ac9aSAndroid Build Coastguard Worker #define use_alloca(n) ((n) <= ALLOCA_CUTOFF)
663*cf84ac9aSAndroid Build Coastguard Worker
664*cf84ac9aSAndroid Build Coastguard Worker /*
665*cf84ac9aSAndroid Build Coastguard Worker * Quote string `str' of length `size' and print the result.
666*cf84ac9aSAndroid Build Coastguard Worker *
667*cf84ac9aSAndroid Build Coastguard Worker * If QUOTE_0_TERMINATED `style' flag is set,
668*cf84ac9aSAndroid Build Coastguard Worker * treat `str' as a NUL-terminated string and
669*cf84ac9aSAndroid Build Coastguard Worker * quote at most (`size' - 1) bytes.
670*cf84ac9aSAndroid Build Coastguard Worker *
671*cf84ac9aSAndroid Build Coastguard Worker * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
672*cf84ac9aSAndroid Build Coastguard Worker * do not add leading and trailing quoting symbols.
673*cf84ac9aSAndroid Build Coastguard Worker *
674*cf84ac9aSAndroid Build Coastguard Worker * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
675*cf84ac9aSAndroid Build Coastguard Worker * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
676*cf84ac9aSAndroid Build Coastguard Worker */
677*cf84ac9aSAndroid Build Coastguard Worker int
print_quoted_string_ex(const char * str,unsigned int size,const unsigned int style,const char * escape_chars)678*cf84ac9aSAndroid Build Coastguard Worker print_quoted_string_ex(const char *str, unsigned int size,
679*cf84ac9aSAndroid Build Coastguard Worker const unsigned int style, const char *escape_chars)
680*cf84ac9aSAndroid Build Coastguard Worker {
681*cf84ac9aSAndroid Build Coastguard Worker char *buf;
682*cf84ac9aSAndroid Build Coastguard Worker char *outstr;
683*cf84ac9aSAndroid Build Coastguard Worker unsigned int alloc_size;
684*cf84ac9aSAndroid Build Coastguard Worker int rc;
685*cf84ac9aSAndroid Build Coastguard Worker
686*cf84ac9aSAndroid Build Coastguard Worker if (size && style & QUOTE_0_TERMINATED)
687*cf84ac9aSAndroid Build Coastguard Worker --size;
688*cf84ac9aSAndroid Build Coastguard Worker
689*cf84ac9aSAndroid Build Coastguard Worker alloc_size = 4 * size;
690*cf84ac9aSAndroid Build Coastguard Worker if (alloc_size / 4 != size) {
691*cf84ac9aSAndroid Build Coastguard Worker error_func_msg("requested %u bytes exceeds %u bytes limit",
692*cf84ac9aSAndroid Build Coastguard Worker size, -1U / 4);
693*cf84ac9aSAndroid Build Coastguard Worker tprints("???");
694*cf84ac9aSAndroid Build Coastguard Worker return -1;
695*cf84ac9aSAndroid Build Coastguard Worker }
696*cf84ac9aSAndroid Build Coastguard Worker alloc_size += 1 + (style & QUOTE_OMIT_LEADING_TRAILING_QUOTES ? 0 : 2) +
697*cf84ac9aSAndroid Build Coastguard Worker (style & QUOTE_EMIT_COMMENT ? 7 : 0);
698*cf84ac9aSAndroid Build Coastguard Worker
699*cf84ac9aSAndroid Build Coastguard Worker if (use_alloca(alloc_size)) {
700*cf84ac9aSAndroid Build Coastguard Worker outstr = alloca(alloc_size);
701*cf84ac9aSAndroid Build Coastguard Worker buf = NULL;
702*cf84ac9aSAndroid Build Coastguard Worker } else {
703*cf84ac9aSAndroid Build Coastguard Worker outstr = buf = malloc(alloc_size);
704*cf84ac9aSAndroid Build Coastguard Worker if (!buf) {
705*cf84ac9aSAndroid Build Coastguard Worker error_func_msg("memory exhausted when tried to allocate"
706*cf84ac9aSAndroid Build Coastguard Worker " %u bytes", alloc_size);
707*cf84ac9aSAndroid Build Coastguard Worker tprints("???");
708*cf84ac9aSAndroid Build Coastguard Worker return -1;
709*cf84ac9aSAndroid Build Coastguard Worker }
710*cf84ac9aSAndroid Build Coastguard Worker }
711*cf84ac9aSAndroid Build Coastguard Worker
712*cf84ac9aSAndroid Build Coastguard Worker rc = string_quote(str, outstr, size, style, escape_chars);
713*cf84ac9aSAndroid Build Coastguard Worker tprints(outstr);
714*cf84ac9aSAndroid Build Coastguard Worker
715*cf84ac9aSAndroid Build Coastguard Worker free(buf);
716*cf84ac9aSAndroid Build Coastguard Worker return rc;
717*cf84ac9aSAndroid Build Coastguard Worker }
718*cf84ac9aSAndroid Build Coastguard Worker
719*cf84ac9aSAndroid Build Coastguard Worker inline int
print_quoted_string(const char * str,unsigned int size,const unsigned int style)720*cf84ac9aSAndroid Build Coastguard Worker print_quoted_string(const char *str, unsigned int size,
721*cf84ac9aSAndroid Build Coastguard Worker const unsigned int style)
722*cf84ac9aSAndroid Build Coastguard Worker {
723*cf84ac9aSAndroid Build Coastguard Worker return print_quoted_string_ex(str, size, style, NULL);
724*cf84ac9aSAndroid Build Coastguard Worker }
725*cf84ac9aSAndroid Build Coastguard Worker
726*cf84ac9aSAndroid Build Coastguard Worker /*
727*cf84ac9aSAndroid Build Coastguard Worker * Quote a NUL-terminated string `str' of length up to `size' - 1
728*cf84ac9aSAndroid Build Coastguard Worker * and print the result.
729*cf84ac9aSAndroid Build Coastguard Worker *
730*cf84ac9aSAndroid Build Coastguard Worker * Returns 0 if NUL was seen, 1 otherwise.
731*cf84ac9aSAndroid Build Coastguard Worker */
732*cf84ac9aSAndroid Build Coastguard Worker int
print_quoted_cstring(const char * str,unsigned int size)733*cf84ac9aSAndroid Build Coastguard Worker print_quoted_cstring(const char *str, unsigned int size)
734*cf84ac9aSAndroid Build Coastguard Worker {
735*cf84ac9aSAndroid Build Coastguard Worker int unterminated =
736*cf84ac9aSAndroid Build Coastguard Worker print_quoted_string(str, size, QUOTE_0_TERMINATED);
737*cf84ac9aSAndroid Build Coastguard Worker
738*cf84ac9aSAndroid Build Coastguard Worker if (unterminated)
739*cf84ac9aSAndroid Build Coastguard Worker tprints("...");
740*cf84ac9aSAndroid Build Coastguard Worker
741*cf84ac9aSAndroid Build Coastguard Worker return unterminated;
742*cf84ac9aSAndroid Build Coastguard Worker }
743*cf84ac9aSAndroid Build Coastguard Worker
744*cf84ac9aSAndroid Build Coastguard Worker /*
745*cf84ac9aSAndroid Build Coastguard Worker * Print path string specified by address `addr' and length `n'.
746*cf84ac9aSAndroid Build Coastguard Worker * If path length exceeds `n', append `...' to the output.
747*cf84ac9aSAndroid Build Coastguard Worker *
748*cf84ac9aSAndroid Build Coastguard Worker * Returns the result of umovenstr.
749*cf84ac9aSAndroid Build Coastguard Worker */
750*cf84ac9aSAndroid Build Coastguard Worker int
printpathn(struct tcb * const tcp,const kernel_ulong_t addr,unsigned int n)751*cf84ac9aSAndroid Build Coastguard Worker printpathn(struct tcb *const tcp, const kernel_ulong_t addr, unsigned int n)
752*cf84ac9aSAndroid Build Coastguard Worker {
753*cf84ac9aSAndroid Build Coastguard Worker char path[PATH_MAX];
754*cf84ac9aSAndroid Build Coastguard Worker int nul_seen;
755*cf84ac9aSAndroid Build Coastguard Worker
756*cf84ac9aSAndroid Build Coastguard Worker if (!addr) {
757*cf84ac9aSAndroid Build Coastguard Worker tprints("NULL");
758*cf84ac9aSAndroid Build Coastguard Worker return -1;
759*cf84ac9aSAndroid Build Coastguard Worker }
760*cf84ac9aSAndroid Build Coastguard Worker
761*cf84ac9aSAndroid Build Coastguard Worker /* Cap path length to the path buffer size */
762*cf84ac9aSAndroid Build Coastguard Worker if (n > sizeof(path) - 1)
763*cf84ac9aSAndroid Build Coastguard Worker n = sizeof(path) - 1;
764*cf84ac9aSAndroid Build Coastguard Worker
765*cf84ac9aSAndroid Build Coastguard Worker /* Fetch one byte more to find out whether path length > n. */
766*cf84ac9aSAndroid Build Coastguard Worker nul_seen = umovestr(tcp, addr, n + 1, path);
767*cf84ac9aSAndroid Build Coastguard Worker if (nul_seen < 0)
768*cf84ac9aSAndroid Build Coastguard Worker printaddr(addr);
769*cf84ac9aSAndroid Build Coastguard Worker else {
770*cf84ac9aSAndroid Build Coastguard Worker path[n++] = !nul_seen;
771*cf84ac9aSAndroid Build Coastguard Worker print_quoted_cstring(path, n);
772*cf84ac9aSAndroid Build Coastguard Worker }
773*cf84ac9aSAndroid Build Coastguard Worker
774*cf84ac9aSAndroid Build Coastguard Worker return nul_seen;
775*cf84ac9aSAndroid Build Coastguard Worker }
776*cf84ac9aSAndroid Build Coastguard Worker
777*cf84ac9aSAndroid Build Coastguard Worker int
printpath(struct tcb * const tcp,const kernel_ulong_t addr)778*cf84ac9aSAndroid Build Coastguard Worker printpath(struct tcb *const tcp, const kernel_ulong_t addr)
779*cf84ac9aSAndroid Build Coastguard Worker {
780*cf84ac9aSAndroid Build Coastguard Worker /* Size must correspond to char path[] size in printpathn */
781*cf84ac9aSAndroid Build Coastguard Worker return printpathn(tcp, addr, PATH_MAX - 1);
782*cf84ac9aSAndroid Build Coastguard Worker }
783*cf84ac9aSAndroid Build Coastguard Worker
784*cf84ac9aSAndroid Build Coastguard Worker /*
785*cf84ac9aSAndroid Build Coastguard Worker * Print string specified by address `addr' and length `len'.
786*cf84ac9aSAndroid Build Coastguard Worker * If `user_style' has QUOTE_0_TERMINATED bit set, treat the string
787*cf84ac9aSAndroid Build Coastguard Worker * as a NUL-terminated string.
788*cf84ac9aSAndroid Build Coastguard Worker * Pass `user_style' on to `string_quote'.
789*cf84ac9aSAndroid Build Coastguard Worker * Append `...' to the output if either the string length exceeds `max_strlen',
790*cf84ac9aSAndroid Build Coastguard Worker * or QUOTE_0_TERMINATED bit is set and the string length exceeds `len'.
791*cf84ac9aSAndroid Build Coastguard Worker *
792*cf84ac9aSAndroid Build Coastguard Worker * Returns the result of umovenstr if style has QUOTE_0_TERMINATED,
793*cf84ac9aSAndroid Build Coastguard Worker * or the result of umoven otherwise.
794*cf84ac9aSAndroid Build Coastguard Worker */
795*cf84ac9aSAndroid Build Coastguard Worker int
printstr_ex(struct tcb * const tcp,const kernel_ulong_t addr,const kernel_ulong_t len,const unsigned int user_style)796*cf84ac9aSAndroid Build Coastguard Worker printstr_ex(struct tcb *const tcp, const kernel_ulong_t addr,
797*cf84ac9aSAndroid Build Coastguard Worker const kernel_ulong_t len, const unsigned int user_style)
798*cf84ac9aSAndroid Build Coastguard Worker {
799*cf84ac9aSAndroid Build Coastguard Worker static char *str;
800*cf84ac9aSAndroid Build Coastguard Worker static char *outstr;
801*cf84ac9aSAndroid Build Coastguard Worker
802*cf84ac9aSAndroid Build Coastguard Worker unsigned int size;
803*cf84ac9aSAndroid Build Coastguard Worker unsigned int style = user_style;
804*cf84ac9aSAndroid Build Coastguard Worker int rc;
805*cf84ac9aSAndroid Build Coastguard Worker int ellipsis;
806*cf84ac9aSAndroid Build Coastguard Worker
807*cf84ac9aSAndroid Build Coastguard Worker if (!addr) {
808*cf84ac9aSAndroid Build Coastguard Worker tprints("NULL");
809*cf84ac9aSAndroid Build Coastguard Worker return -1;
810*cf84ac9aSAndroid Build Coastguard Worker }
811*cf84ac9aSAndroid Build Coastguard Worker /* Allocate static buffers if they are not allocated yet. */
812*cf84ac9aSAndroid Build Coastguard Worker if (!str) {
813*cf84ac9aSAndroid Build Coastguard Worker const unsigned int outstr_size =
814*cf84ac9aSAndroid Build Coastguard Worker 4 * max_strlen + /* for quotes and NUL */ 3;
815*cf84ac9aSAndroid Build Coastguard Worker /*
816*cf84ac9aSAndroid Build Coastguard Worker * We can assume that outstr_size / 4 == max_strlen
817*cf84ac9aSAndroid Build Coastguard Worker * since we have a guarantee that max_strlen <= -1U / 4.
818*cf84ac9aSAndroid Build Coastguard Worker */
819*cf84ac9aSAndroid Build Coastguard Worker
820*cf84ac9aSAndroid Build Coastguard Worker str = xmalloc(max_strlen + 1);
821*cf84ac9aSAndroid Build Coastguard Worker outstr = xmalloc(outstr_size);
822*cf84ac9aSAndroid Build Coastguard Worker }
823*cf84ac9aSAndroid Build Coastguard Worker
824*cf84ac9aSAndroid Build Coastguard Worker /* Fetch one byte more because string_quote may look one byte ahead. */
825*cf84ac9aSAndroid Build Coastguard Worker size = max_strlen + 1;
826*cf84ac9aSAndroid Build Coastguard Worker
827*cf84ac9aSAndroid Build Coastguard Worker if (size > len)
828*cf84ac9aSAndroid Build Coastguard Worker size = len;
829*cf84ac9aSAndroid Build Coastguard Worker if (style & QUOTE_0_TERMINATED)
830*cf84ac9aSAndroid Build Coastguard Worker rc = umovestr(tcp, addr, size, str);
831*cf84ac9aSAndroid Build Coastguard Worker else
832*cf84ac9aSAndroid Build Coastguard Worker rc = umoven(tcp, addr, size, str);
833*cf84ac9aSAndroid Build Coastguard Worker
834*cf84ac9aSAndroid Build Coastguard Worker if (rc < 0) {
835*cf84ac9aSAndroid Build Coastguard Worker printaddr(addr);
836*cf84ac9aSAndroid Build Coastguard Worker return rc;
837*cf84ac9aSAndroid Build Coastguard Worker }
838*cf84ac9aSAndroid Build Coastguard Worker
839*cf84ac9aSAndroid Build Coastguard Worker if (size > max_strlen)
840*cf84ac9aSAndroid Build Coastguard Worker size = max_strlen;
841*cf84ac9aSAndroid Build Coastguard Worker else
842*cf84ac9aSAndroid Build Coastguard Worker str[size] = '\xff';
843*cf84ac9aSAndroid Build Coastguard Worker
844*cf84ac9aSAndroid Build Coastguard Worker /* If string_quote didn't see NUL and (it was supposed to be ASCIZ str
845*cf84ac9aSAndroid Build Coastguard Worker * or we were requested to print more than -s NUM chars)...
846*cf84ac9aSAndroid Build Coastguard Worker */
847*cf84ac9aSAndroid Build Coastguard Worker ellipsis = string_quote(str, outstr, size, style, NULL)
848*cf84ac9aSAndroid Build Coastguard Worker && len
849*cf84ac9aSAndroid Build Coastguard Worker && ((style & QUOTE_0_TERMINATED)
850*cf84ac9aSAndroid Build Coastguard Worker || len > max_strlen);
851*cf84ac9aSAndroid Build Coastguard Worker
852*cf84ac9aSAndroid Build Coastguard Worker tprints(outstr);
853*cf84ac9aSAndroid Build Coastguard Worker if (ellipsis)
854*cf84ac9aSAndroid Build Coastguard Worker tprints("...");
855*cf84ac9aSAndroid Build Coastguard Worker
856*cf84ac9aSAndroid Build Coastguard Worker return rc;
857*cf84ac9aSAndroid Build Coastguard Worker }
858*cf84ac9aSAndroid Build Coastguard Worker
859*cf84ac9aSAndroid Build Coastguard Worker void
dumpiov_upto(struct tcb * const tcp,const int len,const kernel_ulong_t addr,kernel_ulong_t data_size)860*cf84ac9aSAndroid Build Coastguard Worker dumpiov_upto(struct tcb *const tcp, const int len, const kernel_ulong_t addr,
861*cf84ac9aSAndroid Build Coastguard Worker kernel_ulong_t data_size)
862*cf84ac9aSAndroid Build Coastguard Worker {
863*cf84ac9aSAndroid Build Coastguard Worker #if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
864*cf84ac9aSAndroid Build Coastguard Worker union {
865*cf84ac9aSAndroid Build Coastguard Worker struct { uint32_t base; uint32_t len; } *iov32;
866*cf84ac9aSAndroid Build Coastguard Worker struct { uint64_t base; uint64_t len; } *iov64;
867*cf84ac9aSAndroid Build Coastguard Worker } iovu;
868*cf84ac9aSAndroid Build Coastguard Worker #define iov iovu.iov64
869*cf84ac9aSAndroid Build Coastguard Worker #define sizeof_iov \
870*cf84ac9aSAndroid Build Coastguard Worker (current_wordsize == 4 ? (unsigned int) sizeof(*iovu.iov32) \
871*cf84ac9aSAndroid Build Coastguard Worker : (unsigned int) sizeof(*iovu.iov64))
872*cf84ac9aSAndroid Build Coastguard Worker #define iov_iov_base(i) \
873*cf84ac9aSAndroid Build Coastguard Worker (current_wordsize == 4 ? (uint64_t) iovu.iov32[i].base : iovu.iov64[i].base)
874*cf84ac9aSAndroid Build Coastguard Worker #define iov_iov_len(i) \
875*cf84ac9aSAndroid Build Coastguard Worker (current_wordsize == 4 ? (uint64_t) iovu.iov32[i].len : iovu.iov64[i].len)
876*cf84ac9aSAndroid Build Coastguard Worker #else
877*cf84ac9aSAndroid Build Coastguard Worker struct iovec *iov;
878*cf84ac9aSAndroid Build Coastguard Worker #define sizeof_iov ((unsigned int) sizeof(*iov))
879*cf84ac9aSAndroid Build Coastguard Worker #define iov_iov_base(i) ptr_to_kulong(iov[i].iov_base)
880*cf84ac9aSAndroid Build Coastguard Worker #define iov_iov_len(i) iov[i].iov_len
881*cf84ac9aSAndroid Build Coastguard Worker #endif
882*cf84ac9aSAndroid Build Coastguard Worker int i;
883*cf84ac9aSAndroid Build Coastguard Worker unsigned int size = sizeof_iov * len;
884*cf84ac9aSAndroid Build Coastguard Worker if (size / sizeof_iov != (unsigned int) len) {
885*cf84ac9aSAndroid Build Coastguard Worker error_func_msg("requested %u iovec elements exceeds"
886*cf84ac9aSAndroid Build Coastguard Worker " %u iovec limit", len, -1U / sizeof_iov);
887*cf84ac9aSAndroid Build Coastguard Worker return;
888*cf84ac9aSAndroid Build Coastguard Worker }
889*cf84ac9aSAndroid Build Coastguard Worker
890*cf84ac9aSAndroid Build Coastguard Worker iov = malloc(size);
891*cf84ac9aSAndroid Build Coastguard Worker if (!iov) {
892*cf84ac9aSAndroid Build Coastguard Worker error_func_msg("memory exhausted when tried to allocate"
893*cf84ac9aSAndroid Build Coastguard Worker " %u bytes", size);
894*cf84ac9aSAndroid Build Coastguard Worker return;
895*cf84ac9aSAndroid Build Coastguard Worker }
896*cf84ac9aSAndroid Build Coastguard Worker if (umoven(tcp, addr, size, iov) >= 0) {
897*cf84ac9aSAndroid Build Coastguard Worker for (i = 0; i < len; i++) {
898*cf84ac9aSAndroid Build Coastguard Worker kernel_ulong_t iov_len = iov_iov_len(i);
899*cf84ac9aSAndroid Build Coastguard Worker if (iov_len > data_size)
900*cf84ac9aSAndroid Build Coastguard Worker iov_len = data_size;
901*cf84ac9aSAndroid Build Coastguard Worker if (!iov_len)
902*cf84ac9aSAndroid Build Coastguard Worker break;
903*cf84ac9aSAndroid Build Coastguard Worker data_size -= iov_len;
904*cf84ac9aSAndroid Build Coastguard Worker /* include the buffer number to make it easy to
905*cf84ac9aSAndroid Build Coastguard Worker * match up the trace with the source */
906*cf84ac9aSAndroid Build Coastguard Worker tprintf(" * %" PRI_klu " bytes in buffer %d\n", iov_len, i);
907*cf84ac9aSAndroid Build Coastguard Worker dumpstr(tcp, iov_iov_base(i), iov_len);
908*cf84ac9aSAndroid Build Coastguard Worker }
909*cf84ac9aSAndroid Build Coastguard Worker }
910*cf84ac9aSAndroid Build Coastguard Worker free(iov);
911*cf84ac9aSAndroid Build Coastguard Worker #undef sizeof_iov
912*cf84ac9aSAndroid Build Coastguard Worker #undef iov_iov_base
913*cf84ac9aSAndroid Build Coastguard Worker #undef iov_iov_len
914*cf84ac9aSAndroid Build Coastguard Worker #undef iov
915*cf84ac9aSAndroid Build Coastguard Worker }
916*cf84ac9aSAndroid Build Coastguard Worker
917*cf84ac9aSAndroid Build Coastguard Worker void
dumpstr(struct tcb * const tcp,const kernel_ulong_t addr,const int len)918*cf84ac9aSAndroid Build Coastguard Worker dumpstr(struct tcb *const tcp, const kernel_ulong_t addr, const int len)
919*cf84ac9aSAndroid Build Coastguard Worker {
920*cf84ac9aSAndroid Build Coastguard Worker static int strsize = -1;
921*cf84ac9aSAndroid Build Coastguard Worker static unsigned char *str;
922*cf84ac9aSAndroid Build Coastguard Worker
923*cf84ac9aSAndroid Build Coastguard Worker char outbuf[
924*cf84ac9aSAndroid Build Coastguard Worker (
925*cf84ac9aSAndroid Build Coastguard Worker (sizeof(
926*cf84ac9aSAndroid Build Coastguard Worker "xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx "
927*cf84ac9aSAndroid Build Coastguard Worker "1234567890123456") + /*in case I'm off by few:*/ 4)
928*cf84ac9aSAndroid Build Coastguard Worker /*align to 8 to make memset easier:*/ + 7) & -8
929*cf84ac9aSAndroid Build Coastguard Worker ];
930*cf84ac9aSAndroid Build Coastguard Worker const unsigned char *src;
931*cf84ac9aSAndroid Build Coastguard Worker int i;
932*cf84ac9aSAndroid Build Coastguard Worker
933*cf84ac9aSAndroid Build Coastguard Worker if ((len < 0) || (len > INT_MAX - 16))
934*cf84ac9aSAndroid Build Coastguard Worker return;
935*cf84ac9aSAndroid Build Coastguard Worker
936*cf84ac9aSAndroid Build Coastguard Worker memset(outbuf, ' ', sizeof(outbuf));
937*cf84ac9aSAndroid Build Coastguard Worker
938*cf84ac9aSAndroid Build Coastguard Worker if (strsize < len + 16) {
939*cf84ac9aSAndroid Build Coastguard Worker free(str);
940*cf84ac9aSAndroid Build Coastguard Worker str = malloc(len + 16);
941*cf84ac9aSAndroid Build Coastguard Worker if (!str) {
942*cf84ac9aSAndroid Build Coastguard Worker strsize = -1;
943*cf84ac9aSAndroid Build Coastguard Worker error_func_msg("memory exhausted when tried to allocate"
944*cf84ac9aSAndroid Build Coastguard Worker " %zu bytes", (size_t) (len + 16));
945*cf84ac9aSAndroid Build Coastguard Worker return;
946*cf84ac9aSAndroid Build Coastguard Worker }
947*cf84ac9aSAndroid Build Coastguard Worker strsize = len + 16;
948*cf84ac9aSAndroid Build Coastguard Worker }
949*cf84ac9aSAndroid Build Coastguard Worker
950*cf84ac9aSAndroid Build Coastguard Worker if (umoven(tcp, addr, len, str) < 0)
951*cf84ac9aSAndroid Build Coastguard Worker return;
952*cf84ac9aSAndroid Build Coastguard Worker
953*cf84ac9aSAndroid Build Coastguard Worker /* Space-pad to 16 bytes */
954*cf84ac9aSAndroid Build Coastguard Worker i = len;
955*cf84ac9aSAndroid Build Coastguard Worker while (i & 0xf)
956*cf84ac9aSAndroid Build Coastguard Worker str[i++] = ' ';
957*cf84ac9aSAndroid Build Coastguard Worker
958*cf84ac9aSAndroid Build Coastguard Worker i = 0;
959*cf84ac9aSAndroid Build Coastguard Worker src = str;
960*cf84ac9aSAndroid Build Coastguard Worker while (i < len) {
961*cf84ac9aSAndroid Build Coastguard Worker char *dst = outbuf;
962*cf84ac9aSAndroid Build Coastguard Worker /* Hex dump */
963*cf84ac9aSAndroid Build Coastguard Worker do {
964*cf84ac9aSAndroid Build Coastguard Worker if (i < len) {
965*cf84ac9aSAndroid Build Coastguard Worker *dst++ = "0123456789abcdef"[*src >> 4];
966*cf84ac9aSAndroid Build Coastguard Worker *dst++ = "0123456789abcdef"[*src & 0xf];
967*cf84ac9aSAndroid Build Coastguard Worker } else {
968*cf84ac9aSAndroid Build Coastguard Worker *dst++ = ' ';
969*cf84ac9aSAndroid Build Coastguard Worker *dst++ = ' ';
970*cf84ac9aSAndroid Build Coastguard Worker }
971*cf84ac9aSAndroid Build Coastguard Worker dst++; /* space is there by memset */
972*cf84ac9aSAndroid Build Coastguard Worker i++;
973*cf84ac9aSAndroid Build Coastguard Worker if ((i & 7) == 0)
974*cf84ac9aSAndroid Build Coastguard Worker dst++; /* space is there by memset */
975*cf84ac9aSAndroid Build Coastguard Worker src++;
976*cf84ac9aSAndroid Build Coastguard Worker } while (i & 0xf);
977*cf84ac9aSAndroid Build Coastguard Worker /* ASCII dump */
978*cf84ac9aSAndroid Build Coastguard Worker i -= 16;
979*cf84ac9aSAndroid Build Coastguard Worker src -= 16;
980*cf84ac9aSAndroid Build Coastguard Worker do {
981*cf84ac9aSAndroid Build Coastguard Worker if (*src >= ' ' && *src < 0x7f)
982*cf84ac9aSAndroid Build Coastguard Worker *dst++ = *src;
983*cf84ac9aSAndroid Build Coastguard Worker else
984*cf84ac9aSAndroid Build Coastguard Worker *dst++ = '.';
985*cf84ac9aSAndroid Build Coastguard Worker src++;
986*cf84ac9aSAndroid Build Coastguard Worker } while (++i & 0xf);
987*cf84ac9aSAndroid Build Coastguard Worker *dst = '\0';
988*cf84ac9aSAndroid Build Coastguard Worker tprintf(" | %05x %s |\n", i - 16, outbuf);
989*cf84ac9aSAndroid Build Coastguard Worker }
990*cf84ac9aSAndroid Build Coastguard Worker }
991*cf84ac9aSAndroid Build Coastguard Worker
992*cf84ac9aSAndroid Build Coastguard Worker bool
tfetch_mem64(struct tcb * const tcp,const uint64_t addr,const unsigned int len,void * const our_addr)993*cf84ac9aSAndroid Build Coastguard Worker tfetch_mem64(struct tcb *const tcp, const uint64_t addr,
994*cf84ac9aSAndroid Build Coastguard Worker const unsigned int len, void *const our_addr)
995*cf84ac9aSAndroid Build Coastguard Worker {
996*cf84ac9aSAndroid Build Coastguard Worker return addr && verbose(tcp) &&
997*cf84ac9aSAndroid Build Coastguard Worker (entering(tcp) || !syserror(tcp)) &&
998*cf84ac9aSAndroid Build Coastguard Worker !umoven(tcp, addr, len, our_addr);
999*cf84ac9aSAndroid Build Coastguard Worker }
1000*cf84ac9aSAndroid Build Coastguard Worker
1001*cf84ac9aSAndroid Build Coastguard Worker bool
tfetch_mem64_ignore_syserror(struct tcb * const tcp,const uint64_t addr,const unsigned int len,void * const our_addr)1002*cf84ac9aSAndroid Build Coastguard Worker tfetch_mem64_ignore_syserror(struct tcb *const tcp, const uint64_t addr,
1003*cf84ac9aSAndroid Build Coastguard Worker const unsigned int len, void *const our_addr)
1004*cf84ac9aSAndroid Build Coastguard Worker {
1005*cf84ac9aSAndroid Build Coastguard Worker return addr && verbose(tcp) &&
1006*cf84ac9aSAndroid Build Coastguard Worker !umoven(tcp, addr, len, our_addr);
1007*cf84ac9aSAndroid Build Coastguard Worker }
1008*cf84ac9aSAndroid Build Coastguard Worker
1009*cf84ac9aSAndroid Build Coastguard Worker int
umoven_or_printaddr64(struct tcb * const tcp,const uint64_t addr,const unsigned int len,void * const our_addr)1010*cf84ac9aSAndroid Build Coastguard Worker umoven_or_printaddr64(struct tcb *const tcp, const uint64_t addr,
1011*cf84ac9aSAndroid Build Coastguard Worker const unsigned int len, void *const our_addr)
1012*cf84ac9aSAndroid Build Coastguard Worker {
1013*cf84ac9aSAndroid Build Coastguard Worker if (tfetch_mem64(tcp, addr, len, our_addr))
1014*cf84ac9aSAndroid Build Coastguard Worker return 0;
1015*cf84ac9aSAndroid Build Coastguard Worker printaddr64(addr);
1016*cf84ac9aSAndroid Build Coastguard Worker return -1;
1017*cf84ac9aSAndroid Build Coastguard Worker }
1018*cf84ac9aSAndroid Build Coastguard Worker
1019*cf84ac9aSAndroid Build Coastguard Worker int
umoven_or_printaddr64_ignore_syserror(struct tcb * const tcp,const uint64_t addr,const unsigned int len,void * const our_addr)1020*cf84ac9aSAndroid Build Coastguard Worker umoven_or_printaddr64_ignore_syserror(struct tcb *const tcp,
1021*cf84ac9aSAndroid Build Coastguard Worker const uint64_t addr,
1022*cf84ac9aSAndroid Build Coastguard Worker const unsigned int len,
1023*cf84ac9aSAndroid Build Coastguard Worker void *const our_addr)
1024*cf84ac9aSAndroid Build Coastguard Worker {
1025*cf84ac9aSAndroid Build Coastguard Worker if (tfetch_mem64_ignore_syserror(tcp, addr, len, our_addr))
1026*cf84ac9aSAndroid Build Coastguard Worker return 0;
1027*cf84ac9aSAndroid Build Coastguard Worker printaddr64(addr);
1028*cf84ac9aSAndroid Build Coastguard Worker return -1;
1029*cf84ac9aSAndroid Build Coastguard Worker }
1030*cf84ac9aSAndroid Build Coastguard Worker
1031*cf84ac9aSAndroid Build Coastguard Worker bool
print_int32_array_member(struct tcb * tcp,void * elem_buf,size_t elem_size,void * data)1032*cf84ac9aSAndroid Build Coastguard Worker print_int32_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
1033*cf84ac9aSAndroid Build Coastguard Worker void *data)
1034*cf84ac9aSAndroid Build Coastguard Worker {
1035*cf84ac9aSAndroid Build Coastguard Worker tprintf("%" PRId32, *(int32_t *) elem_buf);
1036*cf84ac9aSAndroid Build Coastguard Worker
1037*cf84ac9aSAndroid Build Coastguard Worker return true;
1038*cf84ac9aSAndroid Build Coastguard Worker }
1039*cf84ac9aSAndroid Build Coastguard Worker
1040*cf84ac9aSAndroid Build Coastguard Worker bool
print_uint32_array_member(struct tcb * tcp,void * elem_buf,size_t elem_size,void * data)1041*cf84ac9aSAndroid Build Coastguard Worker print_uint32_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
1042*cf84ac9aSAndroid Build Coastguard Worker void *data)
1043*cf84ac9aSAndroid Build Coastguard Worker {
1044*cf84ac9aSAndroid Build Coastguard Worker tprintf("%" PRIu32, *(uint32_t *) elem_buf);
1045*cf84ac9aSAndroid Build Coastguard Worker
1046*cf84ac9aSAndroid Build Coastguard Worker return true;
1047*cf84ac9aSAndroid Build Coastguard Worker }
1048*cf84ac9aSAndroid Build Coastguard Worker
1049*cf84ac9aSAndroid Build Coastguard Worker bool
print_uint64_array_member(struct tcb * tcp,void * elem_buf,size_t elem_size,void * data)1050*cf84ac9aSAndroid Build Coastguard Worker print_uint64_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
1051*cf84ac9aSAndroid Build Coastguard Worker void *data)
1052*cf84ac9aSAndroid Build Coastguard Worker {
1053*cf84ac9aSAndroid Build Coastguard Worker tprintf("%" PRIu64, *(uint64_t *) elem_buf);
1054*cf84ac9aSAndroid Build Coastguard Worker
1055*cf84ac9aSAndroid Build Coastguard Worker return true;
1056*cf84ac9aSAndroid Build Coastguard Worker }
1057*cf84ac9aSAndroid Build Coastguard Worker
1058*cf84ac9aSAndroid Build Coastguard Worker /*
1059*cf84ac9aSAndroid Build Coastguard Worker * Iteratively fetch and print up to nmemb elements of elem_size size
1060*cf84ac9aSAndroid Build Coastguard Worker * from the array that starts at tracee's address start_addr.
1061*cf84ac9aSAndroid Build Coastguard Worker *
1062*cf84ac9aSAndroid Build Coastguard Worker * Array elements are being fetched to the address specified by elem_buf.
1063*cf84ac9aSAndroid Build Coastguard Worker *
1064*cf84ac9aSAndroid Build Coastguard Worker * The fetcher callback function specified by tfetch_mem_func should follow
1065*cf84ac9aSAndroid Build Coastguard Worker * the same semantics as tfetch_mem function.
1066*cf84ac9aSAndroid Build Coastguard Worker *
1067*cf84ac9aSAndroid Build Coastguard Worker * The printer callback function specified by print_func is expected
1068*cf84ac9aSAndroid Build Coastguard Worker * to print something; if it returns false, no more iterations will be made.
1069*cf84ac9aSAndroid Build Coastguard Worker *
1070*cf84ac9aSAndroid Build Coastguard Worker * The pointer specified by opaque_data is passed to each invocation
1071*cf84ac9aSAndroid Build Coastguard Worker * of print_func callback function.
1072*cf84ac9aSAndroid Build Coastguard Worker *
1073*cf84ac9aSAndroid Build Coastguard Worker * This function prints:
1074*cf84ac9aSAndroid Build Coastguard Worker * - "NULL", if start_addr is NULL;
1075*cf84ac9aSAndroid Build Coastguard Worker * - "[]", if nmemb is 0;
1076*cf84ac9aSAndroid Build Coastguard Worker * - start_addr, if nmemb * elem_size overflows or wraps around;
1077*cf84ac9aSAndroid Build Coastguard Worker * - start_addr, if the first tfetch_mem_func invocation returned false;
1078*cf84ac9aSAndroid Build Coastguard Worker * - elements of the array, delimited by ", ", with the array itself
1079*cf84ac9aSAndroid Build Coastguard Worker * enclosed with [] brackets.
1080*cf84ac9aSAndroid Build Coastguard Worker *
1081*cf84ac9aSAndroid Build Coastguard Worker * If abbrev(tcp) is true, then
1082*cf84ac9aSAndroid Build Coastguard Worker * - the maximum number of elements printed equals to max_strlen;
1083*cf84ac9aSAndroid Build Coastguard Worker * - "..." is printed instead of max_strlen+1 element
1084*cf84ac9aSAndroid Build Coastguard Worker * and no more iterations will be made.
1085*cf84ac9aSAndroid Build Coastguard Worker *
1086*cf84ac9aSAndroid Build Coastguard Worker * This function returns true only if tfetch_mem_func has returned true
1087*cf84ac9aSAndroid Build Coastguard Worker * at least once.
1088*cf84ac9aSAndroid Build Coastguard Worker */
1089*cf84ac9aSAndroid Build Coastguard Worker bool
print_array_ex(struct tcb * const tcp,const kernel_ulong_t start_addr,const size_t nmemb,void * const elem_buf,const size_t elem_size,tfetch_mem_fn tfetch_mem_func,print_fn print_func,void * const opaque_data,unsigned int flags,const struct xlat * index_xlat,size_t index_xlat_size,const char * index_dflt)1090*cf84ac9aSAndroid Build Coastguard Worker print_array_ex(struct tcb *const tcp,
1091*cf84ac9aSAndroid Build Coastguard Worker const kernel_ulong_t start_addr,
1092*cf84ac9aSAndroid Build Coastguard Worker const size_t nmemb,
1093*cf84ac9aSAndroid Build Coastguard Worker void *const elem_buf,
1094*cf84ac9aSAndroid Build Coastguard Worker const size_t elem_size,
1095*cf84ac9aSAndroid Build Coastguard Worker tfetch_mem_fn tfetch_mem_func,
1096*cf84ac9aSAndroid Build Coastguard Worker print_fn print_func,
1097*cf84ac9aSAndroid Build Coastguard Worker void *const opaque_data,
1098*cf84ac9aSAndroid Build Coastguard Worker unsigned int flags,
1099*cf84ac9aSAndroid Build Coastguard Worker const struct xlat *index_xlat,
1100*cf84ac9aSAndroid Build Coastguard Worker size_t index_xlat_size,
1101*cf84ac9aSAndroid Build Coastguard Worker const char *index_dflt)
1102*cf84ac9aSAndroid Build Coastguard Worker {
1103*cf84ac9aSAndroid Build Coastguard Worker if (!start_addr) {
1104*cf84ac9aSAndroid Build Coastguard Worker tprints("NULL");
1105*cf84ac9aSAndroid Build Coastguard Worker return false;
1106*cf84ac9aSAndroid Build Coastguard Worker }
1107*cf84ac9aSAndroid Build Coastguard Worker
1108*cf84ac9aSAndroid Build Coastguard Worker if (!nmemb) {
1109*cf84ac9aSAndroid Build Coastguard Worker tprints("[]");
1110*cf84ac9aSAndroid Build Coastguard Worker return false;
1111*cf84ac9aSAndroid Build Coastguard Worker }
1112*cf84ac9aSAndroid Build Coastguard Worker
1113*cf84ac9aSAndroid Build Coastguard Worker const size_t size = nmemb * elem_size;
1114*cf84ac9aSAndroid Build Coastguard Worker const kernel_ulong_t end_addr = start_addr + size;
1115*cf84ac9aSAndroid Build Coastguard Worker
1116*cf84ac9aSAndroid Build Coastguard Worker if (end_addr <= start_addr || size / elem_size != nmemb) {
1117*cf84ac9aSAndroid Build Coastguard Worker printaddr(start_addr);
1118*cf84ac9aSAndroid Build Coastguard Worker return false;
1119*cf84ac9aSAndroid Build Coastguard Worker }
1120*cf84ac9aSAndroid Build Coastguard Worker
1121*cf84ac9aSAndroid Build Coastguard Worker const kernel_ulong_t abbrev_end =
1122*cf84ac9aSAndroid Build Coastguard Worker (abbrev(tcp) && max_strlen < nmemb) ?
1123*cf84ac9aSAndroid Build Coastguard Worker start_addr + elem_size * max_strlen : end_addr;
1124*cf84ac9aSAndroid Build Coastguard Worker kernel_ulong_t cur;
1125*cf84ac9aSAndroid Build Coastguard Worker kernel_ulong_t idx = 0;
1126*cf84ac9aSAndroid Build Coastguard Worker enum xlat_style xlat_style = flags & XLAT_STYLE_MASK;
1127*cf84ac9aSAndroid Build Coastguard Worker
1128*cf84ac9aSAndroid Build Coastguard Worker for (cur = start_addr; cur < end_addr; cur += elem_size, idx++) {
1129*cf84ac9aSAndroid Build Coastguard Worker if (cur != start_addr)
1130*cf84ac9aSAndroid Build Coastguard Worker tprints(", ");
1131*cf84ac9aSAndroid Build Coastguard Worker
1132*cf84ac9aSAndroid Build Coastguard Worker if (!tfetch_mem_func(tcp, cur, elem_size, elem_buf)) {
1133*cf84ac9aSAndroid Build Coastguard Worker if (cur == start_addr)
1134*cf84ac9aSAndroid Build Coastguard Worker printaddr(cur);
1135*cf84ac9aSAndroid Build Coastguard Worker else {
1136*cf84ac9aSAndroid Build Coastguard Worker tprints("...");
1137*cf84ac9aSAndroid Build Coastguard Worker printaddr_comment(cur);
1138*cf84ac9aSAndroid Build Coastguard Worker }
1139*cf84ac9aSAndroid Build Coastguard Worker break;
1140*cf84ac9aSAndroid Build Coastguard Worker }
1141*cf84ac9aSAndroid Build Coastguard Worker
1142*cf84ac9aSAndroid Build Coastguard Worker if (cur == start_addr)
1143*cf84ac9aSAndroid Build Coastguard Worker tprints("[");
1144*cf84ac9aSAndroid Build Coastguard Worker
1145*cf84ac9aSAndroid Build Coastguard Worker if (cur >= abbrev_end) {
1146*cf84ac9aSAndroid Build Coastguard Worker tprints("...");
1147*cf84ac9aSAndroid Build Coastguard Worker cur = end_addr;
1148*cf84ac9aSAndroid Build Coastguard Worker break;
1149*cf84ac9aSAndroid Build Coastguard Worker }
1150*cf84ac9aSAndroid Build Coastguard Worker
1151*cf84ac9aSAndroid Build Coastguard Worker if (flags & PAF_PRINT_INDICES) {
1152*cf84ac9aSAndroid Build Coastguard Worker tprints("[");
1153*cf84ac9aSAndroid Build Coastguard Worker
1154*cf84ac9aSAndroid Build Coastguard Worker if (!index_xlat) {
1155*cf84ac9aSAndroid Build Coastguard Worker print_xlat_ex(idx, NULL, xlat_style);
1156*cf84ac9aSAndroid Build Coastguard Worker } else if (flags & PAF_INDEX_XLAT_VALUE_INDEXED) {
1157*cf84ac9aSAndroid Build Coastguard Worker printxval_indexn_ex(index_xlat,
1158*cf84ac9aSAndroid Build Coastguard Worker index_xlat_size, idx,
1159*cf84ac9aSAndroid Build Coastguard Worker index_dflt, xlat_style);
1160*cf84ac9aSAndroid Build Coastguard Worker } else {
1161*cf84ac9aSAndroid Build Coastguard Worker printxvals_ex(idx, index_dflt, xlat_style,
1162*cf84ac9aSAndroid Build Coastguard Worker (flags & PAF_INDEX_XLAT_SORTED)
1163*cf84ac9aSAndroid Build Coastguard Worker && idx ? NULL : index_xlat,
1164*cf84ac9aSAndroid Build Coastguard Worker NULL);
1165*cf84ac9aSAndroid Build Coastguard Worker }
1166*cf84ac9aSAndroid Build Coastguard Worker
1167*cf84ac9aSAndroid Build Coastguard Worker tprints("] = ");
1168*cf84ac9aSAndroid Build Coastguard Worker }
1169*cf84ac9aSAndroid Build Coastguard Worker
1170*cf84ac9aSAndroid Build Coastguard Worker if (!print_func(tcp, elem_buf, elem_size, opaque_data)) {
1171*cf84ac9aSAndroid Build Coastguard Worker cur = end_addr;
1172*cf84ac9aSAndroid Build Coastguard Worker break;
1173*cf84ac9aSAndroid Build Coastguard Worker }
1174*cf84ac9aSAndroid Build Coastguard Worker }
1175*cf84ac9aSAndroid Build Coastguard Worker if (cur != start_addr)
1176*cf84ac9aSAndroid Build Coastguard Worker tprints("]");
1177*cf84ac9aSAndroid Build Coastguard Worker
1178*cf84ac9aSAndroid Build Coastguard Worker return cur >= end_addr;
1179*cf84ac9aSAndroid Build Coastguard Worker }
1180*cf84ac9aSAndroid Build Coastguard Worker
1181*cf84ac9aSAndroid Build Coastguard Worker int
printargs(struct tcb * tcp)1182*cf84ac9aSAndroid Build Coastguard Worker printargs(struct tcb *tcp)
1183*cf84ac9aSAndroid Build Coastguard Worker {
1184*cf84ac9aSAndroid Build Coastguard Worker const int n = tcp->s_ent->nargs;
1185*cf84ac9aSAndroid Build Coastguard Worker int i;
1186*cf84ac9aSAndroid Build Coastguard Worker for (i = 0; i < n; ++i)
1187*cf84ac9aSAndroid Build Coastguard Worker tprintf("%s%#" PRI_klx, i ? ", " : "", tcp->u_arg[i]);
1188*cf84ac9aSAndroid Build Coastguard Worker return RVAL_DECODED;
1189*cf84ac9aSAndroid Build Coastguard Worker }
1190*cf84ac9aSAndroid Build Coastguard Worker
1191*cf84ac9aSAndroid Build Coastguard Worker int
printargs_u(struct tcb * tcp)1192*cf84ac9aSAndroid Build Coastguard Worker printargs_u(struct tcb *tcp)
1193*cf84ac9aSAndroid Build Coastguard Worker {
1194*cf84ac9aSAndroid Build Coastguard Worker const int n = tcp->s_ent->nargs;
1195*cf84ac9aSAndroid Build Coastguard Worker int i;
1196*cf84ac9aSAndroid Build Coastguard Worker for (i = 0; i < n; ++i)
1197*cf84ac9aSAndroid Build Coastguard Worker tprintf("%s%u", i ? ", " : "",
1198*cf84ac9aSAndroid Build Coastguard Worker (unsigned int) tcp->u_arg[i]);
1199*cf84ac9aSAndroid Build Coastguard Worker return RVAL_DECODED;
1200*cf84ac9aSAndroid Build Coastguard Worker }
1201*cf84ac9aSAndroid Build Coastguard Worker
1202*cf84ac9aSAndroid Build Coastguard Worker int
printargs_d(struct tcb * tcp)1203*cf84ac9aSAndroid Build Coastguard Worker printargs_d(struct tcb *tcp)
1204*cf84ac9aSAndroid Build Coastguard Worker {
1205*cf84ac9aSAndroid Build Coastguard Worker const int n = tcp->s_ent->nargs;
1206*cf84ac9aSAndroid Build Coastguard Worker int i;
1207*cf84ac9aSAndroid Build Coastguard Worker for (i = 0; i < n; ++i)
1208*cf84ac9aSAndroid Build Coastguard Worker tprintf("%s%d", i ? ", " : "",
1209*cf84ac9aSAndroid Build Coastguard Worker (int) tcp->u_arg[i]);
1210*cf84ac9aSAndroid Build Coastguard Worker return RVAL_DECODED;
1211*cf84ac9aSAndroid Build Coastguard Worker }
1212*cf84ac9aSAndroid Build Coastguard Worker
1213*cf84ac9aSAndroid Build Coastguard Worker /* Print abnormal high bits of a kernel_ulong_t value. */
1214*cf84ac9aSAndroid Build Coastguard Worker void
print_abnormal_hi(const kernel_ulong_t val)1215*cf84ac9aSAndroid Build Coastguard Worker print_abnormal_hi(const kernel_ulong_t val)
1216*cf84ac9aSAndroid Build Coastguard Worker {
1217*cf84ac9aSAndroid Build Coastguard Worker if (current_klongsize > 4) {
1218*cf84ac9aSAndroid Build Coastguard Worker const unsigned int hi = (unsigned int) ((uint64_t) val >> 32);
1219*cf84ac9aSAndroid Build Coastguard Worker if (hi)
1220*cf84ac9aSAndroid Build Coastguard Worker tprintf("%#x<<32|", hi);
1221*cf84ac9aSAndroid Build Coastguard Worker }
1222*cf84ac9aSAndroid Build Coastguard Worker }
1223*cf84ac9aSAndroid Build Coastguard Worker
1224*cf84ac9aSAndroid Build Coastguard Worker #if defined _LARGEFILE64_SOURCE && defined HAVE_OPEN64
1225*cf84ac9aSAndroid Build Coastguard Worker # define open_file open64
1226*cf84ac9aSAndroid Build Coastguard Worker #else
1227*cf84ac9aSAndroid Build Coastguard Worker # define open_file open
1228*cf84ac9aSAndroid Build Coastguard Worker #endif
1229*cf84ac9aSAndroid Build Coastguard Worker
1230*cf84ac9aSAndroid Build Coastguard Worker int
read_int_from_file(struct tcb * tcp,const char * const fname,int * const pvalue)1231*cf84ac9aSAndroid Build Coastguard Worker read_int_from_file(struct tcb *tcp, const char *const fname, int *const pvalue)
1232*cf84ac9aSAndroid Build Coastguard Worker {
1233*cf84ac9aSAndroid Build Coastguard Worker const int fd = open_file(fname, O_RDONLY);
1234*cf84ac9aSAndroid Build Coastguard Worker if (fd < 0)
1235*cf84ac9aSAndroid Build Coastguard Worker return -1;
1236*cf84ac9aSAndroid Build Coastguard Worker
1237*cf84ac9aSAndroid Build Coastguard Worker long lval;
1238*cf84ac9aSAndroid Build Coastguard Worker char buf[sizeof(lval) * 3];
1239*cf84ac9aSAndroid Build Coastguard Worker int n = read(fd, buf, sizeof(buf) - 1);
1240*cf84ac9aSAndroid Build Coastguard Worker int saved_errno = errno;
1241*cf84ac9aSAndroid Build Coastguard Worker close(fd);
1242*cf84ac9aSAndroid Build Coastguard Worker
1243*cf84ac9aSAndroid Build Coastguard Worker if (n < 0) {
1244*cf84ac9aSAndroid Build Coastguard Worker errno = saved_errno;
1245*cf84ac9aSAndroid Build Coastguard Worker return -1;
1246*cf84ac9aSAndroid Build Coastguard Worker }
1247*cf84ac9aSAndroid Build Coastguard Worker
1248*cf84ac9aSAndroid Build Coastguard Worker buf[n] = '\0';
1249*cf84ac9aSAndroid Build Coastguard Worker char *endptr = 0;
1250*cf84ac9aSAndroid Build Coastguard Worker errno = 0;
1251*cf84ac9aSAndroid Build Coastguard Worker lval = strtol(buf, &endptr, 10);
1252*cf84ac9aSAndroid Build Coastguard Worker if (!endptr || (*endptr && '\n' != *endptr)
1253*cf84ac9aSAndroid Build Coastguard Worker #if INT_MAX < LONG_MAX
1254*cf84ac9aSAndroid Build Coastguard Worker || lval > INT_MAX || lval < INT_MIN
1255*cf84ac9aSAndroid Build Coastguard Worker #endif
1256*cf84ac9aSAndroid Build Coastguard Worker || ERANGE == errno) {
1257*cf84ac9aSAndroid Build Coastguard Worker if (!errno)
1258*cf84ac9aSAndroid Build Coastguard Worker errno = EINVAL;
1259*cf84ac9aSAndroid Build Coastguard Worker return -1;
1260*cf84ac9aSAndroid Build Coastguard Worker }
1261*cf84ac9aSAndroid Build Coastguard Worker
1262*cf84ac9aSAndroid Build Coastguard Worker *pvalue = (int) lval;
1263*cf84ac9aSAndroid Build Coastguard Worker return 0;
1264*cf84ac9aSAndroid Build Coastguard Worker }
1265