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