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