• 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  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "defs.h"
35 #include <sys/param.h>
36 #include <fcntl.h>
37 #if HAVE_SYS_XATTR_H
38 # include <sys/xattr.h>
39 #endif
40 #include <sys/uio.h>
41 
42 #include "regs.h"
43 #include "ptrace.h"
44 
45 int
string_to_uint(const char * str)46 string_to_uint(const char *str)
47 {
48 	char *error;
49 	long value;
50 
51 	if (!*str)
52 		return -1;
53 	errno = 0;
54 	value = strtol(str, &error, 10);
55 	if (errno || *error || value < 0 || (long)(int)value != value)
56 		return -1;
57 	return (int)value;
58 }
59 
60 int
tv_nz(const struct timeval * a)61 tv_nz(const struct timeval *a)
62 {
63 	return a->tv_sec || a->tv_usec;
64 }
65 
66 int
tv_cmp(const struct timeval * a,const struct timeval * b)67 tv_cmp(const struct timeval *a, const struct timeval *b)
68 {
69 	if (a->tv_sec < b->tv_sec
70 	    || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
71 		return -1;
72 	if (a->tv_sec > b->tv_sec
73 	    || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
74 		return 1;
75 	return 0;
76 }
77 
78 double
tv_float(const struct timeval * tv)79 tv_float(const struct timeval *tv)
80 {
81 	return tv->tv_sec + tv->tv_usec/1000000.0;
82 }
83 
84 void
tv_add(struct timeval * tv,const struct timeval * a,const struct timeval * b)85 tv_add(struct timeval *tv, const struct timeval *a, const struct timeval *b)
86 {
87 	tv->tv_sec = a->tv_sec + b->tv_sec;
88 	tv->tv_usec = a->tv_usec + b->tv_usec;
89 	if (tv->tv_usec >= 1000000) {
90 		tv->tv_sec++;
91 		tv->tv_usec -= 1000000;
92 	}
93 }
94 
95 void
tv_sub(struct timeval * tv,const struct timeval * a,const struct timeval * b)96 tv_sub(struct timeval *tv, const struct timeval *a, const struct timeval *b)
97 {
98 	tv->tv_sec = a->tv_sec - b->tv_sec;
99 	tv->tv_usec = a->tv_usec - b->tv_usec;
100 	if (((long) tv->tv_usec) < 0) {
101 		tv->tv_sec--;
102 		tv->tv_usec += 1000000;
103 	}
104 }
105 
106 void
tv_div(struct timeval * tv,const struct timeval * a,int n)107 tv_div(struct timeval *tv, const struct timeval *a, int n)
108 {
109 	tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
110 	tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
111 	tv->tv_usec %= 1000000;
112 }
113 
114 void
tv_mul(struct timeval * tv,const struct timeval * a,int n)115 tv_mul(struct timeval *tv, const struct timeval *a, int n)
116 {
117 	tv->tv_usec = a->tv_usec * n;
118 	tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000;
119 	tv->tv_usec %= 1000000;
120 }
121 
122 const char *
xlookup(const struct xlat * xlat,const unsigned int val)123 xlookup(const struct xlat *xlat, const unsigned int val)
124 {
125 	for (; xlat->str != NULL; xlat++)
126 		if (xlat->val == val)
127 			return xlat->str;
128 	return NULL;
129 }
130 
131 static int
xlat_bsearch_compare(const void * a,const void * b)132 xlat_bsearch_compare(const void *a, const void *b)
133 {
134 	const unsigned int val1 = (const unsigned long) a;
135 	const unsigned int val2 = ((const struct xlat *) b)->val;
136 	return (val1 > val2) ? 1 : (val1 < val2) ? -1 : 0;
137 }
138 
139 const char *
xlat_search(const struct xlat * xlat,const size_t nmemb,const unsigned int val)140 xlat_search(const struct xlat *xlat, const size_t nmemb, const unsigned int val)
141 {
142 	const struct xlat *e =
143 		bsearch((const void*) (const unsigned long) val,
144 			xlat, nmemb, sizeof(*xlat), xlat_bsearch_compare);
145 
146 	return e ? e->str : NULL;
147 }
148 
149 #if !defined HAVE_STPCPY
150 char *
stpcpy(char * dst,const char * src)151 stpcpy(char *dst, const char *src)
152 {
153 	while ((*dst = *src++) != '\0')
154 		dst++;
155 	return dst;
156 }
157 #endif
158 
159 /* Find a next bit which is set.
160  * Starts testing at cur_bit.
161  * Returns -1 if no more bits are set.
162  *
163  * We never touch bytes we don't need to.
164  * On big-endian, array is assumed to consist of
165  * current_wordsize wide words: for example, is current_wordsize is 4,
166  * the bytes are walked in 3,2,1,0, 7,6,5,4, 11,10,9,8 ... sequence.
167  * On little-endian machines, word size is immaterial.
168  */
169 int
next_set_bit(const void * bit_array,unsigned cur_bit,unsigned size_bits)170 next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_bits)
171 {
172 	const unsigned endian = 1;
173 	int little_endian = *(char*)&endian;
174 
175 	const uint8_t *array = bit_array;
176 	unsigned pos = cur_bit / 8;
177 	unsigned pos_xor_mask = little_endian ? 0 : current_wordsize-1;
178 
179 	for (;;) {
180 		uint8_t bitmask;
181 		uint8_t cur_byte;
182 
183 		if (cur_bit >= size_bits)
184 			return -1;
185 		cur_byte = array[pos ^ pos_xor_mask];
186 		if (cur_byte == 0) {
187 			cur_bit = (cur_bit + 8) & (-8);
188 			pos++;
189 			continue;
190 		}
191 		bitmask = 1 << (cur_bit & 7);
192 		for (;;) {
193 			if (cur_byte & bitmask)
194 				return cur_bit;
195 			cur_bit++;
196 			if (cur_bit >= size_bits)
197 				return -1;
198 			bitmask <<= 1;
199 			/* This check *can't be* optimized out: */
200 			if (bitmask == 0)
201 				break;
202 		}
203 		pos++;
204 	}
205 }
206 /*
207  * Print entry in struct xlat table, if there.
208  */
209 void
printxval(const struct xlat * xlat,const unsigned int val,const char * dflt)210 printxval(const struct xlat *xlat, const unsigned int val, const char *dflt)
211 {
212 	const char *str = xlookup(xlat, val);
213 
214 	if (str)
215 		tprints(str);
216 	else
217 		tprintf("%#x /* %s */", val, dflt);
218 }
219 
220 /*
221  * Fetch 64bit argument at position arg_no and
222  * return the index of the next argument.
223  */
224 int
getllval(struct tcb * tcp,unsigned long long * val,int arg_no)225 getllval(struct tcb *tcp, unsigned long long *val, int arg_no)
226 {
227 #if SIZEOF_LONG > 4 && SIZEOF_LONG == SIZEOF_LONG_LONG
228 # if SUPPORTED_PERSONALITIES > 1
229 	if (current_wordsize > 4) {
230 # endif
231 		*val = tcp->u_arg[arg_no];
232 		arg_no++;
233 # if SUPPORTED_PERSONALITIES > 1
234 	} else {
235 #  if defined(AARCH64) || defined(POWERPC64)
236 		/* Align arg_no to the next even number. */
237 		arg_no = (arg_no + 1) & 0xe;
238 #  endif /* AARCH64 || POWERPC64 */
239 		*val = LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
240 		arg_no += 2;
241 	}
242 # endif /* SUPPORTED_PERSONALITIES > 1 */
243 #elif SIZEOF_LONG > 4
244 #  error Unsupported configuration: SIZEOF_LONG > 4 && SIZEOF_LONG_LONG > SIZEOF_LONG
245 #elif defined LINUX_MIPSN32
246 	*val = tcp->ext_arg[arg_no];
247 	arg_no++;
248 #elif defined X32
249 	if (current_personality == 0) {
250 		*val = tcp->ext_arg[arg_no];
251 		arg_no++;
252 	} else {
253 		*val = LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
254 		arg_no += 2;
255 	}
256 #else
257 # if defined __ARM_EABI__ || \
258      defined LINUX_MIPSO32 || \
259      defined POWERPC || \
260      defined XTENSA
261 	/* Align arg_no to the next even number. */
262 	arg_no = (arg_no + 1) & 0xe;
263 # endif
264 	*val = LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
265 	arg_no += 2;
266 #endif
267 
268 	return arg_no;
269 }
270 
271 /*
272  * Print 64bit argument at position arg_no and
273  * return the index of the next argument.
274  */
275 int
printllval(struct tcb * tcp,const char * format,int arg_no)276 printllval(struct tcb *tcp, const char *format, int arg_no)
277 {
278 	unsigned long long val = 0;
279 
280 	arg_no = getllval(tcp, &val, arg_no);
281 	tprintf(format, val);
282 	return arg_no;
283 }
284 
285 /*
286  * Interpret `xlat' as an array of flags
287  * print the entries whose bits are on in `flags'
288  * return # of flags printed.
289  */
290 void
addflags(const struct xlat * xlat,int flags)291 addflags(const struct xlat *xlat, int flags)
292 {
293 	for (; xlat->str; xlat++) {
294 		if (xlat->val && (flags & xlat->val) == xlat->val) {
295 			tprintf("|%s", xlat->str);
296 			flags &= ~xlat->val;
297 		}
298 	}
299 	if (flags) {
300 		tprintf("|%#x", flags);
301 	}
302 }
303 
304 /*
305  * Interpret `xlat' as an array of flags.
306  * Print to static string the entries whose bits are on in `flags'
307  * Return static string.
308  */
309 const char *
sprintflags(const char * prefix,const struct xlat * xlat,int flags)310 sprintflags(const char *prefix, const struct xlat *xlat, int flags)
311 {
312 	static char outstr[1024];
313 	char *outptr;
314 	int found = 0;
315 
316 	outptr = stpcpy(outstr, prefix);
317 
318 	for (; xlat->str; xlat++) {
319 		if ((flags & xlat->val) == xlat->val) {
320 			if (found)
321 				*outptr++ = '|';
322 			outptr = stpcpy(outptr, xlat->str);
323 			found = 1;
324 			flags &= ~xlat->val;
325 			if (!flags)
326 				break;
327 		}
328 	}
329 	if (flags) {
330 		if (found)
331 			*outptr++ = '|';
332 		outptr += sprintf(outptr, "%#x", flags);
333 	}
334 
335 	return outstr;
336 }
337 
338 int
printflags(const struct xlat * xlat,int flags,const char * dflt)339 printflags(const struct xlat *xlat, int flags, const char *dflt)
340 {
341 	int n;
342 	const char *sep;
343 
344 	if (flags == 0 && xlat->val == 0) {
345 		tprints(xlat->str);
346 		return 1;
347 	}
348 
349 	sep = "";
350 	for (n = 0; xlat->str; xlat++) {
351 		if (xlat->val && (flags & xlat->val) == xlat->val) {
352 			tprintf("%s%s", sep, xlat->str);
353 			flags &= ~xlat->val;
354 			sep = "|";
355 			n++;
356 		}
357 	}
358 
359 	if (n) {
360 		if (flags) {
361 			tprintf("%s%#x", sep, flags);
362 			n++;
363 		}
364 	} else {
365 		if (flags) {
366 			tprintf("%#x", flags);
367 			if (dflt)
368 				tprintf(" /* %s */", dflt);
369 		} else {
370 			if (dflt)
371 				tprints("0");
372 		}
373 	}
374 
375 	return n;
376 }
377 
378 void
printnum_long(struct tcb * tcp,long addr,const char * fmt)379 printnum_long(struct tcb *tcp, long addr, const char *fmt)
380 {
381 	long num;
382 
383 	if (!addr) {
384 		tprints("NULL");
385 		return;
386 	}
387 	if (umove(tcp, addr, &num) < 0) {
388 		tprintf("%#lx", addr);
389 		return;
390 	}
391 	tprints("[");
392 	tprintf(fmt, num);
393 	tprints("]");
394 }
395 
396 void
printnum_int(struct tcb * tcp,long addr,const char * fmt)397 printnum_int(struct tcb *tcp, long addr, const char *fmt)
398 {
399 	int num;
400 
401 	if (!addr) {
402 		tprints("NULL");
403 		return;
404 	}
405 	if (umove(tcp, addr, &num) < 0) {
406 		tprintf("%#lx", addr);
407 		return;
408 	}
409 	tprints("[");
410 	tprintf(fmt, num);
411 	tprints("]");
412 }
413 
414 const char *
sprinttime(time_t t)415 sprinttime(time_t t)
416 {
417 	struct tm *tmp;
418 	static char buf[sizeof(int) * 3 * 6];
419 
420 	if (t == 0) {
421 		strcpy(buf, "0");
422 		return buf;
423 	}
424 	tmp = localtime(&t);
425 	if (tmp)
426 		snprintf(buf, sizeof buf, "%02d/%02d/%02d-%02d:%02d:%02d",
427 			tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
428 			tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
429 	else
430 		snprintf(buf, sizeof buf, "%lu", (unsigned long) t);
431 
432 	return buf;
433 }
434 
435 static char *
getfdproto(struct tcb * tcp,int fd,char * buf,unsigned bufsize)436 getfdproto(struct tcb *tcp, int fd, char *buf, unsigned bufsize)
437 {
438 #if HAVE_SYS_XATTR_H
439 	ssize_t r;
440 	char path[sizeof("/proc/%u/fd/%u") + 2 * sizeof(int)*3];
441 
442 	if (fd < 0)
443 		return NULL;
444 
445 	sprintf(path, "/proc/%u/fd/%u", tcp->pid, fd);
446 	r = getxattr(path, "system.sockprotoname", buf, bufsize - 1);
447 	if (r <= 0)
448 		return NULL;
449 	else {
450 		/*
451 		 * This is a protection for the case when the kernel
452 		 * side does not append a null byte to the buffer.
453 		 */
454 		buf[r] = '\0';
455 		return buf;
456 	}
457 #else
458 	return NULL;
459 #endif
460 }
461 
462 void
printfd(struct tcb * tcp,int fd)463 printfd(struct tcb *tcp, int fd)
464 {
465 	char path[PATH_MAX + 1];
466 	if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
467 		static const char socket_prefix[] = "socket:[";
468 		const size_t socket_prefix_len = sizeof(socket_prefix) - 1;
469 		const size_t path_len = strlen(path);
470 
471 		tprintf("%d<", fd);
472 		if (show_fd_path > 1 &&
473 		    strncmp(path, socket_prefix, socket_prefix_len) == 0 &&
474 		    path[path_len - 1] == ']') {
475 			unsigned long inodenr;
476 #define PROTO_NAME_LEN 32
477 			char proto_buf[PROTO_NAME_LEN];
478 			const char *proto =
479 				getfdproto(tcp, fd, proto_buf, PROTO_NAME_LEN);
480 			inodenr = strtoul(path + socket_prefix_len, NULL, 10);
481 			if (!print_sockaddr_by_inode(inodenr, proto)) {
482 				if (proto)
483 					tprintf("%s:[%lu]", proto, inodenr);
484 				else
485 					tprints(path);
486 			}
487 		} else {
488 			print_quoted_string(path, path_len,
489 					    QUOTE_OMIT_LEADING_TRAILING_QUOTES);
490 		}
491 		tprints(">");
492 	} else
493 		tprintf("%d", fd);
494 }
495 
496 /*
497  * Quote string `instr' of length `size'
498  * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
499  *
500  * If QUOTE_0_TERMINATED `style' flag is set,
501  * treat `instr' as a NUL-terminated string,
502  * checking up to (`size' + 1) bytes of `instr'.
503  *
504  * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
505  * do not add leading and trailing quoting symbols.
506  *
507  * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
508  * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
509  */
510 static int
string_quote(const char * instr,char * outstr,const unsigned int size,const unsigned int style)511 string_quote(const char *instr, char *outstr, const unsigned int size,
512 	     const unsigned int style)
513 {
514 	const unsigned char *ustr = (const unsigned char *) instr;
515 	char *s = outstr;
516 	unsigned int i;
517 	int usehex, c, eol;
518 
519 	if (style & QUOTE_0_TERMINATED)
520 		eol = '\0';
521 	else
522 		eol = 0x100; /* this can never match a char */
523 
524 	usehex = 0;
525 	if (xflag > 1)
526 		usehex = 1;
527 	else if (xflag) {
528 		/* Check for presence of symbol which require
529 		   to hex-quote the whole string. */
530 		for (i = 0; i < size; ++i) {
531 			c = ustr[i];
532 			/* Check for NUL-terminated string. */
533 			if (c == eol)
534 				break;
535 
536 			/* Force hex unless c is printable or whitespace */
537 			if (c > 0x7e) {
538 				usehex = 1;
539 				break;
540 			}
541 			/* In ASCII isspace is only these chars: "\t\n\v\f\r".
542 			 * They happen to have ASCII codes 9,10,11,12,13.
543 			 */
544 			if (c < ' ' && (unsigned)(c - 9) >= 5) {
545 				usehex = 1;
546 				break;
547 			}
548 		}
549 	}
550 
551 	if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
552 		*s++ = '\"';
553 
554 	if (usehex) {
555 		/* Hex-quote the whole string. */
556 		for (i = 0; i < size; ++i) {
557 			c = ustr[i];
558 			/* Check for NUL-terminated string. */
559 			if (c == eol)
560 				goto asciz_ended;
561 			*s++ = '\\';
562 			*s++ = 'x';
563 			*s++ = "0123456789abcdef"[c >> 4];
564 			*s++ = "0123456789abcdef"[c & 0xf];
565 		}
566 	} else {
567 		for (i = 0; i < size; ++i) {
568 			c = ustr[i];
569 			/* Check for NUL-terminated string. */
570 			if (c == eol)
571 				goto asciz_ended;
572 			switch (c) {
573 				case '\"': case '\\':
574 					*s++ = '\\';
575 					*s++ = c;
576 					break;
577 				case '\f':
578 					*s++ = '\\';
579 					*s++ = 'f';
580 					break;
581 				case '\n':
582 					*s++ = '\\';
583 					*s++ = 'n';
584 					break;
585 				case '\r':
586 					*s++ = '\\';
587 					*s++ = 'r';
588 					break;
589 				case '\t':
590 					*s++ = '\\';
591 					*s++ = 't';
592 					break;
593 				case '\v':
594 					*s++ = '\\';
595 					*s++ = 'v';
596 					break;
597 				default:
598 					if (c >= ' ' && c <= 0x7e)
599 						*s++ = c;
600 					else {
601 						/* Print \octal */
602 						*s++ = '\\';
603 						if (i + 1 < size
604 						    && ustr[i + 1] >= '0'
605 						    && ustr[i + 1] <= '9'
606 						) {
607 							/* Print \ooo */
608 							*s++ = '0' + (c >> 6);
609 							*s++ = '0' + ((c >> 3) & 0x7);
610 						} else {
611 							/* Print \[[o]o]o */
612 							if ((c >> 3) != 0) {
613 								if ((c >> 6) != 0)
614 									*s++ = '0' + (c >> 6);
615 								*s++ = '0' + ((c >> 3) & 0x7);
616 							}
617 						}
618 						*s++ = '0' + (c & 0x7);
619 					}
620 					break;
621 			}
622 		}
623 	}
624 
625 	if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
626 		*s++ = '\"';
627 	*s = '\0';
628 
629 	/* Return zero if we printed entire ASCIZ string (didn't truncate it) */
630 	if (style & QUOTE_0_TERMINATED && ustr[i] == '\0') {
631 		/* We didn't see NUL yet (otherwise we'd jump to 'asciz_ended')
632 		 * but next char is NUL.
633 		 */
634 		return 0;
635 	}
636 
637 	return 1;
638 
639  asciz_ended:
640 	if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
641 		*s++ = '\"';
642 	*s = '\0';
643 	/* Return zero: we printed entire ASCIZ string (didn't truncate it) */
644 	return 0;
645 }
646 
647 #ifndef ALLOCA_CUTOFF
648 # define ALLOCA_CUTOFF	4032
649 #endif
650 #define use_alloca(n) ((n) <= ALLOCA_CUTOFF)
651 
652 /*
653  * Quote string `str' of length `size' and print the result.
654  *
655  * If QUOTE_0_TERMINATED `style' flag is set,
656  * treat `str' as a NUL-terminated string and
657  * quote at most (`size' - 1) bytes.
658  *
659  * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
660  * do not add leading and trailing quoting symbols.
661  *
662  * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
663  * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
664  */
665 int
print_quoted_string(const char * str,unsigned int size,const unsigned int style)666 print_quoted_string(const char *str, unsigned int size,
667 		    const unsigned int style)
668 {
669 	char *buf;
670 	char *outstr;
671 	unsigned int alloc_size;
672 	int rc;
673 
674 	if (size && style & QUOTE_0_TERMINATED)
675 		--size;
676 
677 	alloc_size = 4 * size;
678 	if (alloc_size / 4 != size) {
679 		error_msg("Out of memory");
680 		tprints("???");
681 		return -1;
682 	}
683 	alloc_size += 1 + (style & QUOTE_OMIT_LEADING_TRAILING_QUOTES ? 0 : 2);
684 
685 	if (use_alloca(alloc_size)) {
686 		outstr = alloca(alloc_size);
687 		buf = NULL;
688 	} else {
689 		outstr = buf = malloc(alloc_size);
690 		if (!buf) {
691 			error_msg("Out of memory");
692 			tprints("???");
693 			return -1;
694 		}
695 	}
696 
697 	rc = string_quote(str, outstr, size, style);
698 	tprints(outstr);
699 
700 	free(buf);
701 	return rc;
702 }
703 
704 /*
705  * Print path string specified by address `addr' and length `n'.
706  * If path length exceeds `n', append `...' to the output.
707  */
708 void
printpathn(struct tcb * tcp,long addr,unsigned int n)709 printpathn(struct tcb *tcp, long addr, unsigned int n)
710 {
711 	char path[PATH_MAX + 1];
712 	int nul_seen;
713 
714 	if (!addr) {
715 		tprints("NULL");
716 		return;
717 	}
718 
719 	/* Cap path length to the path buffer size */
720 	if (n > sizeof path - 1)
721 		n = sizeof path - 1;
722 
723 	/* Fetch one byte more to find out whether path length > n. */
724 	nul_seen = umovestr(tcp, addr, n + 1, path);
725 	if (nul_seen < 0)
726 		tprintf("%#lx", addr);
727 	else {
728 		path[n++] = '\0';
729 		print_quoted_string(path, n, QUOTE_0_TERMINATED);
730 		if (!nul_seen)
731 			tprints("...");
732 	}
733 }
734 
735 void
printpath(struct tcb * tcp,long addr)736 printpath(struct tcb *tcp, long addr)
737 {
738 	/* Size must correspond to char path[] size in printpathn */
739 	printpathn(tcp, addr, PATH_MAX);
740 }
741 
742 /*
743  * Print string specified by address `addr' and length `len'.
744  * If `len' < 0, treat the string as a NUL-terminated string.
745  * If string length exceeds `max_strlen', append `...' to the output.
746  */
747 void
printstr(struct tcb * tcp,long addr,long len)748 printstr(struct tcb *tcp, long addr, long len)
749 {
750 	static char *str = NULL;
751 	static char *outstr;
752 	unsigned int size;
753 	unsigned int style;
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 		unsigned int outstr_size = 4 * max_strlen + /*for quotes and NUL:*/ 3;
763 
764 		if (outstr_size / 4 != max_strlen)
765 			die_out_of_memory();
766 		str = malloc(max_strlen + 1);
767 		if (!str)
768 			die_out_of_memory();
769 		outstr = malloc(outstr_size);
770 		if (!outstr)
771 			die_out_of_memory();
772 	}
773 
774 	size = max_strlen;
775 	if (len == -1) {
776 		/*
777 		 * Treat as a NUL-terminated string: fetch one byte more
778 		 * because string_quote may look one byte ahead.
779 		 */
780 		if (umovestr(tcp, addr, size + 1, str) < 0) {
781 			tprintf("%#lx", addr);
782 			return;
783 		}
784 		style = QUOTE_0_TERMINATED;
785 	}
786 	else {
787 		if (size > (unsigned long)len)
788 			size = (unsigned long)len;
789 		if (umoven(tcp, addr, size, str) < 0) {
790 			tprintf("%#lx", addr);
791 			return;
792 		}
793 		style = 0;
794 	}
795 
796 	/* If string_quote didn't see NUL and (it was supposed to be ASCIZ str
797 	 * or we were requested to print more than -s NUM chars)...
798 	 */
799 	ellipsis = (string_quote(str, outstr, size, style) &&
800 			(len < 0 || (unsigned long) len > max_strlen));
801 
802 	tprints(outstr);
803 	if (ellipsis)
804 		tprints("...");
805 }
806 
807 void
dumpiov(struct tcb * tcp,int len,long addr)808 dumpiov(struct tcb *tcp, int len, long addr)
809 {
810 #if SUPPORTED_PERSONALITIES > 1
811 	union {
812 		struct { u_int32_t base; u_int32_t len; } *iov32;
813 		struct { u_int64_t base; u_int64_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) 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 		fprintf(stderr, "Out of memory\n");
836 		return;
837 	}
838 	if (umoven(tcp, addr, size, iov) >= 0) {
839 		for (i = 0; i < len; i++) {
840 			/* include the buffer number to make it easy to
841 			 * match up the trace with the source */
842 			tprintf(" * %lu bytes in buffer %d\n",
843 				(unsigned long)iov_iov_len(i), i);
844 			dumpstr(tcp, (long) iov_iov_base(i),
845 				iov_iov_len(i));
846 		}
847 	}
848 	free(iov);
849 #undef sizeof_iov
850 #undef iov_iov_base
851 #undef iov_iov_len
852 #undef iov
853 }
854 
855 void
dumpstr(struct tcb * tcp,long addr,int len)856 dumpstr(struct tcb *tcp, long addr, int len)
857 {
858 	static int strsize = -1;
859 	static unsigned char *str;
860 
861 	char outbuf[
862 		(
863 			(sizeof(
864 			"xx xx xx xx xx xx xx xx  xx xx xx xx xx xx xx xx  "
865 			"1234567890123456") + /*in case I'm off by few:*/ 4)
866 		/*align to 8 to make memset easier:*/ + 7) & -8
867 	];
868 	const unsigned char *src;
869 	int i;
870 
871 	memset(outbuf, ' ', sizeof(outbuf));
872 
873 	if (strsize < len + 16) {
874 		free(str);
875 		str = malloc(len + 16);
876 		if (!str) {
877 			strsize = -1;
878 			fprintf(stderr, "Out of memory\n");
879 			return;
880 		}
881 		strsize = len + 16;
882 	}
883 
884 	if (umoven(tcp, addr, len, str) < 0)
885 		return;
886 
887 	/* Space-pad to 16 bytes */
888 	i = len;
889 	while (i & 0xf)
890 		str[i++] = ' ';
891 
892 	i = 0;
893 	src = str;
894 	while (i < len) {
895 		char *dst = outbuf;
896 		/* Hex dump */
897 		do {
898 			if (i < len) {
899 				*dst++ = "0123456789abcdef"[*src >> 4];
900 				*dst++ = "0123456789abcdef"[*src & 0xf];
901 			}
902 			else {
903 				*dst++ = ' ';
904 				*dst++ = ' ';
905 			}
906 			dst++; /* space is there by memset */
907 			i++;
908 			if ((i & 7) == 0)
909 				dst++; /* space is there by memset */
910 			src++;
911 		} while (i & 0xf);
912 		/* ASCII dump */
913 		i -= 16;
914 		src -= 16;
915 		do {
916 			if (*src >= ' ' && *src < 0x7f)
917 				*dst++ = *src;
918 			else
919 				*dst++ = '.';
920 			src++;
921 		} while (++i & 0xf);
922 		*dst = '\0';
923 		tprintf(" | %05x  %s |\n", i - 16, outbuf);
924 	}
925 }
926 
927 #ifdef HAVE_PROCESS_VM_READV
928 /* C library supports this, but the kernel might not. */
929 static bool process_vm_readv_not_supported = 0;
930 #else
931 
932 /* Need to do this since process_vm_readv() is not yet available in libc.
933  * When libc is be updated, only "static bool process_vm_readv_not_supported"
934  * line should remain.
935  */
936 #if !defined(__NR_process_vm_readv)
937 # if defined(I386)
938 #  define __NR_process_vm_readv  347
939 # elif defined(X86_64)
940 #  define __NR_process_vm_readv  310
941 # elif defined(POWERPC)
942 #  define __NR_process_vm_readv  351
943 # endif
944 #endif
945 
946 #if defined(__NR_process_vm_readv)
947 static bool process_vm_readv_not_supported = 0;
948 /* 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)949 static ssize_t strace_process_vm_readv(pid_t pid,
950 		 const struct iovec *lvec,
951 		 unsigned long liovcnt,
952 		 const struct iovec *rvec,
953 		 unsigned long riovcnt,
954 		 unsigned long flags)
955 {
956 	return syscall(__NR_process_vm_readv, (long)pid, lvec, liovcnt, rvec, riovcnt, flags);
957 }
958 #define process_vm_readv strace_process_vm_readv
959 #else
960 static bool process_vm_readv_not_supported = 1;
961 # define process_vm_readv(...) (errno = ENOSYS, -1)
962 #endif
963 
964 #endif /* end of hack */
965 
966 static ssize_t
vm_read_mem(pid_t pid,void * laddr,long raddr,size_t len)967 vm_read_mem(pid_t pid, void *laddr, long raddr, size_t len)
968 {
969 	const struct iovec local = {
970 		.iov_base = laddr,
971 		.iov_len = len
972 	};
973 	const struct iovec remote = {
974 		.iov_base = (void *) raddr,
975 		.iov_len = len
976 	};
977 
978 	return process_vm_readv(pid, &local, 1, &remote, 1, 0);
979 }
980 
981 /*
982  * move `len' bytes of data from process `pid'
983  * at address `addr' to our space at `our_addr'
984  */
985 int
umoven(struct tcb * tcp,long addr,unsigned int len,void * our_addr)986 umoven(struct tcb *tcp, long addr, unsigned int len, void *our_addr)
987 {
988 	char *laddr = our_addr;
989 	int pid = tcp->pid;
990 	unsigned int n, m, nread;
991 	union {
992 		long val;
993 		char x[sizeof(long)];
994 	} u;
995 
996 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
997 	if (current_wordsize < sizeof(addr))
998 		addr &= (1ul << 8 * current_wordsize) - 1;
999 #endif
1000 
1001 	if (!process_vm_readv_not_supported) {
1002 		int r = vm_read_mem(pid, laddr, addr, len);
1003 		if ((unsigned int) r == len)
1004 			return 0;
1005 		if (r >= 0) {
1006 			error_msg("umoven: short read (%u < %u) @0x%lx",
1007 				  (unsigned int) r, len, addr);
1008 			return -1;
1009 		}
1010 		switch (errno) {
1011 			case ENOSYS:
1012 				process_vm_readv_not_supported = 1;
1013 				break;
1014 			case EPERM:
1015 				/* operation not permitted, try PTRACE_PEEKDATA */
1016 				break;
1017 			case ESRCH:
1018 				/* the process is gone */
1019 				return -1;
1020 			case EFAULT: case EIO:
1021 				/* address space is inaccessible */
1022 				return -1;
1023 			default:
1024 				/* all the rest is strange and should be reported */
1025 				perror_msg("process_vm_readv");
1026 				return -1;
1027 		}
1028 	}
1029 
1030 	nread = 0;
1031 	if (addr & (sizeof(long) - 1)) {
1032 		/* addr not a multiple of sizeof(long) */
1033 		n = addr & (sizeof(long) - 1);	/* residue */
1034 		addr &= -sizeof(long);		/* aligned address */
1035 		errno = 0;
1036 		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
1037 		switch (errno) {
1038 			case 0:
1039 				break;
1040 			case ESRCH: case EINVAL:
1041 				/* these could be seen if the process is gone */
1042 				return -1;
1043 			case EFAULT: case EIO: case EPERM:
1044 				/* address space is inaccessible */
1045 				return -1;
1046 			default:
1047 				/* all the rest is strange and should be reported */
1048 				perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%lx",
1049 					    pid, addr);
1050 				return -1;
1051 		}
1052 		m = MIN(sizeof(long) - n, len);
1053 		memcpy(laddr, &u.x[n], m);
1054 		addr += sizeof(long);
1055 		laddr += m;
1056 		nread += m;
1057 		len -= m;
1058 	}
1059 	while (len) {
1060 		errno = 0;
1061 		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
1062 		switch (errno) {
1063 			case 0:
1064 				break;
1065 			case ESRCH: case EINVAL:
1066 				/* these could be seen if the process is gone */
1067 				return -1;
1068 			case EFAULT: case EIO: case EPERM:
1069 				/* address space is inaccessible */
1070 				if (nread) {
1071 					perror_msg("umoven: short read (%u < %u) @0x%lx",
1072 						   nread, nread + len, addr - nread);
1073 				}
1074 				return -1;
1075 			default:
1076 				/* all the rest is strange and should be reported */
1077 				perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%lx",
1078 					    pid, addr);
1079 				return -1;
1080 		}
1081 		m = MIN(sizeof(long), len);
1082 		memcpy(laddr, u.x, m);
1083 		addr += sizeof(long);
1084 		laddr += m;
1085 		nread += m;
1086 		len -= m;
1087 	}
1088 
1089 	return 0;
1090 }
1091 
1092 /*
1093  * Like `umove' but make the additional effort of looking
1094  * for a terminating zero byte.
1095  *
1096  * Returns < 0 on error, > 0 if NUL was seen,
1097  * (TODO if useful: return count of bytes including NUL),
1098  * else 0 if len bytes were read but no NUL byte seen.
1099  *
1100  * Note: there is no guarantee we won't overwrite some bytes
1101  * in laddr[] _after_ terminating NUL (but, of course,
1102  * we never write past laddr[len-1]).
1103  */
1104 int
umovestr(struct tcb * tcp,long addr,unsigned int len,char * laddr)1105 umovestr(struct tcb *tcp, long addr, unsigned int len, char *laddr)
1106 {
1107 #if SIZEOF_LONG == 4
1108 	const unsigned long x01010101 = 0x01010101ul;
1109 	const unsigned long x80808080 = 0x80808080ul;
1110 #elif SIZEOF_LONG == 8
1111 	const unsigned long x01010101 = 0x0101010101010101ul;
1112 	const unsigned long x80808080 = 0x8080808080808080ul;
1113 #else
1114 # error SIZEOF_LONG > 8
1115 #endif
1116 
1117 	int pid = tcp->pid;
1118 	unsigned int n, m, nread;
1119 	union {
1120 		unsigned long val;
1121 		char x[sizeof(long)];
1122 	} u;
1123 
1124 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
1125 	if (current_wordsize < sizeof(addr))
1126 		addr &= (1ul << 8 * current_wordsize) - 1;
1127 #endif
1128 
1129 	nread = 0;
1130 	if (!process_vm_readv_not_supported) {
1131 		const size_t page_size = get_pagesize();
1132 		const size_t page_mask = page_size - 1;
1133 
1134 		while (len > 0) {
1135 			unsigned int chunk_len;
1136 			unsigned int end_in_page;
1137 
1138 			/*
1139 			 * Don't cross pages, otherwise we can get EFAULT
1140 			 * and fail to notice that terminating NUL lies
1141 			 * in the existing (first) page.
1142 			 */
1143 			chunk_len = len > page_size ? page_size : len;
1144 			end_in_page = (addr + chunk_len) & page_mask;
1145 			if (chunk_len > end_in_page) /* crosses to the next page */
1146 				chunk_len -= end_in_page;
1147 
1148 			int r = vm_read_mem(pid, laddr, addr, chunk_len);
1149 			if (r > 0) {
1150 				if (memchr(laddr, '\0', r))
1151 					return 1;
1152 				addr += r;
1153 				laddr += r;
1154 				nread += r;
1155 				len -= r;
1156 				continue;
1157 			}
1158 			switch (errno) {
1159 				case ENOSYS:
1160 					process_vm_readv_not_supported = 1;
1161 					goto vm_readv_didnt_work;
1162 				case ESRCH:
1163 					/* the process is gone */
1164 					return -1;
1165 				case EPERM:
1166 					/* operation not permitted, try PTRACE_PEEKDATA */
1167 					if (!nread)
1168 						goto vm_readv_didnt_work;
1169 					/* fall through */
1170 				case EFAULT: case EIO:
1171 					/* address space is inaccessible */
1172 					if (nread) {
1173 						perror_msg("umovestr: short read (%d < %d) @0x%lx",
1174 							   nread, nread + len, addr - nread);
1175 					}
1176 					return -1;
1177 				default:
1178 					/* all the rest is strange and should be reported */
1179 					perror_msg("process_vm_readv");
1180 					return -1;
1181 			}
1182 		}
1183 		return 0;
1184 	}
1185  vm_readv_didnt_work:
1186 
1187 	if (addr & (sizeof(long) - 1)) {
1188 		/* addr not a multiple of sizeof(long) */
1189 		n = addr & (sizeof(long) - 1);	/* residue */
1190 		addr &= -sizeof(long);		/* aligned address */
1191 		errno = 0;
1192 		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
1193 		switch (errno) {
1194 			case 0:
1195 				break;
1196 			case ESRCH: case EINVAL:
1197 				/* these could be seen if the process is gone */
1198 				return -1;
1199 			case EFAULT: case EIO: case EPERM:
1200 				/* address space is inaccessible */
1201 				return -1;
1202 			default:
1203 				/* all the rest is strange and should be reported */
1204 				perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%lx",
1205 					    pid, addr);
1206 				return -1;
1207 		}
1208 		m = MIN(sizeof(long) - n, len);
1209 		memcpy(laddr, &u.x[n], m);
1210 		while (n & (sizeof(long) - 1))
1211 			if (u.x[n++] == '\0')
1212 				return 1;
1213 		addr += sizeof(long);
1214 		laddr += m;
1215 		nread += m;
1216 		len -= m;
1217 	}
1218 
1219 	while (len) {
1220 		errno = 0;
1221 		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
1222 		switch (errno) {
1223 			case 0:
1224 				break;
1225 			case ESRCH: case EINVAL:
1226 				/* these could be seen if the process is gone */
1227 				return -1;
1228 			case EFAULT: case EIO: case EPERM:
1229 				/* address space is inaccessible */
1230 				if (nread) {
1231 					perror_msg("umovestr: short read (%d < %d) @0x%lx",
1232 						   nread, nread + len, addr - nread);
1233 				}
1234 				return -1;
1235 			default:
1236 				/* all the rest is strange and should be reported */
1237 				perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%lx",
1238 					   pid, addr);
1239 				return -1;
1240 		}
1241 		m = MIN(sizeof(long), len);
1242 		memcpy(laddr, u.x, m);
1243 		/* "If a NUL char exists in this word" */
1244 		if ((u.val - x01010101) & ~u.val & x80808080)
1245 			return 1;
1246 		addr += sizeof(long);
1247 		laddr += m;
1248 		nread += m;
1249 		len -= m;
1250 	}
1251 	return 0;
1252 }
1253 
1254 int
upeek(int pid,long off,long * res)1255 upeek(int pid, long off, long *res)
1256 {
1257 	long val;
1258 
1259 	errno = 0;
1260 	val = ptrace(PTRACE_PEEKUSER, (pid_t)pid, (char *) off, 0);
1261 	if (val == -1 && errno) {
1262 		if (errno != ESRCH) {
1263 			perror_msg("upeek: PTRACE_PEEKUSER pid:%d @0x%lx)", pid, off);
1264 		}
1265 		return -1;
1266 	}
1267 	*res = val;
1268 	return 0;
1269 }
1270