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