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