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