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