]> granicus.if.org Git - strace/blob - util.c
struct tcb: make types of syscall arguments unsigned
[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  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include "defs.h"
35 #include <sys/param.h>
36 #include <fcntl.h>
37 #include <stdarg.h>
38 #ifdef HAVE_SYS_XATTR_H
39 # include <sys/xattr.h>
40 #endif
41 #include <sys/uio.h>
42
43 #include "regs.h"
44 #include "ptrace.h"
45
46 int
47 string_to_uint_ex(const char *const str, char **const endptr,
48                   const unsigned int max_val, const char *const accepted_ending)
49 {
50         char *end;
51         long val;
52
53         if (!*str)
54                 return -1;
55
56         errno = 0;
57         val = strtol(str, &end, 10);
58
59         if (str == end || val < 0 || (unsigned long) val > max_val
60             || (val == LONG_MAX && errno == ERANGE))
61                 return -1;
62
63         if (*end && (!accepted_ending || !strchr(accepted_ending, *end)))
64                 return -1;
65
66         if (endptr)
67                 *endptr = end;
68
69         return (int) val;
70 }
71
72 int
73 string_to_uint(const char *const str)
74 {
75         return string_to_uint_upto(str, INT_MAX);
76 }
77
78 int
79 tv_nz(const struct timeval *a)
80 {
81         return a->tv_sec || a->tv_usec;
82 }
83
84 int
85 tv_cmp(const struct timeval *a, const struct timeval *b)
86 {
87         if (a->tv_sec < b->tv_sec
88             || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
89                 return -1;
90         if (a->tv_sec > b->tv_sec
91             || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
92                 return 1;
93         return 0;
94 }
95
96 double
97 tv_float(const struct timeval *tv)
98 {
99         return tv->tv_sec + tv->tv_usec/1000000.0;
100 }
101
102 void
103 tv_add(struct timeval *tv, const struct timeval *a, const struct timeval *b)
104 {
105         tv->tv_sec = a->tv_sec + b->tv_sec;
106         tv->tv_usec = a->tv_usec + b->tv_usec;
107         if (tv->tv_usec >= 1000000) {
108                 tv->tv_sec++;
109                 tv->tv_usec -= 1000000;
110         }
111 }
112
113 void
114 tv_sub(struct timeval *tv, const struct timeval *a, const struct timeval *b)
115 {
116         tv->tv_sec = a->tv_sec - b->tv_sec;
117         tv->tv_usec = a->tv_usec - b->tv_usec;
118         if (((long) tv->tv_usec) < 0) {
119                 tv->tv_sec--;
120                 tv->tv_usec += 1000000;
121         }
122 }
123
124 void
125 tv_div(struct timeval *tv, const struct timeval *a, int n)
126 {
127         tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
128         tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
129         tv->tv_usec %= 1000000;
130 }
131
132 void
133 tv_mul(struct timeval *tv, const struct timeval *a, int n)
134 {
135         tv->tv_usec = a->tv_usec * n;
136         tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000;
137         tv->tv_usec %= 1000000;
138 }
139
140 const char *
141 xlookup(const struct xlat *xlat, const uint64_t val)
142 {
143         for (; xlat->str != NULL; xlat++)
144                 if (xlat->val == val)
145                         return xlat->str;
146         return NULL;
147 }
148
149 static int
150 xlat_bsearch_compare(const void *a, const void *b)
151 {
152         const uint64_t val1 = *(const uint64_t *) a;
153         const uint64_t val2 = ((const struct xlat *) b)->val;
154         return (val1 > val2) ? 1 : (val1 < val2) ? -1 : 0;
155 }
156
157 const char *
158 xlat_search(const struct xlat *xlat, const size_t nmemb, const uint64_t val)
159 {
160         const struct xlat *e =
161                 bsearch((const void*) &val,
162                         xlat, nmemb, sizeof(*xlat), xlat_bsearch_compare);
163
164         return e ? e->str : NULL;
165 }
166
167 #if !defined HAVE_STPCPY
168 char *
169 stpcpy(char *dst, const char *src)
170 {
171         while ((*dst = *src++) != '\0')
172                 dst++;
173         return dst;
174 }
175 #endif
176
177 /* Find a next bit which is set.
178  * Starts testing at cur_bit.
179  * Returns -1 if no more bits are set.
180  *
181  * We never touch bytes we don't need to.
182  * On big-endian, array is assumed to consist of
183  * current_wordsize wide words: for example, is current_wordsize is 4,
184  * the bytes are walked in 3,2,1,0, 7,6,5,4, 11,10,9,8 ... sequence.
185  * On little-endian machines, word size is immaterial.
186  */
187 int
188 next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_bits)
189 {
190         const unsigned endian = 1;
191         int little_endian = * (char *) (void *) &endian;
192
193         const uint8_t *array = bit_array;
194         unsigned pos = cur_bit / 8;
195         unsigned pos_xor_mask = little_endian ? 0 : current_wordsize-1;
196
197         for (;;) {
198                 uint8_t bitmask;
199                 uint8_t cur_byte;
200
201                 if (cur_bit >= size_bits)
202                         return -1;
203                 cur_byte = array[pos ^ pos_xor_mask];
204                 if (cur_byte == 0) {
205                         cur_bit = (cur_bit + 8) & (-8);
206                         pos++;
207                         continue;
208                 }
209                 bitmask = 1 << (cur_bit & 7);
210                 for (;;) {
211                         if (cur_byte & bitmask)
212                                 return cur_bit;
213                         cur_bit++;
214                         if (cur_bit >= size_bits)
215                                 return -1;
216                         bitmask <<= 1;
217                         /* This check *can't be* optimized out: */
218                         if (bitmask == 0)
219                                 break;
220                 }
221                 pos++;
222         }
223 }
224
225 /**
226  * Print entry in struct xlat table, if there.
227  *
228  * @param val  Value to search a literal representation for.
229  * @param dflt String (abbreviated in comment syntax) which should be emitted
230  *             if no appropriate xlat value has been found.
231  * @param xlat (And the following arguments) Pointers to arrays of xlat values.
232  *             The last argument should be NULL.
233  * @return     1 if appropriate xlat value has been found, 0 otherwise.
234  */
235 int
236 printxvals(const uint64_t val, const char *dflt, const struct xlat *xlat, ...)
237 {
238         va_list args;
239
240         va_start(args, xlat);
241         for (; xlat; xlat = va_arg(args, const struct xlat *)) {
242                 const char *str = xlookup(xlat, val);
243
244                 if (str) {
245                         tprints(str);
246                         va_end(args);
247                         return 1;
248                 }
249         }
250         /* No hits -- print raw # instead. */
251         tprintf("%#" PRIx64, val);
252         if (dflt)
253                 tprintf(" /* %s */", dflt);
254
255         va_end(args);
256
257         return 0;
258 }
259
260 /**
261  * Print entry in sorted struct xlat table, if it is there.
262  *
263  * @param xlat      Pointer to an array of xlat values (not terminated with
264  *                  XLAT_END).
265  * @param xlat_size Number of xlat elements present in array (usually ARRAY_SIZE
266  *                  if array is declared in the unit's scope and not
267  *                  terminated with XLAT_END).
268  * @param val       Value to search literal representation for.
269  * @param dflt      String (abbreviated in comment syntax) which should be
270  *                  emitted if no appropriate xlat value has been found.
271  * @return          1 if appropriate xlat value has been found, 0
272  *                  otherwise.
273  */
274 int
275 printxval_searchn(const struct xlat *xlat, size_t xlat_size, uint64_t val,
276         const char *dflt)
277 {
278         const char *s = xlat_search(xlat, xlat_size, val);
279
280         if (s) {
281                 tprints(s);
282                 return 1;
283         }
284
285         tprintf("%#" PRIx64, val);
286         if (dflt)
287                 tprintf(" /* %s */", dflt);
288
289         return 0;
290 }
291
292 /*
293  * Fetch 64bit argument at position arg_no and
294  * return the index of the next argument.
295  */
296 int
297 getllval(struct tcb *tcp, unsigned long long *val, int arg_no)
298 {
299 #if SIZEOF_LONG > 4 && SIZEOF_LONG == SIZEOF_LONG_LONG
300 # if SUPPORTED_PERSONALITIES > 1
301 #  ifdef X86_64
302         if (current_personality != 1) {
303 #  else
304         if (current_wordsize > 4) {
305 #  endif
306 # endif
307                 *val = tcp->u_arg[arg_no];
308                 arg_no++;
309 # if SUPPORTED_PERSONALITIES > 1
310         } else {
311 #  if defined(AARCH64) || defined(POWERPC64)
312                 /* Align arg_no to the next even number. */
313                 arg_no = (arg_no + 1) & 0xe;
314 #  endif /* AARCH64 || POWERPC64 */
315                 *val = LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
316                 arg_no += 2;
317         }
318 # endif /* SUPPORTED_PERSONALITIES > 1 */
319 #elif SIZEOF_LONG > 4
320 #  error Unsupported configuration: SIZEOF_LONG > 4 && SIZEOF_LONG_LONG > SIZEOF_LONG
321 #elif HAVE_STRUCT_TCB_EXT_ARG
322 # if SUPPORTED_PERSONALITIES > 1
323         if (current_personality == 1) {
324                 *val = LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
325                 arg_no += 2;
326         } else
327 # endif
328         {
329                 *val = tcp->ext_arg[arg_no];
330                 arg_no++;
331         }
332 #else
333 # if defined __ARM_EABI__ || \
334      defined LINUX_MIPSO32 || \
335      defined POWERPC || \
336      defined XTENSA
337         /* Align arg_no to the next even number. */
338         arg_no = (arg_no + 1) & 0xe;
339 # elif defined SH
340         /*
341          * The SH4 ABI does allow long longs in odd-numbered registers, but
342          * does not allow them to be split between registers and memory - and
343          * there are only four argument registers for normal functions.  As a
344          * result, pread, for example, takes an extra padding argument before
345          * the offset.  This was changed late in the 2.4 series (around 2.4.20).
346          */
347         if (arg_no == 3)
348                 arg_no++;
349 # endif /* __ARM_EABI__ || LINUX_MIPSO32 || POWERPC || XTENSA || SH */
350         *val = LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
351         arg_no += 2;
352 #endif
353
354         return arg_no;
355 }
356
357 /*
358  * Print 64bit argument at position arg_no and
359  * return the index of the next argument.
360  */
361 int
362 printllval(struct tcb *tcp, const char *format, int arg_no)
363 {
364         unsigned long long val = 0;
365
366         arg_no = getllval(tcp, &val, arg_no);
367         tprintf(format, val);
368         return arg_no;
369 }
370
371 /*
372  * Interpret `xlat' as an array of flags
373  * print the entries whose bits are on in `flags'
374  * return # of flags printed.
375  */
376 void
377 addflags(const struct xlat *xlat, uint64_t flags)
378 {
379         for (; xlat->str; xlat++) {
380                 if (xlat->val && (flags & xlat->val) == xlat->val) {
381                         tprintf("|%s", xlat->str);
382                         flags &= ~xlat->val;
383                 }
384         }
385         if (flags) {
386                 tprintf("|%#" PRIx64, flags);
387         }
388 }
389
390 /*
391  * Interpret `xlat' as an array of flags.
392  * Print to static string the entries whose bits are on in `flags'
393  * Return static string.
394  */
395 const char *
396 sprintflags(const char *prefix, const struct xlat *xlat, uint64_t flags)
397 {
398         static char outstr[1024];
399         char *outptr;
400         int found = 0;
401
402         outptr = stpcpy(outstr, prefix);
403
404         if (flags == 0 && xlat->val == 0 && xlat->str) {
405                 strcpy(outptr, xlat->str);
406                 return outstr;
407         }
408
409         for (; xlat->str; xlat++) {
410                 if (xlat->val && (flags & xlat->val) == xlat->val) {
411                         if (found)
412                                 *outptr++ = '|';
413                         outptr = stpcpy(outptr, xlat->str);
414                         found = 1;
415                         flags &= ~xlat->val;
416                         if (!flags)
417                                 break;
418                 }
419         }
420         if (flags) {
421                 if (found)
422                         *outptr++ = '|';
423                 outptr += sprintf(outptr, "%#" PRIx64, flags);
424         }
425
426         return outstr;
427 }
428
429 int
430 printflags64(const struct xlat *xlat, uint64_t flags, const char *dflt)
431 {
432         int n;
433         const char *sep;
434
435         if (flags == 0 && xlat->val == 0 && xlat->str) {
436                 tprints(xlat->str);
437                 return 1;
438         }
439
440         sep = "";
441         for (n = 0; xlat->str; xlat++) {
442                 if (xlat->val && (flags & xlat->val) == xlat->val) {
443                         tprintf("%s%s", sep, xlat->str);
444                         flags &= ~xlat->val;
445                         sep = "|";
446                         n++;
447                 }
448         }
449
450         if (n) {
451                 if (flags) {
452                         tprintf("%s%#" PRIx64, sep, flags);
453                         n++;
454                 }
455         } else {
456                 if (flags) {
457                         tprintf("%#" PRIx64, flags);
458                         if (dflt)
459                                 tprintf(" /* %s */", dflt);
460                 } else {
461                         if (dflt)
462                                 tprints("0");
463                 }
464         }
465
466         return n;
467 }
468
469 void
470 printaddr_ull(const unsigned long long addr)
471 {
472         if (!addr)
473                 tprints("NULL");
474         else
475                 tprintf("%#llx", addr);
476 }
477
478 #define DEF_PRINTNUM(name, type) \
479 bool                                                                    \
480 printnum_ ## name(struct tcb *tcp, const long addr, const char *fmt)    \
481 {                                                                       \
482         type num;                                                       \
483         if (umove_or_printaddr(tcp, addr, &num))                        \
484                 return false;                                           \
485         tprints("[");                                                   \
486         tprintf(fmt, num);                                              \
487         tprints("]");                                                   \
488         return true;                                                    \
489 }
490
491 #define DEF_PRINTPAIR(name, type) \
492 bool                                                                    \
493 printpair_ ## name(struct tcb *tcp, const long addr, const char *fmt)   \
494 {                                                                       \
495         type pair[2];                                                   \
496         if (umove_or_printaddr(tcp, addr, &pair))                       \
497                 return false;                                           \
498         tprints("[");                                                   \
499         tprintf(fmt, pair[0]);                                          \
500         tprints(", ");                                                  \
501         tprintf(fmt, pair[1]);                                          \
502         tprints("]");                                                   \
503         return true;                                                    \
504 }
505
506 DEF_PRINTNUM(int, int)
507 DEF_PRINTPAIR(int, int)
508 DEF_PRINTNUM(short, short)
509 DEF_PRINTNUM(int64, uint64_t)
510 DEF_PRINTPAIR(int64, uint64_t)
511
512 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
513 bool
514 printnum_long_int(struct tcb *tcp, const long addr,
515                   const char *fmt_long, const char *fmt_int)
516 {
517         if (current_wordsize > sizeof(int)) {
518                 return printnum_int64(tcp, addr, fmt_long);
519         } else {
520                 return printnum_int(tcp, addr, fmt_int);
521         }
522 }
523 #endif
524
525 const char *
526 sprinttime(time_t t)
527 {
528         struct tm *tmp;
529         static char buf[sizeof(int) * 3 * 6 + sizeof("+0000")];
530
531         if (t == 0) {
532                 strcpy(buf, "0");
533                 return buf;
534         }
535         tmp = localtime(&t);
536         if (tmp)
537                 strftime(buf, sizeof(buf), "%FT%T%z", tmp);
538         else
539                 snprintf(buf, sizeof(buf), "%lu", (unsigned long) t);
540
541         return buf;
542 }
543
544 enum sock_proto
545 getfdproto(struct tcb *tcp, int fd)
546 {
547 #ifdef HAVE_SYS_XATTR_H
548         size_t bufsize = 256;
549         char buf[bufsize];
550         ssize_t r;
551         char path[sizeof("/proc/%u/fd/%u") + 2 * sizeof(int)*3];
552
553         if (fd < 0)
554                 return SOCK_PROTO_UNKNOWN;
555
556         sprintf(path, "/proc/%u/fd/%u", tcp->pid, fd);
557         r = getxattr(path, "system.sockprotoname", buf, bufsize - 1);
558         if (r <= 0)
559                 return SOCK_PROTO_UNKNOWN;
560         else {
561                 /*
562                  * This is a protection for the case when the kernel
563                  * side does not append a null byte to the buffer.
564                  */
565                 buf[r] = '\0';
566
567                 return get_proto_by_name(buf);
568         }
569 #else
570         return SOCK_PROTO_UNKNOWN;
571 #endif
572 }
573
574 void
575 printfd(struct tcb *tcp, int fd)
576 {
577         char path[PATH_MAX + 1];
578         if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
579                 static const char socket_prefix[] = "socket:[";
580                 const size_t socket_prefix_len = sizeof(socket_prefix) - 1;
581                 const size_t path_len = strlen(path);
582
583                 tprintf("%d<", fd);
584                 if (show_fd_path > 1 &&
585                     strncmp(path, socket_prefix, socket_prefix_len) == 0 &&
586                     path[path_len - 1] == ']') {
587                         unsigned long inode =
588                                 strtoul(path + socket_prefix_len, NULL, 10);
589
590                         if (!print_sockaddr_by_inode_cached(inode)) {
591                                 const enum sock_proto proto =
592                                         getfdproto(tcp, fd);
593                                 if (!print_sockaddr_by_inode(inode, proto))
594                                         tprints(path);
595                         }
596                 } else {
597                         print_quoted_string(path, path_len,
598                                             QUOTE_OMIT_LEADING_TRAILING_QUOTES);
599                 }
600                 tprints(">");
601         } else
602                 tprintf("%d", fd);
603 }
604
605 /*
606  * Quote string `instr' of length `size'
607  * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
608  *
609  * If QUOTE_0_TERMINATED `style' flag is set,
610  * treat `instr' as a NUL-terminated string,
611  * checking up to (`size' + 1) bytes of `instr'.
612  *
613  * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
614  * do not add leading and trailing quoting symbols.
615  *
616  * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
617  * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
618  */
619 int
620 string_quote(const char *instr, char *outstr, const unsigned int size,
621              const unsigned int style)
622 {
623         const unsigned char *ustr = (const unsigned char *) instr;
624         char *s = outstr;
625         unsigned int i;
626         int usehex, c, eol;
627
628         if (style & QUOTE_0_TERMINATED)
629                 eol = '\0';
630         else
631                 eol = 0x100; /* this can never match a char */
632
633         usehex = 0;
634         if (xflag > 1)
635                 usehex = 1;
636         else if (xflag) {
637                 /* Check for presence of symbol which require
638                    to hex-quote the whole string. */
639                 for (i = 0; i < size; ++i) {
640                         c = ustr[i];
641                         /* Check for NUL-terminated string. */
642                         if (c == eol)
643                                 break;
644
645                         /* Force hex unless c is printable or whitespace */
646                         if (c > 0x7e) {
647                                 usehex = 1;
648                                 break;
649                         }
650                         /* In ASCII isspace is only these chars: "\t\n\v\f\r".
651                          * They happen to have ASCII codes 9,10,11,12,13.
652                          */
653                         if (c < ' ' && (unsigned)(c - 9) >= 5) {
654                                 usehex = 1;
655                                 break;
656                         }
657                 }
658         }
659
660         if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
661                 *s++ = '\"';
662
663         if (usehex) {
664                 /* Hex-quote the whole string. */
665                 for (i = 0; i < size; ++i) {
666                         c = ustr[i];
667                         /* Check for NUL-terminated string. */
668                         if (c == eol)
669                                 goto asciz_ended;
670                         *s++ = '\\';
671                         *s++ = 'x';
672                         *s++ = "0123456789abcdef"[c >> 4];
673                         *s++ = "0123456789abcdef"[c & 0xf];
674                 }
675         } else {
676                 for (i = 0; i < size; ++i) {
677                         c = ustr[i];
678                         /* Check for NUL-terminated string. */
679                         if (c == eol)
680                                 goto asciz_ended;
681                         if ((i == (size - 1)) &&
682                             (style & QUOTE_OMIT_TRAILING_0) && (c == '\0'))
683                                 goto asciz_ended;
684                         switch (c) {
685                                 case '\"': case '\\':
686                                         *s++ = '\\';
687                                         *s++ = c;
688                                         break;
689                                 case '\f':
690                                         *s++ = '\\';
691                                         *s++ = 'f';
692                                         break;
693                                 case '\n':
694                                         *s++ = '\\';
695                                         *s++ = 'n';
696                                         break;
697                                 case '\r':
698                                         *s++ = '\\';
699                                         *s++ = 'r';
700                                         break;
701                                 case '\t':
702                                         *s++ = '\\';
703                                         *s++ = 't';
704                                         break;
705                                 case '\v':
706                                         *s++ = '\\';
707                                         *s++ = 'v';
708                                         break;
709                                 default:
710                                         if (c >= ' ' && c <= 0x7e)
711                                                 *s++ = c;
712                                         else {
713                                                 /* Print \octal */
714                                                 *s++ = '\\';
715                                                 if (i + 1 < size
716                                                     && ustr[i + 1] >= '0'
717                                                     && ustr[i + 1] <= '9'
718                                                 ) {
719                                                         /* Print \ooo */
720                                                         *s++ = '0' + (c >> 6);
721                                                         *s++ = '0' + ((c >> 3) & 0x7);
722                                                 } else {
723                                                         /* Print \[[o]o]o */
724                                                         if ((c >> 3) != 0) {
725                                                                 if ((c >> 6) != 0)
726                                                                         *s++ = '0' + (c >> 6);
727                                                                 *s++ = '0' + ((c >> 3) & 0x7);
728                                                         }
729                                                 }
730                                                 *s++ = '0' + (c & 0x7);
731                                         }
732                                         break;
733                         }
734                 }
735         }
736
737         if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
738                 *s++ = '\"';
739         *s = '\0';
740
741         /* Return zero if we printed entire ASCIZ string (didn't truncate it) */
742         if (style & QUOTE_0_TERMINATED && ustr[i] == '\0') {
743                 /* We didn't see NUL yet (otherwise we'd jump to 'asciz_ended')
744                  * but next char is NUL.
745                  */
746                 return 0;
747         }
748
749         return 1;
750
751  asciz_ended:
752         if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
753                 *s++ = '\"';
754         *s = '\0';
755         /* Return zero: we printed entire ASCIZ string (didn't truncate it) */
756         return 0;
757 }
758
759 #ifndef ALLOCA_CUTOFF
760 # define ALLOCA_CUTOFF  4032
761 #endif
762 #define use_alloca(n) ((n) <= ALLOCA_CUTOFF)
763
764 /*
765  * Quote string `str' of length `size' and print the result.
766  *
767  * If QUOTE_0_TERMINATED `style' flag is set,
768  * treat `str' as a NUL-terminated string and
769  * quote at most (`size' - 1) bytes.
770  *
771  * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
772  * do not add leading and trailing quoting symbols.
773  *
774  * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
775  * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
776  */
777 int
778 print_quoted_string(const char *str, unsigned int size,
779                     const unsigned int style)
780 {
781         char *buf;
782         char *outstr;
783         unsigned int alloc_size;
784         int rc;
785
786         if (size && style & QUOTE_0_TERMINATED)
787                 --size;
788
789         alloc_size = 4 * size;
790         if (alloc_size / 4 != size) {
791                 error_msg("Out of memory");
792                 tprints("???");
793                 return -1;
794         }
795         alloc_size += 1 + (style & QUOTE_OMIT_LEADING_TRAILING_QUOTES ? 0 : 2);
796
797         if (use_alloca(alloc_size)) {
798                 outstr = alloca(alloc_size);
799                 buf = NULL;
800         } else {
801                 outstr = buf = malloc(alloc_size);
802                 if (!buf) {
803                         error_msg("Out of memory");
804                         tprints("???");
805                         return -1;
806                 }
807         }
808
809         rc = string_quote(str, outstr, size, style);
810         tprints(outstr);
811
812         free(buf);
813         return rc;
814 }
815
816 /*
817  * Print path string specified by address `addr' and length `n'.
818  * If path length exceeds `n', append `...' to the output.
819  */
820 void
821 printpathn(struct tcb *tcp, long addr, unsigned int n)
822 {
823         char path[PATH_MAX + 1];
824         int nul_seen;
825
826         if (!addr) {
827                 tprints("NULL");
828                 return;
829         }
830
831         /* Cap path length to the path buffer size */
832         if (n > sizeof path - 1)
833                 n = sizeof path - 1;
834
835         /* Fetch one byte more to find out whether path length > n. */
836         nul_seen = umovestr(tcp, addr, n + 1, path);
837         if (nul_seen < 0)
838                 printaddr(addr);
839         else {
840                 path[n++] = '\0';
841                 print_quoted_string(path, n, QUOTE_0_TERMINATED);
842                 if (!nul_seen)
843                         tprints("...");
844         }
845 }
846
847 void
848 printpath(struct tcb *tcp, long addr)
849 {
850         /* Size must correspond to char path[] size in printpathn */
851         printpathn(tcp, addr, PATH_MAX);
852 }
853
854 /*
855  * Print string specified by address `addr' and length `len'.
856  * If `len' == -1, set QUOTE_0_TERMINATED bit in `user_style'.
857  * If `user_style' has QUOTE_0_TERMINATED bit set, treat the string
858  * as a NUL-terminated string.
859  * Pass `user_style' on to `string_quote'.
860  * Append `...' to the output if either the string length exceeds `max_strlen',
861  * or `len' != -1 and the string length exceeds `len'.
862  */
863 void
864 printstr_ex(struct tcb *tcp, long addr, long len, unsigned int user_style)
865 {
866         static char *str = NULL;
867         static char *outstr;
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;
876         }
877         /* Allocate static buffers if they are not allocated yet. */
878         if (!str) {
879                 unsigned int outstr_size = 4 * max_strlen + /*for quotes and NUL:*/ 3;
880
881                 if (outstr_size / 4 != max_strlen)
882                         die_out_of_memory();
883                 str = xmalloc(max_strlen + 1);
884                 outstr = xmalloc(outstr_size);
885         }
886
887         size = max_strlen + 1;
888         if (len == -1) {
889                 /*
890                  * Treat as a NUL-terminated string: fetch one byte more
891                  * because string_quote may look one byte ahead.
892                  */
893                 style |= QUOTE_0_TERMINATED;
894                 rc = umovestr(tcp, addr, size, str);
895         } else {
896                 if (size > (unsigned long) len)
897                         size = (unsigned long) len;
898                 if (style & QUOTE_0_TERMINATED)
899                         rc = umovestr(tcp, addr, size, str);
900                 else
901                         rc = umoven(tcp, addr, size, str);
902         }
903         if (rc < 0) {
904                 printaddr(addr);
905                 return;
906         }
907
908         if (size > max_strlen)
909                 size = max_strlen;
910         else
911                 str[size] = '\xff';
912
913         /* If string_quote didn't see NUL and (it was supposed to be ASCIZ str
914          * or we were requested to print more than -s NUM chars)...
915          */
916         ellipsis = string_quote(str, outstr, size, style)
917                    && len
918                    && ((style & QUOTE_0_TERMINATED)
919                        || (unsigned long) len > max_strlen);
920
921         tprints(outstr);
922         if (ellipsis)
923                 tprints("...");
924 }
925
926 void
927 dumpiov_upto(struct tcb *tcp, int len, long addr, unsigned long data_size)
928 {
929 #if SUPPORTED_PERSONALITIES > 1
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 ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64))
937 #define iov_iov_base(i) \
938         (current_wordsize == 4 ? (uint64_t) iovu.iov32[i].base : iovu.iov64[i].base)
939 #define iov_iov_len(i) \
940         (current_wordsize == 4 ? (uint64_t) iovu.iov32[i].len : iovu.iov64[i].len)
941 #else
942         struct iovec *iov;
943 #define sizeof_iov sizeof(*iov)
944 #define iov_iov_base(i) iov[i].iov_base
945 #define iov_iov_len(i) iov[i].iov_len
946 #endif
947         int i;
948         unsigned size;
949
950         size = sizeof_iov * len;
951         /* Assuming no sane program has millions of iovs */
952         if ((unsigned)len > 1024*1024 /* insane or negative size? */
953             || (iov = malloc(size)) == NULL) {
954                 error_msg("Out of memory");
955                 return;
956         }
957         if (umoven(tcp, addr, size, iov) >= 0) {
958                 for (i = 0; i < len; i++) {
959                         unsigned long iov_len = iov_iov_len(i);
960                         if (iov_len > data_size)
961                                 iov_len = data_size;
962                         if (!iov_len)
963                                 break;
964                         data_size -= iov_len;
965                         /* include the buffer number to make it easy to
966                          * match up the trace with the source */
967                         tprintf(" * %lu bytes in buffer %d\n", iov_len, i);
968                         dumpstr(tcp, (long) iov_iov_base(i), iov_len);
969                 }
970         }
971         free(iov);
972 #undef sizeof_iov
973 #undef iov_iov_base
974 #undef iov_iov_len
975 #undef iov
976 }
977
978 void
979 dumpstr(struct tcb *tcp, long addr, int len)
980 {
981         static int strsize = -1;
982         static unsigned char *str;
983
984         char outbuf[
985                 (
986                         (sizeof(
987                         "xx xx xx xx xx xx xx xx  xx xx xx xx xx xx xx xx  "
988                         "1234567890123456") + /*in case I'm off by few:*/ 4)
989                 /*align to 8 to make memset easier:*/ + 7) & -8
990         ];
991         const unsigned char *src;
992         int i;
993
994         memset(outbuf, ' ', sizeof(outbuf));
995
996         if (strsize < len + 16) {
997                 free(str);
998                 str = malloc(len + 16);
999                 if (!str) {
1000                         strsize = -1;
1001                         error_msg("Out of memory");
1002                         return;
1003                 }
1004                 strsize = len + 16;
1005         }
1006
1007         if (umoven(tcp, addr, len, str) < 0)
1008                 return;
1009
1010         /* Space-pad to 16 bytes */
1011         i = len;
1012         while (i & 0xf)
1013                 str[i++] = ' ';
1014
1015         i = 0;
1016         src = str;
1017         while (i < len) {
1018                 char *dst = outbuf;
1019                 /* Hex dump */
1020                 do {
1021                         if (i < len) {
1022                                 *dst++ = "0123456789abcdef"[*src >> 4];
1023                                 *dst++ = "0123456789abcdef"[*src & 0xf];
1024                         }
1025                         else {
1026                                 *dst++ = ' ';
1027                                 *dst++ = ' ';
1028                         }
1029                         dst++; /* space is there by memset */
1030                         i++;
1031                         if ((i & 7) == 0)
1032                                 dst++; /* space is there by memset */
1033                         src++;
1034                 } while (i & 0xf);
1035                 /* ASCII dump */
1036                 i -= 16;
1037                 src -= 16;
1038                 do {
1039                         if (*src >= ' ' && *src < 0x7f)
1040                                 *dst++ = *src;
1041                         else
1042                                 *dst++ = '.';
1043                         src++;
1044                 } while (++i & 0xf);
1045                 *dst = '\0';
1046                 tprintf(" | %05x  %s |\n", i - 16, outbuf);
1047         }
1048 }
1049
1050 #ifdef HAVE_PROCESS_VM_READV
1051 /* C library supports this, but the kernel might not. */
1052 static bool process_vm_readv_not_supported = 0;
1053 #else
1054
1055 /* Need to do this since process_vm_readv() is not yet available in libc.
1056  * When libc is be updated, only "static bool process_vm_readv_not_supported"
1057  * line should remain.
1058  */
1059 #if !defined(__NR_process_vm_readv)
1060 # if defined(I386)
1061 #  define __NR_process_vm_readv  347
1062 # elif defined(X86_64)
1063 #  define __NR_process_vm_readv  310
1064 # elif defined(POWERPC)
1065 #  define __NR_process_vm_readv  351
1066 # endif
1067 #endif
1068
1069 #if defined(__NR_process_vm_readv)
1070 static bool process_vm_readv_not_supported = 0;
1071 /* Have to avoid duplicating with the C library headers. */
1072 static ssize_t strace_process_vm_readv(pid_t pid,
1073                  const struct iovec *lvec,
1074                  unsigned long liovcnt,
1075                  const struct iovec *rvec,
1076                  unsigned long riovcnt,
1077                  unsigned long flags)
1078 {
1079         return syscall(__NR_process_vm_readv, (long)pid, lvec, liovcnt, rvec, riovcnt, flags);
1080 }
1081 #define process_vm_readv strace_process_vm_readv
1082 #else
1083 static bool process_vm_readv_not_supported = 1;
1084 # define process_vm_readv(...) (errno = ENOSYS, -1)
1085 #endif
1086
1087 #endif /* end of hack */
1088
1089 static ssize_t
1090 vm_read_mem(pid_t pid, void *laddr, long raddr, size_t len)
1091 {
1092         const struct iovec local = {
1093                 .iov_base = laddr,
1094                 .iov_len = len
1095         };
1096         const struct iovec remote = {
1097                 .iov_base = (void *) raddr,
1098                 .iov_len = len
1099         };
1100
1101         return process_vm_readv(pid, &local, 1, &remote, 1, 0);
1102 }
1103
1104 /*
1105  * move `len' bytes of data from process `pid'
1106  * at address `addr' to our space at `our_addr'
1107  */
1108 int
1109 umoven(struct tcb *tcp, long addr, unsigned int len, void *our_addr)
1110 {
1111         char *laddr = our_addr;
1112         int pid = tcp->pid;
1113         unsigned int n, m, nread;
1114         union {
1115                 long val;
1116                 char x[sizeof(long)];
1117         } u;
1118
1119 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
1120         if (current_wordsize < sizeof(addr))
1121                 addr &= (1ul << 8 * current_wordsize) - 1;
1122 #endif
1123
1124         if (!process_vm_readv_not_supported) {
1125                 int r = vm_read_mem(pid, laddr, addr, len);
1126                 if ((unsigned int) r == len)
1127                         return 0;
1128                 if (r >= 0) {
1129                         error_msg("umoven: short read (%u < %u) @0x%lx",
1130                                   (unsigned int) r, len, addr);
1131                         return -1;
1132                 }
1133                 switch (errno) {
1134                         case ENOSYS:
1135                                 process_vm_readv_not_supported = 1;
1136                                 break;
1137                         case EPERM:
1138                                 /* operation not permitted, try PTRACE_PEEKDATA */
1139                                 break;
1140                         case ESRCH:
1141                                 /* the process is gone */
1142                                 return -1;
1143                         case EFAULT: case EIO:
1144                                 /* address space is inaccessible */
1145                                 return -1;
1146                         default:
1147                                 /* all the rest is strange and should be reported */
1148                                 perror_msg("process_vm_readv");
1149                                 return -1;
1150                 }
1151         }
1152
1153         nread = 0;
1154         if (addr & (sizeof(long) - 1)) {
1155                 /* addr not a multiple of sizeof(long) */
1156                 n = addr & (sizeof(long) - 1);  /* residue */
1157                 addr &= -sizeof(long);          /* aligned address */
1158                 errno = 0;
1159                 u.val = ptrace(PTRACE_PEEKDATA, pid, (void *) addr, 0);
1160                 switch (errno) {
1161                         case 0:
1162                                 break;
1163                         case ESRCH: case EINVAL:
1164                                 /* these could be seen if the process is gone */
1165                                 return -1;
1166                         case EFAULT: case EIO: case EPERM:
1167                                 /* address space is inaccessible */
1168                                 return -1;
1169                         default:
1170                                 /* all the rest is strange and should be reported */
1171                                 perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%lx",
1172                                             pid, addr);
1173                                 return -1;
1174                 }
1175                 m = MIN(sizeof(long) - n, len);
1176                 memcpy(laddr, &u.x[n], m);
1177                 addr += sizeof(long);
1178                 laddr += m;
1179                 nread += m;
1180                 len -= m;
1181         }
1182         while (len) {
1183                 errno = 0;
1184                 u.val = ptrace(PTRACE_PEEKDATA, pid, (void *) addr, 0);
1185                 switch (errno) {
1186                         case 0:
1187                                 break;
1188                         case ESRCH: case EINVAL:
1189                                 /* these could be seen if the process is gone */
1190                                 return -1;
1191                         case EFAULT: case EIO: case EPERM:
1192                                 /* address space is inaccessible */
1193                                 if (nread) {
1194                                         perror_msg("umoven: short read (%u < %u) @0x%lx",
1195                                                    nread, nread + len, addr - nread);
1196                                 }
1197                                 return -1;
1198                         default:
1199                                 /* all the rest is strange and should be reported */
1200                                 perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%lx",
1201                                             pid, addr);
1202                                 return -1;
1203                 }
1204                 m = MIN(sizeof(long), len);
1205                 memcpy(laddr, u.x, m);
1206                 addr += sizeof(long);
1207                 laddr += m;
1208                 nread += m;
1209                 len -= m;
1210         }
1211
1212         return 0;
1213 }
1214
1215 int
1216 umoven_or_printaddr(struct tcb *tcp, const long addr, const unsigned int len,
1217                     void *our_addr)
1218 {
1219         if (!addr || !verbose(tcp) || (exiting(tcp) && syserror(tcp)) ||
1220             umoven(tcp, addr, len, our_addr) < 0) {
1221                 printaddr(addr);
1222                 return -1;
1223         }
1224         return 0;
1225 }
1226
1227 int
1228 umoven_or_printaddr_ignore_syserror(struct tcb *tcp, const long addr,
1229                                     const unsigned int len, void *our_addr)
1230 {
1231         if (!addr || !verbose(tcp) || umoven(tcp, addr, len, our_addr) < 0) {
1232                 printaddr(addr);
1233                 return -1;
1234         }
1235         return 0;
1236 }
1237
1238 /*
1239  * Like `umove' but make the additional effort of looking
1240  * for a terminating zero byte.
1241  *
1242  * Returns < 0 on error, > 0 if NUL was seen,
1243  * (TODO if useful: return count of bytes including NUL),
1244  * else 0 if len bytes were read but no NUL byte seen.
1245  *
1246  * Note: there is no guarantee we won't overwrite some bytes
1247  * in laddr[] _after_ terminating NUL (but, of course,
1248  * we never write past laddr[len-1]).
1249  */
1250 int
1251 umovestr(struct tcb *tcp, long addr, unsigned int len, char *laddr)
1252 {
1253         const unsigned long x01010101 = (unsigned long) 0x0101010101010101ULL;
1254         const unsigned long x80808080 = (unsigned long) 0x8080808080808080ULL;
1255
1256         int pid = tcp->pid;
1257         unsigned int n, m, nread;
1258         union {
1259                 unsigned long val;
1260                 char x[sizeof(long)];
1261         } u;
1262
1263 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
1264         if (current_wordsize < sizeof(addr))
1265                 addr &= (1ul << 8 * current_wordsize) - 1;
1266 #endif
1267
1268         nread = 0;
1269         if (!process_vm_readv_not_supported) {
1270                 const size_t page_size = get_pagesize();
1271                 const size_t page_mask = page_size - 1;
1272
1273                 while (len > 0) {
1274                         unsigned int chunk_len;
1275                         unsigned int end_in_page;
1276
1277                         /*
1278                          * Don't cross pages, otherwise we can get EFAULT
1279                          * and fail to notice that terminating NUL lies
1280                          * in the existing (first) page.
1281                          */
1282                         chunk_len = len > page_size ? page_size : len;
1283                         end_in_page = (addr + chunk_len) & page_mask;
1284                         if (chunk_len > end_in_page) /* crosses to the next page */
1285                                 chunk_len -= end_in_page;
1286
1287                         int r = vm_read_mem(pid, laddr, addr, chunk_len);
1288                         if (r > 0) {
1289                                 if (memchr(laddr, '\0', r))
1290                                         return 1;
1291                                 addr += r;
1292                                 laddr += r;
1293                                 nread += r;
1294                                 len -= r;
1295                                 continue;
1296                         }
1297                         switch (errno) {
1298                                 case ENOSYS:
1299                                         process_vm_readv_not_supported = 1;
1300                                         goto vm_readv_didnt_work;
1301                                 case ESRCH:
1302                                         /* the process is gone */
1303                                         return -1;
1304                                 case EPERM:
1305                                         /* operation not permitted, try PTRACE_PEEKDATA */
1306                                         if (!nread)
1307                                                 goto vm_readv_didnt_work;
1308                                         /* fall through */
1309                                 case EFAULT: case EIO:
1310                                         /* address space is inaccessible */
1311                                         if (nread) {
1312                                                 perror_msg("umovestr: short read (%d < %d) @0x%lx",
1313                                                            nread, nread + len, addr - nread);
1314                                         }
1315                                         return -1;
1316                                 default:
1317                                         /* all the rest is strange and should be reported */
1318                                         perror_msg("process_vm_readv");
1319                                         return -1;
1320                         }
1321                 }
1322                 return 0;
1323         }
1324  vm_readv_didnt_work:
1325
1326         if (addr & (sizeof(long) - 1)) {
1327                 /* addr not a multiple of sizeof(long) */
1328                 n = addr & (sizeof(long) - 1);  /* residue */
1329                 addr &= -sizeof(long);          /* aligned address */
1330                 errno = 0;
1331                 u.val = ptrace(PTRACE_PEEKDATA, pid, (void *) addr, 0);
1332                 switch (errno) {
1333                         case 0:
1334                                 break;
1335                         case ESRCH: case EINVAL:
1336                                 /* these could be seen if the process is gone */
1337                                 return -1;
1338                         case EFAULT: case EIO: case EPERM:
1339                                 /* address space is inaccessible */
1340                                 return -1;
1341                         default:
1342                                 /* all the rest is strange and should be reported */
1343                                 perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%lx",
1344                                             pid, addr);
1345                                 return -1;
1346                 }
1347                 m = MIN(sizeof(long) - n, len);
1348                 memcpy(laddr, &u.x[n], m);
1349                 while (n & (sizeof(long) - 1))
1350                         if (u.x[n++] == '\0')
1351                                 return 1;
1352                 addr += sizeof(long);
1353                 laddr += m;
1354                 nread += m;
1355                 len -= m;
1356         }
1357
1358         while (len) {
1359                 errno = 0;
1360                 u.val = ptrace(PTRACE_PEEKDATA, pid, (void *) addr, 0);
1361                 switch (errno) {
1362                         case 0:
1363                                 break;
1364                         case ESRCH: case EINVAL:
1365                                 /* these could be seen if the process is gone */
1366                                 return -1;
1367                         case EFAULT: case EIO: case EPERM:
1368                                 /* address space is inaccessible */
1369                                 if (nread) {
1370                                         perror_msg("umovestr: short read (%d < %d) @0x%lx",
1371                                                    nread, nread + len, addr - nread);
1372                                 }
1373                                 return -1;
1374                         default:
1375                                 /* all the rest is strange and should be reported */
1376                                 perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%lx",
1377                                            pid, addr);
1378                                 return -1;
1379                 }
1380                 m = MIN(sizeof(long), len);
1381                 memcpy(laddr, u.x, m);
1382                 /* "If a NUL char exists in this word" */
1383                 if ((u.val - x01010101) & ~u.val & x80808080)
1384                         return 1;
1385                 addr += sizeof(long);
1386                 laddr += m;
1387                 nread += m;
1388                 len -= m;
1389         }
1390         return 0;
1391 }
1392
1393 /*
1394  * Iteratively fetch and print up to nmemb elements of elem_size size
1395  * from the array that starts at tracee's address start_addr.
1396  *
1397  * Array elements are being fetched to the address specified by elem_buf.
1398  *
1399  * The fetcher callback function specified by umoven_func should follow
1400  * the same semantics as umoven_or_printaddr function.
1401  *
1402  * The printer callback function specified by print_func is expected
1403  * to print something; if it returns false, no more iterations will be made.
1404  *
1405  * The pointer specified by opaque_data is passed to each invocation
1406  * of print_func callback function.
1407  *
1408  * This function prints:
1409  * - "NULL", if start_addr is NULL;
1410  * - "[]", if nmemb is 0;
1411  * - start_addr, if nmemb * elem_size overflows or wraps around;
1412  * - nothing, if the first element cannot be fetched
1413  *   (if umoven_func returns non-zero), but it is assumed that
1414  *   umoven_func has printed the address it failed to fetch data from;
1415  * - elements of the array, delimited by ", ", with the array itself
1416  *   enclosed with [] brackets.
1417  *
1418  * If abbrev(tcp) is true, then
1419  * - the maximum number of elements printed equals to max_strlen;
1420  * - "..." is printed instead of max_strlen+1 element
1421  *   and no more iterations will be made.
1422  *
1423  * This function returns true only if
1424  * - umoven_func has been called at least once AND
1425  * - umoven_func has not returned false.
1426  */
1427 bool
1428 print_array(struct tcb *tcp,
1429             const unsigned long start_addr,
1430             const size_t nmemb,
1431             void *const elem_buf,
1432             const size_t elem_size,
1433             int (*const umoven_func)(struct tcb *,
1434                                      long,
1435                                      unsigned int,
1436                                      void *),
1437             bool (*const print_func)(struct tcb *,
1438                                      void *elem_buf,
1439                                      size_t elem_size,
1440                                      void *opaque_data),
1441             void *const opaque_data)
1442 {
1443         if (!start_addr) {
1444                 tprints("NULL");
1445                 return false;
1446         }
1447
1448         if (!nmemb) {
1449                 tprints("[]");
1450                 return false;
1451         }
1452
1453         const size_t size = nmemb * elem_size;
1454         const unsigned long end_addr = start_addr + size;
1455
1456         if (end_addr <= start_addr || size / elem_size != nmemb) {
1457                 printaddr(start_addr);
1458                 return false;
1459         }
1460
1461         const unsigned long abbrev_end =
1462                 (abbrev(tcp) && max_strlen < nmemb) ?
1463                         start_addr + elem_size * max_strlen : end_addr;
1464         unsigned long cur;
1465
1466         for (cur = start_addr; cur < end_addr; cur += elem_size) {
1467                 if (cur != start_addr)
1468                         tprints(", ");
1469
1470                 if (umoven_func(tcp, cur, elem_size, elem_buf))
1471                         break;
1472
1473                 if (cur == start_addr)
1474                         tprints("[");
1475
1476                 if (cur >= abbrev_end) {
1477                         tprints("...");
1478                         cur = end_addr;
1479                         break;
1480                 }
1481
1482                 if (!print_func(tcp, elem_buf, elem_size, opaque_data)) {
1483                         cur = end_addr;
1484                         break;
1485                 }
1486         }
1487         if (cur != start_addr)
1488                 tprints("]");
1489
1490         return cur >= end_addr;
1491 }
1492
1493 long long
1494 getarg_ll(struct tcb *tcp, int argn)
1495 {
1496 #if HAVE_STRUCT_TCB_EXT_ARG
1497 # if SUPPORTED_PERSONALITIES > 1
1498         if (current_personality == 1)
1499                 return (long) tcp->u_arg[argn];
1500         else
1501 # endif
1502         return (long long) tcp->ext_arg[argn];
1503 #else
1504         return (long) tcp->u_arg[argn];
1505 #endif
1506 }
1507
1508 unsigned long long
1509 getarg_ull(struct tcb *tcp, int argn)
1510 {
1511 #if HAVE_STRUCT_TCB_EXT_ARG
1512 # if SUPPORTED_PERSONALITIES > 1
1513         if (current_personality == 1)
1514                 return tcp->u_arg[argn];
1515         else
1516 # endif
1517         return tcp->ext_arg[argn];
1518 #else
1519         return tcp->u_arg[argn];
1520 #endif
1521 }
1522
1523 int
1524 printargs(struct tcb *tcp)
1525 {
1526         const int n = tcp->s_ent->nargs;
1527         int i;
1528         for (i = 0; i < n; ++i)
1529                 tprintf("%s%#llx", i ? ", " : "", getarg_ull(tcp, i));
1530         return RVAL_DECODED;
1531 }
1532
1533 int
1534 printargs_u(struct tcb *tcp)
1535 {
1536         const int n = tcp->s_ent->nargs;
1537         int i;
1538         for (i = 0; i < n; ++i)
1539                 tprintf("%s%u", i ? ", " : "",
1540                         (unsigned int) tcp->u_arg[i]);
1541         return RVAL_DECODED;
1542 }
1543
1544 int
1545 printargs_d(struct tcb *tcp)
1546 {
1547         const int n = tcp->s_ent->nargs;
1548         int i;
1549         for (i = 0; i < n; ++i)
1550                 tprintf("%s%d", i ? ", " : "",
1551                         (int) tcp->u_arg[i]);
1552         return RVAL_DECODED;
1553 }
1554
1555 #if defined _LARGEFILE64_SOURCE && defined HAVE_OPEN64
1556 # define open_file open64
1557 #else
1558 # define open_file open
1559 #endif
1560
1561 int
1562 read_int_from_file(const char *const fname, int *const pvalue)
1563 {
1564         const int fd = open_file(fname, O_RDONLY);
1565         if (fd < 0)
1566                 return -1;
1567
1568         long lval;
1569         char buf[sizeof(lval) * 3];
1570         int n = read(fd, buf, sizeof(buf) - 1);
1571         int saved_errno = errno;
1572         close(fd);
1573
1574         if (n < 0) {
1575                 errno = saved_errno;
1576                 return -1;
1577         }
1578
1579         buf[n] = '\0';
1580         char *endptr = 0;
1581         errno = 0;
1582         lval = strtol(buf, &endptr, 10);
1583         if (!endptr || (*endptr && '\n' != *endptr)
1584 #if INT_MAX < LONG_MAX
1585             || lval > INT_MAX || lval < INT_MIN
1586 #endif
1587             || ERANGE == errno) {
1588                 if (!errno)
1589                         errno = EINVAL;
1590                 return -1;
1591         }
1592
1593         *pvalue = (int) lval;
1594         return 0;
1595 }