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