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