]> granicus.if.org Git - strace/blob - util.c
Indentation and whitespace fixes. No code changes.
[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 #elif defined(S390) || defined(S390X)
1011         long psw;
1012         if (upeek(tcp, PT_PSWADDR, &psw) < 0) {
1013                 PRINTBADPC;
1014                 return;
1015         }
1016 # ifdef S390
1017         tprintf("[%08lx] ", psw);
1018 # elif S390X
1019         tprintf("[%16lx] ", psw);
1020 # endif
1021
1022 #elif defined(X86_64)
1023         long rip;
1024
1025         if (upeek(tcp, 8*RIP, &rip) < 0) {
1026                 PRINTBADPC;
1027                 return;
1028         }
1029         tprintf("[%16lx] ", rip);
1030 #elif defined(IA64)
1031         long ip;
1032
1033         if (upeek(tcp, PT_B0, &ip) < 0) {
1034                 PRINTBADPC;
1035                 return;
1036         }
1037         tprintf("[%08lx] ", ip);
1038 #elif defined(POWERPC)
1039         long pc;
1040
1041         if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) {
1042                 PRINTBADPC;
1043                 return;
1044         }
1045 # ifdef POWERPC64
1046         tprintf("[%016lx] ", pc);
1047 # else
1048         tprintf("[%08lx] ", pc);
1049 # endif
1050 #elif defined(M68K)
1051         long pc;
1052
1053         if (upeek(tcp, 4*PT_PC, &pc) < 0) {
1054                 tprints("[????????] ");
1055                 return;
1056         }
1057         tprintf("[%08lx] ", pc);
1058 #elif defined(ALPHA)
1059         long pc;
1060
1061         if (upeek(tcp, REG_PC, &pc) < 0) {
1062                 tprints("[????????????????] ");
1063                 return;
1064         }
1065         tprintf("[%08lx] ", pc);
1066 #elif defined(SPARC) || defined(SPARC64)
1067         struct pt_regs regs;
1068         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1069                 PRINTBADPC;
1070                 return;
1071         }
1072 # if defined(SPARC64)
1073         tprintf("[%08lx] ", regs.tpc);
1074 # else
1075         tprintf("[%08lx] ", regs.pc);
1076 # endif
1077 #elif defined(HPPA)
1078         long pc;
1079
1080         if (upeek(tcp, PT_IAOQ0, &pc) < 0) {
1081                 tprints("[????????] ");
1082                 return;
1083         }
1084         tprintf("[%08lx] ", pc);
1085 #elif defined(MIPS)
1086         long pc;
1087
1088         if (upeek(tcp, REG_EPC, &pc) < 0) {
1089                 tprints("[????????] ");
1090                 return;
1091         }
1092         tprintf("[%08lx] ", pc);
1093 #elif defined(SH)
1094         long pc;
1095
1096         if (upeek(tcp, 4*REG_PC, &pc) < 0) {
1097                 tprints("[????????] ");
1098                 return;
1099         }
1100         tprintf("[%08lx] ", pc);
1101 #elif defined(SH64)
1102         long pc;
1103
1104         if (upeek(tcp, REG_PC, &pc) < 0) {
1105                 tprints("[????????????????] ");
1106                 return;
1107         }
1108         tprintf("[%08lx] ", pc);
1109 #elif defined(ARM)
1110         long pc;
1111
1112         if (upeek(tcp, 4*15, &pc) < 0) {
1113                 PRINTBADPC;
1114                 return;
1115         }
1116         tprintf("[%08lx] ", pc);
1117 #elif defined(AVR32)
1118         long pc;
1119
1120         if (upeek(tcp, REG_PC, &pc) < 0) {
1121                 tprints("[????????] ");
1122                 return;
1123         }
1124         tprintf("[%08lx] ", pc);
1125 #elif defined(BFIN)
1126         long pc;
1127
1128         if (upeek(tcp, PT_PC, &pc) < 0) {
1129                 PRINTBADPC;
1130                 return;
1131         }
1132         tprintf("[%08lx] ", pc);
1133 #elif defined(CRISV10)
1134         long pc;
1135
1136         if (upeek(tcp, 4*PT_IRP, &pc) < 0) {
1137                 PRINTBADPC;
1138                 return;
1139         }
1140         tprintf("[%08lx] ", pc);
1141 #elif defined(CRISV32)
1142         long pc;
1143
1144         if (upeek(tcp, 4*PT_ERP, &pc) < 0) {
1145                 PRINTBADPC;
1146                 return;
1147         }
1148         tprintf("[%08lx] ", pc);
1149 #endif /* architecture */
1150 }
1151
1152 /*
1153  * These #if's are huge, please indent them correctly.
1154  * It's easy to get confused otherwise.
1155  */
1156
1157 #include "syscall.h"
1158
1159 #ifndef CLONE_PTRACE
1160 # define CLONE_PTRACE    0x00002000
1161 #endif
1162 #ifndef CLONE_VFORK
1163 # define CLONE_VFORK     0x00004000
1164 #endif
1165 #ifndef CLONE_VM
1166 # define CLONE_VM        0x00000100
1167 #endif
1168 #ifndef CLONE_STOPPED
1169 # define CLONE_STOPPED   0x02000000
1170 #endif
1171
1172 #ifdef IA64
1173
1174 typedef unsigned long *arg_setup_state;
1175
1176 static int
1177 arg_setup(struct tcb *tcp, arg_setup_state *state)
1178 {
1179         unsigned long cfm, sof, sol;
1180         long bsp;
1181
1182         if (ia32) {
1183                 /* Satisfy a false GCC warning.  */
1184                 *state = NULL;
1185                 return 0;
1186         }
1187
1188         if (upeek(tcp, PT_AR_BSP, &bsp) < 0)
1189                 return -1;
1190         if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
1191                 return -1;
1192
1193         sof = (cfm >> 0) & 0x7f;
1194         sol = (cfm >> 7) & 0x7f;
1195         bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol);
1196
1197         *state = (unsigned long *) bsp;
1198         return 0;
1199 }
1200
1201 # define arg_finish_change(tcp, state)  0
1202
1203 static int
1204 get_arg0(struct tcb *tcp, arg_setup_state *state, long *valp)
1205 {
1206         int ret;
1207
1208         if (ia32)
1209                 ret = upeek(tcp, PT_R11, valp);
1210         else
1211                 ret = umoven(tcp,
1212                               (unsigned long) ia64_rse_skip_regs(*state, 0),
1213                               sizeof(long), (void *) valp);
1214         return ret;
1215 }
1216
1217 static int
1218 get_arg1(struct tcb *tcp, arg_setup_state *state, long *valp)
1219 {
1220         int ret;
1221
1222         if (ia32)
1223                 ret = upeek(tcp, PT_R9, valp);
1224         else
1225                 ret = umoven(tcp,
1226                               (unsigned long) ia64_rse_skip_regs(*state, 1),
1227                               sizeof(long), (void *) valp);
1228         return ret;
1229 }
1230
1231 static int
1232 set_arg0(struct tcb *tcp, arg_setup_state *state, long val)
1233 {
1234         int req = PTRACE_POKEDATA;
1235         void *ap;
1236
1237         if (ia32) {
1238                 ap = (void *) (intptr_t) PT_R11;         /* r11 == EBX */
1239                 req = PTRACE_POKEUSER;
1240         } else
1241                 ap = ia64_rse_skip_regs(*state, 0);
1242         errno = 0;
1243         ptrace(req, tcp->pid, ap, val);
1244         return errno ? -1 : 0;
1245 }
1246
1247 static int
1248 set_arg1(struct tcb *tcp, arg_setup_state *state, long val)
1249 {
1250         int req = PTRACE_POKEDATA;
1251         void *ap;
1252
1253         if (ia32) {
1254                 ap = (void *) (intptr_t) PT_R9;         /* r9 == ECX */
1255                 req = PTRACE_POKEUSER;
1256         } else
1257                 ap = ia64_rse_skip_regs(*state, 1);
1258         errno = 0;
1259         ptrace(req, tcp->pid, ap, val);
1260         return errno ? -1 : 0;
1261 }
1262
1263 /* ia64 does not return the input arguments from functions (and syscalls)
1264    according to ia64 RSE (Register Stack Engine) behavior.  */
1265
1266 # define restore_arg0(tcp, state, val) ((void) (state), 0)
1267 # define restore_arg1(tcp, state, val) ((void) (state), 0)
1268
1269 #elif defined(SPARC) || defined(SPARC64)
1270
1271 typedef struct pt_regs arg_setup_state;
1272
1273 # define arg_setup(tcp, state) \
1274     (ptrace(PTRACE_GETREGS, (tcp)->pid, (char *) (state), 0))
1275 # define arg_finish_change(tcp, state) \
1276     (ptrace(PTRACE_SETREGS, (tcp)->pid, (char *) (state), 0))
1277
1278 # define get_arg0(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O0], 0)
1279 # define get_arg1(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O1], 0)
1280 # define set_arg0(tcp, state, val)  ((state)->u_regs[U_REG_O0] = (val), 0)
1281 # define set_arg1(tcp, state, val)  ((state)->u_regs[U_REG_O1] = (val), 0)
1282 # define restore_arg0(tcp, state, val) 0
1283
1284 #else /* other architectures */
1285
1286 # if defined S390 || defined S390X
1287 /* Note: this is only true for the `clone' system call, which handles
1288    arguments specially.  We could as well say that its first two arguments
1289    are swapped relative to other architectures, but that would just be
1290    another #ifdef in the calls.  */
1291 #  define arg0_offset   PT_GPR3
1292 #  define arg1_offset   PT_ORIGGPR2
1293 #  define restore_arg0(tcp, state, val) ((void) (state), 0)
1294 #  define restore_arg1(tcp, state, val) ((void) (state), 0)
1295 #  define arg0_index    1
1296 #  define arg1_index    0
1297 # elif defined(ALPHA) || defined(MIPS)
1298 #  define arg0_offset   REG_A0
1299 #  define arg1_offset   (REG_A0+1)
1300 # elif defined(AVR32)
1301 #  define arg0_offset   (REG_R12)
1302 #  define arg1_offset   (REG_R11)
1303 # elif defined(POWERPC)
1304 #  define arg0_offset   (sizeof(unsigned long)*PT_R3)
1305 #  define arg1_offset   (sizeof(unsigned long)*PT_R4)
1306 #  define restore_arg0(tcp, state, val) ((void) (state), 0)
1307 # elif defined(HPPA)
1308 #  define arg0_offset   PT_GR26
1309 #  define arg1_offset   (PT_GR26-4)
1310 # elif defined(X86_64)
1311 #  define arg0_offset   ((long)(8*(current_personality ? RBX : RDI)))
1312 #  define arg1_offset   ((long)(8*(current_personality ? RCX : RSI)))
1313 # elif defined(SH)
1314 #  define arg0_offset   (4*(REG_REG0+4))
1315 #  define arg1_offset   (4*(REG_REG0+5))
1316 # elif defined(SH64)
1317    /* ABI defines arg0 & 1 in r2 & r3 */
1318 #  define arg0_offset   (REG_OFFSET+16)
1319 #  define arg1_offset   (REG_OFFSET+24)
1320 #  define restore_arg0(tcp, state, val) 0
1321 # elif defined CRISV10 || defined CRISV32
1322 #  define arg0_offset   (4*PT_R11)
1323 #  define arg1_offset   (4*PT_ORIG_R10)
1324 #  define restore_arg0(tcp, state, val) 0
1325 #  define restore_arg1(tcp, state, val) 0
1326 #  define arg0_index    1
1327 #  define arg1_index    0
1328 # else
1329 #  define arg0_offset   0
1330 #  define arg1_offset   4
1331 #  if defined ARM
1332 #   define restore_arg0(tcp, state, val) 0
1333 #  endif
1334 # endif
1335
1336 typedef int arg_setup_state;
1337
1338 # define arg_setup(tcp, state)         (0)
1339 # define arg_finish_change(tcp, state) 0
1340 # define get_arg0(tcp, cookie, valp)   (upeek((tcp), arg0_offset, (valp)))
1341 # define get_arg1(tcp, cookie, valp)   (upeek((tcp), arg1_offset, (valp)))
1342
1343 static int
1344 set_arg0(struct tcb *tcp, void *cookie, long val)
1345 {
1346         return ptrace(PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val);
1347 }
1348
1349 static int
1350 set_arg1(struct tcb *tcp, void *cookie, long val)
1351 {
1352         return ptrace(PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val);
1353 }
1354
1355 #endif /* architectures */
1356
1357 #ifndef restore_arg0
1358 # define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val))
1359 #endif
1360 #ifndef restore_arg1
1361 # define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val))
1362 #endif
1363
1364 #ifndef arg0_index
1365 # define arg0_index 0
1366 # define arg1_index 1
1367 #endif
1368
1369 int
1370 setbpt(struct tcb *tcp)
1371 {
1372         static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone };
1373         arg_setup_state state;
1374
1375         if (tcp->flags & TCB_BPTSET) {
1376                 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1377                 return -1;
1378         }
1379
1380         /*
1381          * It's a silly kludge to initialize this with a search at runtime.
1382          * But it's better than maintaining another magic thing in the
1383          * godforsaken tables.
1384          */
1385         if (clone_scno[current_personality] == 0) {
1386                 int i;
1387                 for (i = 0; i < nsyscalls; ++i)
1388                         if (sysent[i].sys_func == sys_clone) {
1389                                 clone_scno[current_personality] = i;
1390                                 break;
1391                         }
1392         }
1393
1394         if (sysent[tcp->scno].sys_func == sys_fork ||
1395             sysent[tcp->scno].sys_func == sys_vfork) {
1396                 if (arg_setup(tcp, &state) < 0
1397                     || get_arg0(tcp, &state, &tcp->inst[0]) < 0
1398                     || get_arg1(tcp, &state, &tcp->inst[1]) < 0
1399                     || change_syscall(tcp, clone_scno[current_personality]) < 0
1400                     || set_arg0(tcp, &state, CLONE_PTRACE|SIGCHLD) < 0
1401                     || set_arg1(tcp, &state, 0) < 0
1402                     || arg_finish_change(tcp, &state) < 0)
1403                         return -1;
1404                 tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD;
1405                 tcp->u_arg[arg1_index] = 0;
1406                 tcp->flags |= TCB_BPTSET;
1407                 return 0;
1408         }
1409
1410         if (sysent[tcp->scno].sys_func == sys_clone) {
1411                 /* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)'
1412                    contrary to x86 vfork above.  Even on x86 we turn the
1413                    vfork semantics into plain fork - each application must not
1414                    depend on the vfork specifics according to POSIX.  We would
1415                    hang waiting for the parent resume otherwise.  We need to
1416                    clear also CLONE_VM but only in the CLONE_VFORK case as
1417                    otherwise we would break pthread_create.  */
1418
1419                 long new_arg0 = (tcp->u_arg[arg0_index] | CLONE_PTRACE);
1420                 if (new_arg0 & CLONE_VFORK)
1421                         new_arg0 &= ~(unsigned long)(CLONE_VFORK | CLONE_VM);
1422                 if (arg_setup(tcp, &state) < 0
1423                  || set_arg0(tcp, &state, new_arg0) < 0
1424                  || arg_finish_change(tcp, &state) < 0)
1425                         return -1;
1426                 tcp->flags |= TCB_BPTSET;
1427                 tcp->inst[0] = tcp->u_arg[arg0_index];
1428                 tcp->inst[1] = tcp->u_arg[arg1_index];
1429                 return 0;
1430         }
1431
1432         fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n",
1433                 tcp->scno, tcp->pid);
1434         return -1;
1435 }
1436
1437 int
1438 clearbpt(struct tcb *tcp)
1439 {
1440         arg_setup_state state;
1441         if (arg_setup(tcp, &state) < 0
1442             || restore_arg0(tcp, &state, tcp->inst[0]) < 0
1443             || restore_arg1(tcp, &state, tcp->inst[1]) < 0
1444             || arg_finish_change(tcp, &state))
1445                 if (errno != ESRCH)
1446                         return -1;
1447         tcp->flags &= ~TCB_BPTSET;
1448         return 0;
1449 }