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