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