]> granicus.if.org Git - strace/blob - util.c
Fix compilation warnings reported by gcc -Wsign-compare
[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/user.h>
36 #include <sys/param.h>
37 #include <fcntl.h>
38 #if HAVE_SYS_UIO_H
39 # include <sys/uio.h>
40 #endif
41
42 #if defined(IA64)
43 # include <asm/ptrace_offsets.h>
44 # include <asm/rse.h>
45 #endif
46
47 #ifdef HAVE_SYS_REG_H
48 # include <sys/reg.h>
49 #elif defined(HAVE_LINUX_PTRACE_H)
50 # undef PTRACE_SYSCALL
51 # ifdef HAVE_STRUCT_IA64_FPREG
52 #  define ia64_fpreg XXX_ia64_fpreg
53 # endif
54 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
55 #  define pt_all_user_regs XXX_pt_all_user_regs
56 # endif
57 # ifdef HAVE_STRUCT_PTRACE_PEEKSIGINFO_ARGS
58 #  define ptrace_peeksiginfo_args XXX_ptrace_peeksiginfo_args
59 # endif
60 # include <linux/ptrace.h>
61 # undef ptrace_peeksiginfo_args
62 # undef ia64_fpreg
63 # undef pt_all_user_regs
64 #endif
65
66 int
67 string_to_uint(const char *str)
68 {
69         char *error;
70         long value;
71
72         if (!*str)
73                 return -1;
74         errno = 0;
75         value = strtol(str, &error, 10);
76         if (errno || *error || value < 0 || (long)(int)value != value)
77                 return -1;
78         return (int)value;
79 }
80
81 int
82 tv_nz(const struct timeval *a)
83 {
84         return a->tv_sec || a->tv_usec;
85 }
86
87 int
88 tv_cmp(const struct timeval *a, const struct timeval *b)
89 {
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         if (a->tv_sec > b->tv_sec
94             || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
95                 return 1;
96         return 0;
97 }
98
99 double
100 tv_float(const struct timeval *tv)
101 {
102         return tv->tv_sec + tv->tv_usec/1000000.0;
103 }
104
105 void
106 tv_add(struct timeval *tv, const struct timeval *a, const struct timeval *b)
107 {
108         tv->tv_sec = a->tv_sec + b->tv_sec;
109         tv->tv_usec = a->tv_usec + b->tv_usec;
110         if (tv->tv_usec >= 1000000) {
111                 tv->tv_sec++;
112                 tv->tv_usec -= 1000000;
113         }
114 }
115
116 void
117 tv_sub(struct timeval *tv, const struct timeval *a, const struct timeval *b)
118 {
119         tv->tv_sec = a->tv_sec - b->tv_sec;
120         tv->tv_usec = a->tv_usec - b->tv_usec;
121         if (((long) tv->tv_usec) < 0) {
122                 tv->tv_sec--;
123                 tv->tv_usec += 1000000;
124         }
125 }
126
127 void
128 tv_div(struct timeval *tv, const struct timeval *a, int n)
129 {
130         tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
131         tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
132         tv->tv_usec %= 1000000;
133 }
134
135 void
136 tv_mul(struct timeval *tv, const struct timeval *a, int n)
137 {
138         tv->tv_usec = a->tv_usec * n;
139         tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000;
140         tv->tv_usec %= 1000000;
141 }
142
143 const char *
144 xlookup(const struct xlat *xlat, const unsigned int val)
145 {
146         for (; xlat->str != NULL; xlat++)
147                 if (xlat->val == val)
148                         return xlat->str;
149         return NULL;
150 }
151
152 #if !defined HAVE_STPCPY
153 char *
154 stpcpy(char *dst, const char *src)
155 {
156         while ((*dst = *src++) != '\0')
157                 dst++;
158         return dst;
159 }
160 #endif
161
162 /* Find a next bit which is set.
163  * Starts testing at cur_bit.
164  * Returns -1 if no more bits are set.
165  *
166  * We never touch bytes we don't need to.
167  * On big-endian, array is assumed to consist of
168  * current_wordsize wide words: for example, is current_wordsize is 4,
169  * the bytes are walked in 3,2,1,0, 7,6,5,4, 11,10,9,8 ... sequence.
170  * On little-endian machines, word size is immaterial.
171  */
172 int
173 next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_bits)
174 {
175         const unsigned endian = 1;
176         int little_endian = *(char*)&endian;
177
178         const uint8_t *array = bit_array;
179         unsigned pos = cur_bit / 8;
180         unsigned pos_xor_mask = little_endian ? 0 : current_wordsize-1;
181
182         for (;;) {
183                 uint8_t bitmask;
184                 uint8_t cur_byte;
185
186                 if (cur_bit >= size_bits)
187                         return -1;
188                 cur_byte = array[pos ^ pos_xor_mask];
189                 if (cur_byte == 0) {
190                         cur_bit = (cur_bit + 8) & (-8);
191                         pos++;
192                         continue;
193                 }
194                 bitmask = 1 << (cur_bit & 7);
195                 for (;;) {
196                         if (cur_byte & bitmask)
197                                 return cur_bit;
198                         cur_bit++;
199                         if (cur_bit >= size_bits)
200                                 return -1;
201                         bitmask <<= 1;
202                         /* This check *can't be* optimized out: */
203                         if (bitmask == 0)
204                                 break;
205                 }
206                 pos++;
207         }
208 }
209 /*
210  * Print entry in struct xlat table, if there.
211  */
212 void
213 printxval(const struct xlat *xlat, const unsigned int val, const char *dflt)
214 {
215         const char *str = xlookup(xlat, val);
216
217         if (str)
218                 tprints(str);
219         else
220                 tprintf("%#x /* %s */", val, dflt);
221 }
222
223 /*
224  * Print 64bit argument at position arg_no and return the index of the next
225  * argument.
226  */
227 int
228 printllval(struct tcb *tcp, const char *format, int arg_no)
229 {
230 #if SIZEOF_LONG > 4 && SIZEOF_LONG == SIZEOF_LONG_LONG
231 # if SUPPORTED_PERSONALITIES > 1
232         if (current_wordsize > 4) {
233 # endif
234                 tprintf(format, tcp->u_arg[arg_no]);
235                 arg_no++;
236 # if SUPPORTED_PERSONALITIES > 1
237         } else {
238 #  if defined(AARCH64) || defined(POWERPC64)
239                 /* Align arg_no to the next even number. */
240                 arg_no = (arg_no + 1) & 0xe;
241 #  endif
242                 tprintf(format, LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]));
243                 arg_no += 2;
244         }
245 # endif /* SUPPORTED_PERSONALITIES */
246 #elif SIZEOF_LONG > 4
247 #  error Unsupported configuration: SIZEOF_LONG > 4 && SIZEOF_LONG_LONG > SIZEOF_LONG
248 #elif defined LINUX_MIPSN32
249         tprintf(format, tcp->ext_arg[arg_no]);
250         arg_no++;
251 #elif defined X32
252         if (current_personality == 0) {
253                 tprintf(format, tcp->ext_arg[arg_no]);
254                 arg_no++;
255         } else {
256                 tprintf(format, LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]));
257                 arg_no += 2;
258         }
259 #else
260 # if defined __ARM_EABI__ || \
261      defined LINUX_MIPSO32 || \
262      defined POWERPC || \
263      defined XTENSA
264         /* Align arg_no to the next even number. */
265         arg_no = (arg_no + 1) & 0xe;
266 # endif
267         tprintf(format, LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]));
268         arg_no += 2;
269 #endif
270
271         return arg_no;
272 }
273
274 /*
275  * Interpret `xlat' as an array of flags
276  * print the entries whose bits are on in `flags'
277  * return # of flags printed.
278  */
279 void
280 addflags(const struct xlat *xlat, int flags)
281 {
282         for (; xlat->str; xlat++) {
283                 if (xlat->val && (flags & xlat->val) == xlat->val) {
284                         tprintf("|%s", xlat->str);
285                         flags &= ~xlat->val;
286                 }
287         }
288         if (flags) {
289                 tprintf("|%#x", flags);
290         }
291 }
292
293 /*
294  * Interpret `xlat' as an array of flags.
295  * Print to static string the entries whose bits are on in `flags'
296  * Return static string.
297  */
298 const char *
299 sprintflags(const char *prefix, const struct xlat *xlat, int flags)
300 {
301         static char outstr[1024];
302         char *outptr;
303         int found = 0;
304
305         outptr = stpcpy(outstr, prefix);
306
307         for (; xlat->str; xlat++) {
308                 if ((flags & xlat->val) == xlat->val) {
309                         if (found)
310                                 *outptr++ = '|';
311                         outptr = stpcpy(outptr, xlat->str);
312                         found = 1;
313                         flags &= ~xlat->val;
314                         if (!flags)
315                                 break;
316                 }
317         }
318         if (flags) {
319                 if (found)
320                         *outptr++ = '|';
321                 outptr += sprintf(outptr, "%#x", flags);
322         }
323
324         return outstr;
325 }
326
327 int
328 printflags(const struct xlat *xlat, int flags, const char *dflt)
329 {
330         int n;
331         const char *sep;
332
333         if (flags == 0 && xlat->val == 0) {
334                 tprints(xlat->str);
335                 return 1;
336         }
337
338         sep = "";
339         for (n = 0; xlat->str; xlat++) {
340                 if (xlat->val && (flags & xlat->val) == xlat->val) {
341                         tprintf("%s%s", sep, xlat->str);
342                         flags &= ~xlat->val;
343                         sep = "|";
344                         n++;
345                 }
346         }
347
348         if (n) {
349                 if (flags) {
350                         tprintf("%s%#x", sep, flags);
351                         n++;
352                 }
353         } else {
354                 if (flags) {
355                         tprintf("%#x", flags);
356                         if (dflt)
357                                 tprintf(" /* %s */", dflt);
358                 } else {
359                         if (dflt)
360                                 tprints("0");
361                 }
362         }
363
364         return n;
365 }
366
367 void
368 printnum(struct tcb *tcp, long addr, const char *fmt)
369 {
370         long num;
371
372         if (!addr) {
373                 tprints("NULL");
374                 return;
375         }
376         if (umove(tcp, addr, &num) < 0) {
377                 tprintf("%#lx", addr);
378                 return;
379         }
380         tprints("[");
381         tprintf(fmt, num);
382         tprints("]");
383 }
384
385 void
386 printnum_int(struct tcb *tcp, long addr, const char *fmt)
387 {
388         int num;
389
390         if (!addr) {
391                 tprints("NULL");
392                 return;
393         }
394         if (umove(tcp, addr, &num) < 0) {
395                 tprintf("%#lx", addr);
396                 return;
397         }
398         tprints("[");
399         tprintf(fmt, num);
400         tprints("]");
401 }
402
403 void
404 printfd(struct tcb *tcp, int fd)
405 {
406         char path[PATH_MAX + 1];
407
408         if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0)
409                 tprintf("%d<%s>", fd, path);
410         else
411                 tprintf("%d", fd);
412 }
413
414 void
415 printuid(const char *text, unsigned long uid)
416 {
417         tprintf(((long) uid == -1) ? "%s%ld" : "%s%lu", text, uid);
418 }
419
420 /*
421  * Quote string `instr' of length `size'
422  * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
423  * If `len' is -1, treat `instr' as a NUL-terminated string
424  * and quote at most (`size' - 1) bytes.
425  *
426  * Returns 0 if len == -1 and NUL was seen, 1 otherwise.
427  * Note that if len >= 0, always returns 1.
428  */
429 int
430 string_quote(const char *instr, char *outstr, long len, int size)
431 {
432         const unsigned char *ustr = (const unsigned char *) instr;
433         char *s = outstr;
434         int usehex, c, i, eol;
435
436         eol = 0x100; /* this can never match a char */
437         if (len == -1) {
438                 size--;
439                 eol = '\0';
440         }
441
442         usehex = 0;
443         if (xflag > 1)
444                 usehex = 1;
445         else if (xflag) {
446                 /* Check for presence of symbol which require
447                    to hex-quote the whole string. */
448                 for (i = 0; i < size; ++i) {
449                         c = ustr[i];
450                         /* Check for NUL-terminated string. */
451                         if (c == eol)
452                                 break;
453
454                         /* Force hex unless c is printable or whitespace */
455                         if (c > 0x7e) {
456                                 usehex = 1;
457                                 break;
458                         }
459                         /* In ASCII isspace is only these chars: "\t\n\v\f\r".
460                          * They happen to have ASCII codes 9,10,11,12,13.
461                          */
462                         if (c < ' ' && (unsigned)(c - 9) >= 5) {
463                                 usehex = 1;
464                                 break;
465                         }
466                 }
467         }
468
469         *s++ = '\"';
470
471         if (usehex) {
472                 /* Hex-quote the whole string. */
473                 for (i = 0; i < size; ++i) {
474                         c = ustr[i];
475                         /* Check for NUL-terminated string. */
476                         if (c == eol)
477                                 goto asciz_ended;
478                         *s++ = '\\';
479                         *s++ = 'x';
480                         *s++ = "0123456789abcdef"[c >> 4];
481                         *s++ = "0123456789abcdef"[c & 0xf];
482                 }
483         } else {
484                 for (i = 0; i < size; ++i) {
485                         c = ustr[i];
486                         /* Check for NUL-terminated string. */
487                         if (c == eol)
488                                 goto asciz_ended;
489                         switch (c) {
490                                 case '\"': case '\\':
491                                         *s++ = '\\';
492                                         *s++ = c;
493                                         break;
494                                 case '\f':
495                                         *s++ = '\\';
496                                         *s++ = 'f';
497                                         break;
498                                 case '\n':
499                                         *s++ = '\\';
500                                         *s++ = 'n';
501                                         break;
502                                 case '\r':
503                                         *s++ = '\\';
504                                         *s++ = 'r';
505                                         break;
506                                 case '\t':
507                                         *s++ = '\\';
508                                         *s++ = 't';
509                                         break;
510                                 case '\v':
511                                         *s++ = '\\';
512                                         *s++ = 'v';
513                                         break;
514                                 default:
515                                         if (c >= ' ' && c <= 0x7e)
516                                                 *s++ = c;
517                                         else {
518                                                 /* Print \octal */
519                                                 *s++ = '\\';
520                                                 if (i + 1 < size
521                                                     && ustr[i + 1] >= '0'
522                                                     && ustr[i + 1] <= '9'
523                                                 ) {
524                                                         /* Print \ooo */
525                                                         *s++ = '0' + (c >> 6);
526                                                         *s++ = '0' + ((c >> 3) & 0x7);
527                                                 } else {
528                                                         /* Print \[[o]o]o */
529                                                         if ((c >> 3) != 0) {
530                                                                 if ((c >> 6) != 0)
531                                                                         *s++ = '0' + (c >> 6);
532                                                                 *s++ = '0' + ((c >> 3) & 0x7);
533                                                         }
534                                                 }
535                                                 *s++ = '0' + (c & 0x7);
536                                         }
537                                         break;
538                         }
539                 }
540         }
541
542         *s++ = '\"';
543         *s = '\0';
544
545         /* Return zero if we printed entire ASCIZ string (didn't truncate it) */
546         if (len == -1 && ustr[i] == '\0') {
547                 /* We didn't see NUL yet (otherwise we'd jump to 'asciz_ended')
548                  * but next char is NUL.
549                  */
550                 return 0;
551         }
552
553         return 1;
554
555  asciz_ended:
556         *s++ = '\"';
557         *s = '\0';
558         /* Return zero: we printed entire ASCIZ string (didn't truncate it) */
559         return 0;
560 }
561
562 /*
563  * Print path string specified by address `addr' and length `n'.
564  * If path length exceeds `n', append `...' to the output.
565  */
566 void
567 printpathn(struct tcb *tcp, long addr, unsigned int n)
568 {
569         char path[MAXPATHLEN + 1];
570         int nul_seen;
571
572         if (!addr) {
573                 tprints("NULL");
574                 return;
575         }
576
577         /* Cap path length to the path buffer size */
578         if (n > sizeof path - 1)
579                 n = sizeof path - 1;
580
581         /* Fetch one byte more to find out whether path length > n. */
582         nul_seen = umovestr(tcp, addr, n + 1, path);
583         if (nul_seen < 0)
584                 tprintf("%#lx", addr);
585         else {
586                 char *outstr;
587
588                 path[n] = '\0';
589                 n++;
590                 outstr = alloca(4 * n); /* 4*(n-1) + 3 for quotes and NUL */
591                 string_quote(path, outstr, -1, n);
592                 tprints(outstr);
593                 if (!nul_seen)
594                         tprints("...");
595         }
596 }
597
598 void
599 printpath(struct tcb *tcp, long addr)
600 {
601         /* Size must correspond to char path[] size in printpathn */
602         printpathn(tcp, addr, MAXPATHLEN);
603 }
604
605 /*
606  * Print string specified by address `addr' and length `len'.
607  * If `len' < 0, treat the string as a NUL-terminated string.
608  * If string length exceeds `max_strlen', append `...' to the output.
609  */
610 void
611 printstr(struct tcb *tcp, long addr, long len)
612 {
613         static char *str = NULL;
614         static char *outstr;
615         unsigned int size;
616         int ellipsis;
617
618         if (!addr) {
619                 tprints("NULL");
620                 return;
621         }
622         /* Allocate static buffers if they are not allocated yet. */
623         if (!str) {
624                 unsigned int outstr_size = 4 * max_strlen + /*for quotes and NUL:*/ 3;
625
626                 if (outstr_size / 4 != max_strlen)
627                         die_out_of_memory();
628                 str = malloc(max_strlen + 1);
629                 if (!str)
630                         die_out_of_memory();
631                 outstr = malloc(outstr_size);
632                 if (!outstr)
633                         die_out_of_memory();
634         }
635
636         if (len == -1) {
637                 /*
638                  * Treat as a NUL-terminated string: fetch one byte more
639                  * because string_quote() quotes one byte less.
640                  */
641                 size = max_strlen + 1;
642                 if (umovestr(tcp, addr, size, str) < 0) {
643                         tprintf("%#lx", addr);
644                         return;
645                 }
646         }
647         else {
648                 size = max_strlen;
649                 if (size > (unsigned long)len)
650                         size = (unsigned long)len;
651                 if (umoven(tcp, addr, size, str) < 0) {
652                         tprintf("%#lx", addr);
653                         return;
654                 }
655         }
656
657         /* If string_quote didn't see NUL and (it was supposed to be ASCIZ str
658          * or we were requested to print more than -s NUM chars)...
659          */
660         ellipsis = (string_quote(str, outstr, len, size) &&
661                         (len < 0 || (unsigned long) len > max_strlen));
662
663         tprints(outstr);
664         if (ellipsis)
665                 tprints("...");
666 }
667
668 #if HAVE_SYS_UIO_H
669 void
670 dumpiov(struct tcb *tcp, int len, long addr)
671 {
672 #if SUPPORTED_PERSONALITIES > 1
673         union {
674                 struct { u_int32_t base; u_int32_t len; } *iov32;
675                 struct { u_int64_t base; u_int64_t len; } *iov64;
676         } iovu;
677 #define iov iovu.iov64
678 #define sizeof_iov \
679         (current_wordsize == 4 ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64))
680 #define iov_iov_base(i) \
681         (current_wordsize == 4 ? (uint64_t) iovu.iov32[i].base : iovu.iov64[i].base)
682 #define iov_iov_len(i) \
683         (current_wordsize == 4 ? (uint64_t) iovu.iov32[i].len : iovu.iov64[i].len)
684 #else
685         struct iovec *iov;
686 #define sizeof_iov sizeof(*iov)
687 #define iov_iov_base(i) iov[i].iov_base
688 #define iov_iov_len(i) iov[i].iov_len
689 #endif
690         int i;
691         unsigned size;
692
693         size = sizeof_iov * len;
694         /* Assuming no sane program has millions of iovs */
695         if ((unsigned)len > 1024*1024 /* insane or negative size? */
696             || (iov = malloc(size)) == NULL) {
697                 fprintf(stderr, "Out of memory\n");
698                 return;
699         }
700         if (umoven(tcp, addr, size, (char *) iov) >= 0) {
701                 for (i = 0; i < len; i++) {
702                         /* include the buffer number to make it easy to
703                          * match up the trace with the source */
704                         tprintf(" * %lu bytes in buffer %d\n",
705                                 (unsigned long)iov_iov_len(i), i);
706                         dumpstr(tcp, (long) iov_iov_base(i),
707                                 iov_iov_len(i));
708                 }
709         }
710         free(iov);
711 #undef sizeof_iov
712 #undef iov_iov_base
713 #undef iov_iov_len
714 #undef iov
715 }
716 #endif
717
718 void
719 dumpstr(struct tcb *tcp, long addr, int len)
720 {
721         static int strsize = -1;
722         static unsigned char *str;
723
724         char outbuf[
725                 (
726                         (sizeof(
727                         "xx xx xx xx xx xx xx xx  xx xx xx xx xx xx xx xx  "
728                         "1234567890123456") + /*in case I'm off by few:*/ 4)
729                 /*align to 8 to make memset easier:*/ + 7) & -8
730         ];
731         const unsigned char *src;
732         int i;
733
734         memset(outbuf, ' ', sizeof(outbuf));
735
736         if (strsize < len + 16) {
737                 free(str);
738                 str = malloc(len + 16);
739                 if (!str) {
740                         strsize = -1;
741                         fprintf(stderr, "Out of memory\n");
742                         return;
743                 }
744                 strsize = len + 16;
745         }
746
747         if (umoven(tcp, addr, len, (char *) str) < 0)
748                 return;
749
750         /* Space-pad to 16 bytes */
751         i = len;
752         while (i & 0xf)
753                 str[i++] = ' ';
754
755         i = 0;
756         src = str;
757         while (i < len) {
758                 char *dst = outbuf;
759                 /* Hex dump */
760                 do {
761                         if (i < len) {
762                                 *dst++ = "0123456789abcdef"[*src >> 4];
763                                 *dst++ = "0123456789abcdef"[*src & 0xf];
764                         }
765                         else {
766                                 *dst++ = ' ';
767                                 *dst++ = ' ';
768                         }
769                         dst++; /* space is there by memset */
770                         i++;
771                         if ((i & 7) == 0)
772                                 dst++; /* space is there by memset */
773                         src++;
774                 } while (i & 0xf);
775                 /* ASCII dump */
776                 i -= 16;
777                 src -= 16;
778                 do {
779                         if (*src >= ' ' && *src < 0x7f)
780                                 *dst++ = *src;
781                         else
782                                 *dst++ = '.';
783                         src++;
784                 } while (++i & 0xf);
785                 *dst = '\0';
786                 tprintf(" | %05x  %s |\n", i - 16, outbuf);
787         }
788 }
789
790 #ifdef HAVE_PROCESS_VM_READV
791 /* C library supports this, but the kernel might not. */
792 static bool process_vm_readv_not_supported = 0;
793 #else
794
795 /* Need to do this since process_vm_readv() is not yet available in libc.
796  * When libc is be updated, only "static bool process_vm_readv_not_supported"
797  * line should remain.
798  */
799 #if !defined(__NR_process_vm_readv)
800 # if defined(I386)
801 #  define __NR_process_vm_readv  347
802 # elif defined(X86_64)
803 #  define __NR_process_vm_readv  310
804 # elif defined(POWERPC)
805 #  define __NR_process_vm_readv  351
806 # endif
807 #endif
808
809 #if defined(__NR_process_vm_readv)
810 static bool process_vm_readv_not_supported = 0;
811 /* Have to avoid duplicating with the C library headers. */
812 static ssize_t strace_process_vm_readv(pid_t pid,
813                  const struct iovec *lvec,
814                  unsigned long liovcnt,
815                  const struct iovec *rvec,
816                  unsigned long riovcnt,
817                  unsigned long flags)
818 {
819         return syscall(__NR_process_vm_readv, (long)pid, lvec, liovcnt, rvec, riovcnt, flags);
820 }
821 #define process_vm_readv strace_process_vm_readv
822 #else
823 static bool process_vm_readv_not_supported = 1;
824 # define process_vm_readv(...) (errno = ENOSYS, -1)
825 #endif
826
827 #endif /* end of hack */
828
829 #define PAGMASK (~(PAGSIZ - 1))
830 /*
831  * move `len' bytes of data from process `pid'
832  * at address `addr' to our space at `laddr'
833  */
834 int
835 umoven(struct tcb *tcp, long addr, int len, char *laddr)
836 {
837         int pid = tcp->pid;
838         int n, m, nread;
839         union {
840                 long val;
841                 char x[sizeof(long)];
842         } u;
843
844 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
845         if (current_wordsize < sizeof(addr))
846                 addr &= (1ul << 8 * current_wordsize) - 1;
847 #endif
848
849         if (!process_vm_readv_not_supported) {
850                 struct iovec local[1], remote[1];
851                 int r;
852
853                 local[0].iov_base = laddr;
854                 remote[0].iov_base = (void*)addr;
855                 local[0].iov_len = remote[0].iov_len = len;
856                 r = process_vm_readv(pid, local, 1, remote, 1, 0);
857                 if (r == len)
858                         return 0;
859                 if (r >= 0) {
860                         error_msg("umoven: short read (%d < %d) @0x%lx",
861                                   r, len, addr);
862                         return -1;
863                 }
864                 switch (errno) {
865                         case ENOSYS:
866                                 process_vm_readv_not_supported = 1;
867                                 break;
868                         case ESRCH:
869                                 /* the process is gone */
870                                 return -1;
871                         case EFAULT: case EIO: case EPERM:
872                                 /* address space is inaccessible */
873                                 return -1;
874                         default:
875                                 /* all the rest is strange and should be reported */
876                                 perror_msg("process_vm_readv");
877                                 return -1;
878                 }
879         }
880
881         nread = 0;
882         if (addr & (sizeof(long) - 1)) {
883                 /* addr not a multiple of sizeof(long) */
884                 n = addr - (addr & -sizeof(long)); /* residue */
885                 addr &= -sizeof(long); /* residue */
886                 errno = 0;
887                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
888                 switch (errno) {
889                         case 0:
890                                 break;
891                         case ESRCH: case EINVAL:
892                                 /* these could be seen if the process is gone */
893                                 return -1;
894                         case EFAULT: case EIO: case EPERM:
895                                 /* address space is inaccessible */
896                                 return -1;
897                         default:
898                                 /* all the rest is strange and should be reported */
899                                 perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%lx",
900                                             pid, addr);
901                                 return -1;
902                 }
903                 m = MIN(sizeof(long) - n, len);
904                 memcpy(laddr, &u.x[n], m);
905                 addr += sizeof(long);
906                 laddr += m;
907                 nread += m;
908                 len -= m;
909         }
910         while (len) {
911                 errno = 0;
912                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
913                 switch (errno) {
914                         case 0:
915                                 break;
916                         case ESRCH: case EINVAL:
917                                 /* these could be seen if the process is gone */
918                                 return -1;
919                         case EFAULT: case EIO: case EPERM:
920                                 /* address space is inaccessible */
921                                 if (nread) {
922                                         perror_msg("umoven: short read (%d < %d) @0x%lx",
923                                                    nread, nread + len, addr - nread);
924                                 }
925                                 return -1;
926                         default:
927                                 /* all the rest is strange and should be reported */
928                                 perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%lx",
929                                             pid, addr);
930                                 return -1;
931                 }
932                 m = MIN(sizeof(long), len);
933                 memcpy(laddr, u.x, m);
934                 addr += sizeof(long);
935                 laddr += m;
936                 nread += m;
937                 len -= m;
938         }
939
940         return 0;
941 }
942
943 /*
944  * Like `umove' but make the additional effort of looking
945  * for a terminating zero byte.
946  *
947  * Returns < 0 on error, > 0 if NUL was seen,
948  * (TODO if useful: return count of bytes including NUL),
949  * else 0 if len bytes were read but no NUL byte seen.
950  *
951  * Note: there is no guarantee we won't overwrite some bytes
952  * in laddr[] _after_ terminating NUL (but, of course,
953  * we never write past laddr[len-1]).
954  */
955 int
956 umovestr(struct tcb *tcp, long addr, int len, char *laddr)
957 {
958 #if SIZEOF_LONG == 4
959         const unsigned long x01010101 = 0x01010101ul;
960         const unsigned long x80808080 = 0x80808080ul;
961 #elif SIZEOF_LONG == 8
962         const unsigned long x01010101 = 0x0101010101010101ul;
963         const unsigned long x80808080 = 0x8080808080808080ul;
964 #else
965 # error SIZEOF_LONG > 8
966 #endif
967
968         int pid = tcp->pid;
969         int n, m, nread;
970         union {
971                 unsigned long val;
972                 char x[sizeof(long)];
973         } u;
974
975 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
976         if (current_wordsize < sizeof(addr))
977                 addr &= (1ul << 8 * current_wordsize) - 1;
978 #endif
979
980         nread = 0;
981         if (!process_vm_readv_not_supported) {
982                 struct iovec local[1], remote[1];
983
984                 local[0].iov_base = laddr;
985                 remote[0].iov_base = (void*)addr;
986
987                 while (len > 0) {
988                         int end_in_page;
989                         int r;
990                         int chunk_len;
991
992                         /* Don't read kilobytes: most strings are short */
993                         chunk_len = len;
994                         if (chunk_len > 256)
995                                 chunk_len = 256;
996                         /* Don't cross pages. I guess otherwise we can get EFAULT
997                          * and fail to notice that terminating NUL lies
998                          * in the existing (first) page.
999                          * (I hope there aren't arches with pages < 4K)
1000                          */
1001                         end_in_page = ((addr + chunk_len) & 4095);
1002                         r = chunk_len - end_in_page;
1003                         if (r > 0) /* if chunk_len > end_in_page */
1004                                 chunk_len = r; /* chunk_len -= end_in_page */
1005
1006                         local[0].iov_len = remote[0].iov_len = chunk_len;
1007                         r = process_vm_readv(pid, local, 1, remote, 1, 0);
1008                         if (r > 0) {
1009                                 if (memchr(local[0].iov_base, '\0', r))
1010                                         return 1;
1011                                 local[0].iov_base += r;
1012                                 remote[0].iov_base += r;
1013                                 len -= r;
1014                                 nread += r;
1015                                 continue;
1016                         }
1017                         switch (errno) {
1018                                 case ENOSYS:
1019                                         process_vm_readv_not_supported = 1;
1020                                         goto vm_readv_didnt_work;
1021                                 case ESRCH:
1022                                         /* the process is gone */
1023                                         return -1;
1024                                 case EFAULT: case EIO: case EPERM:
1025                                         /* address space is inaccessible */
1026                                         if (nread) {
1027                                                 perror_msg("umovestr: short read (%d < %d) @0x%lx",
1028                                                            nread, nread + len, addr);
1029                                         }
1030                                         return -1;
1031                                 default:
1032                                         /* all the rest is strange and should be reported */
1033                                         perror_msg("process_vm_readv");
1034                                         return -1;
1035                         }
1036                 }
1037                 return 0;
1038         }
1039  vm_readv_didnt_work:
1040
1041         if (addr & (sizeof(long) - 1)) {
1042                 /* addr not a multiple of sizeof(long) */
1043                 n = addr - (addr & -sizeof(long)); /* residue */
1044                 addr &= -sizeof(long); /* residue */
1045                 errno = 0;
1046                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
1047                 switch (errno) {
1048                         case 0:
1049                                 break;
1050                         case ESRCH: case EINVAL:
1051                                 /* these could be seen if the process is gone */
1052                                 return -1;
1053                         case EFAULT: case EIO: case EPERM:
1054                                 /* address space is inaccessible */
1055                                 return -1;
1056                         default:
1057                                 /* all the rest is strange and should be reported */
1058                                 perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%lx",
1059                                             pid, addr);
1060                                 return -1;
1061                 }
1062                 m = MIN(sizeof(long) - n, len);
1063                 memcpy(laddr, &u.x[n], m);
1064                 while (n & (sizeof(long) - 1))
1065                         if (u.x[n++] == '\0')
1066                                 return 1;
1067                 addr += sizeof(long);
1068                 laddr += m;
1069                 nread += m;
1070                 len -= m;
1071         }
1072
1073         while (len) {
1074                 errno = 0;
1075                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
1076                 switch (errno) {
1077                         case 0:
1078                                 break;
1079                         case ESRCH: case EINVAL:
1080                                 /* these could be seen if the process is gone */
1081                                 return -1;
1082                         case EFAULT: case EIO: case EPERM:
1083                                 /* address space is inaccessible */
1084                                 if (nread) {
1085                                         perror_msg("umovestr: short read (%d < %d) @0x%lx",
1086                                                    nread, nread + len, addr - nread);
1087                                 }
1088                                 return -1;
1089                         default:
1090                                 /* all the rest is strange and should be reported */
1091                                 perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%lx",
1092                                            pid, addr);
1093                                 return -1;
1094                 }
1095                 m = MIN(sizeof(long), len);
1096                 memcpy(laddr, u.x, m);
1097                 /* "If a NUL char exists in this word" */
1098                 if ((u.val - x01010101) & ~u.val & x80808080)
1099                         return 1;
1100                 addr += sizeof(long);
1101                 laddr += m;
1102                 nread += m;
1103                 len -= m;
1104         }
1105         return 0;
1106 }
1107
1108 int
1109 upeek(int pid, long off, long *res)
1110 {
1111         long val;
1112
1113         errno = 0;
1114         val = ptrace(PTRACE_PEEKUSER, (pid_t)pid, (char *) off, 0);
1115         if (val == -1 && errno) {
1116                 if (errno != ESRCH) {
1117                         perror_msg("upeek: PTRACE_PEEKUSER pid:%d @0x%lx)", pid, off);
1118                 }
1119                 return -1;
1120         }
1121         *res = val;
1122         return 0;
1123 }
1124
1125 /* Note! On new kernels (about 2.5.46+), we use PTRACE_O_TRACECLONE
1126  * and PTRACE_O_TRACE[V]FORK for tracing children.
1127  * If you are adding a new arch which is only supported by newer kernels,
1128  * you most likely don't need to add any code below
1129  * beside a dummy "return 0" block in change_syscall().
1130  */
1131
1132 /*
1133  * These #if's are huge, please indent them correctly.
1134  * It's easy to get confused otherwise.
1135  */
1136
1137 #include "syscall.h"
1138
1139 #ifndef CLONE_PTRACE
1140 # define CLONE_PTRACE    0x00002000
1141 #endif
1142 #ifndef CLONE_VFORK
1143 # define CLONE_VFORK     0x00004000
1144 #endif
1145 #ifndef CLONE_VM
1146 # define CLONE_VM        0x00000100
1147 #endif
1148
1149 #ifdef IA64
1150
1151 typedef unsigned long *arg_setup_state;
1152
1153 static int
1154 arg_setup(struct tcb *tcp, arg_setup_state *state)
1155 {
1156         unsigned long cfm, sof, sol;
1157         long bsp;
1158
1159         if (ia64_ia32mode) {
1160                 /* Satisfy a false GCC warning.  */
1161                 *state = NULL;
1162                 return 0;
1163         }
1164
1165         if (upeek(tcp->pid, PT_AR_BSP, &bsp) < 0)
1166                 return -1;
1167         if (upeek(tcp->pid, PT_CFM, (long *) &cfm) < 0)
1168                 return -1;
1169
1170         sof = (cfm >> 0) & 0x7f;
1171         sol = (cfm >> 7) & 0x7f;
1172         bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol);
1173
1174         *state = (unsigned long *) bsp;
1175         return 0;
1176 }
1177
1178 # define arg_finish_change(tcp, state)  0
1179
1180 static int
1181 get_arg0(struct tcb *tcp, arg_setup_state *state, long *valp)
1182 {
1183         int ret;
1184
1185         if (ia64_ia32mode)
1186                 ret = upeek(tcp->pid, PT_R11, valp);
1187         else
1188                 ret = umoven(tcp,
1189                               (unsigned long) ia64_rse_skip_regs(*state, 0),
1190                               sizeof(long), (void *) valp);
1191         return ret;
1192 }
1193
1194 static int
1195 get_arg1(struct tcb *tcp, arg_setup_state *state, long *valp)
1196 {
1197         int ret;
1198
1199         if (ia64_ia32mode)
1200                 ret = upeek(tcp->pid, PT_R9, valp);
1201         else
1202                 ret = umoven(tcp,
1203                               (unsigned long) ia64_rse_skip_regs(*state, 1),
1204                               sizeof(long), (void *) valp);
1205         return ret;
1206 }
1207
1208 static int
1209 set_arg0(struct tcb *tcp, arg_setup_state *state, long val)
1210 {
1211         int req = PTRACE_POKEDATA;
1212         void *ap;
1213
1214         if (ia64_ia32mode) {
1215                 ap = (void *) (intptr_t) PT_R11;         /* r11 == EBX */
1216                 req = PTRACE_POKEUSER;
1217         } else
1218                 ap = ia64_rse_skip_regs(*state, 0);
1219         errno = 0;
1220         ptrace(req, tcp->pid, ap, val);
1221         return errno ? -1 : 0;
1222 }
1223
1224 static int
1225 set_arg1(struct tcb *tcp, arg_setup_state *state, long val)
1226 {
1227         int req = PTRACE_POKEDATA;
1228         void *ap;
1229
1230         if (ia64_ia32mode) {
1231                 ap = (void *) (intptr_t) PT_R9;         /* r9 == ECX */
1232                 req = PTRACE_POKEUSER;
1233         } else
1234                 ap = ia64_rse_skip_regs(*state, 1);
1235         errno = 0;
1236         ptrace(req, tcp->pid, ap, val);
1237         return errno ? -1 : 0;
1238 }
1239
1240 /* ia64 does not return the input arguments from functions (and syscalls)
1241    according to ia64 RSE (Register Stack Engine) behavior.  */
1242
1243 # define restore_arg0(tcp, state, val) ((void) (state), 0)
1244 # define restore_arg1(tcp, state, val) ((void) (state), 0)
1245
1246 #elif defined(SPARC) || defined(SPARC64)
1247
1248 # if defined(SPARC64)
1249 #  undef PTRACE_GETREGS
1250 #  define PTRACE_GETREGS PTRACE_GETREGS64
1251 #  undef PTRACE_SETREGS
1252 #  define PTRACE_SETREGS PTRACE_SETREGS64
1253 # endif
1254
1255 typedef struct pt_regs arg_setup_state;
1256
1257 # define arg_setup(tcp, state) \
1258     (ptrace(PTRACE_GETREGS, (tcp)->pid, (char *) (state), 0))
1259 # define arg_finish_change(tcp, state) \
1260     (ptrace(PTRACE_SETREGS, (tcp)->pid, (char *) (state), 0))
1261
1262 # define get_arg0(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O0], 0)
1263 # define get_arg1(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O1], 0)
1264 # define set_arg0(tcp, state, val)  ((state)->u_regs[U_REG_O0] = (val), 0)
1265 # define set_arg1(tcp, state, val)  ((state)->u_regs[U_REG_O1] = (val), 0)
1266 # define restore_arg0(tcp, state, val) 0
1267
1268 #else /* other architectures */
1269
1270 # if defined S390 || defined S390X
1271 /* Note: this is only true for the `clone' system call, which handles
1272    arguments specially.  We could as well say that its first two arguments
1273    are swapped relative to other architectures, but that would just be
1274    another #ifdef in the calls.  */
1275 #  define arg0_offset   PT_GPR3
1276 #  define arg1_offset   PT_ORIGGPR2
1277 #  define restore_arg0(tcp, state, val) ((void) (state), 0)
1278 #  define restore_arg1(tcp, state, val) ((void) (state), 0)
1279 #  define arg0_index    1
1280 #  define arg1_index    0
1281 # elif defined(ALPHA) || defined(MIPS)
1282 #  define arg0_offset   REG_A0
1283 #  define arg1_offset   (REG_A0+1)
1284 # elif defined(POWERPC)
1285 #  define arg0_offset   (sizeof(unsigned long)*PT_R3)
1286 #  define arg1_offset   (sizeof(unsigned long)*PT_R4)
1287 #  define restore_arg0(tcp, state, val) ((void) (state), 0)
1288 # elif defined(HPPA)
1289 #  define arg0_offset   PT_GR26
1290 #  define arg1_offset   (PT_GR26-4)
1291 # elif defined(X86_64) || defined(X32)
1292 #  define arg0_offset   ((long)(8*(current_personality ? RBX : RDI)))
1293 #  define arg1_offset   ((long)(8*(current_personality ? RCX : RSI)))
1294 # elif defined(SH)
1295 #  define arg0_offset   (4*(REG_REG0+4))
1296 #  define arg1_offset   (4*(REG_REG0+5))
1297 # elif defined(SH64)
1298    /* ABI defines arg0 & 1 in r2 & r3 */
1299 #  define arg0_offset   (REG_OFFSET+16)
1300 #  define arg1_offset   (REG_OFFSET+24)
1301 #  define restore_arg0(tcp, state, val) 0
1302 # elif defined CRISV10 || defined CRISV32
1303 #  define arg0_offset   (4*PT_R11)
1304 #  define arg1_offset   (4*PT_ORIG_R10)
1305 #  define restore_arg0(tcp, state, val) 0
1306 #  define restore_arg1(tcp, state, val) 0
1307 #  define arg0_index    1
1308 #  define arg1_index    0
1309 # else
1310 #  define arg0_offset   0
1311 #  define arg1_offset   4
1312 #  if defined ARM
1313 #   define restore_arg0(tcp, state, val) 0
1314 #  endif
1315 # endif
1316
1317 typedef int arg_setup_state;
1318
1319 # define arg_setup(tcp, state)         (0)
1320 # define arg_finish_change(tcp, state) 0
1321 # define get_arg0(tcp, cookie, valp)   (upeek((tcp)->pid, arg0_offset, (valp)))
1322 # define get_arg1(tcp, cookie, valp)   (upeek((tcp)->pid, arg1_offset, (valp)))
1323
1324 static int
1325 set_arg0(struct tcb *tcp, void *cookie, long val)
1326 {
1327         return ptrace(PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val);
1328 }
1329
1330 static int
1331 set_arg1(struct tcb *tcp, void *cookie, long val)
1332 {
1333         return ptrace(PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val);
1334 }
1335
1336 #endif /* architectures */
1337
1338 #ifndef restore_arg0
1339 # define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val))
1340 #endif
1341 #ifndef restore_arg1
1342 # define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val))
1343 #endif
1344
1345 #ifndef arg0_index
1346 # define arg0_index 0
1347 # define arg1_index 1
1348 #endif
1349
1350 static int
1351 change_syscall(struct tcb *tcp, arg_setup_state *state, int new)
1352 {
1353 #if defined(I386)
1354         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
1355                 return -1;
1356         return 0;
1357 #elif defined(X86_64)
1358         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
1359                 return -1;
1360         return 0;
1361 #elif defined(X32)
1362         /* setbpt/clearbpt never used: */
1363         /* X32 is only supported since about linux-3.0.30 */
1364 #elif defined(POWERPC)
1365         if (ptrace(PTRACE_POKEUSER, tcp->pid,
1366                    (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
1367                 return -1;
1368         return 0;
1369 #elif defined(S390) || defined(S390X)
1370         /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
1371         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new) < 0)
1372                 return -1;
1373         return 0;
1374 #elif defined(M68K)
1375         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new) < 0)
1376                 return -1;
1377         return 0;
1378 #elif defined(SPARC) || defined(SPARC64)
1379         state->u_regs[U_REG_G1] = new;
1380         return 0;
1381 #elif defined(MIPS)
1382         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new) < 0)
1383                 return -1;
1384         return 0;
1385 #elif defined(ALPHA)
1386         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new) < 0)
1387                 return -1;
1388         return 0;
1389 #elif defined(AVR32)
1390         /* setbpt/clearbpt never used: */
1391         /* AVR32 is only supported since about linux-2.6.19 */
1392 #elif defined(BFIN)
1393         /* setbpt/clearbpt never used: */
1394         /* Blackfin is only supported since about linux-2.6.23 */
1395 #elif defined(IA64)
1396         if (ia64_ia32mode) {
1397                 switch (new) {
1398                 case 2:
1399                         break;  /* x86 SYS_fork */
1400                 case SYS_clone:
1401                         new = 120;
1402                         break;
1403                 default:
1404                         fprintf(stderr, "%s: unexpected syscall %d\n",
1405                                 __FUNCTION__, new);
1406                         return -1;
1407                 }
1408                 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new) < 0)
1409                         return -1;
1410         } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new) < 0)
1411                 return -1;
1412         return 0;
1413 #elif defined(HPPA)
1414         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new) < 0)
1415                 return -1;
1416         return 0;
1417 #elif defined(SH)
1418         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new) < 0)
1419                 return -1;
1420         return 0;
1421 #elif defined(SH64)
1422         /* Top half of reg encodes the no. of args n as 0x1n.
1423            Assume 0 args as kernel never actually checks... */
1424         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
1425                                 0x100000 | new) < 0)
1426                 return -1;
1427         return 0;
1428 #elif defined(CRISV10) || defined(CRISV32)
1429         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_R9), new) < 0)
1430                 return -1;
1431         return 0;
1432 #elif defined(ARM)
1433         /* Some kernels support this, some (pre-2.6.16 or so) don't.  */
1434 # ifndef PTRACE_SET_SYSCALL
1435 #  define PTRACE_SET_SYSCALL 23
1436 # endif
1437         if (ptrace(PTRACE_SET_SYSCALL, tcp->pid, 0, new & 0xffff) != 0)
1438                 return -1;
1439         return 0;
1440 #elif defined(AARCH64)
1441         /* setbpt/clearbpt never used: */
1442         /* AARCH64 is only supported since about linux-3.0.31 */
1443 #elif defined(TILE)
1444         /* setbpt/clearbpt never used: */
1445         /* Tilera CPUs are only supported since about linux-2.6.34 */
1446 #elif defined(MICROBLAZE)
1447         /* setbpt/clearbpt never used: */
1448         /* microblaze is only supported since about linux-2.6.30 */
1449 #elif defined(OR1K)
1450         /* never reached; OR1K is only supported by kernels since 3.1.0. */
1451 #elif defined(METAG)
1452         /* setbpt/clearbpt never used: */
1453         /* Meta is only supported since linux-3.7 */
1454 #elif defined(XTENSA)
1455         /* setbpt/clearbpt never used: */
1456         /* Xtensa is only supported since linux 2.6.13 */
1457 #elif defined(ARC)
1458         /* setbpt/clearbpt never used: */
1459         /* ARC only supported since 3.9 */
1460 #else
1461 #warning Do not know how to handle change_syscall for this architecture
1462 #endif /* architecture */
1463         return -1;
1464 }
1465
1466 int
1467 setbpt(struct tcb *tcp)
1468 {
1469         static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone };
1470         arg_setup_state state;
1471
1472         if (tcp->flags & TCB_BPTSET) {
1473                 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1474                 return -1;
1475         }
1476
1477         /*
1478          * It's a silly kludge to initialize this with a search at runtime.
1479          * But it's better than maintaining another magic thing in the
1480          * godforsaken tables.
1481          */
1482         if (clone_scno[current_personality] == 0) {
1483                 unsigned int i;
1484                 for (i = 0; i < nsyscalls; ++i)
1485                         if (sysent[i].sys_func == sys_clone) {
1486                                 clone_scno[current_personality] = i;
1487                                 break;
1488                         }
1489         }
1490
1491         if (tcp->s_ent->sys_func == sys_fork) {
1492                 if (arg_setup(tcp, &state) < 0
1493                     || get_arg0(tcp, &state, &tcp->inst[0]) < 0
1494                     || get_arg1(tcp, &state, &tcp->inst[1]) < 0
1495                     || change_syscall(tcp, &state,
1496                                       clone_scno[current_personality]) < 0
1497                     || set_arg0(tcp, &state, CLONE_PTRACE|SIGCHLD) < 0
1498                     || set_arg1(tcp, &state, 0) < 0
1499                     || arg_finish_change(tcp, &state) < 0)
1500                         return -1;
1501                 tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD;
1502                 tcp->u_arg[arg1_index] = 0;
1503                 tcp->flags |= TCB_BPTSET;
1504                 return 0;
1505         }
1506
1507         if (tcp->s_ent->sys_func == sys_clone) {
1508                 /* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)'
1509                    contrary to x86 vfork above.  Even on x86 we turn the
1510                    vfork semantics into plain fork - each application must not
1511                    depend on the vfork specifics according to POSIX.  We would
1512                    hang waiting for the parent resume otherwise.  We need to
1513                    clear also CLONE_VM but only in the CLONE_VFORK case as
1514                    otherwise we would break pthread_create.  */
1515
1516                 long new_arg0 = (tcp->u_arg[arg0_index] | CLONE_PTRACE);
1517                 if (new_arg0 & CLONE_VFORK)
1518                         new_arg0 &= ~(unsigned long)(CLONE_VFORK | CLONE_VM);
1519                 if (arg_setup(tcp, &state) < 0
1520                  || set_arg0(tcp, &state, new_arg0) < 0
1521                  || arg_finish_change(tcp, &state) < 0)
1522                         return -1;
1523                 tcp->inst[0] = tcp->u_arg[arg0_index];
1524                 tcp->inst[1] = tcp->u_arg[arg1_index];
1525                 tcp->flags |= TCB_BPTSET;
1526                 return 0;
1527         }
1528
1529         fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n",
1530                 tcp->scno, tcp->pid);
1531         return -1;
1532 }
1533
1534 int
1535 clearbpt(struct tcb *tcp)
1536 {
1537         arg_setup_state state;
1538         if (arg_setup(tcp, &state) < 0
1539             || change_syscall(tcp, &state, tcp->scno) < 0
1540             || restore_arg0(tcp, &state, tcp->inst[0]) < 0
1541             || restore_arg1(tcp, &state, tcp->inst[1]) < 0
1542             || arg_finish_change(tcp, &state))
1543                 if (errno != ESRCH)
1544                         return -1;
1545         tcp->flags &= ~TCB_BPTSET;
1546         return 0;
1547 }