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