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