• 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 #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 *)&regs,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 *) &regs, 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, &regs, 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 *)&regs, 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 *)&regs, 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 *)&regs, 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