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