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