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