]> granicus.if.org Git - strace/blob - util.c
Mpersify parsers of utimes, futimesat, and utimensat syscalls
[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 unsigned int 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 unsigned int val1 = (const unsigned long) a;
136         const unsigned int 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 unsigned int val)
142 {
143         const struct xlat *e =
144                 bsearch((const void*) (const unsigned long) 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 unsigned int 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("%#x /* %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         if (current_wordsize > 4) {
241 # endif
242                 *val = tcp->u_arg[arg_no];
243                 arg_no++;
244 # if SUPPORTED_PERSONALITIES > 1
245         } else {
246 #  if defined(AARCH64) || defined(POWERPC64)
247                 /* Align arg_no to the next even number. */
248                 arg_no = (arg_no + 1) & 0xe;
249 #  endif /* AARCH64 || POWERPC64 */
250                 *val = LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
251                 arg_no += 2;
252         }
253 # endif /* SUPPORTED_PERSONALITIES > 1 */
254 #elif SIZEOF_LONG > 4
255 #  error Unsupported configuration: SIZEOF_LONG > 4 && SIZEOF_LONG_LONG > SIZEOF_LONG
256 #elif defined LINUX_MIPSN32
257         *val = tcp->ext_arg[arg_no];
258         arg_no++;
259 #elif defined X32
260         if (current_personality == 0) {
261                 *val = tcp->ext_arg[arg_no];
262                 arg_no++;
263         } else {
264                 *val = LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
265                 arg_no += 2;
266         }
267 #else
268 # if defined __ARM_EABI__ || \
269      defined LINUX_MIPSO32 || \
270      defined POWERPC || \
271      defined XTENSA
272         /* Align arg_no to the next even number. */
273         arg_no = (arg_no + 1) & 0xe;
274 # endif
275         *val = LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
276         arg_no += 2;
277 #endif
278
279         return arg_no;
280 }
281
282 /*
283  * Print 64bit argument at position arg_no and
284  * return the index of the next argument.
285  */
286 int
287 printllval(struct tcb *tcp, const char *format, int arg_no)
288 {
289         unsigned long long val = 0;
290
291         arg_no = getllval(tcp, &val, arg_no);
292         tprintf(format, val);
293         return arg_no;
294 }
295
296 /*
297  * Interpret `xlat' as an array of flags
298  * print the entries whose bits are on in `flags'
299  * return # of flags printed.
300  */
301 void
302 addflags(const struct xlat *xlat, int flags)
303 {
304         for (; xlat->str; xlat++) {
305                 if (xlat->val && (flags & xlat->val) == xlat->val) {
306                         tprintf("|%s", xlat->str);
307                         flags &= ~xlat->val;
308                 }
309         }
310         if (flags) {
311                 tprintf("|%#x", flags);
312         }
313 }
314
315 /*
316  * Interpret `xlat' as an array of flags.
317  * Print to static string the entries whose bits are on in `flags'
318  * Return static string.
319  */
320 const char *
321 sprintflags(const char *prefix, const struct xlat *xlat, int flags)
322 {
323         static char outstr[1024];
324         char *outptr;
325         int found = 0;
326
327         outptr = stpcpy(outstr, prefix);
328
329         for (; xlat->str; xlat++) {
330                 if ((flags & xlat->val) == xlat->val) {
331                         if (found)
332                                 *outptr++ = '|';
333                         outptr = stpcpy(outptr, xlat->str);
334                         found = 1;
335                         flags &= ~xlat->val;
336                         if (!flags)
337                                 break;
338                 }
339         }
340         if (flags) {
341                 if (found)
342                         *outptr++ = '|';
343                 outptr += sprintf(outptr, "%#x", flags);
344         }
345
346         return outstr;
347 }
348
349 int
350 printflags(const struct xlat *xlat, int flags, const char *dflt)
351 {
352         int n;
353         const char *sep;
354
355         if (flags == 0 && xlat->val == 0) {
356                 tprints(xlat->str);
357                 return 1;
358         }
359
360         sep = "";
361         for (n = 0; xlat->str; xlat++) {
362                 if (xlat->val && (flags & xlat->val) == xlat->val) {
363                         tprintf("%s%s", sep, xlat->str);
364                         flags &= ~xlat->val;
365                         sep = "|";
366                         n++;
367                 }
368         }
369
370         if (n) {
371                 if (flags) {
372                         tprintf("%s%#x", sep, flags);
373                         n++;
374                 }
375         } else {
376                 if (flags) {
377                         tprintf("%#x", flags);
378                         if (dflt)
379                                 tprintf(" /* %s */", dflt);
380                 } else {
381                         if (dflt)
382                                 tprints("0");
383                 }
384         }
385
386         return n;
387 }
388
389 void
390 printaddr(const long addr)
391 {
392         if (!addr)
393                 tprints("NULL");
394         else
395                 tprintf("%#lx", addr);
396 }
397
398 #define DEF_PRINTNUM(name, type) \
399 bool                                                                    \
400 printnum_ ## name(struct tcb *tcp, const long addr, const char *fmt)    \
401 {                                                                       \
402         type num;                                                       \
403         if (umove_or_printaddr(tcp, addr, &num))                        \
404                 return false;                                           \
405         tprints("[");                                                   \
406         tprintf(fmt, num);                                              \
407         tprints("]");                                                   \
408         return true;                                                    \
409 }
410
411 #define DEF_PRINTPAIR(name, type) \
412 bool                                                                    \
413 printpair_ ## name(struct tcb *tcp, const long addr, const char *fmt)   \
414 {                                                                       \
415         type pair[2];                                                   \
416         if (umove_or_printaddr(tcp, addr, &pair))                       \
417                 return false;                                           \
418         tprints("[");                                                   \
419         tprintf(fmt, pair[0]);                                          \
420         tprints(", ");                                                  \
421         tprintf(fmt, pair[1]);                                          \
422         tprints("]");                                                   \
423         return true;                                                    \
424 }
425
426 DEF_PRINTNUM(int, int)
427 DEF_PRINTPAIR(int, int)
428 DEF_PRINTNUM(short, short)
429 DEF_PRINTNUM(int64, uint64_t)
430 DEF_PRINTPAIR(int64, uint64_t)
431
432 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
433 bool
434 printnum_long_int(struct tcb *tcp, const long addr,
435                   const char *fmt_long, const char *fmt_int)
436 {
437         if (current_wordsize > sizeof(int)) {
438                 return printnum_int64(tcp, addr, fmt_long);
439         } else {
440                 return printnum_int(tcp, addr, fmt_int);
441         }
442 }
443 #endif
444
445 const char *
446 sprinttime(time_t t)
447 {
448         struct tm *tmp;
449         static char buf[sizeof(int) * 3 * 6];
450
451         if (t == 0) {
452                 strcpy(buf, "0");
453                 return buf;
454         }
455         tmp = localtime(&t);
456         if (tmp)
457                 snprintf(buf, sizeof buf, "%02d/%02d/%02d-%02d:%02d:%02d",
458                         tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
459                         tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
460         else
461                 snprintf(buf, sizeof buf, "%lu", (unsigned long) t);
462
463         return buf;
464 }
465
466 static char *
467 getfdproto(struct tcb *tcp, int fd, char *buf, unsigned bufsize)
468 {
469 #ifdef HAVE_SYS_XATTR_H
470         ssize_t r;
471         char path[sizeof("/proc/%u/fd/%u") + 2 * sizeof(int)*3];
472
473         if (fd < 0)
474                 return NULL;
475
476         sprintf(path, "/proc/%u/fd/%u", tcp->pid, fd);
477         r = getxattr(path, "system.sockprotoname", buf, bufsize - 1);
478         if (r <= 0)
479                 return NULL;
480         else {
481                 /*
482                  * This is a protection for the case when the kernel
483                  * side does not append a null byte to the buffer.
484                  */
485                 buf[r] = '\0';
486                 return buf;
487         }
488 #else
489         return NULL;
490 #endif
491 }
492
493 void
494 printfd(struct tcb *tcp, int fd)
495 {
496         char path[PATH_MAX + 1];
497         if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
498                 static const char socket_prefix[] = "socket:[";
499                 const size_t socket_prefix_len = sizeof(socket_prefix) - 1;
500                 const size_t path_len = strlen(path);
501
502                 tprintf("%d<", fd);
503                 if (show_fd_path > 1 &&
504                     strncmp(path, socket_prefix, socket_prefix_len) == 0 &&
505                     path[path_len - 1] == ']') {
506                         unsigned long inodenr;
507 #define PROTO_NAME_LEN 32
508                         char proto_buf[PROTO_NAME_LEN];
509                         const char *proto =
510                                 getfdproto(tcp, fd, proto_buf, PROTO_NAME_LEN);
511                         inodenr = strtoul(path + socket_prefix_len, NULL, 10);
512                         if (!print_sockaddr_by_inode(inodenr, proto)) {
513                                 if (proto)
514                                         tprintf("%s:[%lu]", proto, inodenr);
515                                 else
516                                         tprints(path);
517                         }
518                 } else {
519                         print_quoted_string(path, path_len,
520                                             QUOTE_OMIT_LEADING_TRAILING_QUOTES);
521                 }
522                 tprints(">");
523         } else
524                 tprintf("%d", fd);
525 }
526
527 /*
528  * Quote string `instr' of length `size'
529  * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
530  *
531  * If QUOTE_0_TERMINATED `style' flag is set,
532  * treat `instr' as a NUL-terminated string,
533  * checking up to (`size' + 1) bytes of `instr'.
534  *
535  * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
536  * do not add leading and trailing quoting symbols.
537  *
538  * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
539  * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
540  */
541 static int
542 string_quote(const char *instr, char *outstr, const unsigned int size,
543              const unsigned int style)
544 {
545         const unsigned char *ustr = (const unsigned char *) instr;
546         char *s = outstr;
547         unsigned int i;
548         int usehex, c, eol;
549
550         if (style & QUOTE_0_TERMINATED)
551                 eol = '\0';
552         else
553                 eol = 0x100; /* this can never match a char */
554
555         usehex = 0;
556         if (xflag > 1)
557                 usehex = 1;
558         else if (xflag) {
559                 /* Check for presence of symbol which require
560                    to hex-quote the whole string. */
561                 for (i = 0; i < size; ++i) {
562                         c = ustr[i];
563                         /* Check for NUL-terminated string. */
564                         if (c == eol)
565                                 break;
566
567                         /* Force hex unless c is printable or whitespace */
568                         if (c > 0x7e) {
569                                 usehex = 1;
570                                 break;
571                         }
572                         /* In ASCII isspace is only these chars: "\t\n\v\f\r".
573                          * They happen to have ASCII codes 9,10,11,12,13.
574                          */
575                         if (c < ' ' && (unsigned)(c - 9) >= 5) {
576                                 usehex = 1;
577                                 break;
578                         }
579                 }
580         }
581
582         if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
583                 *s++ = '\"';
584
585         if (usehex) {
586                 /* Hex-quote the whole string. */
587                 for (i = 0; i < size; ++i) {
588                         c = ustr[i];
589                         /* Check for NUL-terminated string. */
590                         if (c == eol)
591                                 goto asciz_ended;
592                         *s++ = '\\';
593                         *s++ = 'x';
594                         *s++ = "0123456789abcdef"[c >> 4];
595                         *s++ = "0123456789abcdef"[c & 0xf];
596                 }
597         } else {
598                 for (i = 0; i < size; ++i) {
599                         c = ustr[i];
600                         /* Check for NUL-terminated string. */
601                         if (c == eol)
602                                 goto asciz_ended;
603                         switch (c) {
604                                 case '\"': case '\\':
605                                         *s++ = '\\';
606                                         *s++ = c;
607                                         break;
608                                 case '\f':
609                                         *s++ = '\\';
610                                         *s++ = 'f';
611                                         break;
612                                 case '\n':
613                                         *s++ = '\\';
614                                         *s++ = 'n';
615                                         break;
616                                 case '\r':
617                                         *s++ = '\\';
618                                         *s++ = 'r';
619                                         break;
620                                 case '\t':
621                                         *s++ = '\\';
622                                         *s++ = 't';
623                                         break;
624                                 case '\v':
625                                         *s++ = '\\';
626                                         *s++ = 'v';
627                                         break;
628                                 default:
629                                         if (c >= ' ' && c <= 0x7e)
630                                                 *s++ = c;
631                                         else {
632                                                 /* Print \octal */
633                                                 *s++ = '\\';
634                                                 if (i + 1 < size
635                                                     && ustr[i + 1] >= '0'
636                                                     && ustr[i + 1] <= '9'
637                                                 ) {
638                                                         /* Print \ooo */
639                                                         *s++ = '0' + (c >> 6);
640                                                         *s++ = '0' + ((c >> 3) & 0x7);
641                                                 } else {
642                                                         /* Print \[[o]o]o */
643                                                         if ((c >> 3) != 0) {
644                                                                 if ((c >> 6) != 0)
645                                                                         *s++ = '0' + (c >> 6);
646                                                                 *s++ = '0' + ((c >> 3) & 0x7);
647                                                         }
648                                                 }
649                                                 *s++ = '0' + (c & 0x7);
650                                         }
651                                         break;
652                         }
653                 }
654         }
655
656         if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
657                 *s++ = '\"';
658         *s = '\0';
659
660         /* Return zero if we printed entire ASCIZ string (didn't truncate it) */
661         if (style & QUOTE_0_TERMINATED && ustr[i] == '\0') {
662                 /* We didn't see NUL yet (otherwise we'd jump to 'asciz_ended')
663                  * but next char is NUL.
664                  */
665                 return 0;
666         }
667
668         return 1;
669
670  asciz_ended:
671         if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
672                 *s++ = '\"';
673         *s = '\0';
674         /* Return zero: we printed entire ASCIZ string (didn't truncate it) */
675         return 0;
676 }
677
678 #ifndef ALLOCA_CUTOFF
679 # define ALLOCA_CUTOFF  4032
680 #endif
681 #define use_alloca(n) ((n) <= ALLOCA_CUTOFF)
682
683 /*
684  * Quote string `str' of length `size' and print the result.
685  *
686  * If QUOTE_0_TERMINATED `style' flag is set,
687  * treat `str' as a NUL-terminated string and
688  * quote at most (`size' - 1) bytes.
689  *
690  * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
691  * do not add leading and trailing quoting symbols.
692  *
693  * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
694  * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
695  */
696 int
697 print_quoted_string(const char *str, unsigned int size,
698                     const unsigned int style)
699 {
700         char *buf;
701         char *outstr;
702         unsigned int alloc_size;
703         int rc;
704
705         if (size && style & QUOTE_0_TERMINATED)
706                 --size;
707
708         alloc_size = 4 * size;
709         if (alloc_size / 4 != size) {
710                 error_msg("Out of memory");
711                 tprints("???");
712                 return -1;
713         }
714         alloc_size += 1 + (style & QUOTE_OMIT_LEADING_TRAILING_QUOTES ? 0 : 2);
715
716         if (use_alloca(alloc_size)) {
717                 outstr = alloca(alloc_size);
718                 buf = NULL;
719         } else {
720                 outstr = buf = malloc(alloc_size);
721                 if (!buf) {
722                         error_msg("Out of memory");
723                         tprints("???");
724                         return -1;
725                 }
726         }
727
728         rc = string_quote(str, outstr, size, style);
729         tprints(outstr);
730
731         free(buf);
732         return rc;
733 }
734
735 /*
736  * Print path string specified by address `addr' and length `n'.
737  * If path length exceeds `n', append `...' to the output.
738  */
739 void
740 printpathn(struct tcb *tcp, long addr, unsigned int n)
741 {
742         char path[PATH_MAX + 1];
743         int nul_seen;
744
745         if (!addr) {
746                 tprints("NULL");
747                 return;
748         }
749
750         /* Cap path length to the path buffer size */
751         if (n > sizeof path - 1)
752                 n = sizeof path - 1;
753
754         /* Fetch one byte more to find out whether path length > n. */
755         nul_seen = umovestr(tcp, addr, n + 1, path);
756         if (nul_seen < 0)
757                 tprintf("%#lx", addr);
758         else {
759                 path[n++] = '\0';
760                 print_quoted_string(path, n, QUOTE_0_TERMINATED);
761                 if (!nul_seen)
762                         tprints("...");
763         }
764 }
765
766 void
767 printpath(struct tcb *tcp, long addr)
768 {
769         /* Size must correspond to char path[] size in printpathn */
770         printpathn(tcp, addr, PATH_MAX);
771 }
772
773 /*
774  * Print string specified by address `addr' and length `len'.
775  * If `len' < 0, treat the string as a NUL-terminated string.
776  * If string length exceeds `max_strlen', append `...' to the output.
777  */
778 void
779 printstr(struct tcb *tcp, long addr, long len)
780 {
781         static char *str = NULL;
782         static char *outstr;
783         unsigned int size;
784         unsigned int style;
785         int ellipsis;
786
787         if (!addr) {
788                 tprints("NULL");
789                 return;
790         }
791         /* Allocate static buffers if they are not allocated yet. */
792         if (!str) {
793                 unsigned int outstr_size = 4 * max_strlen + /*for quotes and NUL:*/ 3;
794
795                 if (outstr_size / 4 != max_strlen)
796                         die_out_of_memory();
797                 str = xmalloc(max_strlen + 1);
798                 outstr = xmalloc(outstr_size);
799         }
800
801         size = max_strlen;
802         if (len == -1) {
803                 /*
804                  * Treat as a NUL-terminated string: fetch one byte more
805                  * because string_quote may look one byte ahead.
806                  */
807                 if (umovestr(tcp, addr, size + 1, str) < 0) {
808                         tprintf("%#lx", addr);
809                         return;
810                 }
811                 style = QUOTE_0_TERMINATED;
812         }
813         else {
814                 if (size > (unsigned long)len)
815                         size = (unsigned long)len;
816                 if (umoven(tcp, addr, size, str) < 0) {
817                         tprintf("%#lx", addr);
818                         return;
819                 }
820                 style = 0;
821         }
822
823         /* If string_quote didn't see NUL and (it was supposed to be ASCIZ str
824          * or we were requested to print more than -s NUM chars)...
825          */
826         ellipsis = (string_quote(str, outstr, size, style) &&
827                         (len < 0 || (unsigned long) len > max_strlen));
828
829         tprints(outstr);
830         if (ellipsis)
831                 tprints("...");
832 }
833
834 void
835 dumpiov(struct tcb *tcp, int len, long addr)
836 {
837 #if SUPPORTED_PERSONALITIES > 1
838         union {
839                 struct { u_int32_t base; u_int32_t len; } *iov32;
840                 struct { u_int64_t base; u_int64_t len; } *iov64;
841         } iovu;
842 #define iov iovu.iov64
843 #define sizeof_iov \
844         (current_wordsize == 4 ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64))
845 #define iov_iov_base(i) \
846         (current_wordsize == 4 ? (uint64_t) iovu.iov32[i].base : iovu.iov64[i].base)
847 #define iov_iov_len(i) \
848         (current_wordsize == 4 ? (uint64_t) iovu.iov32[i].len : iovu.iov64[i].len)
849 #else
850         struct iovec *iov;
851 #define sizeof_iov sizeof(*iov)
852 #define iov_iov_base(i) iov[i].iov_base
853 #define iov_iov_len(i) iov[i].iov_len
854 #endif
855         int i;
856         unsigned size;
857
858         size = sizeof_iov * len;
859         /* Assuming no sane program has millions of iovs */
860         if ((unsigned)len > 1024*1024 /* insane or negative size? */
861             || (iov = malloc(size)) == NULL) {
862                 error_msg("Out of memory");
863                 return;
864         }
865         if (umoven(tcp, addr, size, iov) >= 0) {
866                 for (i = 0; i < len; i++) {
867                         /* include the buffer number to make it easy to
868                          * match up the trace with the source */
869                         tprintf(" * %lu bytes in buffer %d\n",
870                                 (unsigned long)iov_iov_len(i), i);
871                         dumpstr(tcp, (long) iov_iov_base(i),
872                                 iov_iov_len(i));
873                 }
874         }
875         free(iov);
876 #undef sizeof_iov
877 #undef iov_iov_base
878 #undef iov_iov_len
879 #undef iov
880 }
881
882 void
883 dumpstr(struct tcb *tcp, long addr, int len)
884 {
885         static int strsize = -1;
886         static unsigned char *str;
887
888         char outbuf[
889                 (
890                         (sizeof(
891                         "xx xx xx xx xx xx xx xx  xx xx xx xx xx xx xx xx  "
892                         "1234567890123456") + /*in case I'm off by few:*/ 4)
893                 /*align to 8 to make memset easier:*/ + 7) & -8
894         ];
895         const unsigned char *src;
896         int i;
897
898         memset(outbuf, ' ', sizeof(outbuf));
899
900         if (strsize < len + 16) {
901                 free(str);
902                 str = malloc(len + 16);
903                 if (!str) {
904                         strsize = -1;
905                         error_msg("Out of memory");
906                         return;
907                 }
908                 strsize = len + 16;
909         }
910
911         if (umoven(tcp, addr, len, str) < 0)
912                 return;
913
914         /* Space-pad to 16 bytes */
915         i = len;
916         while (i & 0xf)
917                 str[i++] = ' ';
918
919         i = 0;
920         src = str;
921         while (i < len) {
922                 char *dst = outbuf;
923                 /* Hex dump */
924                 do {
925                         if (i < len) {
926                                 *dst++ = "0123456789abcdef"[*src >> 4];
927                                 *dst++ = "0123456789abcdef"[*src & 0xf];
928                         }
929                         else {
930                                 *dst++ = ' ';
931                                 *dst++ = ' ';
932                         }
933                         dst++; /* space is there by memset */
934                         i++;
935                         if ((i & 7) == 0)
936                                 dst++; /* space is there by memset */
937                         src++;
938                 } while (i & 0xf);
939                 /* ASCII dump */
940                 i -= 16;
941                 src -= 16;
942                 do {
943                         if (*src >= ' ' && *src < 0x7f)
944                                 *dst++ = *src;
945                         else
946                                 *dst++ = '.';
947                         src++;
948                 } while (++i & 0xf);
949                 *dst = '\0';
950                 tprintf(" | %05x  %s |\n", i - 16, outbuf);
951         }
952 }
953
954 #ifdef HAVE_PROCESS_VM_READV
955 /* C library supports this, but the kernel might not. */
956 static bool process_vm_readv_not_supported = 0;
957 #else
958
959 /* Need to do this since process_vm_readv() is not yet available in libc.
960  * When libc is be updated, only "static bool process_vm_readv_not_supported"
961  * line should remain.
962  */
963 #if !defined(__NR_process_vm_readv)
964 # if defined(I386)
965 #  define __NR_process_vm_readv  347
966 # elif defined(X86_64)
967 #  define __NR_process_vm_readv  310
968 # elif defined(POWERPC)
969 #  define __NR_process_vm_readv  351
970 # endif
971 #endif
972
973 #if defined(__NR_process_vm_readv)
974 static bool process_vm_readv_not_supported = 0;
975 /* Have to avoid duplicating with the C library headers. */
976 static ssize_t strace_process_vm_readv(pid_t pid,
977                  const struct iovec *lvec,
978                  unsigned long liovcnt,
979                  const struct iovec *rvec,
980                  unsigned long riovcnt,
981                  unsigned long flags)
982 {
983         return syscall(__NR_process_vm_readv, (long)pid, lvec, liovcnt, rvec, riovcnt, flags);
984 }
985 #define process_vm_readv strace_process_vm_readv
986 #else
987 static bool process_vm_readv_not_supported = 1;
988 # define process_vm_readv(...) (errno = ENOSYS, -1)
989 #endif
990
991 #endif /* end of hack */
992
993 static ssize_t
994 vm_read_mem(pid_t pid, void *laddr, long raddr, size_t len)
995 {
996         const struct iovec local = {
997                 .iov_base = laddr,
998                 .iov_len = len
999         };
1000         const struct iovec remote = {
1001                 .iov_base = (void *) raddr,
1002                 .iov_len = len
1003         };
1004
1005         return process_vm_readv(pid, &local, 1, &remote, 1, 0);
1006 }
1007
1008 /*
1009  * move `len' bytes of data from process `pid'
1010  * at address `addr' to our space at `our_addr'
1011  */
1012 int
1013 umoven(struct tcb *tcp, long addr, unsigned int len, void *our_addr)
1014 {
1015         char *laddr = our_addr;
1016         int pid = tcp->pid;
1017         unsigned int n, m, nread;
1018         union {
1019                 long val;
1020                 char x[sizeof(long)];
1021         } u;
1022
1023 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
1024         if (current_wordsize < sizeof(addr))
1025                 addr &= (1ul << 8 * current_wordsize) - 1;
1026 #endif
1027
1028         if (!process_vm_readv_not_supported) {
1029                 int r = vm_read_mem(pid, laddr, addr, len);
1030                 if ((unsigned int) r == len)
1031                         return 0;
1032                 if (r >= 0) {
1033                         error_msg("umoven: short read (%u < %u) @0x%lx",
1034                                   (unsigned int) r, len, addr);
1035                         return -1;
1036                 }
1037                 switch (errno) {
1038                         case ENOSYS:
1039                                 process_vm_readv_not_supported = 1;
1040                                 break;
1041                         case EPERM:
1042                                 /* operation not permitted, try PTRACE_PEEKDATA */
1043                                 break;
1044                         case ESRCH:
1045                                 /* the process is gone */
1046                                 return -1;
1047                         case EFAULT: case EIO:
1048                                 /* address space is inaccessible */
1049                                 return -1;
1050                         default:
1051                                 /* all the rest is strange and should be reported */
1052                                 perror_msg("process_vm_readv");
1053                                 return -1;
1054                 }
1055         }
1056
1057         nread = 0;
1058         if (addr & (sizeof(long) - 1)) {
1059                 /* addr not a multiple of sizeof(long) */
1060                 n = addr & (sizeof(long) - 1);  /* residue */
1061                 addr &= -sizeof(long);          /* aligned address */
1062                 errno = 0;
1063                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
1064                 switch (errno) {
1065                         case 0:
1066                                 break;
1067                         case ESRCH: case EINVAL:
1068                                 /* these could be seen if the process is gone */
1069                                 return -1;
1070                         case EFAULT: case EIO: case EPERM:
1071                                 /* address space is inaccessible */
1072                                 return -1;
1073                         default:
1074                                 /* all the rest is strange and should be reported */
1075                                 perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%lx",
1076                                             pid, addr);
1077                                 return -1;
1078                 }
1079                 m = MIN(sizeof(long) - n, len);
1080                 memcpy(laddr, &u.x[n], m);
1081                 addr += sizeof(long);
1082                 laddr += m;
1083                 nread += m;
1084                 len -= m;
1085         }
1086         while (len) {
1087                 errno = 0;
1088                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
1089                 switch (errno) {
1090                         case 0:
1091                                 break;
1092                         case ESRCH: case EINVAL:
1093                                 /* these could be seen if the process is gone */
1094                                 return -1;
1095                         case EFAULT: case EIO: case EPERM:
1096                                 /* address space is inaccessible */
1097                                 if (nread) {
1098                                         perror_msg("umoven: short read (%u < %u) @0x%lx",
1099                                                    nread, nread + len, addr - nread);
1100                                 }
1101                                 return -1;
1102                         default:
1103                                 /* all the rest is strange and should be reported */
1104                                 perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%lx",
1105                                             pid, addr);
1106                                 return -1;
1107                 }
1108                 m = MIN(sizeof(long), len);
1109                 memcpy(laddr, u.x, m);
1110                 addr += sizeof(long);
1111                 laddr += m;
1112                 nread += m;
1113                 len -= m;
1114         }
1115
1116         return 0;
1117 }
1118
1119 int
1120 umoven_or_printaddr(struct tcb *tcp, const long addr, const unsigned int len,
1121                     void *our_addr)
1122 {
1123         if (!addr) {
1124                 tprints("NULL");
1125                 return -1;
1126         }
1127         if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)) ||
1128             umoven(tcp, addr, len, our_addr) < 0) {
1129                 tprintf("%#lx", addr);
1130                 return -1;
1131         }
1132         return 0;
1133 }
1134
1135 int
1136 umove_long_or_printaddr(struct tcb *tcp, const long addr, long *ptr)
1137 {
1138         if (current_wordsize < sizeof(*ptr)) {
1139                 uint32_t val32;
1140                 int r = umove_or_printaddr(tcp, addr, &val32);
1141                 if (!r)
1142                         *ptr = (unsigned long) val32;
1143                 return r;
1144         }
1145         return umove_or_printaddr(tcp, addr, ptr);
1146 }
1147
1148 /*
1149  * Like `umove' but make the additional effort of looking
1150  * for a terminating zero byte.
1151  *
1152  * Returns < 0 on error, > 0 if NUL was seen,
1153  * (TODO if useful: return count of bytes including NUL),
1154  * else 0 if len bytes were read but no NUL byte seen.
1155  *
1156  * Note: there is no guarantee we won't overwrite some bytes
1157  * in laddr[] _after_ terminating NUL (but, of course,
1158  * we never write past laddr[len-1]).
1159  */
1160 int
1161 umovestr(struct tcb *tcp, long addr, unsigned int len, char *laddr)
1162 {
1163 #if SIZEOF_LONG == 4
1164         const unsigned long x01010101 = 0x01010101ul;
1165         const unsigned long x80808080 = 0x80808080ul;
1166 #elif SIZEOF_LONG == 8
1167         const unsigned long x01010101 = 0x0101010101010101ul;
1168         const unsigned long x80808080 = 0x8080808080808080ul;
1169 #else
1170 # error SIZEOF_LONG > 8
1171 #endif
1172
1173         int pid = tcp->pid;
1174         unsigned int n, m, nread;
1175         union {
1176                 unsigned long val;
1177                 char x[sizeof(long)];
1178         } u;
1179
1180 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
1181         if (current_wordsize < sizeof(addr))
1182                 addr &= (1ul << 8 * current_wordsize) - 1;
1183 #endif
1184
1185         nread = 0;
1186         if (!process_vm_readv_not_supported) {
1187                 const size_t page_size = get_pagesize();
1188                 const size_t page_mask = page_size - 1;
1189
1190                 while (len > 0) {
1191                         unsigned int chunk_len;
1192                         unsigned int end_in_page;
1193
1194                         /*
1195                          * Don't cross pages, otherwise we can get EFAULT
1196                          * and fail to notice that terminating NUL lies
1197                          * in the existing (first) page.
1198                          */
1199                         chunk_len = len > page_size ? page_size : len;
1200                         end_in_page = (addr + chunk_len) & page_mask;
1201                         if (chunk_len > end_in_page) /* crosses to the next page */
1202                                 chunk_len -= end_in_page;
1203
1204                         int r = vm_read_mem(pid, laddr, addr, chunk_len);
1205                         if (r > 0) {
1206                                 if (memchr(laddr, '\0', r))
1207                                         return 1;
1208                                 addr += r;
1209                                 laddr += r;
1210                                 nread += r;
1211                                 len -= r;
1212                                 continue;
1213                         }
1214                         switch (errno) {
1215                                 case ENOSYS:
1216                                         process_vm_readv_not_supported = 1;
1217                                         goto vm_readv_didnt_work;
1218                                 case ESRCH:
1219                                         /* the process is gone */
1220                                         return -1;
1221                                 case EPERM:
1222                                         /* operation not permitted, try PTRACE_PEEKDATA */
1223                                         if (!nread)
1224                                                 goto vm_readv_didnt_work;
1225                                         /* fall through */
1226                                 case EFAULT: case EIO:
1227                                         /* address space is inaccessible */
1228                                         if (nread) {
1229                                                 perror_msg("umovestr: short read (%d < %d) @0x%lx",
1230                                                            nread, nread + len, addr - nread);
1231                                         }
1232                                         return -1;
1233                                 default:
1234                                         /* all the rest is strange and should be reported */
1235                                         perror_msg("process_vm_readv");
1236                                         return -1;
1237                         }
1238                 }
1239                 return 0;
1240         }
1241  vm_readv_didnt_work:
1242
1243         if (addr & (sizeof(long) - 1)) {
1244                 /* addr not a multiple of sizeof(long) */
1245                 n = addr & (sizeof(long) - 1);  /* residue */
1246                 addr &= -sizeof(long);          /* aligned address */
1247                 errno = 0;
1248                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
1249                 switch (errno) {
1250                         case 0:
1251                                 break;
1252                         case ESRCH: case EINVAL:
1253                                 /* these could be seen if the process is gone */
1254                                 return -1;
1255                         case EFAULT: case EIO: case EPERM:
1256                                 /* address space is inaccessible */
1257                                 return -1;
1258                         default:
1259                                 /* all the rest is strange and should be reported */
1260                                 perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%lx",
1261                                             pid, addr);
1262                                 return -1;
1263                 }
1264                 m = MIN(sizeof(long) - n, len);
1265                 memcpy(laddr, &u.x[n], m);
1266                 while (n & (sizeof(long) - 1))
1267                         if (u.x[n++] == '\0')
1268                                 return 1;
1269                 addr += sizeof(long);
1270                 laddr += m;
1271                 nread += m;
1272                 len -= m;
1273         }
1274
1275         while (len) {
1276                 errno = 0;
1277                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
1278                 switch (errno) {
1279                         case 0:
1280                                 break;
1281                         case ESRCH: case EINVAL:
1282                                 /* these could be seen if the process is gone */
1283                                 return -1;
1284                         case EFAULT: case EIO: case EPERM:
1285                                 /* address space is inaccessible */
1286                                 if (nread) {
1287                                         perror_msg("umovestr: short read (%d < %d) @0x%lx",
1288                                                    nread, nread + len, addr - nread);
1289                                 }
1290                                 return -1;
1291                         default:
1292                                 /* all the rest is strange and should be reported */
1293                                 perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%lx",
1294                                            pid, addr);
1295                                 return -1;
1296                 }
1297                 m = MIN(sizeof(long), len);
1298                 memcpy(laddr, u.x, m);
1299                 /* "If a NUL char exists in this word" */
1300                 if ((u.val - x01010101) & ~u.val & x80808080)
1301                         return 1;
1302                 addr += sizeof(long);
1303                 laddr += m;
1304                 nread += m;
1305                 len -= m;
1306         }
1307         return 0;
1308 }
1309
1310 int
1311 upeek(int pid, long off, long *res)
1312 {
1313         long val;
1314
1315         errno = 0;
1316         val = ptrace(PTRACE_PEEKUSER, (pid_t)pid, (char *) off, 0);
1317         if (val == -1 && errno) {
1318                 if (errno != ESRCH) {
1319                         perror_msg("upeek: PTRACE_PEEKUSER pid:%d @0x%lx)", pid, off);
1320                 }
1321                 return -1;
1322         }
1323         *res = val;
1324         return 0;
1325 }