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