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 #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
    103 tv_nz(a)
    104 struct timeval *a;
    105 {
    106 	return a->tv_sec || a->tv_usec;
    107 }
    108 
    109 int
    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
    123 tv_float(tv)
    124 struct timeval *tv;
    125 {
    126 	return tv->tv_sec + tv->tv_usec/1000000.0;
    127 }
    128 
    129 void
    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
    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
    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
    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 *
    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
    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
    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
    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
    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
    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 *
    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
    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
    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
    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
    425 printfd(struct tcb *tcp, int fd)
    426 {
    427 	tprintf("%d", fd);
    428 }
    429 
    430 void
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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