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