]> granicus.if.org Git - strace/blob - util.c
Turn printaddr into a thin wrapper around printaddr64
[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 #define DEF_PRINTNUM(name, type) \
240 bool                                                                    \
241 printnum_ ## name(struct tcb *const tcp, const kernel_ulong_t addr,     \
242                   const char *const fmt)                                \
243 {                                                                       \
244         type num;                                                       \
245         if (umove_or_printaddr(tcp, addr, &num))                        \
246                 return false;                                           \
247         tprints("[");                                                   \
248         tprintf(fmt, num);                                              \
249         tprints("]");                                                   \
250         return true;                                                    \
251 }
252
253 #define DEF_PRINTNUM_ADDR(name, type) \
254 bool                                                                    \
255 printnum_addr_ ## name(struct tcb *tcp, const kernel_ulong_t addr)      \
256 {                                                                       \
257         type num;                                                       \
258         if (umove_or_printaddr(tcp, addr, &num))                        \
259                 return false;                                           \
260         tprints("[");                                                   \
261         printaddr64(num);                                               \
262         tprints("]");                                                   \
263         return true;                                                    \
264 }
265
266 #define DEF_PRINTPAIR(name, type) \
267 bool                                                                    \
268 printpair_ ## name(struct tcb *const tcp, const kernel_ulong_t addr,    \
269                    const char *const fmt)                               \
270 {                                                                       \
271         type pair[2];                                                   \
272         if (umove_or_printaddr(tcp, addr, &pair))                       \
273                 return false;                                           \
274         tprints("[");                                                   \
275         tprintf(fmt, pair[0]);                                          \
276         tprints(", ");                                                  \
277         tprintf(fmt, pair[1]);                                          \
278         tprints("]");                                                   \
279         return true;                                                    \
280 }
281
282 DEF_PRINTNUM(int, int)
283 DEF_PRINTNUM_ADDR(int, unsigned int)
284 DEF_PRINTPAIR(int, int)
285 DEF_PRINTNUM(short, short)
286 DEF_PRINTNUM(int64, uint64_t)
287 DEF_PRINTNUM_ADDR(int64, uint64_t)
288 DEF_PRINTPAIR(int64, uint64_t)
289
290 #ifndef current_wordsize
291 bool
292 printnum_long_int(struct tcb *const tcp, const kernel_ulong_t addr,
293                   const char *const fmt_long, const char *const fmt_int)
294 {
295         if (current_wordsize > sizeof(int)) {
296                 return printnum_int64(tcp, addr, fmt_long);
297         } else {
298                 return printnum_int(tcp, addr, fmt_int);
299         }
300 }
301
302 bool
303 printnum_addr_long_int(struct tcb *tcp, const kernel_ulong_t addr)
304 {
305         if (current_wordsize > sizeof(int)) {
306                 return printnum_addr_int64(tcp, addr);
307         } else {
308                 return printnum_addr_int(tcp, addr);
309         }
310 }
311 #endif /* !current_wordsize */
312
313 #ifndef current_klongsize
314 bool
315 printnum_addr_klong_int(struct tcb *tcp, const kernel_ulong_t addr)
316 {
317         if (current_klongsize > sizeof(int)) {
318                 return printnum_addr_int64(tcp, addr);
319         } else {
320                 return printnum_addr_int(tcp, addr);
321         }
322 }
323 #endif /* !current_klongsize */
324
325 /**
326  * Prints time to a (static internal) buffer and returns pointer to it.
327  * Returns NULL if the provided time specification is not correct.
328  *
329  * @param sec           Seconds since epoch.
330  * @param part_sec      Amount of second parts since the start of a second.
331  * @param max_part_sec  Maximum value of a valid part_sec.
332  * @param width         1 + floor(log10(max_part_sec)).
333  * @return              Pointer to a statically allocated string on success,
334  *                      NULL on error.
335  */
336 static const char *
337 sprinttime_ex(const long long sec, const unsigned long long part_sec,
338               const unsigned int max_part_sec, const int width)
339 {
340         static char buf[sizeof(int) * 3 * 6 + sizeof(part_sec) * 3
341                         + sizeof("+0000")];
342
343         if ((sec == 0 && part_sec == 0) || part_sec > max_part_sec)
344                 return NULL;
345
346         time_t t = (time_t) sec;
347         struct tm *tmp = (sec == t) ? localtime(&t) : NULL;
348         if (!tmp)
349                 return NULL;
350
351         size_t pos = strftime(buf, sizeof(buf), "%FT%T", tmp);
352         if (!pos)
353                 return NULL;
354
355         if (part_sec > 0)
356                 pos += xsnprintf(buf + pos, sizeof(buf) - pos, ".%0*llu",
357                                  width, part_sec);
358
359         return strftime(buf + pos, sizeof(buf) - pos, "%z", tmp) ? buf : NULL;
360 }
361
362 const char *
363 sprinttime(long long sec)
364 {
365         return sprinttime_ex(sec, 0, 0, 0);
366 }
367
368 const char *
369 sprinttime_usec(long long sec, unsigned long long usec)
370 {
371         return sprinttime_ex(sec, usec, 999999, 6);
372 }
373
374 const char *
375 sprinttime_nsec(long long sec, unsigned long long nsec)
376 {
377         return sprinttime_ex(sec, nsec, 999999999, 9);
378 }
379
380 enum sock_proto
381 getfdproto(struct tcb *tcp, int fd)
382 {
383 #ifdef HAVE_SYS_XATTR_H
384         size_t bufsize = 256;
385         char buf[bufsize];
386         ssize_t r;
387         char path[sizeof("/proc/%u/fd/%u") + 2 * sizeof(int)*3];
388
389         if (fd < 0)
390                 return SOCK_PROTO_UNKNOWN;
391
392         xsprintf(path, "/proc/%u/fd/%u", tcp->pid, fd);
393         r = getxattr(path, "system.sockprotoname", buf, bufsize - 1);
394         if (r <= 0)
395                 return SOCK_PROTO_UNKNOWN;
396         else {
397                 /*
398                  * This is a protection for the case when the kernel
399                  * side does not append a null byte to the buffer.
400                  */
401                 buf[r] = '\0';
402
403                 return get_proto_by_name(buf);
404         }
405 #else
406         return SOCK_PROTO_UNKNOWN;
407 #endif
408 }
409
410 unsigned long
411 getfdinode(struct tcb *tcp, int fd)
412 {
413         char path[PATH_MAX + 1];
414
415         if (getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
416                 const char *str = STR_STRIP_PREFIX(path, "socket:[");
417
418                 if (str != path) {
419                         const size_t str_len = strlen(str);
420                         if (str_len && str[str_len - 1] == ']')
421                                 return strtoul(str, NULL, 10);
422                 }
423         }
424
425         return 0;
426 }
427
428 static bool
429 printsocket(struct tcb *tcp, int fd, const char *path)
430 {
431         const char *str = STR_STRIP_PREFIX(path, "socket:[");
432         size_t len;
433         unsigned long inode;
434
435         return (str != path)
436                 && (len = strlen(str))
437                 && (str[len - 1] == ']')
438                 && (inode = strtoul(str, NULL, 10))
439                 && print_sockaddr_by_inode(tcp, fd, inode);
440 }
441
442 static bool
443 printdev(struct tcb *tcp, int fd, const char *path)
444 {
445         struct_stat st;
446
447         if (path[0] != '/')
448                 return false;
449
450         if (stat_file(path, &st)) {
451                 debug_func_perror_msg("stat(\"%s\")", path);
452                 return false;
453         }
454
455         switch (st.st_mode & S_IFMT) {
456         case S_IFBLK:
457         case S_IFCHR:
458                 print_quoted_string_ex(path, strlen(path),
459                                        QUOTE_OMIT_LEADING_TRAILING_QUOTES,
460                                        "<>");
461                 tprintf("<%s %u:%u>",
462                         S_ISBLK(st.st_mode)? "block" : "char",
463                         major(st.st_rdev), minor(st.st_rdev));
464                 return true;
465         }
466
467         return false;
468 }
469
470 void
471 printfd(struct tcb *tcp, int fd)
472 {
473         char path[PATH_MAX + 1];
474         if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
475                 tprintf("%d<", fd);
476                 if (show_fd_path <= 1
477                     || (!printsocket(tcp, fd, path)
478                          && !printdev(tcp, fd, path))) {
479                         print_quoted_string_ex(path, strlen(path),
480                                 QUOTE_OMIT_LEADING_TRAILING_QUOTES, "<>");
481                 }
482                 tprints(">");
483         } else
484                 tprintf("%d", fd);
485 }
486
487 /*
488  * Quote string `instr' of length `size'
489  * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
490  *
491  * `escape_chars' specifies characters (in addition to characters with
492  * codes 0..31, 127..255, single and double quotes) that should be escaped.
493  *
494  * If QUOTE_0_TERMINATED `style' flag is set,
495  * treat `instr' as a NUL-terminated string,
496  * checking up to (`size' + 1) bytes of `instr'.
497  *
498  * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
499  * do not add leading and trailing quoting symbols.
500  *
501  * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
502  * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
503  */
504 int
505 string_quote(const char *instr, char *outstr, const unsigned int size,
506              const unsigned int style, const char *escape_chars)
507 {
508         const unsigned char *ustr = (const unsigned char *) instr;
509         char *s = outstr;
510         unsigned int i;
511         int usehex, c, eol;
512         bool escape;
513
514         if (style & QUOTE_0_TERMINATED)
515                 eol = '\0';
516         else
517                 eol = 0x100; /* this can never match a char */
518
519         usehex = 0;
520         if ((xflag > 1) || (style & QUOTE_FORCE_HEX)) {
521                 usehex = 1;
522         } else if (xflag) {
523                 /* Check for presence of symbol which require
524                    to hex-quote the whole string. */
525                 for (i = 0; i < size; ++i) {
526                         c = ustr[i];
527                         /* Check for NUL-terminated string. */
528                         if (c == eol)
529                                 break;
530
531                         /* Force hex unless c is printable or whitespace */
532                         if (c > 0x7e) {
533                                 usehex = 1;
534                                 break;
535                         }
536                         /* In ASCII isspace is only these chars: "\t\n\v\f\r".
537                          * They happen to have ASCII codes 9,10,11,12,13.
538                          */
539                         if (c < ' ' && (unsigned)(c - 9) >= 5) {
540                                 usehex = 1;
541                                 break;
542                         }
543                 }
544         }
545
546         if (style & QUOTE_EMIT_COMMENT)
547                 s = stpcpy(s, " /* ");
548         if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
549                 *s++ = '\"';
550
551         if (usehex) {
552                 /* Hex-quote the whole string. */
553                 for (i = 0; i < size; ++i) {
554                         c = ustr[i];
555                         /* Check for NUL-terminated string. */
556                         if (c == eol)
557                                 goto asciz_ended;
558                         *s++ = '\\';
559                         *s++ = 'x';
560                         *s++ = "0123456789abcdef"[c >> 4];
561                         *s++ = "0123456789abcdef"[c & 0xf];
562                 }
563
564                 goto string_ended;
565         }
566
567         for (i = 0; i < size; ++i) {
568                 c = ustr[i];
569                 /* Check for NUL-terminated string. */
570                 if (c == eol)
571                         goto asciz_ended;
572                 if ((i == (size - 1)) &&
573                     (style & QUOTE_OMIT_TRAILING_0) && (c == '\0'))
574                         goto asciz_ended;
575                 switch (c) {
576                 case '\"': case '\\':
577                         *s++ = '\\';
578                         *s++ = c;
579                         break;
580                 case '\f':
581                         *s++ = '\\';
582                         *s++ = 'f';
583                         break;
584                 case '\n':
585                         *s++ = '\\';
586                         *s++ = 'n';
587                         break;
588                 case '\r':
589                         *s++ = '\\';
590                         *s++ = 'r';
591                         break;
592                 case '\t':
593                         *s++ = '\\';
594                         *s++ = 't';
595                         break;
596                 case '\v':
597                         *s++ = '\\';
598                         *s++ = 'v';
599                         break;
600                 default:
601                         escape = (c < ' ') || (c > 0x7e);
602
603                         if (!escape && escape_chars)
604                                 escape = !!strchr(escape_chars, c);
605
606                         if (!escape) {
607                                 *s++ = c;
608                         } else {
609                                 /* Print \octal */
610                                 *s++ = '\\';
611                                 if (i + 1 < size
612                                     && ustr[i + 1] >= '0'
613                                     && ustr[i + 1] <= '7'
614                                 ) {
615                                         /* Print \ooo */
616                                         *s++ = '0' + (c >> 6);
617                                         *s++ = '0' + ((c >> 3) & 0x7);
618                                 } else {
619                                         /* Print \[[o]o]o */
620                                         if ((c >> 3) != 0) {
621                                                 if ((c >> 6) != 0)
622                                                         *s++ = '0' + (c >> 6);
623                                                 *s++ = '0' + ((c >> 3) & 0x7);
624                                         }
625                                 }
626                                 *s++ = '0' + (c & 0x7);
627                         }
628                 }
629         }
630
631  string_ended:
632         if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
633                 *s++ = '\"';
634         if (style & QUOTE_EMIT_COMMENT)
635                 s = stpcpy(s, " */");
636         *s = '\0';
637
638         /* Return zero if we printed entire ASCIZ string (didn't truncate it) */
639         if (style & QUOTE_0_TERMINATED && ustr[i] == '\0') {
640                 /* We didn't see NUL yet (otherwise we'd jump to 'asciz_ended')
641                  * but next char is NUL.
642                  */
643                 return 0;
644         }
645
646         return 1;
647
648  asciz_ended:
649         if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
650                 *s++ = '\"';
651         if (style & QUOTE_EMIT_COMMENT)
652                 s = stpcpy(s, " */");
653         *s = '\0';
654         /* Return zero: we printed entire ASCIZ string (didn't truncate it) */
655         return 0;
656 }
657
658 #ifndef ALLOCA_CUTOFF
659 # define ALLOCA_CUTOFF  4032
660 #endif
661 #define use_alloca(n) ((n) <= ALLOCA_CUTOFF)
662
663 /*
664  * Quote string `str' of length `size' and print the result.
665  *
666  * If QUOTE_0_TERMINATED `style' flag is set,
667  * treat `str' as a NUL-terminated string and
668  * quote at most (`size' - 1) bytes.
669  *
670  * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
671  * do not add leading and trailing quoting symbols.
672  *
673  * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
674  * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
675  */
676 int
677 print_quoted_string_ex(const char *str, unsigned int size,
678                        const unsigned int style, const char *escape_chars)
679 {
680         char *buf;
681         char *outstr;
682         unsigned int alloc_size;
683         int rc;
684
685         if (size && style & QUOTE_0_TERMINATED)
686                 --size;
687
688         alloc_size = 4 * size;
689         if (alloc_size / 4 != size) {
690                 error_func_msg("requested %u bytes exceeds %u bytes limit",
691                                size, -1U / 4);
692                 tprints("???");
693                 return -1;
694         }
695         alloc_size += 1 + (style & QUOTE_OMIT_LEADING_TRAILING_QUOTES ? 0 : 2) +
696                 (style & QUOTE_EMIT_COMMENT ? 7 : 0);
697
698         if (use_alloca(alloc_size)) {
699                 outstr = alloca(alloc_size);
700                 buf = NULL;
701         } else {
702                 outstr = buf = malloc(alloc_size);
703                 if (!buf) {
704                         error_func_msg("memory exhausted when tried to allocate"
705                                        " %u bytes", alloc_size);
706                         tprints("???");
707                         return -1;
708                 }
709         }
710
711         rc = string_quote(str, outstr, size, style, escape_chars);
712         tprints(outstr);
713
714         free(buf);
715         return rc;
716 }
717
718 inline int
719 print_quoted_string(const char *str, unsigned int size,
720                     const unsigned int style)
721 {
722         return print_quoted_string_ex(str, size, style, NULL);
723 }
724
725 /*
726  * Quote a NUL-terminated string `str' of length up to `size' - 1
727  * and print the result.
728  *
729  * Returns 0 if NUL was seen, 1 otherwise.
730  */
731 int
732 print_quoted_cstring(const char *str, unsigned int size)
733 {
734         int unterminated =
735                 print_quoted_string(str, size, QUOTE_0_TERMINATED);
736
737         if (unterminated)
738                 tprints("...");
739
740         return unterminated;
741 }
742
743 /*
744  * Print path string specified by address `addr' and length `n'.
745  * If path length exceeds `n', append `...' to the output.
746  *
747  * Returns the result of umovenstr.
748  */
749 int
750 printpathn(struct tcb *const tcp, const kernel_ulong_t addr, unsigned int n)
751 {
752         char path[PATH_MAX];
753         int nul_seen;
754
755         if (!addr) {
756                 tprints("NULL");
757                 return -1;
758         }
759
760         /* Cap path length to the path buffer size */
761         if (n > sizeof(path) - 1)
762                 n = sizeof(path) - 1;
763
764         /* Fetch one byte more to find out whether path length > n. */
765         nul_seen = umovestr(tcp, addr, n + 1, path);
766         if (nul_seen < 0)
767                 printaddr(addr);
768         else {
769                 path[n++] = !nul_seen;
770                 print_quoted_cstring(path, n);
771         }
772
773         return nul_seen;
774 }
775
776 int
777 printpath(struct tcb *const tcp, const kernel_ulong_t addr)
778 {
779         /* Size must correspond to char path[] size in printpathn */
780         return printpathn(tcp, addr, PATH_MAX - 1);
781 }
782
783 /*
784  * Print string specified by address `addr' and length `len'.
785  * If `user_style' has QUOTE_0_TERMINATED bit set, treat the string
786  * as a NUL-terminated string.
787  * Pass `user_style' on to `string_quote'.
788  * Append `...' to the output if either the string length exceeds `max_strlen',
789  * or QUOTE_0_TERMINATED bit is set and the string length exceeds `len'.
790  *
791  * Returns the result of umovenstr if style has QUOTE_0_TERMINATED,
792  * or the result of umoven otherwise.
793  */
794 int
795 printstr_ex(struct tcb *const tcp, const kernel_ulong_t addr,
796             const kernel_ulong_t len, const unsigned int user_style)
797 {
798         static char *str;
799         static char *outstr;
800
801         unsigned int size;
802         unsigned int style = user_style;
803         int rc;
804         int ellipsis;
805
806         if (!addr) {
807                 tprints("NULL");
808                 return -1;
809         }
810         /* Allocate static buffers if they are not allocated yet. */
811         if (!str) {
812                 const unsigned int outstr_size =
813                         4 * max_strlen + /* for quotes and NUL */ 3;
814                 /*
815                  * We can assume that outstr_size / 4 == max_strlen
816                  * since we have a guarantee that max_strlen <= -1U / 4.
817                  */
818
819                 str = xmalloc(max_strlen + 1);
820                 outstr = xmalloc(outstr_size);
821         }
822
823         /* Fetch one byte more because string_quote may look one byte ahead. */
824         size = max_strlen + 1;
825
826         if (size > len)
827                 size = len;
828         if (style & QUOTE_0_TERMINATED)
829                 rc = umovestr(tcp, addr, size, str);
830         else
831                 rc = umoven(tcp, addr, size, str);
832
833         if (rc < 0) {
834                 printaddr(addr);
835                 return rc;
836         }
837
838         if (size > max_strlen)
839                 size = max_strlen;
840         else
841                 str[size] = '\xff';
842
843         /* If string_quote didn't see NUL and (it was supposed to be ASCIZ str
844          * or we were requested to print more than -s NUM chars)...
845          */
846         ellipsis = string_quote(str, outstr, size, style, NULL)
847                    && len
848                    && ((style & QUOTE_0_TERMINATED)
849                        || len > max_strlen);
850
851         tprints(outstr);
852         if (ellipsis)
853                 tprints("...");
854
855         return rc;
856 }
857
858 void
859 dumpiov_upto(struct tcb *const tcp, const int len, const kernel_ulong_t addr,
860              kernel_ulong_t data_size)
861 {
862 #if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
863         union {
864                 struct { uint32_t base; uint32_t len; } *iov32;
865                 struct { uint64_t base; uint64_t len; } *iov64;
866         } iovu;
867 #define iov iovu.iov64
868 #define sizeof_iov \
869         (current_wordsize == 4 ? (unsigned int) sizeof(*iovu.iov32)     \
870                                : (unsigned int) 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 ((unsigned int) 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 int size = sizeof_iov * len;
883         if (size / sizeof_iov != (unsigned int) len) {
884                 error_func_msg("requested %u iovec elements exceeds"
885                                " %u iovec limit", len, -1U / sizeof_iov);
886                 return;
887         }
888
889         iov = malloc(size);
890         if (!iov) {
891                 error_func_msg("memory exhausted when tried to allocate"
892                                " %u bytes", size);
893                 return;
894         }
895         if (umoven(tcp, addr, size, iov) >= 0) {
896                 for (i = 0; i < len; i++) {
897                         kernel_ulong_t iov_len = iov_iov_len(i);
898                         if (iov_len > data_size)
899                                 iov_len = data_size;
900                         if (!iov_len)
901                                 break;
902                         data_size -= iov_len;
903                         /* include the buffer number to make it easy to
904                          * match up the trace with the source */
905                         tprintf(" * %" PRI_klu " bytes in buffer %d\n", iov_len, i);
906                         dumpstr(tcp, iov_iov_base(i), iov_len);
907                 }
908         }
909         free(iov);
910 #undef sizeof_iov
911 #undef iov_iov_base
912 #undef iov_iov_len
913 #undef iov
914 }
915
916 void
917 dumpstr(struct tcb *const tcp, const kernel_ulong_t addr, const int len)
918 {
919         static int strsize = -1;
920         static unsigned char *str;
921
922         char outbuf[
923                 (
924                         (sizeof(
925                         "xx xx xx xx xx xx xx xx  xx xx xx xx xx xx xx xx  "
926                         "1234567890123456") + /*in case I'm off by few:*/ 4)
927                 /*align to 8 to make memset easier:*/ + 7) & -8
928         ];
929         const unsigned char *src;
930         int i;
931
932         if ((len < 0) || (len > INT_MAX - 16))
933                 return;
934
935         memset(outbuf, ' ', sizeof(outbuf));
936
937         if (strsize < len + 16) {
938                 free(str);
939                 str = malloc(len + 16);
940                 if (!str) {
941                         strsize = -1;
942                         error_func_msg("memory exhausted when tried to allocate"
943                                        " %zu bytes", (size_t) (len + 16));
944                         return;
945                 }
946                 strsize = len + 16;
947         }
948
949         if (umoven(tcp, addr, len, str) < 0)
950                 return;
951
952         /* Space-pad to 16 bytes */
953         i = len;
954         while (i & 0xf)
955                 str[i++] = ' ';
956
957         i = 0;
958         src = str;
959         while (i < len) {
960                 char *dst = outbuf;
961                 /* Hex dump */
962                 do {
963                         if (i < len) {
964                                 *dst++ = "0123456789abcdef"[*src >> 4];
965                                 *dst++ = "0123456789abcdef"[*src & 0xf];
966                         } else {
967                                 *dst++ = ' ';
968                                 *dst++ = ' ';
969                         }
970                         dst++; /* space is there by memset */
971                         i++;
972                         if ((i & 7) == 0)
973                                 dst++; /* space is there by memset */
974                         src++;
975                 } while (i & 0xf);
976                 /* ASCII dump */
977                 i -= 16;
978                 src -= 16;
979                 do {
980                         if (*src >= ' ' && *src < 0x7f)
981                                 *dst++ = *src;
982                         else
983                                 *dst++ = '.';
984                         src++;
985                 } while (++i & 0xf);
986                 *dst = '\0';
987                 tprintf(" | %05x  %s |\n", i - 16, outbuf);
988         }
989 }
990
991 int
992 umoven_or_printaddr64(struct tcb *const tcp, const uint64_t addr,
993                       const unsigned int len, void *const our_addr)
994 {
995         if (!addr || !verbose(tcp) || (exiting(tcp) && syserror(tcp)) ||
996             umoven(tcp, addr, len, our_addr) < 0) {
997                 printaddr64(addr);
998                 return -1;
999         }
1000         return 0;
1001 }
1002
1003 int
1004 umoven_or_printaddr64_ignore_syserror(struct tcb *const tcp,
1005                                     const uint64_t addr,
1006                                     const unsigned int len,
1007                                     void *const our_addr)
1008 {
1009         if (!addr || !verbose(tcp) || umoven(tcp, addr, len, our_addr) < 0) {
1010                 printaddr64(addr);
1011                 return -1;
1012         }
1013         return 0;
1014 }
1015
1016 bool
1017 print_int32_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
1018                          void *data)
1019 {
1020         tprintf("%" PRId32, *(int32_t *) elem_buf);
1021
1022         return true;
1023 }
1024
1025 bool
1026 print_uint32_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
1027                           void *data)
1028 {
1029         tprintf("%" PRIu32, *(uint32_t *) elem_buf);
1030
1031         return true;
1032 }
1033
1034 bool
1035 print_uint64_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
1036                           void *data)
1037 {
1038         tprintf("%" PRIu64, *(uint64_t *) elem_buf);
1039
1040         return true;
1041 }
1042
1043 /*
1044  * Iteratively fetch and print up to nmemb elements of elem_size size
1045  * from the array that starts at tracee's address start_addr.
1046  *
1047  * Array elements are being fetched to the address specified by elem_buf.
1048  *
1049  * The fetcher callback function specified by umoven_func should follow
1050  * the same semantics as umoven_or_printaddr function.
1051  *
1052  * The printer callback function specified by print_func is expected
1053  * to print something; if it returns false, no more iterations will be made.
1054  *
1055  * The pointer specified by opaque_data is passed to each invocation
1056  * of print_func callback function.
1057  *
1058  * This function prints:
1059  * - "NULL", if start_addr is NULL;
1060  * - "[]", if nmemb is 0;
1061  * - start_addr, if nmemb * elem_size overflows or wraps around;
1062  * - nothing, if the first element cannot be fetched
1063  *   (if umoven_func returns non-zero), but it is assumed that
1064  *   umoven_func has printed the address it failed to fetch data from;
1065  * - elements of the array, delimited by ", ", with the array itself
1066  *   enclosed with [] brackets.
1067  *
1068  * If abbrev(tcp) is true, then
1069  * - the maximum number of elements printed equals to max_strlen;
1070  * - "..." is printed instead of max_strlen+1 element
1071  *   and no more iterations will be made.
1072  *
1073  * This function returns true only if
1074  * - umoven_func has been called at least once AND
1075  * - umoven_func has not returned false.
1076  */
1077 bool
1078 print_array(struct tcb *const tcp,
1079             const kernel_ulong_t start_addr,
1080             const size_t nmemb,
1081             void *const elem_buf,
1082             const size_t elem_size,
1083             int (*const umoven_func)(struct tcb *,
1084                                      kernel_ulong_t,
1085                                      unsigned int,
1086                                      void *),
1087             bool (*const print_func)(struct tcb *,
1088                                      void *elem_buf,
1089                                      size_t elem_size,
1090                                      void *opaque_data),
1091             void *const opaque_data)
1092 {
1093         if (!start_addr) {
1094                 tprints("NULL");
1095                 return false;
1096         }
1097
1098         if (!nmemb) {
1099                 tprints("[]");
1100                 return false;
1101         }
1102
1103         const size_t size = nmemb * elem_size;
1104         const kernel_ulong_t end_addr = start_addr + size;
1105
1106         if (end_addr <= start_addr || size / elem_size != nmemb) {
1107                 printaddr(start_addr);
1108                 return false;
1109         }
1110
1111         const kernel_ulong_t abbrev_end =
1112                 (abbrev(tcp) && max_strlen < nmemb) ?
1113                         start_addr + elem_size * max_strlen : end_addr;
1114         kernel_ulong_t cur;
1115
1116         for (cur = start_addr; cur < end_addr; cur += elem_size) {
1117                 if (cur != start_addr)
1118                         tprints(", ");
1119
1120                 if (umoven_func(tcp, cur, elem_size, elem_buf))
1121                         break;
1122
1123                 if (cur == start_addr)
1124                         tprints("[");
1125
1126                 if (cur >= abbrev_end) {
1127                         tprints("...");
1128                         cur = end_addr;
1129                         break;
1130                 }
1131
1132                 if (!print_func(tcp, elem_buf, elem_size, opaque_data)) {
1133                         cur = end_addr;
1134                         break;
1135                 }
1136         }
1137         if (cur != start_addr)
1138                 tprints("]");
1139
1140         return cur >= end_addr;
1141 }
1142
1143 int
1144 printargs(struct tcb *tcp)
1145 {
1146         const int n = tcp->s_ent->nargs;
1147         int i;
1148         for (i = 0; i < n; ++i)
1149                 tprintf("%s%#" PRI_klx, i ? ", " : "", tcp->u_arg[i]);
1150         return RVAL_DECODED;
1151 }
1152
1153 int
1154 printargs_u(struct tcb *tcp)
1155 {
1156         const int n = tcp->s_ent->nargs;
1157         int i;
1158         for (i = 0; i < n; ++i)
1159                 tprintf("%s%u", i ? ", " : "",
1160                         (unsigned int) tcp->u_arg[i]);
1161         return RVAL_DECODED;
1162 }
1163
1164 int
1165 printargs_d(struct tcb *tcp)
1166 {
1167         const int n = tcp->s_ent->nargs;
1168         int i;
1169         for (i = 0; i < n; ++i)
1170                 tprintf("%s%d", i ? ", " : "",
1171                         (int) tcp->u_arg[i]);
1172         return RVAL_DECODED;
1173 }
1174
1175 /* Print abnormal high bits of a kernel_ulong_t value. */
1176 void
1177 print_abnormal_hi(const kernel_ulong_t val)
1178 {
1179         if (current_klongsize > 4) {
1180                 const unsigned int hi = (unsigned int) ((uint64_t) val >> 32);
1181                 if (hi)
1182                         tprintf("%#x<<32|", hi);
1183         }
1184 }
1185
1186 #if defined _LARGEFILE64_SOURCE && defined HAVE_OPEN64
1187 # define open_file open64
1188 #else
1189 # define open_file open
1190 #endif
1191
1192 int
1193 read_int_from_file(struct tcb *tcp, const char *const fname, int *const pvalue)
1194 {
1195         const int fd = open_file(fname, O_RDONLY);
1196         if (fd < 0)
1197                 return -1;
1198
1199         long lval;
1200         char buf[sizeof(lval) * 3];
1201         int n = read(fd, buf, sizeof(buf) - 1);
1202         int saved_errno = errno;
1203         close(fd);
1204
1205         if (n < 0) {
1206                 errno = saved_errno;
1207                 return -1;
1208         }
1209
1210         buf[n] = '\0';
1211         char *endptr = 0;
1212         errno = 0;
1213         lval = strtol(buf, &endptr, 10);
1214         if (!endptr || (*endptr && '\n' != *endptr)
1215 #if INT_MAX < LONG_MAX
1216             || lval > INT_MAX || lval < INT_MIN
1217 #endif
1218             || ERANGE == errno) {
1219                 if (!errno)
1220                         errno = EINVAL;
1221                 return -1;
1222         }
1223
1224         *pvalue = (int) lval;
1225         return 0;
1226 }