]> granicus.if.org Git - strace/blob - util.c
Forbid using mutually exclusive options -D and -p together
[strace] / util.c
1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5  * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6  * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7  *                     Linux for s390 port by D.J. Barrow
8  *                    <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  *      $Id$
34  */
35
36 #include "defs.h"
37
38 #include <signal.h>
39 #include <sys/syscall.h>
40 #include <sys/user.h>
41 #include <sys/param.h>
42 #include <fcntl.h>
43 #if HAVE_SYS_UIO_H
44 #include <sys/uio.h>
45 #endif
46 #ifdef SUNOS4
47 #include <machine/reg.h>
48 #include <a.out.h>
49 #include <link.h>
50 #endif /* SUNOS4 */
51
52 #if defined(linux) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1))
53 #include <linux/ptrace.h>
54 #endif
55
56 #if defined(LINUX) && defined(IA64)
57 # include <asm/ptrace_offsets.h>
58 # include <asm/rse.h>
59 #endif
60
61 #ifdef HAVE_SYS_REG_H
62 #include <sys/reg.h>
63 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
64 #elif defined(HAVE_LINUX_PTRACE_H)
65 #undef PTRACE_SYSCALL
66 # ifdef HAVE_STRUCT_IA64_FPREG
67 #  define ia64_fpreg XXX_ia64_fpreg
68 # endif
69 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
70 #  define pt_all_user_regs XXX_pt_all_user_regs
71 # endif
72 #include <linux/ptrace.h>
73 # undef ia64_fpreg
74 # undef pt_all_user_regs
75 #endif
76
77 #ifdef SUNOS4_KERNEL_ARCH_KLUDGE
78 #include <sys/utsname.h>
79 #endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
80
81 #if defined(LINUXSPARC) && defined (SPARC64)
82 # undef PTRACE_GETREGS
83 # define PTRACE_GETREGS PTRACE_GETREGS64
84 # undef PTRACE_SETREGS
85 # define PTRACE_SETREGS PTRACE_SETREGS64
86 #endif
87
88 /* macros */
89 #ifndef MAX
90 #define MAX(a,b)                (((a) > (b)) ? (a) : (b))
91 #endif
92 #ifndef MIN
93 #define MIN(a,b)                (((a) < (b)) ? (a) : (b))
94 #endif
95
96 int
97 tv_nz(a)
98 struct timeval *a;
99 {
100         return a->tv_sec || a->tv_usec;
101 }
102
103 int
104 tv_cmp(a, b)
105 struct timeval *a, *b;
106 {
107         if (a->tv_sec < b->tv_sec
108             || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
109                 return -1;
110         if (a->tv_sec > b->tv_sec
111             || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
112                 return 1;
113         return 0;
114 }
115
116 double
117 tv_float(tv)
118 struct timeval *tv;
119 {
120         return tv->tv_sec + tv->tv_usec/1000000.0;
121 }
122
123 void
124 tv_add(tv, a, b)
125 struct timeval *tv, *a, *b;
126 {
127         tv->tv_sec = a->tv_sec + b->tv_sec;
128         tv->tv_usec = a->tv_usec + b->tv_usec;
129         if (tv->tv_usec >= 1000000) {
130                 tv->tv_sec++;
131                 tv->tv_usec -= 1000000;
132         }
133 }
134
135 void
136 tv_sub(tv, a, b)
137 struct timeval *tv, *a, *b;
138 {
139         tv->tv_sec = a->tv_sec - b->tv_sec;
140         tv->tv_usec = a->tv_usec - b->tv_usec;
141         if (((long) tv->tv_usec) < 0) {
142                 tv->tv_sec--;
143                 tv->tv_usec += 1000000;
144         }
145 }
146
147 void
148 tv_div(tv, a, n)
149 struct timeval *tv, *a;
150 int n;
151 {
152         tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
153         tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
154         tv->tv_usec %= 1000000;
155 }
156
157 void
158 tv_mul(tv, a, n)
159 struct timeval *tv, *a;
160 int n;
161 {
162         tv->tv_usec = a->tv_usec * n;
163         tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000;
164         tv->tv_usec %= 1000000;
165 }
166
167 const char *
168 xlookup(const struct xlat *xlat, int val)
169 {
170         for (; xlat->str != NULL; xlat++)
171                 if (xlat->val == val)
172                         return xlat->str;
173         return NULL;
174 }
175
176 /*
177  * Generic ptrace wrapper which tracks ESRCH errors
178  * by setting tcp->ptrace_errno to ESRCH.
179  *
180  * We assume that ESRCH indicates likely process death (SIGKILL?),
181  * modulo bugs where process somehow ended up not stopped.
182  * Unfortunately kernel uses ESRCH for that case too. Oh well.
183  *
184  * Currently used by upeek() only.
185  * TODO: use this in all other ptrace() calls while decoding.
186  */
187 long
188 do_ptrace(int request, struct tcb *tcp, void *addr, void *data)
189 {
190         long l;
191
192         errno = 0;
193         l = ptrace(request, tcp->pid, addr, (long) data);
194         /* Non-ESRCH errors might be our invalid reg/mem accesses,
195          * we do not record them. */
196         if (errno == ESRCH)
197                 tcp->ptrace_errno = ESRCH;
198         return l;
199 }
200
201 /*
202  * Used when we want to unblock stopped traced process.
203  * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL.
204  * Returns 0 on success or if error was ESRCH
205  * (presumably process was killed while we talk to it).
206  * Otherwise prints error message and returns -1.
207  */
208 int
209 ptrace_restart(int op, struct tcb *tcp, int sig)
210 {
211         int err;
212         const char *msg;
213
214         errno = 0;
215         ptrace(op, tcp->pid, (void *) 1, (long) sig);
216         err = errno;
217         if (!err || err == ESRCH)
218                 return 0;
219
220         tcp->ptrace_errno = err;
221         msg = "SYSCALL";
222         if (op == PTRACE_CONT)
223                 msg = "CONT";
224         if (op == PTRACE_DETACH)
225                 msg = "DETACH";
226         fprintf(stderr, "strace: ptrace(PTRACE_%s,1,%d): %s\n",
227                         msg, sig, strerror(err));
228         return -1;
229 }
230
231 /*
232  * Print entry in struct xlat table, if there.
233  */
234 void
235 printxval(const struct xlat *xlat, int val, const char *dflt)
236 {
237         const char *str = xlookup(xlat, val);
238
239         if (str)
240                 tprintf("%s", str);
241         else
242                 tprintf("%#x /* %s */", val, dflt);
243 }
244
245 #if HAVE_LONG_LONG
246 /*
247  * Print 64bit argument at position llarg and return the index of the next
248  * argument.
249  */
250 int
251 printllval(struct tcb *tcp, const char *format, int llarg)
252 {
253 # if defined(FREEBSD) \
254      || (defined(LINUX) && defined(POWERPC) && !defined(POWERPC64)) \
255      || defined (LINUX_MIPSO32)
256         /* Align 64bit argument to 64bit boundary.  */
257         if (llarg % 2) llarg++;
258 # endif
259 # if defined LINUX && (defined X86_64 || defined POWERPC64)
260         if (current_personality == 0) {
261                 tprintf(format, tcp->u_arg[llarg]);
262                 llarg++;
263         } else {
264 #  ifdef POWERPC64
265                 /* Align 64bit argument to 64bit boundary.  */
266                 if (llarg % 2) llarg++;
267 #  endif
268                 tprintf(format, LONG_LONG(tcp->u_arg[llarg], tcp->u_arg[llarg + 1]));
269                 llarg += 2;
270         }
271 # elif defined IA64 || defined ALPHA
272         tprintf(format, tcp->u_arg[llarg]);
273         llarg++;
274 # elif defined LINUX_MIPSN32
275         tprintf(format, tcp->ext_arg[llarg]);
276         llarg++;
277 # else
278         tprintf(format, LONG_LONG(tcp->u_arg[llarg], tcp->u_arg[llarg + 1]));
279         llarg += 2;
280 # endif
281         return llarg;
282 }
283 #endif
284
285 /*
286  * Interpret `xlat' as an array of flags
287  * print the entries whose bits are on in `flags'
288  * return # of flags printed.
289  */
290 int
291 addflags(xlat, flags)
292 const struct xlat *xlat;
293 int flags;
294 {
295         int n;
296
297         for (n = 0; xlat->str; xlat++) {
298                 if (xlat->val && (flags & xlat->val) == xlat->val) {
299                         tprintf("|%s", xlat->str);
300                         flags &= ~xlat->val;
301                         n++;
302                 }
303         }
304         if (flags) {
305                 tprintf("|%#x", flags);
306                 n++;
307         }
308         return n;
309 }
310
311 /*
312  * Interpret `xlat' as an array of flags/
313  * Print to static string the entries whose bits are on in `flags'
314  * Return static string.
315  */
316 const char *
317 sprintflags(const char *prefix, const struct xlat *xlat, int flags)
318 {
319         static char outstr[1024];
320         int found = 0;
321
322         strcpy(outstr, prefix);
323
324         for (; xlat->str; xlat++) {
325                 if ((flags & xlat->val) == xlat->val) {
326                         if (found)
327                                 strcat(outstr, "|");
328                         strcat(outstr, xlat->str);
329                         flags &= ~xlat->val;
330                         found = 1;
331                 }
332         }
333         if (flags) {
334                 if (found)
335                         strcat(outstr, "|");
336                 sprintf(outstr + strlen(outstr), "%#x", flags);
337         }
338
339         return outstr;
340 }
341
342 int
343 printflags(xlat, flags, dflt)
344 const struct xlat *xlat;
345 int flags;
346 const char *dflt;
347 {
348         int n;
349         char *sep;
350
351         if (flags == 0 && xlat->val == 0) {
352                 tprintf("%s", xlat->str);
353                 return 1;
354         }
355
356         sep = "";
357         for (n = 0; xlat->str; xlat++) {
358                 if (xlat->val && (flags & xlat->val) == xlat->val) {
359                         tprintf("%s%s", sep, xlat->str);
360                         flags &= ~xlat->val;
361                         sep = "|";
362                         n++;
363                 }
364         }
365
366         if (n) {
367                 if (flags) {
368                         tprintf("%s%#x", sep, flags);
369                         n++;
370                 }
371         } else {
372                 if (flags) {
373                         tprintf("%#x", flags);
374                         if (dflt)
375                                 tprintf(" /* %s */", dflt);
376                 } else {
377                         if (dflt)
378                                 tprintf("0");
379                 }
380         }
381
382         return n;
383 }
384
385 void
386 printnum(tcp, addr, fmt)
387 struct tcb *tcp;
388 long addr;
389 char *fmt;
390 {
391         long num;
392
393         if (!addr) {
394                 tprintf("NULL");
395                 return;
396         }
397         if (umove(tcp, addr, &num) < 0) {
398                 tprintf("%#lx", addr);
399                 return;
400         }
401         tprintf("[");
402         tprintf(fmt, num);
403         tprintf("]");
404 }
405
406 void
407 printnum_int(tcp, addr, fmt)
408 struct tcb *tcp;
409 long addr;
410 char *fmt;
411 {
412         int num;
413
414         if (!addr) {
415                 tprintf("NULL");
416                 return;
417         }
418         if (umove(tcp, addr, &num) < 0) {
419                 tprintf("%#lx", addr);
420                 return;
421         }
422         tprintf("[");
423         tprintf(fmt, num);
424         tprintf("]");
425 }
426
427 void
428 printuid(text, uid)
429 const char *text;
430 unsigned long uid;
431 {
432         tprintf("%s", text);
433         tprintf((uid == -1) ? "%ld" : "%lu", uid);
434 }
435
436 static char path[MAXPATHLEN + 1];
437
438 /*
439  * Quote string `instr' of length `size'
440  * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
441  * If `len' < 0, treat `instr' as a NUL-terminated string
442  * and quote at most (`size' - 1) bytes.
443  */
444 static int
445 string_quote(const char *instr, char *outstr, int len, int size)
446 {
447         const unsigned char *ustr = (const unsigned char *) instr;
448         char *s = outstr;
449         int usehex = 0, c, i;
450
451         if (xflag > 1)
452                 usehex = 1;
453         else if (xflag) {
454                 /* Check for presence of symbol which require
455                    to hex-quote the whole string. */
456                 for (i = 0; i < size; ++i) {
457                         c = ustr[i];
458                         /* Check for NUL-terminated string. */
459                         if (len < 0) {
460                                 if (c == '\0')
461                                         break;
462                                 /* Quote at most size - 1 bytes. */
463                                 if (i == size - 1)
464                                         continue;
465                         }
466                         if (!isprint(c) && !isspace(c)) {
467                                 usehex = 1;
468                                 break;
469                         }
470                 }
471         }
472
473         *s++ = '\"';
474
475         if (usehex) {
476                 /* Hex-quote the whole string. */
477                 for (i = 0; i < size; ++i) {
478                         c = ustr[i];
479                         /* Check for NUL-terminated string. */
480                         if (len < 0) {
481                                 if (c == '\0')
482                                         break;
483                                 /* Quote at most size - 1 bytes. */
484                                 if (i == size - 1)
485                                         continue;
486                         }
487                         sprintf(s, "\\x%02x", c);
488                         s += 4;
489                 }
490         } else {
491                 for (i = 0; i < size; ++i) {
492                         c = ustr[i];
493                         /* Check for NUL-terminated string. */
494                         if (len < 0) {
495                                 if (c == '\0')
496                                         break;
497                                 /* Quote at most size - 1 bytes. */
498                                 if (i == size - 1)
499                                         continue;
500                         }
501                         switch (c) {
502                                 case '\"': case '\\':
503                                         *s++ = '\\';
504                                         *s++ = c;
505                                         break;
506                                 case '\f':
507                                         *s++ = '\\';
508                                         *s++ = 'f';
509                                         break;
510                                 case '\n':
511                                         *s++ = '\\';
512                                         *s++ = 'n';
513                                         break;
514                                 case '\r':
515                                         *s++ = '\\';
516                                         *s++ = 'r';
517                                         break;
518                                 case '\t':
519                                         *s++ = '\\';
520                                         *s++ = 't';
521                                         break;
522                                 case '\v':
523                                         *s++ = '\\';
524                                         *s++ = 'v';
525                                         break;
526                                 default:
527                                         if (isprint(c))
528                                                 *s++ = c;
529                                         else if (i + 1 < size
530                                                  && isdigit(ustr[i + 1])) {
531                                                 sprintf(s, "\\%03o", c);
532                                                 s += 4;
533                                         } else {
534                                                 sprintf(s, "\\%o", c);
535                                                 s += strlen(s);
536                                         }
537                                         break;
538                         }
539                 }
540         }
541
542         *s++ = '\"';
543         *s = '\0';
544
545         /* Return nonzero if the string was unterminated.  */
546         return i == size;
547 }
548
549 /*
550  * Print path string specified by address `addr' and length `n'.
551  * If path length exceeds `n', append `...' to the output.
552  */
553 void
554 printpathn(struct tcb *tcp, long addr, int n)
555 {
556         if (!addr) {
557                 tprintf("NULL");
558                 return;
559         }
560
561         /* Cap path length to the path buffer size,
562            and NUL-terminate the buffer. */
563         if (n > sizeof path - 1)
564                 n = sizeof path - 1;
565         path[n] = '\0';
566
567         /* Fetch one byte more to find out whether path length > n. */
568         if (umovestr(tcp, addr, n + 1, path) < 0)
569                 tprintf("%#lx", addr);
570         else {
571                 static char outstr[4*(sizeof path - 1) + sizeof "\"...\""];
572                 int trunc = (path[n] != '\0');
573
574                 if (trunc)
575                         path[n] = '\0';
576                 (void) string_quote(path, outstr, -1, n + 1);
577                 if (trunc)
578                         strcat(outstr, "...");
579                 tprintf("%s", outstr);
580         }
581 }
582
583 void
584 printpath(struct tcb *tcp, long addr)
585 {
586         printpathn(tcp, addr, sizeof path - 1);
587 }
588
589 /*
590  * Print string specified by address `addr' and length `len'.
591  * If `len' < 0, treat the string as a NUL-terminated string.
592  * If string length exceeds `max_strlen', append `...' to the output.
593  */
594 void
595 printstr(struct tcb *tcp, long addr, int len)
596 {
597         static char *str = NULL;
598         static char *outstr;
599         int size;
600
601         if (!addr) {
602                 tprintf("NULL");
603                 return;
604         }
605         /* Allocate static buffers if they are not allocated yet. */
606         if (!str)
607                 str = malloc(max_strlen + 1);
608         if (!outstr)
609                 outstr = malloc(4 * max_strlen + sizeof "\"...\"");
610         if (!str || !outstr) {
611                 fprintf(stderr, "out of memory\n");
612                 tprintf("%#lx", addr);
613                 return;
614         }
615
616         if (len < 0) {
617                 /*
618                  * Treat as a NUL-terminated string: fetch one byte more
619                  * because string_quote() quotes one byte less.
620                  */
621                 size = max_strlen + 1;
622                 str[max_strlen] = '\0';
623                 if (umovestr(tcp, addr, size, str) < 0) {
624                         tprintf("%#lx", addr);
625                         return;
626                 }
627         }
628         else {
629                 size = MIN(len, max_strlen);
630                 if (umoven(tcp, addr, size, str) < 0) {
631                         tprintf("%#lx", addr);
632                         return;
633                 }
634         }
635
636         if (string_quote(str, outstr, len, size) &&
637             (len < 0 || len > max_strlen))
638                 strcat(outstr, "...");
639
640         tprintf("%s", outstr);
641 }
642
643 #if HAVE_SYS_UIO_H
644 void
645 dumpiov(tcp, len, addr)
646 struct tcb * tcp;
647 int len;
648 long addr;
649 {
650 #if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
651         union {
652                 struct { u_int32_t base; u_int32_t len; } *iov32;
653                 struct { u_int64_t base; u_int64_t len; } *iov64;
654         } iovu;
655 #define iov iovu.iov64
656 #define sizeof_iov \
657   (personality_wordsize[current_personality] == 4 \
658    ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64))
659 #define iov_iov_base(i) \
660   (personality_wordsize[current_personality] == 4 \
661    ? (u_int64_t) iovu.iov32[i].base : iovu.iov64[i].base)
662 #define iov_iov_len(i) \
663   (personality_wordsize[current_personality] == 4 \
664    ? (u_int64_t) iovu.iov32[i].len : iovu.iov64[i].len)
665 #else
666         struct iovec *iov;
667 #define sizeof_iov sizeof(*iov)
668 #define iov_iov_base(i) iov[i].iov_base
669 #define iov_iov_len(i) iov[i].iov_len
670 #endif
671         int i;
672         unsigned long size;
673
674         size = sizeof_iov * (unsigned long) len;
675         if (size / sizeof_iov != len
676             || (iov = malloc(size)) == NULL) {
677                 fprintf(stderr, "out of memory\n");
678                 return;
679         }
680         if (umoven(tcp, addr, size, (char *) iov) >= 0) {
681                 for (i = 0; i < len; i++) {
682                         /* include the buffer number to make it easy to
683                          * match up the trace with the source */
684                         tprintf(" * %lu bytes in buffer %d\n",
685                                 (unsigned long)iov_iov_len(i), i);
686                         dumpstr(tcp, (long) iov_iov_base(i),
687                                 iov_iov_len(i));
688                 }
689         }
690         free((char *) iov);
691 #undef sizeof_iov
692 #undef iov_iov_base
693 #undef iov_iov_len
694 #undef iov
695 }
696 #endif
697
698 void
699 dumpstr(tcp, addr, len)
700 struct tcb *tcp;
701 long addr;
702 int len;
703 {
704         static int strsize = -1;
705         static unsigned char *str;
706         static char outstr[80];
707         char *s;
708         int i, j;
709
710         if (strsize < len) {
711                 if (str)
712                         free(str);
713                 if ((str = malloc(len)) == NULL) {
714                         fprintf(stderr, "out of memory\n");
715                         return;
716                 }
717                 strsize = len;
718         }
719
720         if (umoven(tcp, addr, len, (char *) str) < 0)
721                 return;
722
723         for (i = 0; i < len; i += 16) {
724                 s = outstr;
725                 sprintf(s, " | %05x ", i);
726                 s += 9;
727                 for (j = 0; j < 16; j++) {
728                         if (j == 8)
729                                 *s++ = ' ';
730                         if (i + j < len) {
731                                 sprintf(s, " %02x", str[i + j]);
732                                 s += 3;
733                         }
734                         else {
735                                 *s++ = ' '; *s++ = ' '; *s++ = ' ';
736                         }
737                 }
738                 *s++ = ' '; *s++ = ' ';
739                 for (j = 0; j < 16; j++) {
740                         if (j == 8)
741                                 *s++ = ' ';
742                         if (i + j < len) {
743                                 if (isprint(str[i + j]))
744                                         *s++ = str[i + j];
745                                 else
746                                         *s++ = '.';
747                         }
748                         else
749                                 *s++ = ' ';
750                 }
751                 tprintf("%s |\n", outstr);
752         }
753 }
754
755 #define PAGMASK (~(PAGSIZ - 1))
756 /*
757  * move `len' bytes of data from process `pid'
758  * at address `addr' to our space at `laddr'
759  */
760 int
761 umoven(struct tcb *tcp, long addr, int len, char *laddr)
762 {
763 #ifdef LINUX
764         int pid = tcp->pid;
765         int n, m;
766         int started = 0;
767         union {
768                 long val;
769                 char x[sizeof(long)];
770         } u;
771
772         if (addr & (sizeof(long) - 1)) {
773                 /* addr not a multiple of sizeof(long) */
774                 n = addr - (addr & -sizeof(long)); /* residue */
775                 addr &= -sizeof(long); /* residue */
776                 errno = 0;
777                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
778                 if (errno) {
779                         if (started && (errno==EPERM || errno==EIO)) {
780                                 /* Ran into 'end of memory' - stupid "printpath" */
781                                 return 0;
782                         }
783                         /* But if not started, we had a bogus address. */
784                         if (addr != 0 && errno != EIO && errno != ESRCH)
785                                 perror("ptrace: umoven");
786                         return -1;
787                 }
788                 started = 1;
789                 memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
790                 addr += sizeof(long), laddr += m, len -= m;
791         }
792         while (len) {
793                 errno = 0;
794                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
795                 if (errno) {
796                         if (started && (errno==EPERM || errno==EIO)) {
797                                 /* Ran into 'end of memory' - stupid "printpath" */
798                                 return 0;
799                         }
800                         if (addr != 0 && errno != EIO && errno != ESRCH)
801                                 perror("ptrace: umoven");
802                         return -1;
803                 }
804                 started = 1;
805                 memcpy(laddr, u.x, m = MIN(sizeof(long), len));
806                 addr += sizeof(long), laddr += m, len -= m;
807         }
808 #endif /* LINUX */
809
810 #ifdef SUNOS4
811         int pid = tcp->pid;
812         int n;
813
814         while (len) {
815                 n = MIN(len, PAGSIZ);
816                 n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
817                 if (ptrace(PTRACE_READDATA, pid,
818                            (char *) addr, len, laddr) < 0) {
819                         if (errno != ESRCH) {
820                                 perror("umoven: ptrace(PTRACE_READDATA, ...)");
821                                 abort();
822                         }
823                         return -1;
824                 }
825                 len -= n;
826                 addr += n;
827                 laddr += n;
828         }
829 #endif /* SUNOS4 */
830
831 #ifdef USE_PROCFS
832 #ifdef HAVE_MP_PROCFS
833         int fd = tcp->pfd_as;
834 #else
835         int fd = tcp->pfd;
836 #endif
837         lseek(fd, addr, SEEK_SET);
838         if (read(fd, laddr, len) == -1)
839                 return -1;
840 #endif /* USE_PROCFS */
841
842         return 0;
843 }
844
845 /*
846  * like `umove' but make the additional effort of looking
847  * for a terminating zero byte.
848  */
849 int
850 umovestr(struct tcb *tcp, long addr, int len, char *laddr)
851 {
852 #ifdef USE_PROCFS
853 #ifdef HAVE_MP_PROCFS
854         int fd = tcp->pfd_as;
855 #else
856         int fd = tcp->pfd;
857 #endif
858         /* Some systems (e.g. FreeBSD) can be upset if we read off the
859            end of valid memory,  avoid this by trying to read up
860            to page boundaries.  But we don't know what a page is (and
861            getpagesize(2) (if it exists) doesn't necessarily return
862            hardware page size).  Assume all pages >= 1024 (a-historical
863            I know) */
864
865         int page = 1024;        /* How to find this? */
866         int move = page - (addr & (page - 1));
867         int left = len;
868
869         lseek(fd, addr, SEEK_SET);
870
871         while (left) {
872                 if (move > left) move = left;
873                 if ((move = read(fd, laddr, move)) <= 0)
874                         return left != len ? 0 : -1;
875                 if (memchr (laddr, 0, move)) break;
876                 left -= move;
877                 laddr += move;
878                 addr += move;
879                 move = page;
880         }
881 #else /* !USE_PROCFS */
882         int started = 0;
883         int pid = tcp->pid;
884         int i, n, m;
885         union {
886                 long val;
887                 char x[sizeof(long)];
888         } u;
889
890         if (addr & (sizeof(long) - 1)) {
891                 /* addr not a multiple of sizeof(long) */
892                 n = addr - (addr & -sizeof(long)); /* residue */
893                 addr &= -sizeof(long); /* residue */
894                 errno = 0;
895                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
896                 if (errno) {
897                         if (started && (errno==EPERM || errno==EIO)) {
898                                 /* Ran into 'end of memory' - stupid "printpath" */
899                                 return 0;
900                         }
901                         if (addr != 0 && errno != EIO && errno != ESRCH)
902                                 perror("umovestr");
903                         return -1;
904                 }
905                 started = 1;
906                 memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len));
907                 while (n & (sizeof(long) - 1))
908                         if (u.x[n++] == '\0')
909                                 return 0;
910                 addr += sizeof(long), laddr += m, len -= m;
911         }
912         while (len) {
913                 errno = 0;
914                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
915                 if (errno) {
916                         if (started && (errno==EPERM || errno==EIO)) {
917                                 /* Ran into 'end of memory' - stupid "printpath" */
918                                 return 0;
919                         }
920                         if (addr != 0 && errno != EIO && errno != ESRCH)
921                                 perror("umovestr");
922                         return -1;
923                 }
924                 started = 1;
925                 memcpy(laddr, u.x, m = MIN(sizeof(long), len));
926                 for (i = 0; i < sizeof(long); i++)
927                         if (u.x[i] == '\0')
928                                 return 0;
929
930                 addr += sizeof(long), laddr += m, len -= m;
931         }
932 #endif /* !USE_PROCFS */
933         return 0;
934 }
935
936 #ifdef LINUX
937 # if !defined (SPARC) && !defined(SPARC64)
938 #  define PTRACE_WRITETEXT      101
939 #  define PTRACE_WRITEDATA      102
940 # endif /* !SPARC && !SPARC64 */
941 #endif /* LINUX */
942
943 #ifdef SUNOS4
944
945 static int
946 uload(cmd, pid, addr, len, laddr)
947 int cmd;
948 int pid;
949 long addr;
950 int len;
951 char *laddr;
952 {
953         int peek, poke;
954         int n, m;
955         union {
956                 long val;
957                 char x[sizeof(long)];
958         } u;
959
960         if (cmd == PTRACE_WRITETEXT) {
961                 peek = PTRACE_PEEKTEXT;
962                 poke = PTRACE_POKETEXT;
963         }
964         else {
965                 peek = PTRACE_PEEKDATA;
966                 poke = PTRACE_POKEDATA;
967         }
968         if (addr & (sizeof(long) - 1)) {
969                 /* addr not a multiple of sizeof(long) */
970                 n = addr - (addr & -sizeof(long)); /* residue */
971                 addr &= -sizeof(long);
972                 errno = 0;
973                 u.val = ptrace(peek, pid, (char *) addr, 0);
974                 if (errno) {
975                         perror("uload: POKE");
976                         return -1;
977                 }
978                 memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len));
979                 if (ptrace(poke, pid, (char *)addr, u.val) < 0) {
980                         perror("uload: POKE");
981                         return -1;
982                 }
983                 addr += sizeof(long), laddr += m, len -= m;
984         }
985         while (len) {
986                 if (len < sizeof(long))
987                         u.val = ptrace(peek, pid, (char *) addr, 0);
988                 memcpy(u.x, laddr, m = MIN(sizeof(long), len));
989                 if (ptrace(poke, pid, (char *) addr, u.val) < 0) {
990                         perror("uload: POKE");
991                         return -1;
992                 }
993                 addr += sizeof(long), laddr += m, len -= m;
994         }
995         return 0;
996 }
997
998 int
999 tload(pid, addr, len, laddr)
1000 int pid;
1001 int addr, len;
1002 char *laddr;
1003 {
1004         return uload(PTRACE_WRITETEXT, pid, addr, len, laddr);
1005 }
1006
1007 int
1008 dload(pid, addr, len, laddr)
1009 int pid;
1010 int addr;
1011 int len;
1012 char *laddr;
1013 {
1014         return uload(PTRACE_WRITEDATA, pid, addr, len, laddr);
1015 }
1016
1017 #endif /* SUNOS4 */
1018
1019 #ifndef USE_PROCFS
1020
1021 int
1022 upeek(tcp, off, res)
1023 struct tcb *tcp;
1024 long off;
1025 long *res;
1026 {
1027         long val;
1028
1029 # ifdef SUNOS4_KERNEL_ARCH_KLUDGE
1030         {
1031                 static int is_sun4m = -1;
1032                 struct utsname name;
1033
1034                 /* Round up the usual suspects. */
1035                 if (is_sun4m == -1) {
1036                         if (uname(&name) < 0) {
1037                                 perror("upeek: uname?");
1038                                 exit(1);
1039                         }
1040                         is_sun4m = strcmp(name.machine, "sun4m") == 0;
1041                         if (is_sun4m) {
1042                                 const struct xlat *x;
1043
1044                                 for (x = struct_user_offsets; x->str; x++)
1045                                         x->val += 1024;
1046                         }
1047                 }
1048                 if (is_sun4m)
1049                         off += 1024;
1050         }
1051 # endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
1052         errno = 0;
1053         val = do_ptrace(PTRACE_PEEKUSER, tcp, (char *) off, 0);
1054         if (val == -1 && errno) {
1055                 if (errno != ESRCH) {
1056                         char buf[60];
1057                         sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)", tcp->pid, off);
1058                         perror(buf);
1059                 }
1060                 return -1;
1061         }
1062         *res = val;
1063         return 0;
1064 }
1065
1066 #endif /* !USE_PROCFS */
1067
1068 void
1069 printcall(struct tcb *tcp)
1070 {
1071 #define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \
1072                            sizeof(long) == 8 ? "[????????????????] " : \
1073                            NULL /* crash */)
1074
1075 #ifdef LINUX
1076 # ifdef I386
1077         long eip;
1078
1079         if (upeek(tcp, 4*EIP, &eip) < 0) {
1080                 PRINTBADPC;
1081                 return;
1082         }
1083         tprintf("[%08lx] ", eip);
1084
1085 # elif defined(S390) || defined(S390X)
1086         long psw;
1087         if(upeek(tcp,PT_PSWADDR,&psw) < 0) {
1088                 PRINTBADPC;
1089                 return;
1090         }
1091 #  ifdef S390
1092         tprintf("[%08lx] ", psw);
1093 #  elif S390X
1094         tprintf("[%16lx] ", psw);
1095 #  endif
1096
1097 # elif defined(X86_64)
1098         long rip;
1099
1100         if (upeek(tcp, 8*RIP, &rip) < 0) {
1101                 PRINTBADPC;
1102                 return;
1103         }
1104         tprintf("[%16lx] ", rip);
1105 # elif defined(IA64)
1106         long ip;
1107
1108         if (upeek(tcp, PT_B0, &ip) < 0) {
1109                 PRINTBADPC;
1110                 return;
1111         }
1112         tprintf("[%08lx] ", ip);
1113 # elif defined(POWERPC)
1114         long pc;
1115
1116         if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) {
1117                 PRINTBADPC;
1118                 return;
1119         }
1120 #  ifdef POWERPC64
1121         tprintf("[%016lx] ", pc);
1122 #  else
1123         tprintf("[%08lx] ", pc);
1124 #  endif
1125 # elif defined(M68K)
1126         long pc;
1127
1128         if (upeek(tcp, 4*PT_PC, &pc) < 0) {
1129                 tprintf ("[????????] ");
1130                 return;
1131         }
1132         tprintf("[%08lx] ", pc);
1133 # elif defined(ALPHA)
1134         long pc;
1135
1136         if (upeek(tcp, REG_PC, &pc) < 0) {
1137                 tprintf ("[????????????????] ");
1138                 return;
1139         }
1140         tprintf("[%08lx] ", pc);
1141 # elif defined(SPARC) || defined(SPARC64)
1142         struct pt_regs regs;
1143         if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0) {
1144                 PRINTBADPC;
1145                 return;
1146         }
1147 #  if defined(SPARC64)
1148         tprintf("[%08lx] ", regs.tpc);
1149 #  else
1150         tprintf("[%08lx] ", regs.pc);
1151 #  endif
1152 # elif defined(HPPA)
1153         long pc;
1154
1155         if(upeek(tcp,PT_IAOQ0,&pc) < 0) {
1156                 tprintf ("[????????] ");
1157                 return;
1158         }
1159         tprintf("[%08lx] ", pc);
1160 # elif defined(MIPS)
1161         long pc;
1162
1163         if (upeek(tcp, REG_EPC, &pc) < 0) {
1164                 tprintf ("[????????] ");
1165                 return;
1166         }
1167         tprintf("[%08lx] ", pc);
1168 # elif defined(SH)
1169         long pc;
1170
1171         if (upeek(tcp, 4*REG_PC, &pc) < 0) {
1172                 tprintf ("[????????] ");
1173                 return;
1174         }
1175         tprintf("[%08lx] ", pc);
1176 # elif defined(SH64)
1177         long pc;
1178
1179         if (upeek(tcp, REG_PC, &pc) < 0) {
1180                 tprintf ("[????????????????] ");
1181                 return;
1182         }
1183         tprintf("[%08lx] ", pc);
1184 # elif defined(ARM)
1185         long pc;
1186
1187         if (upeek(tcp, 4*15, &pc) < 0) {
1188                 PRINTBADPC;
1189                 return;
1190         }
1191         tprintf("[%08lx] ", pc);
1192 # elif defined(AVR32)
1193         long pc;
1194
1195         if (upeek(tcp, REG_PC, &pc) < 0) {
1196                 tprintf("[????????] ");
1197                 return;
1198         }
1199         tprintf("[%08lx] ", pc);
1200 # elif defined(BFIN)
1201         long pc;
1202
1203         if (upeek(tcp, PT_PC, &pc) < 0) {
1204                 PRINTBADPC;
1205                 return;
1206         }
1207         tprintf("[%08lx] ", pc);
1208 #elif defined(CRISV10)
1209         long pc;
1210
1211         if (upeek(tcp, 4*PT_IRP, &pc) < 0) {
1212                 PRINTBADPC;
1213                 return;
1214         }
1215         tprintf("[%08lx] ", pc);
1216 #elif defined(CRISV32)
1217         long pc;
1218
1219         if (upeek(tcp, 4*PT_ERP, &pc) < 0) {
1220                 PRINTBADPC;
1221                 return;
1222         }
1223         tprintf("[%08lx] ", pc);
1224 # endif /* architecture */
1225 #endif /* LINUX */
1226
1227 #ifdef SUNOS4
1228         struct regs regs;
1229
1230         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
1231                 perror("printcall: ptrace(PTRACE_GETREGS, ...)");
1232                 PRINTBADPC;
1233                 return;
1234         }
1235         tprintf("[%08x] ", regs.r_o7);
1236 #endif /* SUNOS4 */
1237
1238 #ifdef SVR4
1239         /* XXX */
1240         PRINTBADPC;
1241 #endif
1242
1243 #ifdef FREEBSD
1244         struct reg regs;
1245         pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
1246         tprintf("[%08x] ", regs.r_eip);
1247 #endif /* FREEBSD */
1248 }
1249
1250
1251 /*
1252  * These #if's are huge, please indent them correctly.
1253  * It's easy to get confused otherwise.
1254  */
1255 #ifndef USE_PROCFS
1256
1257 #ifdef LINUX
1258
1259 #  include "syscall.h"
1260
1261 #  include <sys/syscall.h>
1262 #  ifndef CLONE_PTRACE
1263 #   define CLONE_PTRACE    0x00002000
1264 #  endif
1265 #  ifndef CLONE_VFORK
1266 #   define CLONE_VFORK     0x00004000
1267 #  endif
1268 #  ifndef CLONE_VM
1269 #   define CLONE_VM        0x00000100
1270 #  endif
1271 #  ifndef CLONE_STOPPED
1272 #   define CLONE_STOPPED   0x02000000
1273 #  endif
1274
1275 #  ifdef IA64
1276
1277 /* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32
1278    subsystem has them for x86... */
1279 #   define SYS_fork     2
1280 #   define SYS_vfork    190
1281
1282 typedef unsigned long *arg_setup_state;
1283
1284 static int
1285 arg_setup(struct tcb *tcp, arg_setup_state *state)
1286 {
1287         unsigned long cfm, sof, sol;
1288         long bsp;
1289
1290         if (ia32) {
1291                 /* Satisfy a false GCC warning.  */
1292                 *state = NULL;
1293                 return 0;
1294         }
1295
1296         if (upeek(tcp, PT_AR_BSP, &bsp) < 0)
1297                 return -1;
1298         if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
1299                 return -1;
1300
1301         sof = (cfm >> 0) & 0x7f;
1302         sol = (cfm >> 7) & 0x7f;
1303         bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol);
1304
1305         *state = (unsigned long *) bsp;
1306         return 0;
1307 }
1308
1309 #   define arg_finish_change(tcp, state)        0
1310
1311 #   ifdef SYS_fork
1312 static int
1313 get_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp)
1314 {
1315         int ret;
1316
1317         if (ia32)
1318                 ret = upeek (tcp, PT_R11, valp);
1319         else
1320                 ret = umoven (tcp,
1321                               (unsigned long) ia64_rse_skip_regs(*state, 0),
1322                               sizeof(long), (void *) valp);
1323         return ret;
1324 }
1325
1326 static int
1327 get_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp)
1328 {
1329         int ret;
1330
1331         if (ia32)
1332                 ret = upeek (tcp, PT_R9, valp);
1333         else
1334                 ret = umoven (tcp,
1335                               (unsigned long) ia64_rse_skip_regs(*state, 1),
1336                               sizeof(long), (void *) valp);
1337         return ret;
1338 }
1339 #   endif
1340
1341 static int
1342 set_arg0 (struct tcb *tcp, arg_setup_state *state, long val)
1343 {
1344         int req = PTRACE_POKEDATA;
1345         void *ap;
1346
1347         if (ia32) {
1348                 ap = (void *) (intptr_t) PT_R11;         /* r11 == EBX */
1349                 req = PTRACE_POKEUSER;
1350         } else
1351                 ap = ia64_rse_skip_regs(*state, 0);
1352         errno = 0;
1353         ptrace(req, tcp->pid, ap, val);
1354         return errno ? -1 : 0;
1355 }
1356
1357 static int
1358 set_arg1 (struct tcb *tcp, arg_setup_state *state, long val)
1359 {
1360         int req = PTRACE_POKEDATA;
1361         void *ap;
1362
1363         if (ia32) {
1364                 ap = (void *) (intptr_t) PT_R9;         /* r9 == ECX */
1365                 req = PTRACE_POKEUSER;
1366         } else
1367                 ap = ia64_rse_skip_regs(*state, 1);
1368         errno = 0;
1369         ptrace(req, tcp->pid, ap, val);
1370         return errno ? -1 : 0;
1371 }
1372
1373 /* ia64 does not return the input arguments from functions (and syscalls)
1374    according to ia64 RSE (Register Stack Engine) behavior.  */
1375
1376 #   define restore_arg0(tcp, state, val) ((void) (state), 0)
1377 #   define restore_arg1(tcp, state, val) ((void) (state), 0)
1378
1379 #  elif defined (SPARC) || defined (SPARC64)
1380
1381 typedef struct pt_regs arg_setup_state;
1382
1383 #   define arg_setup(tcp, state) \
1384     (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0))
1385 #   define arg_finish_change(tcp, state) \
1386     (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0))
1387
1388 #   define get_arg0(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O0], 0)
1389 #   define get_arg1(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O1], 0)
1390 #   define set_arg0(tcp, state, val) ((state)->u_regs[U_REG_O0] = (val), 0)
1391 #   define set_arg1(tcp, state, val) ((state)->u_regs[U_REG_O1] = (val), 0)
1392 #   define restore_arg0(tcp, state, val) 0
1393
1394 #  else /* other architectures */
1395
1396 #   if defined S390 || defined S390X
1397 /* Note: this is only true for the `clone' system call, which handles
1398    arguments specially.  We could as well say that its first two arguments
1399    are swapped relative to other architectures, but that would just be
1400    another #ifdef in the calls.  */
1401 #    define arg0_offset PT_GPR3
1402 #    define arg1_offset PT_ORIGGPR2
1403 #    define restore_arg0(tcp, state, val) ((void) (state), 0)
1404 #    define restore_arg1(tcp, state, val) ((void) (state), 0)
1405 #    define arg0_index  1
1406 #    define arg1_index  0
1407 #   elif defined (ALPHA) || defined (MIPS)
1408 #    define arg0_offset REG_A0
1409 #    define arg1_offset (REG_A0+1)
1410 #   elif defined (AVR32)
1411 #    define arg0_offset (REG_R12)
1412 #    define arg1_offset (REG_R11)
1413 #   elif defined (POWERPC)
1414 #    define arg0_offset (sizeof(unsigned long)*PT_R3)
1415 #    define arg1_offset (sizeof(unsigned long)*PT_R4)
1416 #    define restore_arg0(tcp, state, val) ((void) (state), 0)
1417 #   elif defined (HPPA)
1418 #    define arg0_offset  PT_GR26
1419 #    define arg1_offset  (PT_GR26-4)
1420 #   elif defined (X86_64)
1421 #    define arg0_offset ((long)(8*(current_personality ? RBX : RDI)))
1422 #    define arg1_offset ((long)(8*(current_personality ? RCX : RSI)))
1423 #   elif defined (SH)
1424 #    define arg0_offset (4*(REG_REG0+4))
1425 #    define arg1_offset (4*(REG_REG0+5))
1426 #   elif defined (SH64)
1427     /* ABI defines arg0 & 1 in r2 & r3 */
1428 #    define arg0_offset   (REG_OFFSET+16)
1429 #    define arg1_offset   (REG_OFFSET+24)
1430 #    define restore_arg0(tcp, state, val) 0
1431 #   elif defined CRISV10 || defined CRISV32
1432 #    define arg0_offset   (4*PT_R11)
1433 #    define arg1_offset   (4*PT_ORIG_R10)
1434 #    define restore_arg0(tcp, state, val) 0
1435 #    define restore_arg1(tcp, state, val) 0
1436 #    define arg0_index   1
1437 #    define arg1_index   0
1438 #   else
1439 #    define arg0_offset 0
1440 #    define arg1_offset 4
1441 #    if defined ARM
1442 #     define restore_arg0(tcp, state, val) 0
1443 #    endif
1444 #   endif
1445
1446 typedef int arg_setup_state;
1447
1448 #   define arg_setup(tcp, state) (0)
1449 #   define arg_finish_change(tcp, state)        0
1450 #   define get_arg0(tcp, cookie, valp) \
1451     (upeek ((tcp), arg0_offset, (valp)))
1452 #   define get_arg1(tcp, cookie, valp) \
1453     (upeek ((tcp), arg1_offset, (valp)))
1454
1455 static int
1456 set_arg0 (struct tcb *tcp, void *cookie, long val)
1457 {
1458         return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val);
1459 }
1460
1461 static int
1462 set_arg1 (struct tcb *tcp, void *cookie, long val)
1463 {
1464         return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val);
1465 }
1466
1467 #  endif /* architectures */
1468
1469 #  ifndef restore_arg0
1470 #   define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val))
1471 #  endif
1472 #  ifndef restore_arg1
1473 #   define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val))
1474 #  endif
1475
1476 #  ifndef arg0_index
1477 #   define arg0_index 0
1478 #   define arg1_index 1
1479 #  endif
1480
1481 int
1482 setbpt(struct tcb *tcp)
1483 {
1484         static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone };
1485         arg_setup_state state;
1486
1487         if (tcp->flags & TCB_BPTSET) {
1488                 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1489                 return -1;
1490         }
1491
1492         /*
1493          * It's a silly kludge to initialize this with a search at runtime.
1494          * But it's better than maintaining another magic thing in the
1495          * godforsaken tables.
1496          */
1497         if (clone_scno[current_personality] == 0) {
1498                 int i;
1499                 for (i = 0; i < nsyscalls; ++i)
1500                         if (sysent[i].sys_func == sys_clone) {
1501                                 clone_scno[current_personality] = i;
1502                                 break;
1503                         }
1504         }
1505
1506         switch (known_scno(tcp)) {
1507 #  ifdef SYS_vfork
1508         case SYS_vfork:
1509 #  endif
1510 #  ifdef SYS_fork
1511         case SYS_fork:
1512 #  endif
1513 #  if defined SYS_fork || defined SYS_vfork
1514                 if (arg_setup (tcp, &state) < 0
1515                     || get_arg0 (tcp, &state, &tcp->inst[0]) < 0
1516                     || get_arg1 (tcp, &state, &tcp->inst[1]) < 0
1517                     || change_syscall(tcp, clone_scno[current_personality]) < 0
1518                     || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0
1519                     || set_arg1 (tcp, &state, 0) < 0
1520                     || arg_finish_change (tcp, &state) < 0)
1521                         return -1;
1522                 tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD;
1523                 tcp->u_arg[arg1_index] = 0;
1524                 tcp->flags |= TCB_BPTSET;
1525                 return 0;
1526 #  endif
1527
1528         case SYS_clone:
1529 #  ifdef SYS_clone2
1530         case SYS_clone2:
1531 #  endif
1532                 /* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)'
1533                    contrary to x86 SYS_vfork above.  Even on x86 we turn the
1534                    vfork semantics into plain fork - each application must not
1535                    depend on the vfork specifics according to POSIX.  We would
1536                    hang waiting for the parent resume otherwise.  We need to
1537                    clear also CLONE_VM but only in the CLONE_VFORK case as
1538                    otherwise we would break pthread_create.  */
1539
1540                 if ((arg_setup (tcp, &state) < 0
1541                     || set_arg0 (tcp, &state,
1542                                  (tcp->u_arg[arg0_index] | CLONE_PTRACE)
1543                                  & ~(tcp->u_arg[arg0_index] & CLONE_VFORK
1544                                      ? CLONE_VFORK | CLONE_VM : 0)) < 0
1545                     || arg_finish_change (tcp, &state) < 0))
1546                         return -1;
1547                 tcp->flags |= TCB_BPTSET;
1548                 tcp->inst[0] = tcp->u_arg[arg0_index];
1549                 tcp->inst[1] = tcp->u_arg[arg1_index];
1550                 return 0;
1551
1552         default:
1553                 fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n",
1554                         tcp->scno, tcp->pid);
1555                 break;
1556         }
1557
1558         return -1;
1559 }
1560
1561 int
1562 clearbpt(tcp)
1563 struct tcb *tcp;
1564 {
1565         arg_setup_state state;
1566         if (arg_setup (tcp, &state) < 0
1567             || restore_arg0 (tcp, &state, tcp->inst[0]) < 0
1568             || restore_arg1 (tcp, &state, tcp->inst[1]) < 0
1569             || arg_finish_change (tcp, &state))
1570                 if (errno != ESRCH) return -1;
1571         tcp->flags &= ~TCB_BPTSET;
1572         return 0;
1573 }
1574
1575 # else /* !defined LINUX */
1576
1577 int
1578 setbpt(tcp)
1579 struct tcb *tcp;
1580 {
1581 #  ifdef SUNOS4
1582 #   ifdef SPARC /* This code is slightly sparc specific */
1583
1584         struct regs regs;
1585 #    define BPT 0x91d02001      /* ta   1 */
1586 #    define LOOP        0x10800000      /* ba   0 */
1587 #    define LOOPA       0x30800000      /* ba,a 0 */
1588 #    define NOP 0x01000000
1589 #    if LOOPA
1590         static int loopdeloop[1] = {LOOPA};
1591 #    else
1592         static int loopdeloop[2] = {LOOP, NOP};
1593 #    endif
1594
1595         if (tcp->flags & TCB_BPTSET) {
1596                 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1597                 return -1;
1598         }
1599         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1600                 perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
1601                 return -1;
1602         }
1603         tcp->baddr = regs.r_o7 + 8;
1604         if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr,
1605                                 sizeof tcp->inst, (char *)tcp->inst) < 0) {
1606                 perror("setbpt: ptrace(PTRACE_READTEXT, ...)");
1607                 return -1;
1608         }
1609
1610         /*
1611          * XXX - BRUTAL MODE ON
1612          * We cannot set a real BPT in the child, since it will not be
1613          * traced at the moment it will reach the trap and would probably
1614          * die with a core dump.
1615          * Thus, we are force our way in by taking out two instructions
1616          * and insert an eternal loop in stead, in expectance of the SIGSTOP
1617          * generated by out PTRACE_ATTACH.
1618          * Of cause, if we evaporate ourselves in the middle of all this...
1619          */
1620         if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
1621                         sizeof loopdeloop, (char *) loopdeloop) < 0) {
1622                 perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)");
1623                 return -1;
1624         }
1625         tcp->flags |= TCB_BPTSET;
1626
1627 #   endif /* SPARC */
1628 #  endif /* SUNOS4 */
1629
1630         return 0;
1631 }
1632
1633 int
1634 clearbpt(tcp)
1635 struct tcb *tcp;
1636 {
1637 #  ifdef SUNOS4
1638 #   ifdef SPARC
1639
1640 #    if !LOOPA
1641         struct regs regs;
1642 #    endif
1643
1644         if (!(tcp->flags & TCB_BPTSET)) {
1645                 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
1646                 return -1;
1647         }
1648         if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
1649                                 sizeof tcp->inst, (char *) tcp->inst) < 0) {
1650                 perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)");
1651                 return -1;
1652         }
1653         tcp->flags &= ~TCB_BPTSET;
1654
1655 #    if !LOOPA
1656         /*
1657          * Since we don't have a single instruction breakpoint, we may have
1658          * to adjust the program counter after removing our `breakpoint'.
1659          */
1660         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1661                 perror("clearbpt: ptrace(PTRACE_GETREGS, ...)");
1662                 return -1;
1663         }
1664         if ((regs.r_pc < tcp->baddr) ||
1665                                 (regs.r_pc > tcp->baddr + 4)) {
1666                 /* The breakpoint has not been reached yet */
1667                 if (debug)
1668                         fprintf(stderr,
1669                                 "NOTE: PC not at bpt (pc %#x baddr %#x)\n",
1670                                         regs.r_pc, tcp->baddr);
1671                 return 0;
1672         }
1673         if (regs.r_pc != tcp->baddr)
1674                 if (debug)
1675                         fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n",
1676                                 regs.r_pc, tcp->baddr);
1677
1678         regs.r_pc = tcp->baddr;
1679         if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1680                 perror("clearbpt: ptrace(PTRACE_SETREGS, ...)");
1681                 return -1;
1682         }
1683 #    endif /* LOOPA */
1684 #   endif /* SPARC */
1685 #  endif /* SUNOS4 */
1686
1687         return 0;
1688 }
1689
1690 # endif /* !defined LINUX */
1691
1692 #endif /* !USE_PROCFS */
1693
1694
1695 #ifdef SUNOS4
1696
1697 static int
1698 getex(tcp, hdr)
1699 struct tcb *tcp;
1700 struct exec *hdr;
1701 {
1702         int n;
1703
1704         for (n = 0; n < sizeof *hdr; n += 4) {
1705                 long res;
1706                 if (upeek(tcp, uoff(u_exdata) + n, &res) < 0)
1707                         return -1;
1708                 memcpy(((char *) hdr) + n, &res, 4);
1709         }
1710         if (debug) {
1711                 fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n",
1712                         hdr->a_magic, hdr->a_toolversion, hdr->a_machtype);
1713                 fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n",
1714                         hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry);
1715         }
1716         return 0;
1717 }
1718
1719 int
1720 fixvfork(tcp)
1721 struct tcb *tcp;
1722 {
1723         int pid = tcp->pid;
1724         /*
1725          * Change `vfork' in a freshly exec'ed dynamically linked
1726          * executable's (internal) symbol table to plain old `fork'
1727          */
1728
1729         struct exec hdr;
1730         struct link_dynamic dyn;
1731         struct link_dynamic_2 ld;
1732         char *strtab, *cp;
1733
1734         if (getex(tcp, &hdr) < 0)
1735                 return -1;
1736         if (!hdr.a_dynamic)
1737                 return -1;
1738
1739         if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) {
1740                 fprintf(stderr, "Cannot read DYNAMIC\n");
1741                 return -1;
1742         }
1743         if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) {
1744                 fprintf(stderr, "Cannot read link_dynamic_2\n");
1745                 return -1;
1746         }
1747         if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) {
1748                 fprintf(stderr, "out of memory\n");
1749                 return -1;
1750         }
1751         if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
1752                                         (int)ld.ld_symb_size, strtab) < 0)
1753                 goto err;
1754
1755         for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
1756                 if (strcmp(cp, "_vfork") == 0) {
1757                         if (debug)
1758                                 fprintf(stderr, "fixvfork: FOUND _vfork\n");
1759                         strcpy(cp, "_fork");
1760                         break;
1761                 }
1762                 cp += strlen(cp)+1;
1763         }
1764         if (cp < strtab + ld.ld_symb_size)
1765                 /*
1766                  * Write entire symbol table back to avoid
1767                  * memory alignment bugs in ptrace
1768                  */
1769                 if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
1770                                         (int)ld.ld_symb_size, strtab) < 0)
1771                         goto err;
1772
1773         free(strtab);
1774         return 0;
1775
1776 err:
1777         free(strtab);
1778         return -1;
1779 }
1780
1781 #endif /* SUNOS4 */