• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *)&regs,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 *) &regs, 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, &regs, 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 *)&regs, 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 *)&regs, 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 *)&regs, 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