]> granicus.if.org Git - strace/blob - util.c
84baf7a194c13404cec7d6f2a5d665004625e193
[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 #if 0
97 void
98 tv_tv(tv, a, b)
99 struct timeval *tv;
100 int a;
101 int b;
102 {
103         tv->tv_sec = a;
104         tv->tv_usec = b;
105 }
106 #endif
107
108 int
109 tv_nz(a)
110 struct timeval *a;
111 {
112         return a->tv_sec || a->tv_usec;
113 }
114
115 int
116 tv_cmp(a, b)
117 struct timeval *a, *b;
118 {
119         if (a->tv_sec < b->tv_sec
120             || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
121                 return -1;
122         if (a->tv_sec > b->tv_sec
123             || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
124                 return 1;
125         return 0;
126 }
127
128 double
129 tv_float(tv)
130 struct timeval *tv;
131 {
132         return tv->tv_sec + tv->tv_usec/1000000.0;
133 }
134
135 void
136 tv_add(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 (tv->tv_usec >= 1000000) {
142                 tv->tv_sec++;
143                 tv->tv_usec -= 1000000;
144         }
145 }
146
147 void
148 tv_sub(tv, a, b)
149 struct timeval *tv, *a, *b;
150 {
151         tv->tv_sec = a->tv_sec - b->tv_sec;
152         tv->tv_usec = a->tv_usec - b->tv_usec;
153         if (((long) tv->tv_usec) < 0) {
154                 tv->tv_sec--;
155                 tv->tv_usec += 1000000;
156         }
157 }
158
159 void
160 tv_div(tv, a, n)
161 struct timeval *tv, *a;
162 int n;
163 {
164         tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
165         tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
166         tv->tv_usec %= 1000000;
167 }
168
169 void
170 tv_mul(tv, a, n)
171 struct timeval *tv, *a;
172 int n;
173 {
174         tv->tv_usec = a->tv_usec * n;
175         tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000;
176         tv->tv_usec %= 1000000;
177 }
178
179 const char *
180 xlookup(const struct xlat *xlat, int val)
181 {
182         for (; xlat->str != NULL; xlat++)
183                 if (xlat->val == val)
184                         return xlat->str;
185         return NULL;
186 }
187
188 /*
189  * Generic ptrace wrapper which tracks ESRCH errors
190  * by setting tcp->ptrace_errno to ESRCH.
191  *
192  * We assume that ESRCH indicates likely process death (SIGKILL?),
193  * modulo bugs where process somehow ended up not stopped.
194  * Unfortunately kernel uses ESRCH for that case too. Oh well.
195  *
196  * Currently used by upeek() only.
197  * TODO: use this in all other ptrace() calls while decoding.
198  */
199 long
200 do_ptrace(int request, struct tcb *tcp, void *addr, void *data)
201 {
202         long l;
203
204         errno = 0;
205         l = ptrace(request, tcp->pid, addr, (long) data);
206         /* Non-ESRCH errors might be our invalid reg/mem accesses,
207          * we do not record them. */
208         if (errno == ESRCH)
209                 tcp->ptrace_errno = ESRCH;
210         return l;
211 }
212
213 /*
214  * Used when we want to unblock stopped traced process.
215  * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL.
216  * Returns 0 on success or if error was ESRCH
217  * (presumably process was killed while we talk to it).
218  * Otherwise prints error message and returns -1.
219  */
220 int
221 ptrace_restart(int op, struct tcb *tcp, int sig)
222 {
223         int err;
224         const char *msg;
225
226         errno = 0;
227         ptrace(op, tcp->pid, (void *) 1, (long) sig);
228         err = errno;
229         if (!err || err == ESRCH)
230                 return 0;
231
232         tcp->ptrace_errno = err;
233         msg = "SYSCALL";
234         if (op == PTRACE_CONT)
235                 msg = "CONT";
236         if (op == PTRACE_DETACH)
237                 msg = "DETACH";
238         fprintf(stderr, "strace: ptrace(PTRACE_%s,1,%d): %s\n",
239                         msg, sig, strerror(err));
240         return -1;
241 }
242
243 /*
244  * Print entry in struct xlat table, if there.
245  */
246 void
247 printxval(const struct xlat *xlat, int val, const char *dflt)
248 {
249         const char *str = xlookup(xlat, val);
250
251         if (str)
252                 tprintf("%s", str);
253         else
254                 tprintf("%#x /* %s */", val, dflt);
255 }
256
257 /*
258  * Interpret `xlat' as an array of flags
259  * print the entries whose bits are on in `flags'
260  * return # of flags printed.
261  */
262 int
263 addflags(xlat, flags)
264 const struct xlat *xlat;
265 int flags;
266 {
267         int n;
268
269         for (n = 0; xlat->str; xlat++) {
270                 if (xlat->val && (flags & xlat->val) == xlat->val) {
271                         tprintf("|%s", xlat->str);
272                         flags &= ~xlat->val;
273                         n++;
274                 }
275         }
276         if (flags) {
277                 tprintf("|%#x", flags);
278                 n++;
279         }
280         return n;
281 }
282
283 /*
284  * Interpret `xlat' as an array of flags/
285  * Print to static string the entries whose bits are on in `flags'
286  * Return static string.
287  */
288 const char *
289 sprintflags(const char *prefix, const struct xlat *xlat, int flags)
290 {
291         static char outstr[1024];
292         int found = 0;
293
294         strcpy(outstr, prefix);
295
296         for (; xlat->str; xlat++) {
297                 if ((flags & xlat->val) == xlat->val) {
298                         if (found)
299                                 strcat(outstr, "|");
300                         strcat(outstr, xlat->str);
301                         flags &= ~xlat->val;
302                         found = 1;
303                 }
304         }
305         if (flags) {
306                 if (found)
307                         strcat(outstr, "|");
308                 sprintf(outstr + strlen(outstr), "%#x", flags);
309         }
310
311         return outstr;
312 }
313
314 int
315 printflags(xlat, flags, dflt)
316 const struct xlat *xlat;
317 int flags;
318 const char *dflt;
319 {
320         int n;
321         char *sep;
322
323         if (flags == 0 && xlat->val == 0) {
324                 tprintf("%s", xlat->str);
325                 return 1;
326         }
327
328         sep = "";
329         for (n = 0; xlat->str; xlat++) {
330                 if (xlat->val && (flags & xlat->val) == xlat->val) {
331                         tprintf("%s%s", sep, xlat->str);
332                         flags &= ~xlat->val;
333                         sep = "|";
334                         n++;
335                 }
336         }
337
338         if (n) {
339                 if (flags) {
340                         tprintf("%s%#x", sep, flags);
341                         n++;
342                 }
343         } else {
344                 if (flags) {
345                         tprintf("%#x", flags);
346                         if (dflt)
347                                 tprintf(" /* %s */", dflt);
348                 } else {
349                         if (dflt)
350                                 tprintf("0");
351                 }
352         }
353
354         return n;
355 }
356
357 void
358 printnum(tcp, addr, fmt)
359 struct tcb *tcp;
360 long addr;
361 char *fmt;
362 {
363         long num;
364
365         if (!addr) {
366                 tprintf("NULL");
367                 return;
368         }
369         if (umove(tcp, addr, &num) < 0) {
370                 tprintf("%#lx", addr);
371                 return;
372         }
373         tprintf("[");
374         tprintf(fmt, num);
375         tprintf("]");
376 }
377
378 void
379 printnum_int(tcp, addr, fmt)
380 struct tcb *tcp;
381 long addr;
382 char *fmt;
383 {
384         int num;
385
386         if (!addr) {
387                 tprintf("NULL");
388                 return;
389         }
390         if (umove(tcp, addr, &num) < 0) {
391                 tprintf("%#lx", addr);
392                 return;
393         }
394         tprintf("[");
395         tprintf(fmt, num);
396         tprintf("]");
397 }
398
399 void
400 printuid(text, uid)
401 const char *text;
402 unsigned long uid;
403 {
404         tprintf("%s", text);
405         tprintf((uid == -1) ? "%ld" : "%lu", uid);
406 }
407
408 static char path[MAXPATHLEN + 1];
409
410 /*
411  * Quote string `instr' of length `size'
412  * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
413  * If `len' < 0, treat `instr' as a NUL-terminated string
414  * and quote at most (`size' - 1) bytes.
415  */
416 static int
417 string_quote(const char *instr, char *outstr, int len, int size)
418 {
419         const unsigned char *ustr = (const unsigned char *) instr;
420         char *s = outstr;
421         int usehex = 0, c, i;
422
423         if (xflag > 1)
424                 usehex = 1;
425         else if (xflag) {
426                 /* Check for presence of symbol which require
427                    to hex-quote the whole string. */
428                 for (i = 0; i < size; ++i) {
429                         c = ustr[i];
430                         /* Check for NUL-terminated string. */
431                         if (len < 0) {
432                                 if (c == '\0')
433                                         break;
434                                 /* Quote at most size - 1 bytes. */
435                                 if (i == size - 1)
436                                         continue;
437                         }
438                         if (!isprint(c) && !isspace(c)) {
439                                 usehex = 1;
440                                 break;
441                         }
442                 }
443         }
444
445         *s++ = '\"';
446
447         if (usehex) {
448                 /* Hex-quote the whole string. */
449                 for (i = 0; i < size; ++i) {
450                         c = ustr[i];
451                         /* Check for NUL-terminated string. */
452                         if (len < 0) {
453                                 if (c == '\0')
454                                         break;
455                                 /* Quote at most size - 1 bytes. */
456                                 if (i == size - 1)
457                                         continue;
458                         }
459                         sprintf(s, "\\x%02x", c);
460                         s += 4;
461                 }
462         } else {
463                 for (i = 0; i < size; ++i) {
464                         c = ustr[i];
465                         /* Check for NUL-terminated string. */
466                         if (len < 0) {
467                                 if (c == '\0')
468                                         break;
469                                 /* Quote at most size - 1 bytes. */
470                                 if (i == size - 1)
471                                         continue;
472                         }
473                         switch (c) {
474                                 case '\"': case '\\':
475                                         *s++ = '\\';
476                                         *s++ = c;
477                                         break;
478                                 case '\f':
479                                         *s++ = '\\';
480                                         *s++ = 'f';
481                                         break;
482                                 case '\n':
483                                         *s++ = '\\';
484                                         *s++ = 'n';
485                                         break;
486                                 case '\r':
487                                         *s++ = '\\';
488                                         *s++ = 'r';
489                                         break;
490                                 case '\t':
491                                         *s++ = '\\';
492                                         *s++ = 't';
493                                         break;
494                                 case '\v':
495                                         *s++ = '\\';
496                                         *s++ = 'v';
497                                         break;
498                                 default:
499                                         if (isprint(c))
500                                                 *s++ = c;
501                                         else if (i + 1 < size
502                                                  && isdigit(ustr[i + 1])) {
503                                                 sprintf(s, "\\%03o", c);
504                                                 s += 4;
505                                         } else {
506                                                 sprintf(s, "\\%o", c);
507                                                 s += strlen(s);
508                                         }
509                                         break;
510                         }
511                 }
512         }
513
514         *s++ = '\"';
515         *s = '\0';
516
517         /* Return nonzero if the string was unterminated.  */
518         return i == size;
519 }
520
521 /*
522  * Print path string specified by address `addr' and length `n'.
523  * If path length exceeds `n', append `...' to the output.
524  */
525 void
526 printpathn(struct tcb *tcp, long addr, int n)
527 {
528         if (!addr) {
529                 tprintf("NULL");
530                 return;
531         }
532
533         /* Cap path length to the path buffer size,
534            and NUL-terminate the buffer. */
535         if (n > sizeof path - 1)
536                 n = sizeof path - 1;
537         path[n] = '\0';
538
539         /* Fetch one byte more to find out whether path length > n. */
540         if (umovestr(tcp, addr, n + 1, path) < 0)
541                 tprintf("%#lx", addr);
542         else {
543                 static char outstr[4*(sizeof path - 1) + sizeof "\"...\""];
544                 int trunc = (path[n] != '\0');
545
546                 if (trunc)
547                         path[n] = '\0';
548                 (void) string_quote(path, outstr, -1, n + 1);
549                 if (trunc)
550                         strcat(outstr, "...");
551                 tprintf("%s", outstr);
552         }
553 }
554
555 void
556 printpath(struct tcb *tcp, long addr)
557 {
558         printpathn(tcp, addr, sizeof path - 1);
559 }
560
561 /*
562  * Print string specified by address `addr' and length `len'.
563  * If `len' < 0, treat the string as a NUL-terminated string.
564  * If string length exceeds `max_strlen', append `...' to the output.
565  */
566 void
567 printstr(struct tcb *tcp, long addr, int len)
568 {
569         static char *str = NULL;
570         static char *outstr;
571         int size;
572
573         if (!addr) {
574                 tprintf("NULL");
575                 return;
576         }
577         /* Allocate static buffers if they are not allocated yet. */
578         if (!str)
579                 str = malloc(max_strlen + 1);
580         if (!outstr)
581                 outstr = malloc(4 * max_strlen + sizeof "\"...\"");
582         if (!str || !outstr) {
583                 fprintf(stderr, "out of memory\n");
584                 tprintf("%#lx", addr);
585                 return;
586         }
587
588         if (len < 0) {
589                 /*
590                  * Treat as a NUL-terminated string: fetch one byte more
591                  * because string_quote() quotes one byte less.
592                  */
593                 size = max_strlen + 1;
594                 str[max_strlen] = '\0';
595                 if (umovestr(tcp, addr, size, str) < 0) {
596                         tprintf("%#lx", addr);
597                         return;
598                 }
599         }
600         else {
601                 size = MIN(len, max_strlen);
602                 if (umoven(tcp, addr, size, str) < 0) {
603                         tprintf("%#lx", addr);
604                         return;
605                 }
606         }
607
608         if (string_quote(str, outstr, len, size) &&
609             (len < 0 || len > max_strlen))
610                 strcat(outstr, "...");
611
612         tprintf("%s", outstr);
613 }
614
615 #if HAVE_SYS_UIO_H
616 void
617 dumpiov(tcp, len, addr)
618 struct tcb * tcp;
619 int len;
620 long addr;
621 {
622 #if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
623         union {
624                 struct { u_int32_t base; u_int32_t len; } *iov32;
625                 struct { u_int64_t base; u_int64_t len; } *iov64;
626         } iovu;
627 #define iov iovu.iov64
628 #define sizeof_iov \
629   (personality_wordsize[current_personality] == 4 \
630    ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64))
631 #define iov_iov_base(i) \
632   (personality_wordsize[current_personality] == 4 \
633    ? (u_int64_t) iovu.iov32[i].base : iovu.iov64[i].base)
634 #define iov_iov_len(i) \
635   (personality_wordsize[current_personality] == 4 \
636    ? (u_int64_t) iovu.iov32[i].len : iovu.iov64[i].len)
637 #else
638         struct iovec *iov;
639 #define sizeof_iov sizeof(*iov)
640 #define iov_iov_base(i) iov[i].iov_base
641 #define iov_iov_len(i) iov[i].iov_len
642 #endif
643         int i;
644         unsigned long size;
645
646         size = sizeof_iov * (unsigned long) len;
647         if (size / sizeof_iov != len
648             || (iov = malloc(size)) == NULL) {
649                 fprintf(stderr, "out of memory\n");
650                 return;
651         }
652         if (umoven(tcp, addr, size, (char *) iov) >= 0) {
653                 for (i = 0; i < len; i++) {
654                         /* include the buffer number to make it easy to
655                          * match up the trace with the source */
656                         tprintf(" * %lu bytes in buffer %d\n",
657                                 (unsigned long)iov_iov_len(i), i);
658                         dumpstr(tcp, (long) iov_iov_base(i),
659                                 iov_iov_len(i));
660                 }
661         }
662         free((char *) iov);
663 #undef sizeof_iov
664 #undef iov_iov_base
665 #undef iov_iov_len
666 #undef iov
667 }
668 #endif
669
670 void
671 dumpstr(tcp, addr, len)
672 struct tcb *tcp;
673 long addr;
674 int len;
675 {
676         static int strsize = -1;
677         static unsigned char *str;
678         static char outstr[80];
679         char *s;
680         int i, j;
681
682         if (strsize < len) {
683                 if (str)
684                         free(str);
685                 if ((str = malloc(len)) == NULL) {
686                         fprintf(stderr, "out of memory\n");
687                         return;
688                 }
689                 strsize = len;
690         }
691
692         if (umoven(tcp, addr, len, (char *) str) < 0)
693                 return;
694
695         for (i = 0; i < len; i += 16) {
696                 s = outstr;
697                 sprintf(s, " | %05x ", i);
698                 s += 9;
699                 for (j = 0; j < 16; j++) {
700                         if (j == 8)
701                                 *s++ = ' ';
702                         if (i + j < len) {
703                                 sprintf(s, " %02x", str[i + j]);
704                                 s += 3;
705                         }
706                         else {
707                                 *s++ = ' '; *s++ = ' '; *s++ = ' ';
708                         }
709                 }
710                 *s++ = ' '; *s++ = ' ';
711                 for (j = 0; j < 16; j++) {
712                         if (j == 8)
713                                 *s++ = ' ';
714                         if (i + j < len) {
715                                 if (isprint(str[i + j]))
716                                         *s++ = str[i + j];
717                                 else
718                                         *s++ = '.';
719                         }
720                         else
721                                 *s++ = ' ';
722                 }
723                 tprintf("%s |\n", outstr);
724         }
725 }
726
727 #define PAGMASK (~(PAGSIZ - 1))
728 /*
729  * move `len' bytes of data from process `pid'
730  * at address `addr' to our space at `laddr'
731  */
732 int
733 umoven(struct tcb *tcp, long addr, int len, char *laddr)
734 {
735 #ifdef LINUX
736         int pid = tcp->pid;
737         int n, m;
738         int started = 0;
739         union {
740                 long val;
741                 char x[sizeof(long)];
742         } u;
743
744         if (addr & (sizeof(long) - 1)) {
745                 /* addr not a multiple of sizeof(long) */
746                 n = addr - (addr & -sizeof(long)); /* residue */
747                 addr &= -sizeof(long); /* residue */
748                 errno = 0;
749                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
750                 if (errno) {
751                         if (started && (errno==EPERM || errno==EIO)) {
752                                 /* Ran into 'end of memory' - stupid "printpath" */
753                                 return 0;
754                         }
755                         /* But if not started, we had a bogus address. */
756                         if (addr != 0 && errno != EIO && errno != ESRCH)
757                                 perror("ptrace: umoven");
758                         return -1;
759                 }
760                 started = 1;
761                 memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
762                 addr += sizeof(long), laddr += m, len -= m;
763         }
764         while (len) {
765                 errno = 0;
766                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
767                 if (errno) {
768                         if (started && (errno==EPERM || errno==EIO)) {
769                                 /* Ran into 'end of memory' - stupid "printpath" */
770                                 return 0;
771                         }
772                         if (addr != 0 && errno != EIO && errno != ESRCH)
773                                 perror("ptrace: umoven");
774                         return -1;
775                 }
776                 started = 1;
777                 memcpy(laddr, u.x, m = MIN(sizeof(long), len));
778                 addr += sizeof(long), laddr += m, len -= m;
779         }
780 #endif /* LINUX */
781
782 #ifdef SUNOS4
783         int pid = tcp->pid;
784 #if 0
785         int n, m;
786         union {
787                 long val;
788                 char x[sizeof(long)];
789         } u;
790
791         if (addr & (sizeof(long) - 1)) {
792                 /* addr not a multiple of sizeof(long) */
793                 n = addr - (addr & -sizeof(long)); /* residue */
794                 addr &= -sizeof(long); /* residue */
795                 errno = 0;
796                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
797                 if (errno) {
798                         if (errno != ESRCH)
799                                 perror("umoven");
800                         return -1;
801                 }
802                 memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
803                 addr += sizeof(long), laddr += m, len -= m;
804         }
805         while (len) {
806                 errno = 0;
807                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
808                 if (errno) {
809                         if (errno != ESRCH)
810                                 perror("umoven");
811                         return -1;
812                 }
813                 memcpy(laddr, u.x, m = MIN(sizeof(long), len));
814                 addr += sizeof(long), laddr += m, len -= m;
815         }
816 #else /* !oldway */
817         int n;
818
819         while (len) {
820                 n = MIN(len, PAGSIZ);
821                 n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
822                 if (ptrace(PTRACE_READDATA, pid,
823                            (char *) addr, len, laddr) < 0) {
824                         if (errno != ESRCH) {
825                                 perror("umoven: ptrace(PTRACE_READDATA, ...)");
826                                 abort();
827                         }
828                         return -1;
829                 }
830                 len -= n;
831                 addr += n;
832                 laddr += n;
833         }
834 #endif /* !oldway */
835 #endif /* SUNOS4 */
836
837 #ifdef USE_PROCFS
838 #ifdef HAVE_MP_PROCFS
839         int fd = tcp->pfd_as;
840 #else
841         int fd = tcp->pfd;
842 #endif
843         lseek(fd, addr, SEEK_SET);
844         if (read(fd, laddr, len) == -1)
845                 return -1;
846 #endif /* USE_PROCFS */
847
848         return 0;
849 }
850
851 /*
852  * like `umove' but make the additional effort of looking
853  * for a terminating zero byte.
854  */
855 int
856 umovestr(struct tcb *tcp, long addr, int len, char *laddr)
857 {
858 #ifdef USE_PROCFS
859 #ifdef HAVE_MP_PROCFS
860         int fd = tcp->pfd_as;
861 #else
862         int fd = tcp->pfd;
863 #endif
864         /* Some systems (e.g. FreeBSD) can be upset if we read off the
865            end of valid memory,  avoid this by trying to read up
866            to page boundaries.  But we don't know what a page is (and
867            getpagesize(2) (if it exists) doesn't necessarily return
868            hardware page size).  Assume all pages >= 1024 (a-historical
869            I know) */
870
871         int page = 1024;        /* How to find this? */
872         int move = page - (addr & (page - 1));
873         int left = len;
874
875         lseek(fd, addr, SEEK_SET);
876
877         while (left) {
878                 if (move > left) move = left;
879                 if ((move = read(fd, laddr, move)) <= 0)
880                         return left != len ? 0 : -1;
881                 if (memchr (laddr, 0, move)) break;
882                 left -= move;
883                 laddr += move;
884                 addr += move;
885                 move = page;
886         }
887 #else /* !USE_PROCFS */
888         int started = 0;
889         int pid = tcp->pid;
890         int i, n, m;
891         union {
892                 long val;
893                 char x[sizeof(long)];
894         } u;
895
896         if (addr & (sizeof(long) - 1)) {
897                 /* addr not a multiple of sizeof(long) */
898                 n = addr - (addr & -sizeof(long)); /* residue */
899                 addr &= -sizeof(long); /* residue */
900                 errno = 0;
901                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
902                 if (errno) {
903                         if (started && (errno==EPERM || errno==EIO)) {
904                                 /* Ran into 'end of memory' - stupid "printpath" */
905                                 return 0;
906                         }
907                         if (addr != 0 && errno != EIO && errno != ESRCH)
908                                 perror("umovestr");
909                         return -1;
910                 }
911                 started = 1;
912                 memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len));
913                 while (n & (sizeof(long) - 1))
914                         if (u.x[n++] == '\0')
915                                 return 0;
916                 addr += sizeof(long), laddr += m, len -= m;
917         }
918         while (len) {
919                 errno = 0;
920                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
921                 if (errno) {
922                         if (started && (errno==EPERM || errno==EIO)) {
923                                 /* Ran into 'end of memory' - stupid "printpath" */
924                                 return 0;
925                         }
926                         if (addr != 0 && errno != EIO && errno != ESRCH)
927                                 perror("umovestr");
928                         return -1;
929                 }
930                 started = 1;
931                 memcpy(laddr, u.x, m = MIN(sizeof(long), len));
932                 for (i = 0; i < sizeof(long); i++)
933                         if (u.x[i] == '\0')
934                                 return 0;
935
936                 addr += sizeof(long), laddr += m, len -= m;
937         }
938 #endif /* !USE_PROCFS */
939         return 0;
940 }
941
942 #ifdef LINUX
943 # if !defined (SPARC) && !defined(SPARC64)
944 #  define PTRACE_WRITETEXT      101
945 #  define PTRACE_WRITEDATA      102
946 # endif /* !SPARC && !SPARC64 */
947 #endif /* LINUX */
948
949 #ifdef SUNOS4
950
951 static int
952 uload(cmd, pid, addr, len, laddr)
953 int cmd;
954 int pid;
955 long addr;
956 int len;
957 char *laddr;
958 {
959 # if 0
960         int n;
961
962         while (len) {
963                 n = MIN(len, PAGSIZ);
964                 n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
965                 if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) {
966                         perror("uload: ptrace(PTRACE_WRITE, ...)");
967                         return -1;
968                 }
969                 len -= n;
970                 addr += n;
971                 laddr += n;
972         }
973 # else
974         int peek, poke;
975         int n, m;
976         union {
977                 long val;
978                 char x[sizeof(long)];
979         } u;
980
981         if (cmd == PTRACE_WRITETEXT) {
982                 peek = PTRACE_PEEKTEXT;
983                 poke = PTRACE_POKETEXT;
984         }
985         else {
986                 peek = PTRACE_PEEKDATA;
987                 poke = PTRACE_POKEDATA;
988         }
989         if (addr & (sizeof(long) - 1)) {
990                 /* addr not a multiple of sizeof(long) */
991                 n = addr - (addr & -sizeof(long)); /* residue */
992                 addr &= -sizeof(long);
993                 errno = 0;
994                 u.val = ptrace(peek, pid, (char *) addr, 0);
995                 if (errno) {
996                         perror("uload: POKE");
997                         return -1;
998                 }
999                 memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len));
1000                 if (ptrace(poke, pid, (char *)addr, u.val) < 0) {
1001                         perror("uload: POKE");
1002                         return -1;
1003                 }
1004                 addr += sizeof(long), laddr += m, len -= m;
1005         }
1006         while (len) {
1007                 if (len < sizeof(long))
1008                         u.val = ptrace(peek, pid, (char *) addr, 0);
1009                 memcpy(u.x, laddr, m = MIN(sizeof(long), len));
1010                 if (ptrace(poke, pid, (char *) addr, u.val) < 0) {
1011                         perror("uload: POKE");
1012                         return -1;
1013                 }
1014                 addr += sizeof(long), laddr += m, len -= m;
1015         }
1016 # endif
1017         return 0;
1018 }
1019
1020 int
1021 tload(pid, addr, len, laddr)
1022 int pid;
1023 int addr, len;
1024 char *laddr;
1025 {
1026         return uload(PTRACE_WRITETEXT, pid, addr, len, laddr);
1027 }
1028
1029 int
1030 dload(pid, addr, len, laddr)
1031 int pid;
1032 int addr;
1033 int len;
1034 char *laddr;
1035 {
1036         return uload(PTRACE_WRITEDATA, pid, addr, len, laddr);
1037 }
1038
1039 #endif /* SUNOS4 */
1040
1041 #ifndef USE_PROCFS
1042
1043 int
1044 upeek(tcp, off, res)
1045 struct tcb *tcp;
1046 long off;
1047 long *res;
1048 {
1049         long val;
1050
1051 # ifdef SUNOS4_KERNEL_ARCH_KLUDGE
1052         {
1053                 static int is_sun4m = -1;
1054                 struct utsname name;
1055
1056                 /* Round up the usual suspects. */
1057                 if (is_sun4m == -1) {
1058                         if (uname(&name) < 0) {
1059                                 perror("upeek: uname?");
1060                                 exit(1);
1061                         }
1062                         is_sun4m = strcmp(name.machine, "sun4m") == 0;
1063                         if (is_sun4m) {
1064                                 const struct xlat *x;
1065
1066                                 for (x = struct_user_offsets; x->str; x++)
1067                                         x->val += 1024;
1068                         }
1069                 }
1070                 if (is_sun4m)
1071                         off += 1024;
1072         }
1073 # endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
1074         errno = 0;
1075         val = do_ptrace(PTRACE_PEEKUSER, tcp, (char *) off, 0);
1076         if (val == -1 && errno) {
1077                 if (errno != ESRCH) {
1078                         char buf[60];
1079                         sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)", tcp->pid, off);
1080                         perror(buf);
1081                 }
1082                 return -1;
1083         }
1084         *res = val;
1085         return 0;
1086 }
1087
1088 #endif /* !USE_PROCFS */
1089
1090 #if 0
1091 long
1092 getpc(struct tcb *tcp)
1093 {
1094
1095 #ifdef LINUX
1096         long pc;
1097 # if defined(I386)
1098         if (upeek(tcp, 4*EIP, &pc) < 0)
1099                 return -1;
1100 # elif defined(X86_64)
1101         if (upeek(tcp, 8*RIP, &pc) < 0)
1102                 return -1;
1103 # elif defined(IA64)
1104         if (upeek(tcp, PT_B0, &pc) < 0)
1105                 return -1;
1106 # elif defined(ARM)
1107         if (upeek(tcp, 4*15, &pc) < 0)
1108                 return -1;
1109 # elif defined(AVR32)
1110         if (upeek(tcp, REG_PC, &pc) < 0)
1111                 return -1;
1112 # elif defined(BFIN)
1113         if (upeek(tcp, REG_PC, &pc) < 0)
1114                 return -1;
1115 # elif defined(POWERPC)
1116         if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0)
1117                 return -1;
1118 # elif defined(M68K)
1119         if (upeek(tcp, 4*PT_PC, &pc) < 0)
1120                 return -1;
1121 # elif defined(ALPHA)
1122         if (upeek(tcp, REG_PC, &pc) < 0)
1123                 return -1;
1124 # elif defined(MIPS)
1125         if (upeek(tcp, REG_EPC, &pc) < 0)
1126                 return -1;
1127 # elif defined(SPARC) || defined(SPARC64)
1128         struct pt_regs regs;
1129         if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
1130                 return -1;
1131 #  if defined(SPARC64)
1132         pc = regs.tpc;
1133 #  else
1134         pc = regs.pc;
1135 #  endif
1136 # elif defined(S390) || defined(S390X)
1137         if(upeek(tcp,PT_PSWADDR,&pc) < 0)
1138                 return -1;
1139 # elif defined(HPPA)
1140         if(upeek(tcp,PT_IAOQ0,&pc) < 0)
1141                 return -1;
1142 # elif defined(SH)
1143         if (upeek(tcp, 4*REG_PC ,&pc) < 0)
1144                 return -1;
1145 # elif defined(SH64)
1146         if (upeek(tcp, REG_PC ,&pc) < 0)
1147                 return -1;
1148 # endif
1149         return pc;
1150 #endif /* LINUX */
1151
1152 #ifdef SUNOS4
1153         /*
1154          * Return current program counter for `pid'
1155          * Assumes PC is never 0xffffffff
1156          */
1157         struct regs regs;
1158
1159         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
1160                 perror("getpc: ptrace(PTRACE_GETREGS, ...)");
1161                 return -1;
1162         }
1163         return regs.r_pc;
1164 #endif /* SUNOS4 */
1165
1166 #ifdef SVR4
1167         /* XXX */
1168         return 0;
1169 #endif /* SVR4 */
1170
1171 #ifdef FREEBSD
1172         struct reg regs;
1173         pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
1174         return regs.r_eip;
1175 #endif /* FREEBSD */
1176 }
1177 #endif /* 0 */
1178
1179 void
1180 printcall(struct tcb *tcp)
1181 {
1182 #define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \
1183                            sizeof(long) == 8 ? "[????????????????] " : \
1184                            NULL /* crash */)
1185
1186 #ifdef LINUX
1187 # ifdef I386
1188         long eip;
1189
1190         if (upeek(tcp, 4*EIP, &eip) < 0) {
1191                 PRINTBADPC;
1192                 return;
1193         }
1194         tprintf("[%08lx] ", eip);
1195
1196 # elif defined(S390) || defined(S390X)
1197         long psw;
1198         if(upeek(tcp,PT_PSWADDR,&psw) < 0) {
1199                 PRINTBADPC;
1200                 return;
1201         }
1202 #  ifdef S390
1203         tprintf("[%08lx] ", psw);
1204 #  elif S390X
1205         tprintf("[%16lx] ", psw);
1206 #  endif
1207
1208 # elif defined(X86_64)
1209         long rip;
1210
1211         if (upeek(tcp, 8*RIP, &rip) < 0) {
1212                 PRINTBADPC;
1213                 return;
1214         }
1215         tprintf("[%16lx] ", rip);
1216 # elif defined(IA64)
1217         long ip;
1218
1219         if (upeek(tcp, PT_B0, &ip) < 0) {
1220                 PRINTBADPC;
1221                 return;
1222         }
1223         tprintf("[%08lx] ", ip);
1224 # elif defined(POWERPC)
1225         long pc;
1226
1227         if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) {
1228                 tprintf ("[????????] ");
1229                 return;
1230         }
1231         tprintf("[%08lx] ", pc);
1232 # elif defined(M68K)
1233         long pc;
1234
1235         if (upeek(tcp, 4*PT_PC, &pc) < 0) {
1236                 tprintf ("[????????] ");
1237                 return;
1238         }
1239         tprintf("[%08lx] ", pc);
1240 # elif defined(ALPHA)
1241         long pc;
1242
1243         if (upeek(tcp, REG_PC, &pc) < 0) {
1244                 tprintf ("[????????????????] ");
1245                 return;
1246         }
1247         tprintf("[%08lx] ", pc);
1248 # elif defined(SPARC) || defined(SPARC64)
1249         struct pt_regs regs;
1250         if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0) {
1251                 PRINTBADPC;
1252                 return;
1253         }
1254 #  if defined(SPARC64)
1255         tprintf("[%08lx] ", regs.tpc);
1256 #  else
1257         tprintf("[%08lx] ", regs.pc);
1258 #  endif
1259 # elif defined(HPPA)
1260         long pc;
1261
1262         if(upeek(tcp,PT_IAOQ0,&pc) < 0) {
1263                 tprintf ("[????????] ");
1264                 return;
1265         }
1266         tprintf("[%08lx] ", pc);
1267 # elif defined(MIPS)
1268         long pc;
1269
1270         if (upeek(tcp, REG_EPC, &pc) < 0) {
1271                 tprintf ("[????????] ");
1272                 return;
1273         }
1274         tprintf("[%08lx] ", pc);
1275 # elif defined(SH)
1276         long pc;
1277
1278         if (upeek(tcp, 4*REG_PC, &pc) < 0) {
1279                 tprintf ("[????????] ");
1280                 return;
1281         }
1282         tprintf("[%08lx] ", pc);
1283 # elif defined(SH64)
1284         long pc;
1285
1286         if (upeek(tcp, REG_PC, &pc) < 0) {
1287                 tprintf ("[????????????????] ");
1288                 return;
1289         }
1290         tprintf("[%08lx] ", pc);
1291 # elif defined(ARM)
1292         long pc;
1293
1294         if (upeek(tcp, 4*15, &pc) < 0) {
1295                 PRINTBADPC;
1296                 return;
1297         }
1298         tprintf("[%08lx] ", pc);
1299 # elif defined(AVR32)
1300         long pc;
1301
1302         if (upeek(tcp, REG_PC, &pc) < 0) {
1303                 tprintf("[????????] ");
1304                 return;
1305         }
1306         tprintf("[%08lx] ", pc);
1307 # elif defined(BFIN)
1308         long pc;
1309
1310         if (upeek(tcp, PT_PC, &pc) < 0) {
1311                 PRINTBADPC;
1312                 return;
1313         }
1314         tprintf("[%08lx] ", pc);
1315 #elif defined(CRISV10)
1316         long pc;
1317
1318         if (upeek(tcp, 4*PT_IRP, &pc) < 0) {
1319                 PRINTBADPC;
1320                 return;
1321         }
1322         tprintf("[%08lx] ", pc);
1323 #elif defined(CRISV32)
1324         long pc;
1325
1326         if (upeek(tcp, 4*PT_ERP, &pc) < 0) {
1327                 PRINTBADPC;
1328                 return;
1329         }
1330         tprintf("[%08lx] ", pc);
1331 # endif /* architecture */
1332 #endif /* LINUX */
1333
1334 #ifdef SUNOS4
1335         struct regs regs;
1336
1337         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
1338                 perror("printcall: ptrace(PTRACE_GETREGS, ...)");
1339                 PRINTBADPC;
1340                 return;
1341         }
1342         tprintf("[%08x] ", regs.r_o7);
1343 #endif /* SUNOS4 */
1344
1345 #ifdef SVR4
1346         /* XXX */
1347         PRINTBADPC;
1348 #endif
1349
1350 #ifdef FREEBSD
1351         struct reg regs;
1352         pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
1353         tprintf("[%08x] ", regs.r_eip);
1354 #endif /* FREEBSD */
1355 }
1356
1357
1358 /*
1359  * These #if's are huge, please indent them correctly.
1360  * It's easy to get confused otherwise.
1361  */
1362 #ifndef USE_PROCFS
1363
1364 # if defined LINUX
1365
1366 #  include "syscall.h"
1367
1368 #  include <sys/syscall.h>
1369 #  ifndef CLONE_PTRACE
1370 #   define CLONE_PTRACE    0x00002000
1371 #  endif
1372 #  ifndef CLONE_VFORK
1373 #   define CLONE_VFORK     0x00004000
1374 #  endif
1375 #  ifndef CLONE_VM
1376 #   define CLONE_VM        0x00000100
1377 #  endif
1378 #  ifndef CLONE_STOPPED
1379 #   define CLONE_STOPPED   0x02000000
1380 #  endif
1381
1382 #  ifdef IA64
1383
1384 /* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32
1385    subsystem has them for x86... */
1386 #   define SYS_fork     2
1387 #   define SYS_vfork    190
1388
1389 typedef unsigned long *arg_setup_state;
1390
1391 static int
1392 arg_setup(struct tcb *tcp, arg_setup_state *state)
1393 {
1394         unsigned long cfm, sof, sol;
1395         long bsp;
1396
1397         if (ia32) {
1398                 /* Satisfy a false GCC warning.  */
1399                 *state = NULL;
1400                 return 0;
1401         }
1402
1403         if (upeek(tcp, PT_AR_BSP, &bsp) < 0)
1404                 return -1;
1405         if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
1406                 return -1;
1407
1408         sof = (cfm >> 0) & 0x7f;
1409         sol = (cfm >> 7) & 0x7f;
1410         bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol);
1411
1412         *state = (unsigned long *) bsp;
1413         return 0;
1414 }
1415
1416 #   define arg_finish_change(tcp, state)        0
1417
1418 #   ifdef SYS_fork
1419 static int
1420 get_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp)
1421 {
1422         int ret;
1423
1424         if (ia32)
1425                 ret = upeek (tcp, PT_R11, valp);
1426         else
1427                 ret = umoven (tcp,
1428                               (unsigned long) ia64_rse_skip_regs(*state, 0),
1429                               sizeof(long), (void *) valp);
1430         return ret;
1431 }
1432
1433 static int
1434 get_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp)
1435 {
1436         int ret;
1437
1438         if (ia32)
1439                 ret = upeek (tcp, PT_R9, valp);
1440         else
1441                 ret = umoven (tcp,
1442                               (unsigned long) ia64_rse_skip_regs(*state, 1),
1443                               sizeof(long), (void *) valp);
1444         return ret;
1445 }
1446 #   endif
1447
1448 static int
1449 set_arg0 (struct tcb *tcp, arg_setup_state *state, long val)
1450 {
1451         int req = PTRACE_POKEDATA;
1452         void *ap;
1453
1454         if (ia32) {
1455                 ap = (void *) (intptr_t) PT_R11;         /* r11 == EBX */
1456                 req = PTRACE_POKEUSER;
1457         } else
1458                 ap = ia64_rse_skip_regs(*state, 0);
1459         errno = 0;
1460         ptrace(req, tcp->pid, ap, val);
1461         return errno ? -1 : 0;
1462 }
1463
1464 static int
1465 set_arg1 (struct tcb *tcp, arg_setup_state *state, long val)
1466 {
1467         int req = PTRACE_POKEDATA;
1468         void *ap;
1469
1470         if (ia32) {
1471                 ap = (void *) (intptr_t) PT_R9;         /* r9 == ECX */
1472                 req = PTRACE_POKEUSER;
1473         } else
1474                 ap = ia64_rse_skip_regs(*state, 1);
1475         errno = 0;
1476         ptrace(req, tcp->pid, ap, val);
1477         return errno ? -1 : 0;
1478 }
1479
1480 /* ia64 does not return the input arguments from functions (and syscalls)
1481    according to ia64 RSE (Register Stack Engine) behavior.  */
1482
1483 #   define restore_arg0(tcp, state, val) ((void) (state), 0)
1484 #   define restore_arg1(tcp, state, val) ((void) (state), 0)
1485
1486 #  elif defined (SPARC) || defined (SPARC64)
1487
1488 typedef struct pt_regs arg_setup_state;
1489
1490 #   define arg_setup(tcp, state) \
1491     (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0))
1492 #   define arg_finish_change(tcp, state) \
1493     (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0))
1494
1495 #   define get_arg0(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O0], 0)
1496 #   define get_arg1(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O1], 0)
1497 #   define set_arg0(tcp, state, val) ((state)->u_regs[U_REG_O0] = (val), 0)
1498 #   define set_arg1(tcp, state, val) ((state)->u_regs[U_REG_O1] = (val), 0)
1499 #   define restore_arg0(tcp, state, val) 0
1500
1501 #  else /* other architectures */
1502
1503 #   if defined S390 || defined S390X
1504 /* Note: this is only true for the `clone' system call, which handles
1505    arguments specially.  We could as well say that its first two arguments
1506    are swapped relative to other architectures, but that would just be
1507    another #ifdef in the calls.  */
1508 #    define arg0_offset PT_GPR3
1509 #    define arg1_offset PT_ORIGGPR2
1510 #    define restore_arg0(tcp, state, val) ((void) (state), 0)
1511 #    define restore_arg1(tcp, state, val) ((void) (state), 0)
1512 #    define arg0_index  1
1513 #    define arg1_index  0
1514 #   elif defined (ALPHA) || defined (MIPS)
1515 #    define arg0_offset REG_A0
1516 #    define arg1_offset (REG_A0+1)
1517 #   elif defined (AVR32)
1518 #    define arg0_offset (REG_R12)
1519 #    define arg1_offset (REG_R11)
1520 #   elif defined (POWERPC)
1521 #    define arg0_offset (sizeof(unsigned long)*PT_R3)
1522 #    define arg1_offset (sizeof(unsigned long)*PT_R4)
1523 #    define restore_arg0(tcp, state, val) ((void) (state), 0)
1524 #   elif defined (HPPA)
1525 #    define arg0_offset  PT_GR26
1526 #    define arg1_offset  (PT_GR26-4)
1527 #   elif defined (X86_64)
1528 #    define arg0_offset ((long)(8*(current_personality ? RBX : RDI)))
1529 #    define arg1_offset ((long)(8*(current_personality ? RCX : RSI)))
1530 #   elif defined (SH)
1531 #    define arg0_offset (4*(REG_REG0+4))
1532 #    define arg1_offset (4*(REG_REG0+5))
1533 #   elif defined (SH64)
1534     /* ABI defines arg0 & 1 in r2 & r3 */
1535 #    define arg0_offset   (REG_OFFSET+16)
1536 #    define arg1_offset   (REG_OFFSET+24)
1537 #    define restore_arg0(tcp, state, val) 0
1538 #   elif defined CRISV10 || defined CRISV32
1539 #    define arg0_offset   (4*PT_R11)
1540 #    define arg1_offset   (4*PT_ORIG_R10)
1541 #    define restore_arg0(tcp, state, val) 0
1542 #    define restore_arg1(tcp, state, val) 0
1543 #    define arg0_index   1
1544 #    define arg1_index   0
1545 #   else
1546 #    define arg0_offset 0
1547 #    define arg1_offset 4
1548 #    if defined ARM
1549 #     define restore_arg0(tcp, state, val) 0
1550 #    endif
1551 #   endif
1552
1553 typedef int arg_setup_state;
1554
1555 #   define arg_setup(tcp, state) (0)
1556 #   define arg_finish_change(tcp, state)        0
1557 #   define get_arg0(tcp, cookie, valp) \
1558     (upeek ((tcp), arg0_offset, (valp)))
1559 #   define get_arg1(tcp, cookie, valp) \
1560     (upeek ((tcp), arg1_offset, (valp)))
1561
1562 static int
1563 set_arg0 (struct tcb *tcp, void *cookie, long val)
1564 {
1565         return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val);
1566 }
1567
1568 static int
1569 set_arg1 (struct tcb *tcp, void *cookie, long val)
1570 {
1571         return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val);
1572 }
1573
1574 #  endif /* architectures */
1575
1576 #  ifndef restore_arg0
1577 #   define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val))
1578 #  endif
1579 #  ifndef restore_arg1
1580 #   define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val))
1581 #  endif
1582
1583 #  ifndef arg0_index
1584 #   define arg0_index 0
1585 #   define arg1_index 1
1586 #  endif
1587
1588 int
1589 setbpt(struct tcb *tcp)
1590 {
1591         static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone };
1592         arg_setup_state state;
1593
1594         if (tcp->flags & TCB_BPTSET) {
1595                 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1596                 return -1;
1597         }
1598
1599         /*
1600          * It's a silly kludge to initialize this with a search at runtime.
1601          * But it's better than maintaining another magic thing in the
1602          * godforsaken tables.
1603          */
1604         if (clone_scno[current_personality] == 0) {
1605                 int i;
1606                 for (i = 0; i < nsyscalls; ++i)
1607                         if (sysent[i].sys_func == sys_clone) {
1608                                 clone_scno[current_personality] = i;
1609                                 break;
1610                         }
1611         }
1612
1613         switch (known_scno(tcp)) {
1614 #  ifdef SYS_vfork
1615         case SYS_vfork:
1616 #  endif
1617 #  ifdef SYS_fork
1618         case SYS_fork:
1619 #  endif
1620 #  if defined SYS_fork || defined SYS_vfork
1621                 if (arg_setup (tcp, &state) < 0
1622                     || get_arg0 (tcp, &state, &tcp->inst[0]) < 0
1623                     || get_arg1 (tcp, &state, &tcp->inst[1]) < 0
1624                     || change_syscall(tcp, clone_scno[current_personality]) < 0
1625                     || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0
1626                     || set_arg1 (tcp, &state, 0) < 0
1627                     || arg_finish_change (tcp, &state) < 0)
1628                         return -1;
1629                 tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD;
1630                 tcp->u_arg[arg1_index] = 0;
1631                 tcp->flags |= TCB_BPTSET;
1632                 return 0;
1633 #  endif
1634
1635         case SYS_clone:
1636 #  ifdef SYS_clone2
1637         case SYS_clone2:
1638 #  endif
1639                 /* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)'
1640                    contrary to x86 SYS_vfork above.  Even on x86 we turn the
1641                    vfork semantics into plain fork - each application must not
1642                    depend on the vfork specifics according to POSIX.  We would
1643                    hang waiting for the parent resume otherwise.  We need to
1644                    clear also CLONE_VM but only in the CLONE_VFORK case as
1645                    otherwise we would break pthread_create.  */
1646
1647                 if ((arg_setup (tcp, &state) < 0
1648                     || set_arg0 (tcp, &state,
1649                                  (tcp->u_arg[arg0_index] | CLONE_PTRACE)
1650                                  & ~(tcp->u_arg[arg0_index] & CLONE_VFORK
1651                                      ? CLONE_VFORK | CLONE_VM : 0)) < 0
1652                     || arg_finish_change (tcp, &state) < 0))
1653                         return -1;
1654                 tcp->flags |= TCB_BPTSET;
1655                 tcp->inst[0] = tcp->u_arg[arg0_index];
1656                 tcp->inst[1] = tcp->u_arg[arg1_index];
1657                 return 0;
1658
1659         default:
1660                 fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n",
1661                         tcp->scno, tcp->pid);
1662                 break;
1663         }
1664
1665         return -1;
1666 }
1667
1668 int
1669 clearbpt(tcp)
1670 struct tcb *tcp;
1671 {
1672         arg_setup_state state;
1673         if (arg_setup (tcp, &state) < 0
1674             || restore_arg0 (tcp, &state, tcp->inst[0]) < 0
1675             || restore_arg1 (tcp, &state, tcp->inst[1]) < 0
1676             || arg_finish_change (tcp, &state))
1677                 return -1;
1678         tcp->flags &= ~TCB_BPTSET;
1679         return 0;
1680 }
1681
1682 # else /* !defined LINUX */
1683
1684 int
1685 setbpt(tcp)
1686 struct tcb *tcp;
1687 {
1688 #  ifdef LINUX
1689         DEAD CODE HERE? WE ARE IN 'else !defined LINUX'
1690 #   if defined (SPARC) || defined (SPARC64)
1691         /* We simply use the SunOS breakpoint code. */
1692
1693         struct regs regs;
1694         unsigned long inst;
1695 #    define LOOPA       0x30800000      /* ba,a 0 */
1696
1697         if (tcp->flags & TCB_BPTSET) {
1698                 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1699                 return -1;
1700         }
1701         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1702                 perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
1703                 return -1;
1704         }
1705         tcp->baddr = regs.r_o7 + 8;
1706         errno = 0;
1707         tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0);
1708         if(errno) {
1709                 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1710                 return -1;
1711         }
1712
1713         /*
1714          * XXX - BRUTAL MODE ON
1715          * We cannot set a real BPT in the child, since it will not be
1716          * traced at the moment it will reach the trap and would probably
1717          * die with a core dump.
1718          * Thus, we are force our way in by taking out two instructions
1719          * and insert an eternal loop instead, in expectance of the SIGSTOP
1720          * generated by our PTRACE_ATTACH.
1721          * Of cause, if we evaporate ourselves in the middle of all this...
1722          */
1723         errno = 0;
1724         inst = LOOPA;
1725 #    if defined (SPARC64)
1726         inst <<= 32;
1727         inst |= (tcp->inst[0] & 0xffffffffUL);
1728 #    endif
1729         ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, inst);
1730         if(errno) {
1731                 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1732                 return -1;
1733         }
1734         tcp->flags |= TCB_BPTSET;
1735
1736 #   else /* !SPARC && !SPARC64 */
1737 #    ifdef IA64
1738         if (ia32) {
1739 #               define LOOP     0x0000feeb
1740                 if (tcp->flags & TCB_BPTSET) {
1741                         fprintf(stderr, "PANIC: bpt already set in pid %u\n",
1742                                 tcp->pid);
1743                         return -1;
1744                 }
1745                 if (upeek(tcp, PT_CR_IIP, &tcp->baddr) < 0)
1746                         return -1;
1747                 if (debug)
1748                         fprintf(stderr, "[%d] setting bpt at %lx\n",
1749                                 tcp->pid, tcp->baddr);
1750                 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid,
1751                                       (char *) tcp->baddr, 0);
1752                 if (errno) {
1753                         perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1754                         return -1;
1755                 }
1756                 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
1757                 if (errno) {
1758                         perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1759                         return -1;
1760                 }
1761                 tcp->flags |= TCB_BPTSET;
1762         } else {
1763                 /*
1764                  * Our strategy here is to replace the bundle that
1765                  * contained the clone() syscall with a bundle of the
1766                  * form:
1767                  *
1768                  *      { 1: br 1b; br 1b; br 1b }
1769                  *
1770                  * This ensures that the newly forked child will loop
1771                  * endlessly until we've got a chance to attach to it.
1772                  */
1773 #                       define LOOP0    0x0000100000000017
1774 #                       define LOOP1    0x4000000000200000
1775                 unsigned long addr, ipsr;
1776                 pid_t pid;
1777
1778                 pid = tcp->pid;
1779                 if (upeek(tcp, PT_CR_IPSR, &ipsr) < 0)
1780                         return -1;
1781                 if (upeek(tcp, PT_CR_IIP, &addr) < 0)
1782                         return -1;
1783                 /* store "ri" in low two bits */
1784                 tcp->baddr = addr | ((ipsr >> 41) & 0x3);
1785
1786                 errno = 0;
1787                 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0,
1788                                       0);
1789                 tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8,
1790                                       0);
1791                 if (errno) {
1792                         perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1793                         return -1;
1794                 }
1795
1796                 errno = 0;
1797                 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0);
1798                 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1);
1799                 if (errno) {
1800                         perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1801                         return -1;
1802                 }
1803                 tcp->flags |= TCB_BPTSET;
1804         }
1805 #    else /* !IA64 */
1806
1807 #     if defined (I386) || defined(X86_64)
1808 #      define LOOP      0x0000feeb
1809 #     elif defined (M68K)
1810 #      define LOOP      0x60fe0000
1811 #     elif defined (ALPHA)
1812 #      define LOOP      0xc3ffffff
1813 #     elif defined (POWERPC)
1814 #      define LOOP      0x48000000
1815 #     elif defined(ARM)
1816 #      define LOOP      0xEAFFFFFE
1817 #     elif defined(MIPS)
1818 #      define LOOP      0x1000ffff
1819 #     elif defined(S390)
1820 #      define LOOP      0xa7f40000      /* BRC 15,0 */
1821 #     elif defined(S390X)
1822 #      define LOOP   0xa7f4000000000000UL /* BRC 15,0 */
1823 #     elif defined(HPPA)
1824 #      define LOOP      0xe81f1ff7      /* b,l,n <loc>,r0 */
1825 #     elif defined(SH)
1826 #      ifdef __LITTLE_ENDIAN__
1827 #       define LOOP   0x0000affe
1828 #      else
1829 #       define LOOP   0xfeaf0000
1830 #      endif
1831 #     else
1832 #      error unknown architecture
1833 #     endif
1834
1835         if (tcp->flags & TCB_BPTSET) {
1836                 fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid);
1837                 return -1;
1838         }
1839 #     if defined (I386)
1840         if (upeek(tcp, 4*EIP, &tcp->baddr) < 0)
1841                 return -1;
1842 #     elif defined (X86_64)
1843         if (upeek(tcp, 8*RIP, &tcp->baddr) < 0)
1844                 return -1;
1845 #     elif defined (M68K)
1846         if (upeek(tcp, 4*PT_PC, &tcp->baddr) < 0)
1847                 return -1;
1848 #     elif defined (ALPHA)
1849         return -1;
1850 #     elif defined (ARM)
1851         return -1;
1852 #     elif defined (MIPS)
1853         return -1;              /* FIXME: I do not know what i do - Flo */
1854 #     elif defined (POWERPC)
1855         if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &tcp->baddr) < 0)
1856                 return -1;
1857 #     elif defined(S390) || defined(S390X)
1858         if (upeek(tcp,PT_PSWADDR, &tcp->baddr) < 0)
1859                 return -1;
1860 #     elif defined(HPPA)
1861         if (upeek(tcp, PT_IAOQ0, &tcp->baddr) < 0)
1862                 return -1;
1863         tcp->baddr &= ~0x03;
1864 #     elif defined(SH)
1865         if (upeek(tcp, 4*REG_PC, &tcp->baddr) < 0)
1866                 return -1;
1867 #     else
1868 #      error unknown architecture
1869 #     endif
1870         if (debug)
1871                 fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr);
1872         tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0);
1873         if (errno) {
1874                 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1875                 return -1;
1876         }
1877         ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
1878         if (errno) {
1879                 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1880                 return -1;
1881         }
1882         tcp->flags |= TCB_BPTSET;
1883
1884 #    endif /* !IA64 */
1885 #   endif /* !SPARC && !SPARC64 */
1886 #  endif /* LINUX */
1887
1888 #  ifdef SUNOS4
1889 #   ifdef SPARC /* This code is slightly sparc specific */
1890
1891         struct regs regs;
1892 #    define BPT 0x91d02001      /* ta   1 */
1893 #    define LOOP        0x10800000      /* ba   0 */
1894 #    define LOOPA       0x30800000      /* ba,a 0 */
1895 #    define NOP 0x01000000
1896 #    if LOOPA
1897         static int loopdeloop[1] = {LOOPA};
1898 #    else
1899         static int loopdeloop[2] = {LOOP, NOP};
1900 #    endif
1901
1902         if (tcp->flags & TCB_BPTSET) {
1903                 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1904                 return -1;
1905         }
1906         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1907                 perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
1908                 return -1;
1909         }
1910         tcp->baddr = regs.r_o7 + 8;
1911         if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr,
1912                                 sizeof tcp->inst, (char *)tcp->inst) < 0) {
1913                 perror("setbpt: ptrace(PTRACE_READTEXT, ...)");
1914                 return -1;
1915         }
1916
1917         /*
1918          * XXX - BRUTAL MODE ON
1919          * We cannot set a real BPT in the child, since it will not be
1920          * traced at the moment it will reach the trap and would probably
1921          * die with a core dump.
1922          * Thus, we are force our way in by taking out two instructions
1923          * and insert an eternal loop in stead, in expectance of the SIGSTOP
1924          * generated by out PTRACE_ATTACH.
1925          * Of cause, if we evaporate ourselves in the middle of all this...
1926          */
1927         if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
1928                         sizeof loopdeloop, (char *) loopdeloop) < 0) {
1929                 perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)");
1930                 return -1;
1931         }
1932         tcp->flags |= TCB_BPTSET;
1933
1934 #   endif /* SPARC */
1935 #  endif /* SUNOS4 */
1936
1937         return 0;
1938 }
1939
1940 int
1941 clearbpt(tcp)
1942 struct tcb *tcp;
1943 {
1944
1945 #  ifdef LINUX
1946         DEAD CODE HERE? WE ARE IN 'else !defined LINUX'
1947 #   if defined(I386) || defined(X86_64)
1948         long eip;
1949 #   elif defined(POWERPC)
1950         long pc;
1951 #   elif defined(M68K)
1952         long pc;
1953 #   elif defined(ALPHA)
1954         long pc;
1955 #   elif defined(HPPA)
1956         long iaoq;
1957 #   elif defined(SH)
1958         long pc;
1959 #   endif /* architecture */
1960
1961 #   if defined (SPARC) || defined (SPARC64)
1962         /* Again, we borrow the SunOS breakpoint code. */
1963         if (!(tcp->flags & TCB_BPTSET)) {
1964                 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
1965                 return -1;
1966         }
1967         errno = 0;
1968         ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
1969         if(errno) {
1970                 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
1971                 return -1;
1972         }
1973         tcp->flags &= ~TCB_BPTSET;
1974 #   elif defined(IA64)
1975         if (ia32) {
1976                 unsigned long addr;
1977
1978                 if (debug)
1979                         fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
1980                 if (!(tcp->flags & TCB_BPTSET)) {
1981                         fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
1982                         return -1;
1983                 }
1984                 errno = 0;
1985                 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
1986                 if (errno) {
1987                         perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
1988                         return -1;
1989                 }
1990                 tcp->flags &= ~TCB_BPTSET;
1991
1992                 if (upeek(tcp, PT_CR_IIP, &addr) < 0)
1993                         return -1;
1994                 if (addr != tcp->baddr) {
1995                         /* The breakpoint has not been reached yet.  */
1996                         if (debug)
1997                                 fprintf(stderr,
1998                                         "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1999                                                 addr, tcp->baddr);
2000                         return 0;
2001                 }
2002         } else {
2003                 unsigned long addr, ipsr;
2004                 pid_t pid;
2005
2006                 pid = tcp->pid;
2007
2008                 if (upeek(tcp, PT_CR_IPSR, &ipsr) < 0)
2009                         return -1;
2010                 if (upeek(tcp, PT_CR_IIP, &addr) < 0)
2011                         return -1;
2012
2013                 /* restore original bundle: */
2014                 errno = 0;
2015                 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]);
2016                 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]);
2017                 if (errno) {
2018                         perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)");
2019                         return -1;
2020                 }
2021
2022                 /* restore original "ri" in ipsr: */
2023                 ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41);
2024                 errno = 0;
2025                 ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr);
2026                 if (errno) {
2027                         perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)");
2028                         return -1;
2029                 }
2030
2031                 tcp->flags &= ~TCB_BPTSET;
2032
2033                 if (addr != (tcp->baddr & ~0x3)) {
2034                         /* the breakpoint has not been reached yet.  */
2035                         if (debug)
2036                                 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2037                                         addr, tcp->baddr);
2038                         return 0;
2039                 }
2040         }
2041 #   else /* !IA64 && !SPARC && !SPARC64 */
2042
2043         if (debug)
2044                 fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
2045         if (!(tcp->flags & TCB_BPTSET)) {
2046                 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
2047                 return -1;
2048         }
2049         errno = 0;
2050         ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
2051         if (errno) {
2052                 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
2053                 return -1;
2054         }
2055         tcp->flags &= ~TCB_BPTSET;
2056
2057 #    ifdef I386
2058         if (upeek(tcp, 4*EIP, &eip) < 0)
2059                 return -1;
2060         if (eip != tcp->baddr) {
2061                 /* The breakpoint has not been reached yet.  */
2062                 if (debug)
2063                         fprintf(stderr,
2064                                 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2065                                         eip, tcp->baddr);
2066                 return 0;
2067         }
2068 #    elif defined(X86_64)
2069         if (upeek(tcp, 8*RIP, &eip) < 0)
2070                 return -1;
2071         if (eip != tcp->baddr) {
2072                 /* The breakpoint has not been reached yet.  */
2073                 if (debug)
2074                         fprintf(stderr,
2075                                 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2076                                         eip, tcp->baddr);
2077                 return 0;
2078         }
2079 #    elif defined(POWERPC)
2080         if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0)
2081                 return -1;
2082         if (pc != tcp->baddr) {
2083                 /* The breakpoint has not been reached yet.  */
2084                 if (debug)
2085                         fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2086                                 pc, tcp->baddr);
2087                 return 0;
2088         }
2089 #    elif defined(M68K)
2090         if (upeek(tcp, 4*PT_PC, &pc) < 0)
2091                 return -1;
2092         if (pc != tcp->baddr) {
2093                 /* The breakpoint has not been reached yet.  */
2094                 if (debug)
2095                         fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2096                                 pc, tcp->baddr);
2097                 return 0;
2098         }
2099 #    elif defined(ALPHA)
2100         if (upeek(tcp, REG_PC, &pc) < 0)
2101                 return -1;
2102         if (pc != tcp->baddr) {
2103                 /* The breakpoint has not been reached yet.  */
2104                 if (debug)
2105                         fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2106                                 pc, tcp->baddr);
2107                 return 0;
2108         }
2109 #    elif defined(HPPA)
2110         if (upeek(tcp, PT_IAOQ0, &iaoq) < 0)
2111                 return -1;
2112         iaoq &= ~0x03;
2113         if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) {
2114                 /* The breakpoint has not been reached yet.  */
2115                 if (debug)
2116                         fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n",
2117                                 iaoq, tcp->baddr);
2118                 return 0;
2119         }
2120         iaoq = tcp->baddr | 3;
2121         /* We should be pointing at a 'ldi -1000,r1' in glibc, so it is
2122          * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit
2123          * has no significant effect.
2124          */
2125         ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq);
2126         ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq);
2127 #    elif defined(SH)
2128         if (upeek(tcp, 4*REG_PC, &pc) < 0)
2129                 return -1;
2130         if (pc != tcp->baddr) {
2131                 /* The breakpoint has not been reached yet.  */
2132                 if (debug)
2133                         fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2134                                 pc, tcp->baddr);
2135                 return 0;
2136         }
2137
2138 #    endif /* arch */
2139 #   endif /* !SPARC && !SPARC64 && !IA64 */
2140 #  endif /* LINUX */
2141
2142 #  ifdef SUNOS4
2143 #   ifdef SPARC
2144
2145 #    if !LOOPA
2146         struct regs regs;
2147 #    endif
2148
2149         if (!(tcp->flags & TCB_BPTSET)) {
2150                 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
2151                 return -1;
2152         }
2153         if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
2154                                 sizeof tcp->inst, (char *) tcp->inst) < 0) {
2155                 perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)");
2156                 return -1;
2157         }
2158         tcp->flags &= ~TCB_BPTSET;
2159
2160 #    if !LOOPA
2161         /*
2162          * Since we don't have a single instruction breakpoint, we may have
2163          * to adjust the program counter after removing our `breakpoint'.
2164          */
2165         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
2166                 perror("clearbpt: ptrace(PTRACE_GETREGS, ...)");
2167                 return -1;
2168         }
2169         if ((regs.r_pc < tcp->baddr) ||
2170                                 (regs.r_pc > tcp->baddr + 4)) {
2171                 /* The breakpoint has not been reached yet */
2172                 if (debug)
2173                         fprintf(stderr,
2174                                 "NOTE: PC not at bpt (pc %#x baddr %#x)\n",
2175                                         regs.r_pc, tcp->baddr);
2176                 return 0;
2177         }
2178         if (regs.r_pc != tcp->baddr)
2179                 if (debug)
2180                         fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n",
2181                                 regs.r_pc, tcp->baddr);
2182
2183         regs.r_pc = tcp->baddr;
2184         if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0) {
2185                 perror("clearbpt: ptrace(PTRACE_SETREGS, ...)");
2186                 return -1;
2187         }
2188 #    endif /* LOOPA */
2189 #   endif /* SPARC */
2190 #  endif /* SUNOS4 */
2191
2192         return 0;
2193 }
2194
2195 # endif /* !defined LINUX */
2196
2197 #endif /* !USE_PROCFS */
2198
2199
2200 #ifdef SUNOS4
2201
2202 static int
2203 getex(tcp, hdr)
2204 struct tcb *tcp;
2205 struct exec *hdr;
2206 {
2207         int n;
2208
2209         for (n = 0; n < sizeof *hdr; n += 4) {
2210                 long res;
2211                 if (upeek(tcp, uoff(u_exdata) + n, &res) < 0)
2212                         return -1;
2213                 memcpy(((char *) hdr) + n, &res, 4);
2214         }
2215         if (debug) {
2216                 fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n",
2217                         hdr->a_magic, hdr->a_toolversion, hdr->a_machtype);
2218                 fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n",
2219                         hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry);
2220         }
2221         return 0;
2222 }
2223
2224 int
2225 fixvfork(tcp)
2226 struct tcb *tcp;
2227 {
2228         int pid = tcp->pid;
2229         /*
2230          * Change `vfork' in a freshly exec'ed dynamically linked
2231          * executable's (internal) symbol table to plain old `fork'
2232          */
2233
2234         struct exec hdr;
2235         struct link_dynamic dyn;
2236         struct link_dynamic_2 ld;
2237         char *strtab, *cp;
2238
2239         if (getex(tcp, &hdr) < 0)
2240                 return -1;
2241         if (!hdr.a_dynamic)
2242                 return -1;
2243
2244         if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) {
2245                 fprintf(stderr, "Cannot read DYNAMIC\n");
2246                 return -1;
2247         }
2248         if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) {
2249                 fprintf(stderr, "Cannot read link_dynamic_2\n");
2250                 return -1;
2251         }
2252         if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) {
2253                 fprintf(stderr, "out of memory\n");
2254                 return -1;
2255         }
2256         if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
2257                                         (int)ld.ld_symb_size, strtab) < 0)
2258                 goto err;
2259
2260 # if 0
2261         for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
2262                 fprintf(stderr, "[symbol: %s]\n", cp);
2263                 cp += strlen(cp)+1;
2264         }
2265         return 0;
2266 # endif
2267         for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
2268                 if (strcmp(cp, "_vfork") == 0) {
2269                         if (debug)
2270                                 fprintf(stderr, "fixvfork: FOUND _vfork\n");
2271                         strcpy(cp, "_fork");
2272                         break;
2273                 }
2274                 cp += strlen(cp)+1;
2275         }
2276         if (cp < strtab + ld.ld_symb_size)
2277                 /*
2278                  * Write entire symbol table back to avoid
2279                  * memory alignment bugs in ptrace
2280                  */
2281                 if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
2282                                         (int)ld.ld_symb_size, strtab) < 0)
2283                         goto err;
2284
2285         free(strtab);
2286         return 0;
2287
2288 err:
2289         free(strtab);
2290         return -1;
2291 }
2292
2293 #endif /* SUNOS4 */