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