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