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