• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5  * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6  * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7  *                     Linux for s390 port by D.J. Barrow
8  *                    <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
9  * Copyright (c) 1999-2017 The strace developers.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include "defs.h"
36 #include <sys/param.h>
37 #include <fcntl.h>
38 #include <stdarg.h>
39 #ifdef HAVE_SYS_XATTR_H
40 # include <sys/xattr.h>
41 #endif
42 #include <sys/uio.h>
43 #include <asm/unistd.h>
44 
45 #include "scno.h"
46 #include "regs.h"
47 #include "ptrace.h"
48 
49 int
string_to_uint_ex(const char * const str,char ** const endptr,const unsigned int max_val,const char * const accepted_ending)50 string_to_uint_ex(const char *const str, char **const endptr,
51 		  const unsigned int max_val, const char *const accepted_ending)
52 {
53 	char *end;
54 	long val;
55 
56 	if (!*str)
57 		return -1;
58 
59 	errno = 0;
60 	val = strtol(str, &end, 10);
61 
62 	if (str == end || val < 0 || (unsigned long) val > max_val
63 	    || (val == LONG_MAX && errno == ERANGE))
64 		return -1;
65 
66 	if (*end && (!accepted_ending || !strchr(accepted_ending, *end)))
67 		return -1;
68 
69 	if (endptr)
70 		*endptr = end;
71 
72 	return (int) val;
73 }
74 
75 int
string_to_uint(const char * const str)76 string_to_uint(const char *const str)
77 {
78 	return string_to_uint_upto(str, INT_MAX);
79 }
80 
81 int
tv_nz(const struct timeval * a)82 tv_nz(const struct timeval *a)
83 {
84 	return a->tv_sec || a->tv_usec;
85 }
86 
87 int
tv_cmp(const struct timeval * a,const struct timeval * b)88 tv_cmp(const struct timeval *a, const struct timeval *b)
89 {
90 	if (a->tv_sec < b->tv_sec
91 	    || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
92 		return -1;
93 	if (a->tv_sec > b->tv_sec
94 	    || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
95 		return 1;
96 	return 0;
97 }
98 
99 double
tv_float(const struct timeval * tv)100 tv_float(const struct timeval *tv)
101 {
102 	return tv->tv_sec + tv->tv_usec/1000000.0;
103 }
104 
105 void
tv_add(struct timeval * tv,const struct timeval * a,const struct timeval * b)106 tv_add(struct timeval *tv, const struct timeval *a, const struct timeval *b)
107 {
108 	tv->tv_sec = a->tv_sec + b->tv_sec;
109 	tv->tv_usec = a->tv_usec + b->tv_usec;
110 	if (tv->tv_usec >= 1000000) {
111 		tv->tv_sec++;
112 		tv->tv_usec -= 1000000;
113 	}
114 }
115 
116 void
tv_sub(struct timeval * tv,const struct timeval * a,const struct timeval * b)117 tv_sub(struct timeval *tv, const struct timeval *a, const struct timeval *b)
118 {
119 	tv->tv_sec = a->tv_sec - b->tv_sec;
120 	tv->tv_usec = a->tv_usec - b->tv_usec;
121 	if (((long) tv->tv_usec) < 0) {
122 		tv->tv_sec--;
123 		tv->tv_usec += 1000000;
124 	}
125 }
126 
127 void
tv_div(struct timeval * tv,const struct timeval * a,int n)128 tv_div(struct timeval *tv, const struct timeval *a, int n)
129 {
130 	tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
131 	tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
132 	tv->tv_usec %= 1000000;
133 }
134 
135 void
tv_mul(struct timeval * tv,const struct timeval * a,int n)136 tv_mul(struct timeval *tv, const struct timeval *a, int n)
137 {
138 	tv->tv_usec = a->tv_usec * n;
139 	tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000;
140 	tv->tv_usec %= 1000000;
141 }
142 
143 #if !defined HAVE_STPCPY
144 char *
stpcpy(char * dst,const char * src)145 stpcpy(char *dst, const char *src)
146 {
147 	while ((*dst = *src++) != '\0')
148 		dst++;
149 	return dst;
150 }
151 #endif
152 
153 /* Find a next bit which is set.
154  * Starts testing at cur_bit.
155  * Returns -1 if no more bits are set.
156  *
157  * We never touch bytes we don't need to.
158  * On big-endian, array is assumed to consist of
159  * current_wordsize wide words: for example, is current_wordsize is 4,
160  * the bytes are walked in 3,2,1,0, 7,6,5,4, 11,10,9,8 ... sequence.
161  * On little-endian machines, word size is immaterial.
162  */
163 int
next_set_bit(const void * bit_array,unsigned cur_bit,unsigned size_bits)164 next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_bits)
165 {
166 	const unsigned endian = 1;
167 	int little_endian = *(char *) (void *) &endian;
168 
169 	const uint8_t *array = bit_array;
170 	unsigned pos = cur_bit / 8;
171 	unsigned pos_xor_mask = little_endian ? 0 : current_wordsize-1;
172 
173 	for (;;) {
174 		uint8_t bitmask;
175 		uint8_t cur_byte;
176 
177 		if (cur_bit >= size_bits)
178 			return -1;
179 		cur_byte = array[pos ^ pos_xor_mask];
180 		if (cur_byte == 0) {
181 			cur_bit = (cur_bit + 8) & (-8);
182 			pos++;
183 			continue;
184 		}
185 		bitmask = 1 << (cur_bit & 7);
186 		for (;;) {
187 			if (cur_byte & bitmask)
188 				return cur_bit;
189 			cur_bit++;
190 			if (cur_bit >= size_bits)
191 				return -1;
192 			bitmask <<= 1;
193 			/* This check *can't be* optimized out: */
194 			if (bitmask == 0)
195 				break;
196 		}
197 		pos++;
198 	}
199 }
200 
201 /*
202  * Fetch 64bit argument at position arg_no and
203  * return the index of the next argument.
204  */
205 int
getllval(struct tcb * tcp,unsigned long long * val,int arg_no)206 getllval(struct tcb *tcp, unsigned long long *val, int arg_no)
207 {
208 #if SIZEOF_KERNEL_LONG_T > 4
209 # ifndef current_klongsize
210 	if (current_klongsize < SIZEOF_KERNEL_LONG_T) {
211 #  if defined(AARCH64) || defined(POWERPC64)
212 		/* Align arg_no to the next even number. */
213 		arg_no = (arg_no + 1) & 0xe;
214 #  endif /* AARCH64 || POWERPC64 */
215 		*val = ULONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
216 		arg_no += 2;
217 	} else
218 # endif /* !current_klongsize */
219 	{
220 		*val = tcp->u_arg[arg_no];
221 		arg_no++;
222 	}
223 #else /* SIZEOF_KERNEL_LONG_T == 4 */
224 # if defined __ARM_EABI__	\
225   || defined LINUX_MIPSO32	\
226   || defined POWERPC		\
227   || defined XTENSA
228 	/* Align arg_no to the next even number. */
229 	arg_no = (arg_no + 1) & 0xe;
230 # elif defined SH
231 	/*
232 	 * The SH4 ABI does allow long longs in odd-numbered registers, but
233 	 * does not allow them to be split between registers and memory - and
234 	 * there are only four argument registers for normal functions.  As a
235 	 * result, pread, for example, takes an extra padding argument before
236 	 * the offset.  This was changed late in the 2.4 series (around 2.4.20).
237 	 */
238 	if (arg_no == 3)
239 		arg_no++;
240 # endif /* __ARM_EABI__ || LINUX_MIPSO32 || POWERPC || XTENSA || SH */
241 	*val = ULONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
242 	arg_no += 2;
243 #endif
244 
245 	return arg_no;
246 }
247 
248 /*
249  * Print 64bit argument at position arg_no and
250  * return the index of the next argument.
251  */
252 int
printllval(struct tcb * tcp,const char * format,int arg_no)253 printllval(struct tcb *tcp, const char *format, int arg_no)
254 {
255 	unsigned long long val = 0;
256 
257 	arg_no = getllval(tcp, &val, arg_no);
258 	tprintf(format, val);
259 	return arg_no;
260 }
261 
262 void
printaddr(const kernel_ulong_t addr)263 printaddr(const kernel_ulong_t addr)
264 {
265 	if (!addr)
266 		tprints("NULL");
267 	else
268 		tprintf("%#" PRI_klx, addr);
269 }
270 
271 #define DEF_PRINTNUM(name, type) \
272 bool									\
273 printnum_ ## name(struct tcb *const tcp, const kernel_ulong_t addr,	\
274 		  const char *const fmt)				\
275 {									\
276 	type num;							\
277 	if (umove_or_printaddr(tcp, addr, &num))			\
278 		return false;						\
279 	tprints("[");							\
280 	tprintf(fmt, num);						\
281 	tprints("]");							\
282 	return true;							\
283 }
284 
285 #define DEF_PRINTNUM_ADDR(name, type) \
286 bool									\
287 printnum_addr_ ## name(struct tcb *tcp, const kernel_ulong_t addr)	\
288 {									\
289 	type num;							\
290 	if (umove_or_printaddr(tcp, addr, &num))			\
291 		return false;						\
292 	tprints("[");							\
293 	printaddr(num);							\
294 	tprints("]");							\
295 	return true;							\
296 }
297 
298 #define DEF_PRINTPAIR(name, type) \
299 bool									\
300 printpair_ ## name(struct tcb *const tcp, const kernel_ulong_t addr,	\
301 		   const char *const fmt)				\
302 {									\
303 	type pair[2];							\
304 	if (umove_or_printaddr(tcp, addr, &pair))			\
305 		return false;						\
306 	tprints("[");							\
307 	tprintf(fmt, pair[0]);						\
308 	tprints(", ");							\
309 	tprintf(fmt, pair[1]);						\
310 	tprints("]");							\
311 	return true;							\
312 }
313 
DEF_PRINTNUM(int,int)314 DEF_PRINTNUM(int, int)
315 DEF_PRINTNUM_ADDR(int, unsigned int)
316 DEF_PRINTPAIR(int, int)
317 DEF_PRINTNUM(short, short)
318 DEF_PRINTNUM(int64, uint64_t)
319 DEF_PRINTNUM_ADDR(int64, uint64_t)
320 DEF_PRINTPAIR(int64, uint64_t)
321 
322 #ifndef current_wordsize
323 bool
324 printnum_long_int(struct tcb *const tcp, const kernel_ulong_t addr,
325 		  const char *const fmt_long, const char *const fmt_int)
326 {
327 	if (current_wordsize > sizeof(int)) {
328 		return printnum_int64(tcp, addr, fmt_long);
329 	} else {
330 		return printnum_int(tcp, addr, fmt_int);
331 	}
332 }
333 
334 bool
printnum_addr_long_int(struct tcb * tcp,const kernel_ulong_t addr)335 printnum_addr_long_int(struct tcb *tcp, const kernel_ulong_t addr)
336 {
337 	if (current_wordsize > sizeof(int)) {
338 		return printnum_addr_int64(tcp, addr);
339 	} else {
340 		return printnum_addr_int(tcp, addr);
341 	}
342 }
343 #endif /* !current_wordsize */
344 
345 #ifndef current_klongsize
346 bool
printnum_addr_klong_int(struct tcb * tcp,const kernel_ulong_t addr)347 printnum_addr_klong_int(struct tcb *tcp, const kernel_ulong_t addr)
348 {
349 	if (current_klongsize > sizeof(int)) {
350 		return printnum_addr_int64(tcp, addr);
351 	} else {
352 		return printnum_addr_int(tcp, addr);
353 	}
354 }
355 #endif /* !current_klongsize */
356 
357 /**
358  * Prints time to a (static internal) buffer and returns pointer to it.
359  *
360  * @param sec		Seconds since epoch.
361  * @param part_sec	Amount of second parts since the start of a second.
362  * @param max_part_sec	Maximum value of a valid part_sec.
363  * @param width		1 + floor(log10(max_part_sec)).
364  */
365 static const char *
sprinttime_ex(const long long sec,const unsigned long long part_sec,const unsigned int max_part_sec,const int width)366 sprinttime_ex(const long long sec, const unsigned long long part_sec,
367 	      const unsigned int max_part_sec, const int width)
368 {
369 	static char buf[sizeof(int) * 3 * 6 + sizeof(part_sec) * 3
370 			+ sizeof("+0000")];
371 
372 	if ((sec == 0 && part_sec == 0) || part_sec > max_part_sec)
373 		return NULL;
374 
375 	time_t t = (time_t) sec;
376 	struct tm *tmp = (sec == t) ? localtime(&t) : NULL;
377 	if (!tmp)
378 		return NULL;
379 
380 	size_t pos = strftime(buf, sizeof(buf), "%FT%T", tmp);
381 	if (!pos)
382 		return NULL;
383 
384 	if (part_sec > 0) {
385 		int ret = snprintf(buf + pos, sizeof(buf) - pos, ".%0*llu",
386 				   width, part_sec);
387 
388 		if (ret < 0 || (size_t) ret >= sizeof(buf) - pos)
389 			return NULL;
390 
391 		pos += ret;
392 	}
393 
394 	return strftime(buf + pos, sizeof(buf) - pos, "%z", tmp) ? buf : NULL;
395 }
396 
397 const char *
sprinttime(long long sec)398 sprinttime(long long sec)
399 {
400 	return sprinttime_ex(sec, 0, 0, 0);
401 }
402 
403 const char *
sprinttime_usec(long long sec,unsigned long long usec)404 sprinttime_usec(long long sec, unsigned long long usec)
405 {
406 	return sprinttime_ex(sec, usec, 999999, 6);
407 }
408 
409 const char *
sprinttime_nsec(long long sec,unsigned long long nsec)410 sprinttime_nsec(long long sec, unsigned long long nsec)
411 {
412 	return sprinttime_ex(sec, nsec, 999999999, 9);
413 }
414 
415 enum sock_proto
getfdproto(struct tcb * tcp,int fd)416 getfdproto(struct tcb *tcp, int fd)
417 {
418 #ifdef HAVE_SYS_XATTR_H
419 	size_t bufsize = 256;
420 	char buf[bufsize];
421 	ssize_t r;
422 	char path[sizeof("/proc/%u/fd/%u") + 2 * sizeof(int)*3];
423 
424 	if (fd < 0)
425 		return SOCK_PROTO_UNKNOWN;
426 
427 	sprintf(path, "/proc/%u/fd/%u", tcp->pid, fd);
428 	r = getxattr(path, "system.sockprotoname", buf, bufsize - 1);
429 	if (r <= 0)
430 		return SOCK_PROTO_UNKNOWN;
431 	else {
432 		/*
433 		 * This is a protection for the case when the kernel
434 		 * side does not append a null byte to the buffer.
435 		 */
436 		buf[r] = '\0';
437 
438 		return get_proto_by_name(buf);
439 	}
440 #else
441 	return SOCK_PROTO_UNKNOWN;
442 #endif
443 }
444 
445 unsigned long
getfdinode(struct tcb * tcp,int fd)446 getfdinode(struct tcb *tcp, int fd)
447 {
448 	char path[PATH_MAX + 1];
449 
450 	if (getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
451 		const char *str = STR_STRIP_PREFIX(path, "socket:[");
452 
453 		if (str != path) {
454 			const size_t str_len = strlen(str);
455 			if (str_len && str[str_len - 1] == ']')
456 				return strtoul(str, NULL, 10);
457 		}
458 	}
459 
460 	return 0;
461 }
462 
463 void
printfd(struct tcb * tcp,int fd)464 printfd(struct tcb *tcp, int fd)
465 {
466 	char path[PATH_MAX + 1];
467 	if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
468 		const char *str;
469 		size_t len;
470 		unsigned long inode;
471 
472 		tprintf("%d<", fd);
473 		if (show_fd_path <= 1
474 		    || (str = STR_STRIP_PREFIX(path, "socket:[")) == path
475 		    || !(len = strlen(str))
476 		    || str[len - 1] != ']'
477 		    || !(inode = strtoul(str, NULL, 10))
478 		    || !print_sockaddr_by_inode(tcp, fd, inode)) {
479 			print_quoted_string(path, strlen(path),
480 					    QUOTE_OMIT_LEADING_TRAILING_QUOTES);
481 		}
482 		tprints(">");
483 	} else
484 		tprintf("%d", fd);
485 }
486 
487 /*
488  * Quote string `instr' of length `size'
489  * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
490  *
491  * If QUOTE_0_TERMINATED `style' flag is set,
492  * treat `instr' as a NUL-terminated string,
493  * checking up to (`size' + 1) bytes of `instr'.
494  *
495  * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
496  * do not add leading and trailing quoting symbols.
497  *
498  * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
499  * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
500  */
501 int
string_quote(const char * instr,char * outstr,const unsigned int size,const unsigned int style)502 string_quote(const char *instr, char *outstr, const unsigned int size,
503 	     const unsigned int style)
504 {
505 	const unsigned char *ustr = (const unsigned char *) instr;
506 	char *s = outstr;
507 	unsigned int i;
508 	int usehex, c, eol;
509 
510 	if (style & QUOTE_0_TERMINATED)
511 		eol = '\0';
512 	else
513 		eol = 0x100; /* this can never match a char */
514 
515 	usehex = 0;
516 	if ((xflag > 1) || (style & QUOTE_FORCE_HEX)) {
517 		usehex = 1;
518 	} else if (xflag) {
519 		/* Check for presence of symbol which require
520 		   to hex-quote the whole string. */
521 		for (i = 0; i < size; ++i) {
522 			c = ustr[i];
523 			/* Check for NUL-terminated string. */
524 			if (c == eol)
525 				break;
526 
527 			/* Force hex unless c is printable or whitespace */
528 			if (c > 0x7e) {
529 				usehex = 1;
530 				break;
531 			}
532 			/* In ASCII isspace is only these chars: "\t\n\v\f\r".
533 			 * They happen to have ASCII codes 9,10,11,12,13.
534 			 */
535 			if (c < ' ' && (unsigned)(c - 9) >= 5) {
536 				usehex = 1;
537 				break;
538 			}
539 		}
540 	}
541 
542 	if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
543 		*s++ = '\"';
544 
545 	if (usehex) {
546 		/* Hex-quote the whole string. */
547 		for (i = 0; i < size; ++i) {
548 			c = ustr[i];
549 			/* Check for NUL-terminated string. */
550 			if (c == eol)
551 				goto asciz_ended;
552 			*s++ = '\\';
553 			*s++ = 'x';
554 			*s++ = "0123456789abcdef"[c >> 4];
555 			*s++ = "0123456789abcdef"[c & 0xf];
556 		}
557 	} else {
558 		for (i = 0; i < size; ++i) {
559 			c = ustr[i];
560 			/* Check for NUL-terminated string. */
561 			if (c == eol)
562 				goto asciz_ended;
563 			if ((i == (size - 1)) &&
564 			    (style & QUOTE_OMIT_TRAILING_0) && (c == '\0'))
565 				goto asciz_ended;
566 			switch (c) {
567 				case '\"': case '\\':
568 					*s++ = '\\';
569 					*s++ = c;
570 					break;
571 				case '\f':
572 					*s++ = '\\';
573 					*s++ = 'f';
574 					break;
575 				case '\n':
576 					*s++ = '\\';
577 					*s++ = 'n';
578 					break;
579 				case '\r':
580 					*s++ = '\\';
581 					*s++ = 'r';
582 					break;
583 				case '\t':
584 					*s++ = '\\';
585 					*s++ = 't';
586 					break;
587 				case '\v':
588 					*s++ = '\\';
589 					*s++ = 'v';
590 					break;
591 				default:
592 					if (c >= ' ' && c <= 0x7e)
593 						*s++ = c;
594 					else {
595 						/* Print \octal */
596 						*s++ = '\\';
597 						if (i + 1 < size
598 						    && ustr[i + 1] >= '0'
599 						    && ustr[i + 1] <= '9'
600 						) {
601 							/* Print \ooo */
602 							*s++ = '0' + (c >> 6);
603 							*s++ = '0' + ((c >> 3) & 0x7);
604 						} else {
605 							/* Print \[[o]o]o */
606 							if ((c >> 3) != 0) {
607 								if ((c >> 6) != 0)
608 									*s++ = '0' + (c >> 6);
609 								*s++ = '0' + ((c >> 3) & 0x7);
610 							}
611 						}
612 						*s++ = '0' + (c & 0x7);
613 					}
614 					break;
615 			}
616 		}
617 	}
618 
619 	if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
620 		*s++ = '\"';
621 	*s = '\0';
622 
623 	/* Return zero if we printed entire ASCIZ string (didn't truncate it) */
624 	if (style & QUOTE_0_TERMINATED && ustr[i] == '\0') {
625 		/* We didn't see NUL yet (otherwise we'd jump to 'asciz_ended')
626 		 * but next char is NUL.
627 		 */
628 		return 0;
629 	}
630 
631 	return 1;
632 
633  asciz_ended:
634 	if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
635 		*s++ = '\"';
636 	*s = '\0';
637 	/* Return zero: we printed entire ASCIZ string (didn't truncate it) */
638 	return 0;
639 }
640 
641 #ifndef ALLOCA_CUTOFF
642 # define ALLOCA_CUTOFF	4032
643 #endif
644 #define use_alloca(n) ((n) <= ALLOCA_CUTOFF)
645 
646 /*
647  * Quote string `str' of length `size' and print the result.
648  *
649  * If QUOTE_0_TERMINATED `style' flag is set,
650  * treat `str' as a NUL-terminated string and
651  * quote at most (`size' - 1) bytes.
652  *
653  * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
654  * do not add leading and trailing quoting symbols.
655  *
656  * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
657  * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
658  */
659 int
print_quoted_string(const char * str,unsigned int size,const unsigned int style)660 print_quoted_string(const char *str, unsigned int size,
661 		    const unsigned int style)
662 {
663 	char *buf;
664 	char *outstr;
665 	unsigned int alloc_size;
666 	int rc;
667 
668 	if (size && style & QUOTE_0_TERMINATED)
669 		--size;
670 
671 	alloc_size = 4 * size;
672 	if (alloc_size / 4 != size) {
673 		error_msg("Out of memory");
674 		tprints("???");
675 		return -1;
676 	}
677 	alloc_size += 1 + (style & QUOTE_OMIT_LEADING_TRAILING_QUOTES ? 0 : 2);
678 
679 	if (use_alloca(alloc_size)) {
680 		outstr = alloca(alloc_size);
681 		buf = NULL;
682 	} else {
683 		outstr = buf = malloc(alloc_size);
684 		if (!buf) {
685 			error_msg("Out of memory");
686 			tprints("???");
687 			return -1;
688 		}
689 	}
690 
691 	rc = string_quote(str, outstr, size, style);
692 	tprints(outstr);
693 
694 	free(buf);
695 	return rc;
696 }
697 
698 /*
699  * Print path string specified by address `addr' and length `n'.
700  * If path length exceeds `n', append `...' to the output.
701  */
702 void
printpathn(struct tcb * const tcp,const kernel_ulong_t addr,unsigned int n)703 printpathn(struct tcb *const tcp, const kernel_ulong_t addr, unsigned int n)
704 {
705 	char path[PATH_MAX + 1];
706 	int nul_seen;
707 
708 	if (!addr) {
709 		tprints("NULL");
710 		return;
711 	}
712 
713 	/* Cap path length to the path buffer size */
714 	if (n > sizeof(path) - 1)
715 		n = sizeof(path) - 1;
716 
717 	/* Fetch one byte more to find out whether path length > n. */
718 	nul_seen = umovestr(tcp, addr, n + 1, path);
719 	if (nul_seen < 0)
720 		printaddr(addr);
721 	else {
722 		path[n++] = '\0';
723 		print_quoted_string(path, n, QUOTE_0_TERMINATED);
724 		if (!nul_seen)
725 			tprints("...");
726 	}
727 }
728 
729 void
printpath(struct tcb * const tcp,const kernel_ulong_t addr)730 printpath(struct tcb *const tcp, const kernel_ulong_t addr)
731 {
732 	/* Size must correspond to char path[] size in printpathn */
733 	printpathn(tcp, addr, PATH_MAX);
734 }
735 
736 /*
737  * Print string specified by address `addr' and length `len'.
738  * If `user_style' has QUOTE_0_TERMINATED bit set, treat the string
739  * as a NUL-terminated string.
740  * Pass `user_style' on to `string_quote'.
741  * Append `...' to the output if either the string length exceeds `max_strlen',
742  * or QUOTE_0_TERMINATED bit is set and the string length exceeds `len'.
743  */
744 void
printstr_ex(struct tcb * const tcp,const kernel_ulong_t addr,const kernel_ulong_t len,const unsigned int user_style)745 printstr_ex(struct tcb *const tcp, const kernel_ulong_t addr,
746 	    const kernel_ulong_t len, const unsigned int user_style)
747 {
748 	static char *str;
749 	static char *outstr;
750 
751 	unsigned int size;
752 	unsigned int style = user_style;
753 	int rc;
754 	int ellipsis;
755 
756 	if (!addr) {
757 		tprints("NULL");
758 		return;
759 	}
760 	/* Allocate static buffers if they are not allocated yet. */
761 	if (!str) {
762 		const unsigned int outstr_size =
763 			4 * max_strlen + /* for quotes and NUL */ 3;
764 		/*
765 		 * We can assume that outstr_size / 4 == max_strlen
766 		 * since we have a guarantee that max_strlen <= -1U / 4.
767 		 */
768 
769 		str = xmalloc(max_strlen + 1);
770 		outstr = xmalloc(outstr_size);
771 	}
772 
773 	/* Fetch one byte more because string_quote may look one byte ahead. */
774 	size = max_strlen + 1;
775 
776 	if (size > len)
777 		size = len;
778 	if (style & QUOTE_0_TERMINATED)
779 		rc = umovestr(tcp, addr, size, str);
780 	else
781 		rc = umoven(tcp, addr, size, str);
782 
783 	if (rc < 0) {
784 		printaddr(addr);
785 		return;
786 	}
787 
788 	if (size > max_strlen)
789 		size = max_strlen;
790 	else
791 		str[size] = '\xff';
792 
793 	/* If string_quote didn't see NUL and (it was supposed to be ASCIZ str
794 	 * or we were requested to print more than -s NUM chars)...
795 	 */
796 	ellipsis = string_quote(str, outstr, size, style)
797 		   && len
798 		   && ((style & QUOTE_0_TERMINATED)
799 		       || len > max_strlen);
800 
801 	tprints(outstr);
802 	if (ellipsis)
803 		tprints("...");
804 }
805 
806 void
dumpiov_upto(struct tcb * const tcp,const int len,const kernel_ulong_t addr,kernel_ulong_t data_size)807 dumpiov_upto(struct tcb *const tcp, const int len, const kernel_ulong_t addr,
808 	     kernel_ulong_t data_size)
809 {
810 #if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
811 	union {
812 		struct { uint32_t base; uint32_t len; } *iov32;
813 		struct { uint64_t base; uint64_t len; } *iov64;
814 	} iovu;
815 #define iov iovu.iov64
816 #define sizeof_iov \
817 	(current_wordsize == 4 ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64))
818 #define iov_iov_base(i) \
819 	(current_wordsize == 4 ? (uint64_t) iovu.iov32[i].base : iovu.iov64[i].base)
820 #define iov_iov_len(i) \
821 	(current_wordsize == 4 ? (uint64_t) iovu.iov32[i].len : iovu.iov64[i].len)
822 #else
823 	struct iovec *iov;
824 #define sizeof_iov sizeof(*iov)
825 #define iov_iov_base(i) ptr_to_kulong(iov[i].iov_base)
826 #define iov_iov_len(i) iov[i].iov_len
827 #endif
828 	int i;
829 	unsigned size;
830 
831 	size = sizeof_iov * len;
832 	/* Assuming no sane program has millions of iovs */
833 	if ((unsigned)len > 1024*1024 /* insane or negative size? */
834 	    || (iov = malloc(size)) == NULL) {
835 		error_msg("Out of memory");
836 		return;
837 	}
838 	if (umoven(tcp, addr, size, iov) >= 0) {
839 		for (i = 0; i < len; i++) {
840 			kernel_ulong_t iov_len = iov_iov_len(i);
841 			if (iov_len > data_size)
842 				iov_len = data_size;
843 			if (!iov_len)
844 				break;
845 			data_size -= iov_len;
846 			/* include the buffer number to make it easy to
847 			 * match up the trace with the source */
848 			tprintf(" * %" PRI_klu " bytes in buffer %d\n", iov_len, i);
849 			dumpstr(tcp, iov_iov_base(i), iov_len);
850 		}
851 	}
852 	free(iov);
853 #undef sizeof_iov
854 #undef iov_iov_base
855 #undef iov_iov_len
856 #undef iov
857 }
858 
859 void
dumpstr(struct tcb * const tcp,const kernel_ulong_t addr,const int len)860 dumpstr(struct tcb *const tcp, const kernel_ulong_t addr, const int len)
861 {
862 	static int strsize = -1;
863 	static unsigned char *str;
864 
865 	char outbuf[
866 		(
867 			(sizeof(
868 			"xx xx xx xx xx xx xx xx  xx xx xx xx xx xx xx xx  "
869 			"1234567890123456") + /*in case I'm off by few:*/ 4)
870 		/*align to 8 to make memset easier:*/ + 7) & -8
871 	];
872 	const unsigned char *src;
873 	int i;
874 
875 	memset(outbuf, ' ', sizeof(outbuf));
876 
877 	if (strsize < len + 16) {
878 		free(str);
879 		str = malloc(len + 16);
880 		if (!str) {
881 			strsize = -1;
882 			error_msg("Out of memory");
883 			return;
884 		}
885 		strsize = len + 16;
886 	}
887 
888 	if (umoven(tcp, addr, len, str) < 0)
889 		return;
890 
891 	/* Space-pad to 16 bytes */
892 	i = len;
893 	while (i & 0xf)
894 		str[i++] = ' ';
895 
896 	i = 0;
897 	src = str;
898 	while (i < len) {
899 		char *dst = outbuf;
900 		/* Hex dump */
901 		do {
902 			if (i < len) {
903 				*dst++ = "0123456789abcdef"[*src >> 4];
904 				*dst++ = "0123456789abcdef"[*src & 0xf];
905 			} else {
906 				*dst++ = ' ';
907 				*dst++ = ' ';
908 			}
909 			dst++; /* space is there by memset */
910 			i++;
911 			if ((i & 7) == 0)
912 				dst++; /* space is there by memset */
913 			src++;
914 		} while (i & 0xf);
915 		/* ASCII dump */
916 		i -= 16;
917 		src -= 16;
918 		do {
919 			if (*src >= ' ' && *src < 0x7f)
920 				*dst++ = *src;
921 			else
922 				*dst++ = '.';
923 			src++;
924 		} while (++i & 0xf);
925 		*dst = '\0';
926 		tprintf(" | %05x  %s |\n", i - 16, outbuf);
927 	}
928 }
929 
930 static bool process_vm_readv_not_supported;
931 
932 #ifndef HAVE_PROCESS_VM_READV
933 /*
934  * Need to do this since process_vm_readv() is not yet available in libc.
935  * When libc is be updated, only "static bool process_vm_readv_not_supported"
936  * line should remain.
937  */
938 /* Have to avoid duplicating with the C library headers. */
strace_process_vm_readv(pid_t pid,const struct iovec * lvec,unsigned long liovcnt,const struct iovec * rvec,unsigned long riovcnt,unsigned long flags)939 static ssize_t strace_process_vm_readv(pid_t pid,
940 		 const struct iovec *lvec,
941 		 unsigned long liovcnt,
942 		 const struct iovec *rvec,
943 		 unsigned long riovcnt,
944 		 unsigned long flags)
945 {
946 	return syscall(__NR_process_vm_readv, (long)pid, lvec, liovcnt, rvec, riovcnt, flags);
947 }
948 # define process_vm_readv strace_process_vm_readv
949 #endif /* !HAVE_PROCESS_VM_READV */
950 
951 static ssize_t
vm_read_mem(const pid_t pid,void * const laddr,const kernel_ulong_t raddr,const size_t len)952 vm_read_mem(const pid_t pid, void *const laddr,
953 	    const kernel_ulong_t raddr, const size_t len)
954 {
955 	const unsigned long truncated_raddr = raddr;
956 
957 	if (raddr != (kernel_ulong_t) truncated_raddr) {
958 		errno = EIO;
959 		return -1;
960 	}
961 
962 	const struct iovec local = {
963 		.iov_base = laddr,
964 		.iov_len = len
965 	};
966 	const struct iovec remote = {
967 		.iov_base = (void *) truncated_raddr,
968 		.iov_len = len
969 	};
970 
971 	return process_vm_readv(pid, &local, 1, &remote, 1, 0);
972 }
973 
974 /*
975  * move `len' bytes of data from process `pid'
976  * at address `addr' to our space at `our_addr'
977  */
978 int
umoven(struct tcb * const tcp,kernel_ulong_t addr,unsigned int len,void * const our_addr)979 umoven(struct tcb *const tcp, kernel_ulong_t addr, unsigned int len,
980        void *const our_addr)
981 {
982 	char *laddr = our_addr;
983 	int pid = tcp->pid;
984 	unsigned int n, m, nread;
985 	union {
986 		long val;
987 		char x[sizeof(long)];
988 	} u;
989 
990 #if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
991 	if (current_wordsize < sizeof(addr)
992 	    && (addr & (~(kernel_ulong_t) -1U))) {
993 		return -1;
994 	}
995 #endif
996 
997 	if (!process_vm_readv_not_supported) {
998 		int r = vm_read_mem(pid, laddr, addr, len);
999 		if ((unsigned int) r == len)
1000 			return 0;
1001 		if (r >= 0) {
1002 			error_msg("umoven: short read (%u < %u) @0x%" PRI_klx,
1003 				  (unsigned int) r, len, addr);
1004 			return -1;
1005 		}
1006 		switch (errno) {
1007 			case ENOSYS:
1008 				process_vm_readv_not_supported = 1;
1009 				break;
1010 			case EPERM:
1011 				/* operation not permitted, try PTRACE_PEEKDATA */
1012 				break;
1013 			case ESRCH:
1014 				/* the process is gone */
1015 				return -1;
1016 			case EFAULT: case EIO:
1017 				/* address space is inaccessible */
1018 				return -1;
1019 			default:
1020 				/* all the rest is strange and should be reported */
1021 				perror_msg("process_vm_readv");
1022 				return -1;
1023 		}
1024 	}
1025 
1026 	nread = 0;
1027 	if (addr & (sizeof(long) - 1)) {
1028 		/* addr not a multiple of sizeof(long) */
1029 		n = addr & (sizeof(long) - 1);	/* residue */
1030 		addr &= -sizeof(long);		/* aligned address */
1031 		errno = 0;
1032 		u.val = ptrace(PTRACE_PEEKDATA, pid, addr, 0);
1033 		switch (errno) {
1034 			case 0:
1035 				break;
1036 			case ESRCH: case EINVAL:
1037 				/* these could be seen if the process is gone */
1038 				return -1;
1039 			case EFAULT: case EIO: case EPERM:
1040 				/* address space is inaccessible */
1041 				return -1;
1042 			default:
1043 				/* all the rest is strange and should be reported */
1044 				perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%" PRI_klx,
1045 					    pid, addr);
1046 				return -1;
1047 		}
1048 		m = MIN(sizeof(long) - n, len);
1049 		memcpy(laddr, &u.x[n], m);
1050 		addr += sizeof(long);
1051 		laddr += m;
1052 		nread += m;
1053 		len -= m;
1054 	}
1055 	while (len) {
1056 		errno = 0;
1057 		u.val = ptrace(PTRACE_PEEKDATA, pid, addr, 0);
1058 		switch (errno) {
1059 			case 0:
1060 				break;
1061 			case ESRCH: case EINVAL:
1062 				/* these could be seen if the process is gone */
1063 				return -1;
1064 			case EFAULT: case EIO: case EPERM:
1065 				/* address space is inaccessible */
1066 				if (nread) {
1067 					perror_msg("umoven: short read (%u < %u) @0x%" PRI_klx,
1068 						   nread, nread + len, addr - nread);
1069 				}
1070 				return -1;
1071 			default:
1072 				/* all the rest is strange and should be reported */
1073 				perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%" PRI_klx,
1074 					    pid, addr);
1075 				return -1;
1076 		}
1077 		m = MIN(sizeof(long), len);
1078 		memcpy(laddr, u.x, m);
1079 		addr += sizeof(long);
1080 		laddr += m;
1081 		nread += m;
1082 		len -= m;
1083 	}
1084 
1085 	return 0;
1086 }
1087 
1088 int
umoven_or_printaddr(struct tcb * const tcp,const kernel_ulong_t addr,const unsigned int len,void * const our_addr)1089 umoven_or_printaddr(struct tcb *const tcp, const kernel_ulong_t addr,
1090 		    const unsigned int len, void *const our_addr)
1091 {
1092 	if (!addr || !verbose(tcp) || (exiting(tcp) && syserror(tcp)) ||
1093 	    umoven(tcp, addr, len, our_addr) < 0) {
1094 		printaddr(addr);
1095 		return -1;
1096 	}
1097 	return 0;
1098 }
1099 
1100 int
umoven_or_printaddr_ignore_syserror(struct tcb * const tcp,const kernel_ulong_t addr,const unsigned int len,void * const our_addr)1101 umoven_or_printaddr_ignore_syserror(struct tcb *const tcp,
1102 				    const kernel_ulong_t addr,
1103 				    const unsigned int len,
1104 				    void *const our_addr)
1105 {
1106 	if (!addr || !verbose(tcp) || umoven(tcp, addr, len, our_addr) < 0) {
1107 		printaddr(addr);
1108 		return -1;
1109 	}
1110 	return 0;
1111 }
1112 
1113 /*
1114  * Like `umove' but make the additional effort of looking
1115  * for a terminating zero byte.
1116  *
1117  * Returns < 0 on error, > 0 if NUL was seen,
1118  * (TODO if useful: return count of bytes including NUL),
1119  * else 0 if len bytes were read but no NUL byte seen.
1120  *
1121  * Note: there is no guarantee we won't overwrite some bytes
1122  * in laddr[] _after_ terminating NUL (but, of course,
1123  * we never write past laddr[len-1]).
1124  */
1125 int
umovestr(struct tcb * const tcp,kernel_ulong_t addr,unsigned int len,char * laddr)1126 umovestr(struct tcb *const tcp, kernel_ulong_t addr, unsigned int len, char *laddr)
1127 {
1128 	const unsigned long x01010101 = (unsigned long) 0x0101010101010101ULL;
1129 	const unsigned long x80808080 = (unsigned long) 0x8080808080808080ULL;
1130 
1131 	int pid = tcp->pid;
1132 	unsigned int n, m, nread;
1133 	union {
1134 		unsigned long val;
1135 		char x[sizeof(long)];
1136 	} u;
1137 
1138 #if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
1139 	if (current_wordsize < sizeof(addr)
1140 	    && (addr & (~(kernel_ulong_t) -1U))) {
1141 		return -1;
1142 	}
1143 #endif
1144 
1145 	nread = 0;
1146 	if (!process_vm_readv_not_supported) {
1147 		const size_t page_size = get_pagesize();
1148 		const size_t page_mask = page_size - 1;
1149 
1150 		while (len > 0) {
1151 			unsigned int chunk_len;
1152 			unsigned int end_in_page;
1153 
1154 			/*
1155 			 * Don't cross pages, otherwise we can get EFAULT
1156 			 * and fail to notice that terminating NUL lies
1157 			 * in the existing (first) page.
1158 			 */
1159 			chunk_len = len > page_size ? page_size : len;
1160 			end_in_page = (addr + chunk_len) & page_mask;
1161 			if (chunk_len > end_in_page) /* crosses to the next page */
1162 				chunk_len -= end_in_page;
1163 
1164 			int r = vm_read_mem(pid, laddr, addr, chunk_len);
1165 			if (r > 0) {
1166 				if (memchr(laddr, '\0', r))
1167 					return 1;
1168 				addr += r;
1169 				laddr += r;
1170 				nread += r;
1171 				len -= r;
1172 				continue;
1173 			}
1174 			switch (errno) {
1175 				case ENOSYS:
1176 					process_vm_readv_not_supported = 1;
1177 					goto vm_readv_didnt_work;
1178 				case ESRCH:
1179 					/* the process is gone */
1180 					return -1;
1181 				case EPERM:
1182 					/* operation not permitted, try PTRACE_PEEKDATA */
1183 					if (!nread)
1184 						goto vm_readv_didnt_work;
1185 					/* fall through */
1186 				case EFAULT: case EIO:
1187 					/* address space is inaccessible */
1188 					if (nread) {
1189 						perror_msg("umovestr: short read (%d < %d) @0x%" PRI_klx,
1190 							   nread, nread + len, addr - nread);
1191 					}
1192 					return -1;
1193 				default:
1194 					/* all the rest is strange and should be reported */
1195 					perror_msg("process_vm_readv");
1196 					return -1;
1197 			}
1198 		}
1199 		return 0;
1200 	}
1201  vm_readv_didnt_work:
1202 
1203 	if (addr & (sizeof(long) - 1)) {
1204 		/* addr not a multiple of sizeof(long) */
1205 		n = addr & (sizeof(long) - 1);	/* residue */
1206 		addr &= -sizeof(long);		/* aligned address */
1207 		errno = 0;
1208 		u.val = ptrace(PTRACE_PEEKDATA, pid, addr, 0);
1209 		switch (errno) {
1210 			case 0:
1211 				break;
1212 			case ESRCH: case EINVAL:
1213 				/* these could be seen if the process is gone */
1214 				return -1;
1215 			case EFAULT: case EIO: case EPERM:
1216 				/* address space is inaccessible */
1217 				return -1;
1218 			default:
1219 				/* all the rest is strange and should be reported */
1220 				perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%" PRI_klx,
1221 					    pid, addr);
1222 				return -1;
1223 		}
1224 		m = MIN(sizeof(long) - n, len);
1225 		memcpy(laddr, &u.x[n], m);
1226 		while (n & (sizeof(long) - 1))
1227 			if (u.x[n++] == '\0')
1228 				return 1;
1229 		addr += sizeof(long);
1230 		laddr += m;
1231 		nread += m;
1232 		len -= m;
1233 	}
1234 
1235 	while (len) {
1236 		errno = 0;
1237 		u.val = ptrace(PTRACE_PEEKDATA, pid, addr, 0);
1238 		switch (errno) {
1239 			case 0:
1240 				break;
1241 			case ESRCH: case EINVAL:
1242 				/* these could be seen if the process is gone */
1243 				return -1;
1244 			case EFAULT: case EIO: case EPERM:
1245 				/* address space is inaccessible */
1246 				if (nread) {
1247 					perror_msg("umovestr: short read (%d < %d) @0x%" PRI_klx,
1248 						   nread, nread + len, addr - nread);
1249 				}
1250 				return -1;
1251 			default:
1252 				/* all the rest is strange and should be reported */
1253 				perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%" PRI_klx,
1254 					   pid, addr);
1255 				return -1;
1256 		}
1257 		m = MIN(sizeof(long), len);
1258 		memcpy(laddr, u.x, m);
1259 		/* "If a NUL char exists in this word" */
1260 		if ((u.val - x01010101) & ~u.val & x80808080)
1261 			return 1;
1262 		addr += sizeof(long);
1263 		laddr += m;
1264 		nread += m;
1265 		len -= m;
1266 	}
1267 	return 0;
1268 }
1269 
1270 /*
1271  * Iteratively fetch and print up to nmemb elements of elem_size size
1272  * from the array that starts at tracee's address start_addr.
1273  *
1274  * Array elements are being fetched to the address specified by elem_buf.
1275  *
1276  * The fetcher callback function specified by umoven_func should follow
1277  * the same semantics as umoven_or_printaddr function.
1278  *
1279  * The printer callback function specified by print_func is expected
1280  * to print something; if it returns false, no more iterations will be made.
1281  *
1282  * The pointer specified by opaque_data is passed to each invocation
1283  * of print_func callback function.
1284  *
1285  * This function prints:
1286  * - "NULL", if start_addr is NULL;
1287  * - "[]", if nmemb is 0;
1288  * - start_addr, if nmemb * elem_size overflows or wraps around;
1289  * - nothing, if the first element cannot be fetched
1290  *   (if umoven_func returns non-zero), but it is assumed that
1291  *   umoven_func has printed the address it failed to fetch data from;
1292  * - elements of the array, delimited by ", ", with the array itself
1293  *   enclosed with [] brackets.
1294  *
1295  * If abbrev(tcp) is true, then
1296  * - the maximum number of elements printed equals to max_strlen;
1297  * - "..." is printed instead of max_strlen+1 element
1298  *   and no more iterations will be made.
1299  *
1300  * This function returns true only if
1301  * - umoven_func has been called at least once AND
1302  * - umoven_func has not returned false.
1303  */
1304 bool
print_array(struct tcb * const tcp,const kernel_ulong_t start_addr,const size_t nmemb,void * const elem_buf,const size_t elem_size,int (* const umoven_func)(struct tcb *,kernel_ulong_t,unsigned int,void *),bool (* const print_func)(struct tcb *,void * elem_buf,size_t elem_size,void * opaque_data),void * const opaque_data)1305 print_array(struct tcb *const tcp,
1306 	    const kernel_ulong_t start_addr,
1307 	    const size_t nmemb,
1308 	    void *const elem_buf,
1309 	    const size_t elem_size,
1310 	    int (*const umoven_func)(struct tcb *,
1311 				     kernel_ulong_t,
1312 				     unsigned int,
1313 				     void *),
1314 	    bool (*const print_func)(struct tcb *,
1315 				     void *elem_buf,
1316 				     size_t elem_size,
1317 				     void *opaque_data),
1318 	    void *const opaque_data)
1319 {
1320 	if (!start_addr) {
1321 		tprints("NULL");
1322 		return false;
1323 	}
1324 
1325 	if (!nmemb) {
1326 		tprints("[]");
1327 		return false;
1328 	}
1329 
1330 	const size_t size = nmemb * elem_size;
1331 	const kernel_ulong_t end_addr = start_addr + size;
1332 
1333 	if (end_addr <= start_addr || size / elem_size != nmemb) {
1334 		printaddr(start_addr);
1335 		return false;
1336 	}
1337 
1338 	const kernel_ulong_t abbrev_end =
1339 		(abbrev(tcp) && max_strlen < nmemb) ?
1340 			start_addr + elem_size * max_strlen : end_addr;
1341 	kernel_ulong_t cur;
1342 
1343 	for (cur = start_addr; cur < end_addr; cur += elem_size) {
1344 		if (cur != start_addr)
1345 			tprints(", ");
1346 
1347 		if (umoven_func(tcp, cur, elem_size, elem_buf))
1348 			break;
1349 
1350 		if (cur == start_addr)
1351 			tprints("[");
1352 
1353 		if (cur >= abbrev_end) {
1354 			tprints("...");
1355 			cur = end_addr;
1356 			break;
1357 		}
1358 
1359 		if (!print_func(tcp, elem_buf, elem_size, opaque_data)) {
1360 			cur = end_addr;
1361 			break;
1362 		}
1363 	}
1364 	if (cur != start_addr)
1365 		tprints("]");
1366 
1367 	return cur >= end_addr;
1368 }
1369 
1370 int
printargs(struct tcb * tcp)1371 printargs(struct tcb *tcp)
1372 {
1373 	const int n = tcp->s_ent->nargs;
1374 	int i;
1375 	for (i = 0; i < n; ++i)
1376 		tprintf("%s%#" PRI_klx, i ? ", " : "", tcp->u_arg[i]);
1377 	return RVAL_DECODED;
1378 }
1379 
1380 int
printargs_u(struct tcb * tcp)1381 printargs_u(struct tcb *tcp)
1382 {
1383 	const int n = tcp->s_ent->nargs;
1384 	int i;
1385 	for (i = 0; i < n; ++i)
1386 		tprintf("%s%u", i ? ", " : "",
1387 			(unsigned int) tcp->u_arg[i]);
1388 	return RVAL_DECODED;
1389 }
1390 
1391 int
printargs_d(struct tcb * tcp)1392 printargs_d(struct tcb *tcp)
1393 {
1394 	const int n = tcp->s_ent->nargs;
1395 	int i;
1396 	for (i = 0; i < n; ++i)
1397 		tprintf("%s%d", i ? ", " : "",
1398 			(int) tcp->u_arg[i]);
1399 	return RVAL_DECODED;
1400 }
1401 
1402 /* Print abnormal high bits of a kernel_ulong_t value. */
1403 void
print_abnormal_hi(const kernel_ulong_t val)1404 print_abnormal_hi(const kernel_ulong_t val)
1405 {
1406 	if (current_klongsize > 4) {
1407 		const unsigned int hi = (unsigned int) ((uint64_t) val >> 32);
1408 		if (hi)
1409 			tprintf("%#x<<32|", hi);
1410 	}
1411 }
1412 
1413 #if defined _LARGEFILE64_SOURCE && defined HAVE_OPEN64
1414 # define open_file open64
1415 #else
1416 # define open_file open
1417 #endif
1418 
1419 int
read_int_from_file(const char * const fname,int * const pvalue)1420 read_int_from_file(const char *const fname, int *const pvalue)
1421 {
1422 	const int fd = open_file(fname, O_RDONLY);
1423 	if (fd < 0)
1424 		return -1;
1425 
1426 	long lval;
1427 	char buf[sizeof(lval) * 3];
1428 	int n = read(fd, buf, sizeof(buf) - 1);
1429 	int saved_errno = errno;
1430 	close(fd);
1431 
1432 	if (n < 0) {
1433 		errno = saved_errno;
1434 		return -1;
1435 	}
1436 
1437 	buf[n] = '\0';
1438 	char *endptr = 0;
1439 	errno = 0;
1440 	lval = strtol(buf, &endptr, 10);
1441 	if (!endptr || (*endptr && '\n' != *endptr)
1442 #if INT_MAX < LONG_MAX
1443 	    || lval > INT_MAX || lval < INT_MIN
1444 #endif
1445 	    || ERANGE == errno) {
1446 		if (!errno)
1447 			errno = EINVAL;
1448 		return -1;
1449 	}
1450 
1451 	*pvalue = (int) lval;
1452 	return 0;
1453 }
1454