Home | History | Annotate | Download | only in strace
      1 /*
      2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl>
      3  * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl>
      4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com>
      5  * Copyright (c) 1996-1999 Wichert Akkerman <wichert (at) cistron.nl>
      6  * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
      7  *                     Linux for s390 port by D.J. Barrow
      8  *                    <barrow_dj (at) mail.yahoo.com,djbarrow (at) 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
     99 tv_nz(a)
    100 struct timeval *a;
    101 {
    102 	return a->tv_sec || a->tv_usec;
    103 }
    104 
    105 int
    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
    119 tv_float(tv)
    120 struct timeval *tv;
    121 {
    122 	return tv->tv_sec + tv->tv_usec/1000000.0;
    123 }
    124 
    125 void
    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
    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
    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
    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 *
    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
    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
    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
    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
    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
    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 *
    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
    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
    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
    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
    421 printfd(struct tcb *tcp, int fd)
    422 {
    423 	tprintf("%d", fd);
    424 }
    425 
    426 void
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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