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