]> granicus.if.org Git - strace/blob - util.c
Silence compiler warnings about implicit cast from pointer to integer
[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, (long) 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, (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(struct tcb *tcp, long addr, int len, char *laddr)
789 {
790 #ifdef LINUX
791         int pid = tcp->pid;
792         int n, m;
793         int started = 0;
794         union {
795                 long val;
796                 char x[sizeof(long)];
797         } u;
798
799         if (addr & (sizeof(long) - 1)) {
800                 /* addr not a multiple of sizeof(long) */
801                 n = addr - (addr & -sizeof(long)); /* residue */
802                 addr &= -sizeof(long); /* residue */
803                 errno = 0;
804                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
805                 if (errno) {
806                         if (started && (errno==EPERM || errno==EIO)) {
807                                 /* Ran into 'end of memory' - stupid "printpath" */
808                                 return 0;
809                         }
810                         /* But if not started, we had a bogus address. */
811                         if (addr != 0 && errno != EIO && errno != ESRCH)
812                                 perror("ptrace: umoven");
813                         return -1;
814                 }
815                 started = 1;
816                 memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
817                 addr += sizeof(long), laddr += m, len -= m;
818         }
819         while (len) {
820                 errno = 0;
821                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
822                 if (errno) {
823                         if (started && (errno==EPERM || errno==EIO)) {
824                                 /* Ran into 'end of memory' - stupid "printpath" */
825                                 return 0;
826                         }
827                         if (addr != 0 && errno != EIO && errno != ESRCH)
828                                 perror("ptrace: umoven");
829                         return -1;
830                 }
831                 started = 1;
832                 memcpy(laddr, u.x, m = MIN(sizeof(long), len));
833                 addr += sizeof(long), laddr += m, len -= m;
834         }
835 #endif /* LINUX */
836
837 #ifdef SUNOS4
838         int pid = tcp->pid;
839 #if 0
840         int n, m;
841         union {
842                 long val;
843                 char x[sizeof(long)];
844         } u;
845
846         if (addr & (sizeof(long) - 1)) {
847                 /* addr not a multiple of sizeof(long) */
848                 n = addr - (addr & -sizeof(long)); /* residue */
849                 addr &= -sizeof(long); /* residue */
850                 errno = 0;
851                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
852                 if (errno) {
853                         if (errno != ESRCH)
854                                 perror("umoven");
855                         return -1;
856                 }
857                 memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
858                 addr += sizeof(long), laddr += m, len -= m;
859         }
860         while (len) {
861                 errno = 0;
862                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
863                 if (errno) {
864                         if (errno != ESRCH)
865                                 perror("umoven");
866                         return -1;
867                 }
868                 memcpy(laddr, u.x, m = MIN(sizeof(long), len));
869                 addr += sizeof(long), laddr += m, len -= m;
870         }
871 #else /* !oldway */
872         int n;
873
874         while (len) {
875                 n = MIN(len, PAGSIZ);
876                 n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
877                 if (ptrace(PTRACE_READDATA, pid,
878                            (char *) addr, len, laddr) < 0) {
879                         if (errno != ESRCH) {
880                                 perror("umoven: ptrace(PTRACE_READDATA, ...)");
881                                 abort();
882                         }
883                         return -1;
884                 }
885                 len -= n;
886                 addr += n;
887                 laddr += n;
888         }
889 #endif /* !oldway */
890 #endif /* SUNOS4 */
891
892 #ifdef USE_PROCFS
893 #ifdef HAVE_MP_PROCFS
894         int fd = tcp->pfd_as;
895 #else
896         int fd = tcp->pfd;
897 #endif
898         lseek(fd, addr, SEEK_SET);
899         if (read(fd, laddr, len) == -1)
900                 return -1;
901 #endif /* USE_PROCFS */
902
903         return 0;
904 }
905
906 /*
907  * like `umove' but make the additional effort of looking
908  * for a terminating zero byte.
909  */
910 int
911 umovestr(struct tcb *tcp, long addr, int len, char *laddr)
912 {
913 #ifdef USE_PROCFS
914 #ifdef HAVE_MP_PROCFS
915         int fd = tcp->pfd_as;
916 #else
917         int fd = tcp->pfd;
918 #endif
919         /* Some systems (e.g. FreeBSD) can be upset if we read off the
920            end of valid memory,  avoid this by trying to read up
921            to page boundaries.  But we don't know what a page is (and
922            getpagesize(2) (if it exists) doesn't necessarily return
923            hardware page size).  Assume all pages >= 1024 (a-historical
924            I know) */
925
926         int page = 1024;        /* How to find this? */
927         int move = page - (addr & (page - 1));
928         int left = len;
929
930         lseek(fd, addr, SEEK_SET);
931
932         while (left) {
933                 if (move > left) move = left;
934                 if ((move = read(fd, laddr, move)) <= 0)
935                         return left != len ? 0 : -1;
936                 if (memchr (laddr, 0, move)) break;
937                 left -= move;
938                 laddr += move;
939                 addr += move;
940                 move = page;
941         }
942 #else /* !USE_PROCFS */
943         int started = 0;
944         int pid = tcp->pid;
945         int i, n, m;
946         union {
947                 long val;
948                 char x[sizeof(long)];
949         } u;
950
951         if (addr & (sizeof(long) - 1)) {
952                 /* addr not a multiple of sizeof(long) */
953                 n = addr - (addr & -sizeof(long)); /* residue */
954                 addr &= -sizeof(long); /* residue */
955                 errno = 0;
956                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
957                 if (errno) {
958                         if (started && (errno==EPERM || errno==EIO)) {
959                                 /* Ran into 'end of memory' - stupid "printpath" */
960                                 return 0;
961                         }
962                         if (addr != 0 && errno != EIO && errno != ESRCH)
963                                 perror("umovestr");
964                         return -1;
965                 }
966                 started = 1;
967                 memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len));
968                 while (n & (sizeof(long) - 1))
969                         if (u.x[n++] == '\0')
970                                 return 0;
971                 addr += sizeof(long), laddr += m, len -= m;
972         }
973         while (len) {
974                 errno = 0;
975                 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
976                 if (errno) {
977                         if (started && (errno==EPERM || errno==EIO)) {
978                                 /* Ran into 'end of memory' - stupid "printpath" */
979                                 return 0;
980                         }
981                         if (addr != 0 && errno != EIO && errno != ESRCH)
982                                 perror("umovestr");
983                         return -1;
984                 }
985                 started = 1;
986                 memcpy(laddr, u.x, m = MIN(sizeof(long), len));
987                 for (i = 0; i < sizeof(long); i++)
988                         if (u.x[i] == '\0')
989                                 return 0;
990
991                 addr += sizeof(long), laddr += m, len -= m;
992         }
993 #endif /* !USE_PROCFS */
994         return 0;
995 }
996
997 #ifdef LINUX
998 # if !defined (SPARC) && !defined(SPARC64)
999 #  define PTRACE_WRITETEXT      101
1000 #  define PTRACE_WRITEDATA      102
1001 # endif /* !SPARC && !SPARC64 */
1002 #endif /* LINUX */
1003
1004 #ifdef SUNOS4
1005
1006 static int
1007 uload(cmd, pid, addr, len, laddr)
1008 int cmd;
1009 int pid;
1010 long addr;
1011 int len;
1012 char *laddr;
1013 {
1014 # if 0
1015         int n;
1016
1017         while (len) {
1018                 n = MIN(len, PAGSIZ);
1019                 n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
1020                 if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) {
1021                         perror("uload: ptrace(PTRACE_WRITE, ...)");
1022                         return -1;
1023                 }
1024                 len -= n;
1025                 addr += n;
1026                 laddr += n;
1027         }
1028 # else
1029         int peek, poke;
1030         int n, m;
1031         union {
1032                 long val;
1033                 char x[sizeof(long)];
1034         } u;
1035
1036         if (cmd == PTRACE_WRITETEXT) {
1037                 peek = PTRACE_PEEKTEXT;
1038                 poke = PTRACE_POKETEXT;
1039         }
1040         else {
1041                 peek = PTRACE_PEEKDATA;
1042                 poke = PTRACE_POKEDATA;
1043         }
1044         if (addr & (sizeof(long) - 1)) {
1045                 /* addr not a multiple of sizeof(long) */
1046                 n = addr - (addr & -sizeof(long)); /* residue */
1047                 addr &= -sizeof(long);
1048                 errno = 0;
1049                 u.val = ptrace(peek, pid, (char *) addr, 0);
1050                 if (errno) {
1051                         perror("uload: POKE");
1052                         return -1;
1053                 }
1054                 memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len));
1055                 if (ptrace(poke, pid, (char *)addr, u.val) < 0) {
1056                         perror("uload: POKE");
1057                         return -1;
1058                 }
1059                 addr += sizeof(long), laddr += m, len -= m;
1060         }
1061         while (len) {
1062                 if (len < sizeof(long))
1063                         u.val = ptrace(peek, pid, (char *) addr, 0);
1064                 memcpy(u.x, laddr, m = MIN(sizeof(long), len));
1065                 if (ptrace(poke, pid, (char *) addr, u.val) < 0) {
1066                         perror("uload: POKE");
1067                         return -1;
1068                 }
1069                 addr += sizeof(long), laddr += m, len -= m;
1070         }
1071 # endif
1072         return 0;
1073 }
1074
1075 int
1076 tload(pid, addr, len, laddr)
1077 int pid;
1078 int addr, len;
1079 char *laddr;
1080 {
1081         return uload(PTRACE_WRITETEXT, pid, addr, len, laddr);
1082 }
1083
1084 int
1085 dload(pid, addr, len, laddr)
1086 int pid;
1087 int addr;
1088 int len;
1089 char *laddr;
1090 {
1091         return uload(PTRACE_WRITEDATA, pid, addr, len, laddr);
1092 }
1093
1094 #endif /* SUNOS4 */
1095
1096 #ifndef USE_PROCFS
1097
1098 int
1099 upeek(tcp, off, res)
1100 struct tcb *tcp;
1101 long off;
1102 long *res;
1103 {
1104         long val;
1105
1106 # ifdef SUNOS4_KERNEL_ARCH_KLUDGE
1107         {
1108                 static int is_sun4m = -1;
1109                 struct utsname name;
1110
1111                 /* Round up the usual suspects. */
1112                 if (is_sun4m == -1) {
1113                         if (uname(&name) < 0) {
1114                                 perror("upeek: uname?");
1115                                 exit(1);
1116                         }
1117                         is_sun4m = strcmp(name.machine, "sun4m") == 0;
1118                         if (is_sun4m) {
1119                                 const struct xlat *x;
1120
1121                                 for (x = struct_user_offsets; x->str; x++)
1122                                         x->val += 1024;
1123                         }
1124                 }
1125                 if (is_sun4m)
1126                         off += 1024;
1127         }
1128 # endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
1129         errno = 0;
1130         val = do_ptrace(PTRACE_PEEKUSER, tcp, (char *) off, 0);
1131         if (val == -1 && errno) {
1132                 if (errno != ESRCH) {
1133                         char buf[60];
1134                         sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)", tcp->pid, off);
1135                         perror(buf);
1136                 }
1137                 return -1;
1138         }
1139         *res = val;
1140         return 0;
1141 }
1142
1143 #endif /* !USE_PROCFS */
1144
1145 #if 0
1146 long
1147 getpc(struct tcb *tcp)
1148 {
1149
1150 #ifdef LINUX
1151         long pc;
1152 # if defined(I386)
1153         if (upeek(tcp, 4*EIP, &pc) < 0)
1154                 return -1;
1155 # elif defined(X86_64)
1156         if (upeek(tcp, 8*RIP, &pc) < 0)
1157                 return -1;
1158 # elif defined(IA64)
1159         if (upeek(tcp, PT_B0, &pc) < 0)
1160                 return -1;
1161 # elif defined(ARM)
1162         if (upeek(tcp, 4*15, &pc) < 0)
1163                 return -1;
1164 # elif defined(AVR32)
1165         if (upeek(tcp, REG_PC, &pc) < 0)
1166                 return -1;
1167 # elif defined(BFIN)
1168         if (upeek(tcp, REG_PC, &pc) < 0)
1169                 return -1;
1170 # elif defined(POWERPC)
1171         if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0)
1172                 return -1;
1173 # elif defined(M68K)
1174         if (upeek(tcp, 4*PT_PC, &pc) < 0)
1175                 return -1;
1176 # elif defined(ALPHA)
1177         if (upeek(tcp, REG_PC, &pc) < 0)
1178                 return -1;
1179 # elif defined(MIPS)
1180         if (upeek(tcp, REG_EPC, &pc) < 0)
1181                 return -1;
1182 # elif defined(SPARC) || defined(SPARC64)
1183         struct regs regs;
1184         if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
1185                 return -1;
1186         pc = regs.r_pc;
1187 # elif defined(S390) || defined(S390X)
1188         if(upeek(tcp,PT_PSWADDR,&pc) < 0)
1189                 return -1;
1190 # elif defined(HPPA)
1191         if(upeek(tcp,PT_IAOQ0,&pc) < 0)
1192                 return -1;
1193 # elif defined(SH)
1194         if (upeek(tcp, 4*REG_PC ,&pc) < 0)
1195                 return -1;
1196 # elif defined(SH64)
1197         if (upeek(tcp, REG_PC ,&pc) < 0)
1198                 return -1;
1199 # endif
1200         return pc;
1201 #endif /* LINUX */
1202
1203 #ifdef SUNOS4
1204         /*
1205          * Return current program counter for `pid'
1206          * Assumes PC is never 0xffffffff
1207          */
1208         struct regs regs;
1209
1210         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
1211                 perror("getpc: ptrace(PTRACE_GETREGS, ...)");
1212                 return -1;
1213         }
1214         return regs.r_pc;
1215 #endif /* SUNOS4 */
1216
1217 #ifdef SVR4
1218         /* XXX */
1219         return 0;
1220 #endif /* SVR4 */
1221
1222 #ifdef FREEBSD
1223         struct reg regs;
1224         pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
1225         return regs.r_eip;
1226 #endif /* FREEBSD */
1227 }
1228 #endif /* 0 */
1229
1230 void
1231 printcall(struct tcb *tcp)
1232 {
1233 #define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \
1234                            sizeof(long) == 8 ? "[????????????????] " : \
1235                            NULL /* crash */)
1236
1237 #ifdef LINUX
1238 # ifdef I386
1239         long eip;
1240
1241         if (upeek(tcp, 4*EIP, &eip) < 0) {
1242                 PRINTBADPC;
1243                 return;
1244         }
1245         tprintf("[%08lx] ", eip);
1246
1247 # elif defined(S390) || defined(S390X)
1248         long psw;
1249         if(upeek(tcp,PT_PSWADDR,&psw) < 0) {
1250                 PRINTBADPC;
1251                 return;
1252         }
1253 #  ifdef S390
1254         tprintf("[%08lx] ", psw);
1255 #  elif S390X
1256         tprintf("[%16lx] ", psw);
1257 #  endif
1258
1259 # elif defined(X86_64)
1260         long rip;
1261
1262         if (upeek(tcp, 8*RIP, &rip) < 0) {
1263                 PRINTBADPC;
1264                 return;
1265         }
1266         tprintf("[%16lx] ", rip);
1267 # elif defined(IA64)
1268         long ip;
1269
1270         if (upeek(tcp, PT_B0, &ip) < 0) {
1271                 PRINTBADPC;
1272                 return;
1273         }
1274         tprintf("[%08lx] ", ip);
1275 # elif defined(POWERPC)
1276         long pc;
1277
1278         if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) {
1279                 tprintf ("[????????] ");
1280                 return;
1281         }
1282         tprintf("[%08lx] ", pc);
1283 # elif defined(M68K)
1284         long pc;
1285
1286         if (upeek(tcp, 4*PT_PC, &pc) < 0) {
1287                 tprintf ("[????????] ");
1288                 return;
1289         }
1290         tprintf("[%08lx] ", pc);
1291 # elif defined(ALPHA)
1292         long pc;
1293
1294         if (upeek(tcp, REG_PC, &pc) < 0) {
1295                 tprintf ("[????????????????] ");
1296                 return;
1297         }
1298         tprintf("[%08lx] ", pc);
1299 # elif defined(SPARC) || defined(SPARC64)
1300         struct regs regs;
1301         if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0) {
1302                 PRINTBADPC;
1303                 return;
1304         }
1305         tprintf("[%08lx] ", regs.r_pc);
1306 # elif defined(HPPA)
1307         long pc;
1308
1309         if(upeek(tcp,PT_IAOQ0,&pc) < 0) {
1310                 tprintf ("[????????] ");
1311                 return;
1312         }
1313         tprintf("[%08lx] ", pc);
1314 # elif defined(MIPS)
1315         long pc;
1316
1317         if (upeek(tcp, REG_EPC, &pc) < 0) {
1318                 tprintf ("[????????] ");
1319                 return;
1320         }
1321         tprintf("[%08lx] ", pc);
1322 # elif defined(SH)
1323         long pc;
1324
1325         if (upeek(tcp, 4*REG_PC, &pc) < 0) {
1326                 tprintf ("[????????] ");
1327                 return;
1328         }
1329         tprintf("[%08lx] ", pc);
1330 # elif defined(SH64)
1331         long pc;
1332
1333         if (upeek(tcp, REG_PC, &pc) < 0) {
1334                 tprintf ("[????????????????] ");
1335                 return;
1336         }
1337         tprintf("[%08lx] ", pc);
1338 # elif defined(ARM)
1339         long pc;
1340
1341         if (upeek(tcp, 4*15, &pc) < 0) {
1342                 PRINTBADPC;
1343                 return;
1344         }
1345         tprintf("[%08lx] ", pc);
1346 # elif defined(AVR32)
1347         long pc;
1348
1349         if (upeek(tcp, REG_PC, &pc) < 0) {
1350                 tprintf("[????????] ");
1351                 return;
1352         }
1353         tprintf("[%08lx] ", pc);
1354 # elif defined(BFIN)
1355         long pc;
1356
1357         if (upeek(tcp, PT_PC, &pc) < 0) {
1358                 PRINTBADPC;
1359                 return;
1360         }
1361         tprintf("[%08lx] ", pc);
1362 #elif defined(CRISV10)
1363         long pc;
1364
1365         if (upeek(tcp, 4*PT_IRP, &pc) < 0) {
1366                 PRINTBADPC;
1367                 return;
1368         }
1369         tprintf("[%08lx] ", pc);
1370 #elif defined(CRISV32)
1371         long pc;
1372
1373         if (upeek(tcp, 4*PT_ERP, &pc) < 0) {
1374                 PRINTBADPC;
1375                 return;
1376         }
1377         tprintf("[%08lx] ", pc);
1378 # endif /* architecture */
1379 #endif /* LINUX */
1380
1381 #ifdef SUNOS4
1382         struct regs regs;
1383
1384         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
1385                 perror("printcall: ptrace(PTRACE_GETREGS, ...)");
1386                 PRINTBADPC;
1387                 return;
1388         }
1389         tprintf("[%08x] ", regs.r_o7);
1390 #endif /* SUNOS4 */
1391
1392 #ifdef SVR4
1393         /* XXX */
1394         PRINTBADPC;
1395 #endif
1396
1397 #ifdef FREEBSD
1398         struct reg regs;
1399         pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
1400         tprintf("[%08x] ", regs.r_eip);
1401 #endif /* FREEBSD */
1402 }
1403
1404
1405 /*
1406  * These #if's are huge, please indent them correctly.
1407  * It's easy to get confused otherwise.
1408  */
1409 #ifndef USE_PROCFS
1410
1411 # if defined LINUX
1412
1413 #  include "syscall.h"
1414
1415 #  include <sys/syscall.h>
1416 #  ifndef CLONE_PTRACE
1417 #   define CLONE_PTRACE    0x00002000
1418 #  endif
1419 #  ifndef CLONE_VFORK
1420 #   define CLONE_VFORK     0x00004000
1421 #  endif
1422 #  ifndef CLONE_VM
1423 #   define CLONE_VM        0x00000100
1424 #  endif
1425 #  ifndef CLONE_STOPPED
1426 #   define CLONE_STOPPED   0x02000000
1427 #  endif
1428
1429 #  ifdef IA64
1430
1431 /* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32
1432    subsystem has them for x86... */
1433 #   define SYS_fork     2
1434 #   define SYS_vfork    190
1435
1436 typedef unsigned long *arg_setup_state;
1437
1438 static int
1439 arg_setup(struct tcb *tcp, arg_setup_state *state)
1440 {
1441         unsigned long cfm, sof, sol;
1442         long bsp;
1443
1444         if (ia32) {
1445                 /* Satisfy a false GCC warning.  */
1446                 *state = NULL;
1447                 return 0;
1448         }
1449
1450         if (upeek(tcp, PT_AR_BSP, &bsp) < 0)
1451                 return -1;
1452         if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
1453                 return -1;
1454
1455         sof = (cfm >> 0) & 0x7f;
1456         sol = (cfm >> 7) & 0x7f;
1457         bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol);
1458
1459         *state = (unsigned long *) bsp;
1460         return 0;
1461 }
1462
1463 #   define arg_finish_change(tcp, state)        0
1464
1465 #   ifdef SYS_fork
1466 static int
1467 get_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp)
1468 {
1469         int ret;
1470
1471         if (ia32)
1472                 ret = upeek (tcp, PT_R11, valp);
1473         else
1474                 ret = umoven (tcp,
1475                               (unsigned long) ia64_rse_skip_regs(*state, 0),
1476                               sizeof(long), (void *) valp);
1477         return ret;
1478 }
1479
1480 static int
1481 get_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp)
1482 {
1483         int ret;
1484
1485         if (ia32)
1486                 ret = upeek (tcp, PT_R9, valp);
1487         else
1488                 ret = umoven (tcp,
1489                               (unsigned long) ia64_rse_skip_regs(*state, 1),
1490                               sizeof(long), (void *) valp);
1491         return ret;
1492 }
1493 #   endif
1494
1495 static int
1496 set_arg0 (struct tcb *tcp, arg_setup_state *state, long val)
1497 {
1498         int req = PTRACE_POKEDATA;
1499         void *ap;
1500
1501         if (ia32) {
1502                 ap = (void *) (intptr_t) PT_R11;         /* r11 == EBX */
1503                 req = PTRACE_POKEUSER;
1504         } else
1505                 ap = ia64_rse_skip_regs(*state, 0);
1506         errno = 0;
1507         ptrace(req, tcp->pid, ap, val);
1508         return errno ? -1 : 0;
1509 }
1510
1511 static int
1512 set_arg1 (struct tcb *tcp, arg_setup_state *state, long val)
1513 {
1514         int req = PTRACE_POKEDATA;
1515         void *ap;
1516
1517         if (ia32) {
1518                 ap = (void *) (intptr_t) PT_R9;         /* r9 == ECX */
1519                 req = PTRACE_POKEUSER;
1520         } else
1521                 ap = ia64_rse_skip_regs(*state, 1);
1522         errno = 0;
1523         ptrace(req, tcp->pid, ap, val);
1524         return errno ? -1 : 0;
1525 }
1526
1527 /* ia64 does not return the input arguments from functions (and syscalls)
1528    according to ia64 RSE (Register Stack Engine) behavior.  */
1529
1530 #   define restore_arg0(tcp, state, val) ((void) (state), 0)
1531 #   define restore_arg1(tcp, state, val) ((void) (state), 0)
1532
1533 #  elif defined (SPARC) || defined (SPARC64)
1534
1535 typedef struct regs arg_setup_state;
1536
1537 #   define arg_setup(tcp, state) \
1538     (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0))
1539 #   define arg_finish_change(tcp, state) \
1540     (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0))
1541
1542 #   define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0)
1543 #   define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0)
1544 #   define set_arg0(tcp, state, val) ((state)->r_o0 = (val), 0)
1545 #   define set_arg1(tcp, state, val) ((state)->r_o1 = (val), 0)
1546 #   define restore_arg0(tcp, state, val) 0
1547
1548 #  else /* other architectures */
1549
1550 #   if defined S390 || defined S390X
1551 /* Note: this is only true for the `clone' system call, which handles
1552    arguments specially.  We could as well say that its first two arguments
1553    are swapped relative to other architectures, but that would just be
1554    another #ifdef in the calls.  */
1555 #    define arg0_offset PT_GPR3
1556 #    define arg1_offset PT_ORIGGPR2
1557 #    define restore_arg0(tcp, state, val) ((void) (state), 0)
1558 #    define restore_arg1(tcp, state, val) ((void) (state), 0)
1559 #    define arg0_index  1
1560 #    define arg1_index  0
1561 #   elif defined (ALPHA) || defined (MIPS)
1562 #    define arg0_offset REG_A0
1563 #    define arg1_offset (REG_A0+1)
1564 #   elif defined (AVR32)
1565 #    define arg0_offset (REG_R12)
1566 #    define arg1_offset (REG_R11)
1567 #   elif defined (POWERPC)
1568 #    define arg0_offset (sizeof(unsigned long)*PT_R3)
1569 #    define arg1_offset (sizeof(unsigned long)*PT_R4)
1570 #    define restore_arg0(tcp, state, val) ((void) (state), 0)
1571 #   elif defined (HPPA)
1572 #    define arg0_offset  PT_GR26
1573 #    define arg1_offset  (PT_GR26-4)
1574 #   elif defined (X86_64)
1575 #    define arg0_offset ((long)(8*(current_personality ? RBX : RDI)))
1576 #    define arg1_offset ((long)(8*(current_personality ? RCX : RSI)))
1577 #   elif defined (SH)
1578 #    define arg0_offset (4*(REG_REG0+4))
1579 #    define arg1_offset (4*(REG_REG0+5))
1580 #   elif defined (SH64)
1581     /* ABI defines arg0 & 1 in r2 & r3 */
1582 #    define arg0_offset   (REG_OFFSET+16)
1583 #    define arg1_offset   (REG_OFFSET+24)
1584 #    define restore_arg0(tcp, state, val) 0
1585 #   elif defined CRISV10 || defined CRISV32
1586 #    define arg0_offset   (4*PT_R11)
1587 #    define arg1_offset   (4*PT_ORIG_R10)
1588 #    define restore_arg0(tcp, state, val) 0
1589 #    define restore_arg1(tcp, state, val) 0
1590 #    define arg0_index   1
1591 #    define arg1_index   0
1592 #   else
1593 #    define arg0_offset 0
1594 #    define arg1_offset 4
1595 #    if defined ARM
1596 #     define restore_arg0(tcp, state, val) 0
1597 #    endif
1598 #   endif
1599
1600 typedef int arg_setup_state;
1601
1602 #   define arg_setup(tcp, state) (0)
1603 #   define arg_finish_change(tcp, state)        0
1604 #   define get_arg0(tcp, cookie, valp) \
1605     (upeek ((tcp), arg0_offset, (valp)))
1606 #   define get_arg1(tcp, cookie, valp) \
1607     (upeek ((tcp), arg1_offset, (valp)))
1608
1609 static int
1610 set_arg0 (struct tcb *tcp, void *cookie, long val)
1611 {
1612         return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val);
1613 }
1614
1615 static int
1616 set_arg1 (struct tcb *tcp, void *cookie, long val)
1617 {
1618         return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val);
1619 }
1620
1621 #  endif /* architectures */
1622
1623 #  ifndef restore_arg0
1624 #   define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val))
1625 #  endif
1626 #  ifndef restore_arg1
1627 #   define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val))
1628 #  endif
1629
1630 #  ifndef arg0_index
1631 #   define arg0_index 0
1632 #   define arg1_index 1
1633 #  endif
1634
1635 int
1636 setbpt(struct tcb *tcp)
1637 {
1638         static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone };
1639         arg_setup_state state;
1640
1641         if (tcp->flags & TCB_BPTSET) {
1642                 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1643                 return -1;
1644         }
1645
1646         /*
1647          * It's a silly kludge to initialize this with a search at runtime.
1648          * But it's better than maintaining another magic thing in the
1649          * godforsaken tables.
1650          */
1651         if (clone_scno[current_personality] == 0) {
1652                 int i;
1653                 for (i = 0; i < nsyscalls; ++i)
1654                         if (sysent[i].sys_func == sys_clone) {
1655                                 clone_scno[current_personality] = i;
1656                                 break;
1657                         }
1658         }
1659
1660         switch (known_scno(tcp)) {
1661 #  ifdef SYS_vfork
1662         case SYS_vfork:
1663 #  endif
1664 #  ifdef SYS_fork
1665         case SYS_fork:
1666 #  endif
1667 #  if defined SYS_fork || defined SYS_vfork
1668                 if (arg_setup (tcp, &state) < 0
1669                     || get_arg0 (tcp, &state, &tcp->inst[0]) < 0
1670                     || get_arg1 (tcp, &state, &tcp->inst[1]) < 0
1671                     || change_syscall(tcp, clone_scno[current_personality]) < 0
1672                     || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0
1673                     || set_arg1 (tcp, &state, 0) < 0
1674                     || arg_finish_change (tcp, &state) < 0)
1675                         return -1;
1676                 tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD;
1677                 tcp->u_arg[arg1_index] = 0;
1678                 tcp->flags |= TCB_BPTSET;
1679                 return 0;
1680 #  endif
1681
1682         case SYS_clone:
1683 #  ifdef SYS_clone2
1684         case SYS_clone2:
1685 #  endif
1686                 /* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)'
1687                    contrary to x86 SYS_vfork above.  Even on x86 we turn the
1688                    vfork semantics into plain fork - each application must not
1689                    depend on the vfork specifics according to POSIX.  We would
1690                    hang waiting for the parent resume otherwise.  We need to
1691                    clear also CLONE_VM but only in the CLONE_VFORK case as
1692                    otherwise we would break pthread_create.  */
1693
1694                 if ((arg_setup (tcp, &state) < 0
1695                     || set_arg0 (tcp, &state,
1696                                  (tcp->u_arg[arg0_index] | CLONE_PTRACE)
1697                                  & ~(tcp->u_arg[arg0_index] & CLONE_VFORK
1698                                      ? CLONE_VFORK | CLONE_VM : 0)) < 0
1699                     || arg_finish_change (tcp, &state) < 0))
1700                         return -1;
1701                 tcp->flags |= TCB_BPTSET;
1702                 tcp->inst[0] = tcp->u_arg[arg0_index];
1703                 tcp->inst[1] = tcp->u_arg[arg1_index];
1704                 return 0;
1705
1706         default:
1707                 fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n",
1708                         tcp->scno, tcp->pid);
1709                 break;
1710         }
1711
1712         return -1;
1713 }
1714
1715 int
1716 clearbpt(tcp)
1717 struct tcb *tcp;
1718 {
1719         arg_setup_state state;
1720         if (arg_setup (tcp, &state) < 0
1721             || restore_arg0 (tcp, &state, tcp->inst[0]) < 0
1722             || restore_arg1 (tcp, &state, tcp->inst[1]) < 0
1723             || arg_finish_change (tcp, &state))
1724                 return -1;
1725         tcp->flags &= ~TCB_BPTSET;
1726         return 0;
1727 }
1728
1729 # else /* !defined LINUX */
1730
1731 int
1732 setbpt(tcp)
1733 struct tcb *tcp;
1734 {
1735 #  ifdef LINUX
1736         DEAD CODE HERE? WE ARE IN 'else !defined LINUX'
1737 #   if defined (SPARC) || defined (SPARC64)
1738         /* We simply use the SunOS breakpoint code. */
1739
1740         struct regs regs;
1741         unsigned long inst;
1742 #    define LOOPA       0x30800000      /* ba,a 0 */
1743
1744         if (tcp->flags & TCB_BPTSET) {
1745                 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1746                 return -1;
1747         }
1748         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1749                 perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
1750                 return -1;
1751         }
1752         tcp->baddr = regs.r_o7 + 8;
1753         errno = 0;
1754         tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0);
1755         if(errno) {
1756                 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1757                 return -1;
1758         }
1759
1760         /*
1761          * XXX - BRUTAL MODE ON
1762          * We cannot set a real BPT in the child, since it will not be
1763          * traced at the moment it will reach the trap and would probably
1764          * die with a core dump.
1765          * Thus, we are force our way in by taking out two instructions
1766          * and insert an eternal loop instead, in expectance of the SIGSTOP
1767          * generated by our PTRACE_ATTACH.
1768          * Of cause, if we evaporate ourselves in the middle of all this...
1769          */
1770         errno = 0;
1771         inst = LOOPA;
1772 #    if defined (SPARC64)
1773         inst <<= 32;
1774         inst |= (tcp->inst[0] & 0xffffffffUL);
1775 #    endif
1776         ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, inst);
1777         if(errno) {
1778                 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1779                 return -1;
1780         }
1781         tcp->flags |= TCB_BPTSET;
1782
1783 #   else /* !SPARC && !SPARC64 */
1784 #    ifdef IA64
1785         if (ia32) {
1786 #               define LOOP     0x0000feeb
1787                 if (tcp->flags & TCB_BPTSET) {
1788                         fprintf(stderr, "PANIC: bpt already set in pid %u\n",
1789                                 tcp->pid);
1790                         return -1;
1791                 }
1792                 if (upeek(tcp, PT_CR_IIP, &tcp->baddr) < 0)
1793                         return -1;
1794                 if (debug)
1795                         fprintf(stderr, "[%d] setting bpt at %lx\n",
1796                                 tcp->pid, tcp->baddr);
1797                 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid,
1798                                       (char *) tcp->baddr, 0);
1799                 if (errno) {
1800                         perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1801                         return -1;
1802                 }
1803                 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
1804                 if (errno) {
1805                         perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1806                         return -1;
1807                 }
1808                 tcp->flags |= TCB_BPTSET;
1809         } else {
1810                 /*
1811                  * Our strategy here is to replace the bundle that
1812                  * contained the clone() syscall with a bundle of the
1813                  * form:
1814                  *
1815                  *      { 1: br 1b; br 1b; br 1b }
1816                  *
1817                  * This ensures that the newly forked child will loop
1818                  * endlessly until we've got a chance to attach to it.
1819                  */
1820 #                       define LOOP0    0x0000100000000017
1821 #                       define LOOP1    0x4000000000200000
1822                 unsigned long addr, ipsr;
1823                 pid_t pid;
1824
1825                 pid = tcp->pid;
1826                 if (upeek(tcp, PT_CR_IPSR, &ipsr) < 0)
1827                         return -1;
1828                 if (upeek(tcp, PT_CR_IIP, &addr) < 0)
1829                         return -1;
1830                 /* store "ri" in low two bits */
1831                 tcp->baddr = addr | ((ipsr >> 41) & 0x3);
1832
1833                 errno = 0;
1834                 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0,
1835                                       0);
1836                 tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8,
1837                                       0);
1838                 if (errno) {
1839                         perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1840                         return -1;
1841                 }
1842
1843                 errno = 0;
1844                 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0);
1845                 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1);
1846                 if (errno) {
1847                         perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1848                         return -1;
1849                 }
1850                 tcp->flags |= TCB_BPTSET;
1851         }
1852 #    else /* !IA64 */
1853
1854 #     if defined (I386) || defined(X86_64)
1855 #      define LOOP      0x0000feeb
1856 #     elif defined (M68K)
1857 #      define LOOP      0x60fe0000
1858 #     elif defined (ALPHA)
1859 #      define LOOP      0xc3ffffff
1860 #     elif defined (POWERPC)
1861 #      define LOOP      0x48000000
1862 #     elif defined(ARM)
1863 #      define LOOP      0xEAFFFFFE
1864 #     elif defined(MIPS)
1865 #      define LOOP      0x1000ffff
1866 #     elif defined(S390)
1867 #      define LOOP      0xa7f40000      /* BRC 15,0 */
1868 #     elif defined(S390X)
1869 #      define LOOP   0xa7f4000000000000UL /* BRC 15,0 */
1870 #     elif defined(HPPA)
1871 #      define LOOP      0xe81f1ff7      /* b,l,n <loc>,r0 */
1872 #     elif defined(SH)
1873 #      ifdef __LITTLE_ENDIAN__
1874 #       define LOOP   0x0000affe
1875 #      else
1876 #       define LOOP   0xfeaf0000
1877 #      endif
1878 #     else
1879 #      error unknown architecture
1880 #     endif
1881
1882         if (tcp->flags & TCB_BPTSET) {
1883                 fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid);
1884                 return -1;
1885         }
1886 #     if defined (I386)
1887         if (upeek(tcp, 4*EIP, &tcp->baddr) < 0)
1888                 return -1;
1889 #     elif defined (X86_64)
1890         if (upeek(tcp, 8*RIP, &tcp->baddr) < 0)
1891                 return -1;
1892 #     elif defined (M68K)
1893         if (upeek(tcp, 4*PT_PC, &tcp->baddr) < 0)
1894                 return -1;
1895 #     elif defined (ALPHA)
1896         return -1;
1897 #     elif defined (ARM)
1898         return -1;
1899 #     elif defined (MIPS)
1900         return -1;              /* FIXME: I do not know what i do - Flo */
1901 #     elif defined (POWERPC)
1902         if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &tcp->baddr) < 0)
1903                 return -1;
1904 #     elif defined(S390) || defined(S390X)
1905         if (upeek(tcp,PT_PSWADDR, &tcp->baddr) < 0)
1906                 return -1;
1907 #     elif defined(HPPA)
1908         if (upeek(tcp, PT_IAOQ0, &tcp->baddr) < 0)
1909                 return -1;
1910         tcp->baddr &= ~0x03;
1911 #     elif defined(SH)
1912         if (upeek(tcp, 4*REG_PC, &tcp->baddr) < 0)
1913                 return -1;
1914 #     else
1915 #      error unknown architecture
1916 #     endif
1917         if (debug)
1918                 fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr);
1919         tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0);
1920         if (errno) {
1921                 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1922                 return -1;
1923         }
1924         ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
1925         if (errno) {
1926                 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1927                 return -1;
1928         }
1929         tcp->flags |= TCB_BPTSET;
1930
1931 #    endif /* !IA64 */
1932 #   endif /* !SPARC && !SPARC64 */
1933 #  endif /* LINUX */
1934
1935 #  ifdef SUNOS4
1936 #   ifdef SPARC /* This code is slightly sparc specific */
1937
1938         struct regs regs;
1939 #    define BPT 0x91d02001      /* ta   1 */
1940 #    define LOOP        0x10800000      /* ba   0 */
1941 #    define LOOPA       0x30800000      /* ba,a 0 */
1942 #    define NOP 0x01000000
1943 #    if LOOPA
1944         static int loopdeloop[1] = {LOOPA};
1945 #    else
1946         static int loopdeloop[2] = {LOOP, NOP};
1947 #    endif
1948
1949         if (tcp->flags & TCB_BPTSET) {
1950                 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1951                 return -1;
1952         }
1953         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1954                 perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
1955                 return -1;
1956         }
1957         tcp->baddr = regs.r_o7 + 8;
1958         if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr,
1959                                 sizeof tcp->inst, (char *)tcp->inst) < 0) {
1960                 perror("setbpt: ptrace(PTRACE_READTEXT, ...)");
1961                 return -1;
1962         }
1963
1964         /*
1965          * XXX - BRUTAL MODE ON
1966          * We cannot set a real BPT in the child, since it will not be
1967          * traced at the moment it will reach the trap and would probably
1968          * die with a core dump.
1969          * Thus, we are force our way in by taking out two instructions
1970          * and insert an eternal loop in stead, in expectance of the SIGSTOP
1971          * generated by out PTRACE_ATTACH.
1972          * Of cause, if we evaporate ourselves in the middle of all this...
1973          */
1974         if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
1975                         sizeof loopdeloop, (char *) loopdeloop) < 0) {
1976                 perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)");
1977                 return -1;
1978         }
1979         tcp->flags |= TCB_BPTSET;
1980
1981 #   endif /* SPARC */
1982 #  endif /* SUNOS4 */
1983
1984         return 0;
1985 }
1986
1987 int
1988 clearbpt(tcp)
1989 struct tcb *tcp;
1990 {
1991
1992 #  ifdef LINUX
1993         DEAD CODE HERE? WE ARE IN 'else !defined LINUX'
1994 #   if defined(I386) || defined(X86_64)
1995         long eip;
1996 #   elif defined(POWERPC)
1997         long pc;
1998 #   elif defined(M68K)
1999         long pc;
2000 #   elif defined(ALPHA)
2001         long pc;
2002 #   elif defined(HPPA)
2003         long iaoq;
2004 #   elif defined(SH)
2005         long pc;
2006 #   endif /* architecture */
2007
2008 #   if defined (SPARC) || defined (SPARC64)
2009         /* Again, we borrow the SunOS breakpoint code. */
2010         if (!(tcp->flags & TCB_BPTSET)) {
2011                 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
2012                 return -1;
2013         }
2014         errno = 0;
2015         ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
2016         if(errno) {
2017                 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
2018                 return -1;
2019         }
2020         tcp->flags &= ~TCB_BPTSET;
2021 #   elif defined(IA64)
2022         if (ia32) {
2023                 unsigned long addr;
2024
2025                 if (debug)
2026                         fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
2027                 if (!(tcp->flags & TCB_BPTSET)) {
2028                         fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
2029                         return -1;
2030                 }
2031                 errno = 0;
2032                 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
2033                 if (errno) {
2034                         perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
2035                         return -1;
2036                 }
2037                 tcp->flags &= ~TCB_BPTSET;
2038
2039                 if (upeek(tcp, PT_CR_IIP, &addr) < 0)
2040                         return -1;
2041                 if (addr != tcp->baddr) {
2042                         /* The breakpoint has not been reached yet.  */
2043                         if (debug)
2044                                 fprintf(stderr,
2045                                         "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2046                                                 addr, tcp->baddr);
2047                         return 0;
2048                 }
2049         } else {
2050                 unsigned long addr, ipsr;
2051                 pid_t pid;
2052
2053                 pid = tcp->pid;
2054
2055                 if (upeek(tcp, PT_CR_IPSR, &ipsr) < 0)
2056                         return -1;
2057                 if (upeek(tcp, PT_CR_IIP, &addr) < 0)
2058                         return -1;
2059
2060                 /* restore original bundle: */
2061                 errno = 0;
2062                 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]);
2063                 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]);
2064                 if (errno) {
2065                         perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)");
2066                         return -1;
2067                 }
2068
2069                 /* restore original "ri" in ipsr: */
2070                 ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41);
2071                 errno = 0;
2072                 ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr);
2073                 if (errno) {
2074                         perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)");
2075                         return -1;
2076                 }
2077
2078                 tcp->flags &= ~TCB_BPTSET;
2079
2080                 if (addr != (tcp->baddr & ~0x3)) {
2081                         /* the breakpoint has not been reached yet.  */
2082                         if (debug)
2083                                 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2084                                         addr, tcp->baddr);
2085                         return 0;
2086                 }
2087         }
2088 #   else /* !IA64 && !SPARC && !SPARC64 */
2089
2090         if (debug)
2091                 fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
2092         if (!(tcp->flags & TCB_BPTSET)) {
2093                 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
2094                 return -1;
2095         }
2096         errno = 0;
2097         ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
2098         if (errno) {
2099                 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
2100                 return -1;
2101         }
2102         tcp->flags &= ~TCB_BPTSET;
2103
2104 #    ifdef I386
2105         if (upeek(tcp, 4*EIP, &eip) < 0)
2106                 return -1;
2107         if (eip != tcp->baddr) {
2108                 /* The breakpoint has not been reached yet.  */
2109                 if (debug)
2110                         fprintf(stderr,
2111                                 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2112                                         eip, tcp->baddr);
2113                 return 0;
2114         }
2115 #    elif defined(X86_64)
2116         if (upeek(tcp, 8*RIP, &eip) < 0)
2117                 return -1;
2118         if (eip != tcp->baddr) {
2119                 /* The breakpoint has not been reached yet.  */
2120                 if (debug)
2121                         fprintf(stderr,
2122                                 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2123                                         eip, tcp->baddr);
2124                 return 0;
2125         }
2126 #    elif defined(POWERPC)
2127         if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0)
2128                 return -1;
2129         if (pc != tcp->baddr) {
2130                 /* The breakpoint has not been reached yet.  */
2131                 if (debug)
2132                         fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2133                                 pc, tcp->baddr);
2134                 return 0;
2135         }
2136 #    elif defined(M68K)
2137         if (upeek(tcp, 4*PT_PC, &pc) < 0)
2138                 return -1;
2139         if (pc != tcp->baddr) {
2140                 /* The breakpoint has not been reached yet.  */
2141                 if (debug)
2142                         fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2143                                 pc, tcp->baddr);
2144                 return 0;
2145         }
2146 #    elif defined(ALPHA)
2147         if (upeek(tcp, REG_PC, &pc) < 0)
2148                 return -1;
2149         if (pc != tcp->baddr) {
2150                 /* The breakpoint has not been reached yet.  */
2151                 if (debug)
2152                         fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2153                                 pc, tcp->baddr);
2154                 return 0;
2155         }
2156 #    elif defined(HPPA)
2157         if (upeek(tcp, PT_IAOQ0, &iaoq) < 0)
2158                 return -1;
2159         iaoq &= ~0x03;
2160         if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) {
2161                 /* The breakpoint has not been reached yet.  */
2162                 if (debug)
2163                         fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n",
2164                                 iaoq, tcp->baddr);
2165                 return 0;
2166         }
2167         iaoq = tcp->baddr | 3;
2168         /* We should be pointing at a 'ldi -1000,r1' in glibc, so it is
2169          * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit
2170          * has no significant effect.
2171          */
2172         ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq);
2173         ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq);
2174 #    elif defined(SH)
2175         if (upeek(tcp, 4*REG_PC, &pc) < 0)
2176                 return -1;
2177         if (pc != tcp->baddr) {
2178                 /* The breakpoint has not been reached yet.  */
2179                 if (debug)
2180                         fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2181                                 pc, tcp->baddr);
2182                 return 0;
2183         }
2184
2185 #    endif /* arch */
2186 #   endif /* !SPARC && !SPARC64 && !IA64 */
2187 #  endif /* LINUX */
2188
2189 #  ifdef SUNOS4
2190 #   ifdef SPARC
2191
2192 #    if !LOOPA
2193         struct regs regs;
2194 #    endif
2195
2196         if (!(tcp->flags & TCB_BPTSET)) {
2197                 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
2198                 return -1;
2199         }
2200         if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
2201                                 sizeof tcp->inst, (char *) tcp->inst) < 0) {
2202                 perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)");
2203                 return -1;
2204         }
2205         tcp->flags &= ~TCB_BPTSET;
2206
2207 #    if !LOOPA
2208         /*
2209          * Since we don't have a single instruction breakpoint, we may have
2210          * to adjust the program counter after removing our `breakpoint'.
2211          */
2212         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
2213                 perror("clearbpt: ptrace(PTRACE_GETREGS, ...)");
2214                 return -1;
2215         }
2216         if ((regs.r_pc < tcp->baddr) ||
2217                                 (regs.r_pc > tcp->baddr + 4)) {
2218                 /* The breakpoint has not been reached yet */
2219                 if (debug)
2220                         fprintf(stderr,
2221                                 "NOTE: PC not at bpt (pc %#x baddr %#x)\n",
2222                                         regs.r_pc, tcp->baddr);
2223                 return 0;
2224         }
2225         if (regs.r_pc != tcp->baddr)
2226                 if (debug)
2227                         fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n",
2228                                 regs.r_pc, tcp->baddr);
2229
2230         regs.r_pc = tcp->baddr;
2231         if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0) {
2232                 perror("clearbpt: ptrace(PTRACE_SETREGS, ...)");
2233                 return -1;
2234         }
2235 #    endif /* LOOPA */
2236 #   endif /* SPARC */
2237 #  endif /* SUNOS4 */
2238
2239         return 0;
2240 }
2241
2242 # endif /* !defined LINUX */
2243
2244 #endif /* !USE_PROCFS */
2245
2246
2247 #ifdef SUNOS4
2248
2249 static int
2250 getex(tcp, hdr)
2251 struct tcb *tcp;
2252 struct exec *hdr;
2253 {
2254         int n;
2255
2256         for (n = 0; n < sizeof *hdr; n += 4) {
2257                 long res;
2258                 if (upeek(tcp, uoff(u_exdata) + n, &res) < 0)
2259                         return -1;
2260                 memcpy(((char *) hdr) + n, &res, 4);
2261         }
2262         if (debug) {
2263                 fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n",
2264                         hdr->a_magic, hdr->a_toolversion, hdr->a_machtype);
2265                 fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n",
2266                         hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry);
2267         }
2268         return 0;
2269 }
2270
2271 int
2272 fixvfork(tcp)
2273 struct tcb *tcp;
2274 {
2275         int pid = tcp->pid;
2276         /*
2277          * Change `vfork' in a freshly exec'ed dynamically linked
2278          * executable's (internal) symbol table to plain old `fork'
2279          */
2280
2281         struct exec hdr;
2282         struct link_dynamic dyn;
2283         struct link_dynamic_2 ld;
2284         char *strtab, *cp;
2285
2286         if (getex(tcp, &hdr) < 0)
2287                 return -1;
2288         if (!hdr.a_dynamic)
2289                 return -1;
2290
2291         if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) {
2292                 fprintf(stderr, "Cannot read DYNAMIC\n");
2293                 return -1;
2294         }
2295         if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) {
2296                 fprintf(stderr, "Cannot read link_dynamic_2\n");
2297                 return -1;
2298         }
2299         if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) {
2300                 fprintf(stderr, "out of memory\n");
2301                 return -1;
2302         }
2303         if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
2304                                         (int)ld.ld_symb_size, strtab) < 0)
2305                 goto err;
2306
2307 # if 0
2308         for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
2309                 fprintf(stderr, "[symbol: %s]\n", cp);
2310                 cp += strlen(cp)+1;
2311         }
2312         return 0;
2313 # endif
2314         for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
2315                 if (strcmp(cp, "_vfork") == 0) {
2316                         if (debug)
2317                                 fprintf(stderr, "fixvfork: FOUND _vfork\n");
2318                         strcpy(cp, "_fork");
2319                         break;
2320                 }
2321                 cp += strlen(cp)+1;
2322         }
2323         if (cp < strtab + ld.ld_symb_size)
2324                 /*
2325                  * Write entire symbol table back to avoid
2326                  * memory alignment bugs in ptrace
2327                  */
2328                 if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
2329                                         (int)ld.ld_symb_size, strtab) < 0)
2330                         goto err;
2331
2332         free(strtab);
2333         return 0;
2334
2335 err:
2336         free(strtab);
2337         return -1;
2338 }
2339
2340 #endif /* SUNOS4 */