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