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: util.c,v 1.62 2005/06/08 20:45:28 roland Exp $
     34  */
     35 
     36 #include "defs.h"
     37 #include "../syscall-android.h"
     38 
     39 #include <signal.h>
     40 #include <sys/syscall.h>
     41 #ifndef HAVE_ANDROID_OS
     42 #include <sys/user.h>
     43 #endif
     44 #include <sys/param.h>
     45 #include <fcntl.h>
     46 #if HAVE_SYS_UIO_H
     47 #include <sys/uio.h>
     48 #endif
     49 #ifdef SUNOS4
     50 #include <machine/reg.h>
     51 #include <a.out.h>
     52 #include <link.h>
     53 #endif /* SUNOS4 */
     54 
     55 #if defined(linux) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1))
     56 #include <linux/ptrace.h>
     57 #endif
     58 
     59 #if defined(LINUX) && defined(IA64)
     60 # include <asm/ptrace_offsets.h>
     61 # include <asm/rse.h>
     62 #endif
     63 
     64 #ifdef HAVE_SYS_REG_H
     65 #include <sys/reg.h>
     66 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
     67 #elif defined(HAVE_LINUX_PTRACE_H)
     68 #undef PTRACE_SYSCALL
     69 # ifdef HAVE_STRUCT_IA64_FPREG
     70 #  define ia64_fpreg XXX_ia64_fpreg
     71 # endif
     72 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
     73 #  define pt_all_user_regs XXX_pt_all_user_regs
     74 # endif
     75 #include <linux/ptrace.h>
     76 # undef ia64_fpreg
     77 # undef pt_all_user_regs
     78 #endif
     79 
     80 #ifdef SUNOS4_KERNEL_ARCH_KLUDGE
     81 #include <sys/utsname.h>
     82 #endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
     83 
     84 #if defined(LINUXSPARC)
     85 
     86 # define fpq kernel_fpq
     87 # define fq kernel_fq
     88 # define fpu kernel_fpu
     89 # include <asm/reg.h>
     90 # undef fpq
     91 # undef fq
     92 # undef fpu
     93 
     94 #if defined (SPARC64)
     95 # define r_pc r_tpc
     96 # undef PTRACE_GETREGS
     97 # define PTRACE_GETREGS PTRACE_GETREGS64
     98 # undef PTRACE_SETREGS
     99 # define PTRACE_SETREGS PTRACE_SETREGS64
    100 #endif /* SPARC64 */
    101 
    102 #if !defined(__GLIBC__)
    103 
    104 #include <linux/unistd.h>
    105 
    106 #define _hack_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\
    107           type5,arg5,syscall) \
    108 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
    109 { \
    110       long __res; \
    111 \
    112 __asm__ volatile ("or %%g0, %1, %%o0\n\t" \
    113                   "or %%g0, %2, %%o1\n\t" \
    114                   "or %%g0, %3, %%o2\n\t" \
    115                   "or %%g0, %4, %%o3\n\t" \
    116                   "or %%g0, %5, %%o4\n\t" \
    117                   "or %%g0, %6, %%g1\n\t" \
    118 #if defined (SPARC64)
    119                   "t 0x6d\n\t" \
    120 #else
    121                   "t 0x10\n\t" \
    122 #endif
    123                   "bcc 1f\n\t" \
    124                   "or %%g0, %%o0, %0\n\t" \
    125                   "sub %%g0, %%o0, %0\n\t" \
    126                   "1:\n\t" \
    127                   : "=r" (__res) \
    128                   : "0" ((long)(arg1)),"1" ((long)(arg2)), \
    129                     "2" ((long)(arg3)),"3" ((long)(arg4)),"4" ((long)(arg5)), \
    130                     "i" (__NR_##syscall)  \
    131                   : "g1", "o0", "o1", "o2", "o3", "o4"); \
    132 if (__res>=0) \
    133         return (type) __res; \
    134 errno = -__res; \
    135 return -1; \
    136 }
    137 
    138 static _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,int,__addr2,ptrace)
    139 
    140 #define _ptrace
    141 
    142 #endif
    143 
    144 #endif
    145 
    146 /* macros */
    147 #ifndef MAX
    148 #define MAX(a,b)		(((a) > (b)) ? (a) : (b))
    149 #endif
    150 #ifndef MIN
    151 #define MIN(a,b)		(((a) < (b)) ? (a) : (b))
    152 #endif
    153 
    154 #if 0
    155 void
    156 tv_tv(tv, a, b)
    157 struct timeval *tv;
    158 int a;
    159 int b;
    160 {
    161 	tv->tv_sec = a;
    162 	tv->tv_usec = b;
    163 }
    164 #endif
    165 
    166 int
    167 tv_nz(a)
    168 struct timeval *a;
    169 {
    170 	return a->tv_sec || a->tv_usec;
    171 }
    172 
    173 int
    174 tv_cmp(a, b)
    175 struct timeval *a, *b;
    176 {
    177 	if (a->tv_sec < b->tv_sec
    178 	    || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
    179 		return -1;
    180 	if (a->tv_sec > b->tv_sec
    181 	    || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
    182 		return 1;
    183 	return 0;
    184 }
    185 
    186 double
    187 tv_float(tv)
    188 struct timeval *tv;
    189 {
    190 	return tv->tv_sec + tv->tv_usec/1000000.0;
    191 }
    192 
    193 void
    194 tv_add(tv, a, b)
    195 struct timeval *tv, *a, *b;
    196 {
    197 	tv->tv_sec = a->tv_sec + b->tv_sec;
    198 	tv->tv_usec = a->tv_usec + b->tv_usec;
    199 	if (tv->tv_usec > 1000000) {
    200 		tv->tv_sec++;
    201 		tv->tv_usec -= 1000000;
    202 	}
    203 }
    204 
    205 void
    206 tv_sub(tv, a, b)
    207 struct timeval *tv, *a, *b;
    208 {
    209 	tv->tv_sec = a->tv_sec - b->tv_sec;
    210 	tv->tv_usec = a->tv_usec - b->tv_usec;
    211 	if (((long) tv->tv_usec) < 0) {
    212 		tv->tv_sec--;
    213 		tv->tv_usec += 1000000;
    214 	}
    215 }
    216 
    217 void
    218 tv_div(tv, a, n)
    219 struct timeval *tv, *a;
    220 int n;
    221 {
    222 	tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
    223 	tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
    224 	tv->tv_usec %= 1000000;
    225 }
    226 
    227 void
    228 tv_mul(tv, a, n)
    229 struct timeval *tv, *a;
    230 int n;
    231 {
    232 	tv->tv_usec = a->tv_usec * n;
    233 	tv->tv_sec = a->tv_sec * n + a->tv_usec / 1000000;
    234 	tv->tv_usec %= 1000000;
    235 }
    236 
    237 char *
    238 xlookup(xlat, val)
    239 const struct xlat *xlat;
    240 int val;
    241 {
    242 	for (; xlat->str != NULL; xlat++)
    243 		if (xlat->val == val)
    244 			return xlat->str;
    245 	return NULL;
    246 }
    247 
    248 /*
    249  * Print entry in struct xlat table, if there.
    250  */
    251 void
    252 printxval(xlat, val, dflt)
    253 const struct xlat *xlat;
    254 int val;
    255 const char *dflt;
    256 {
    257 	char *str = xlookup(xlat, val);
    258 
    259 	if (str)
    260 		tprintf("%s", str);
    261 	else
    262 		tprintf("%#x /* %s */", val, dflt);
    263 }
    264 
    265 /*
    266  * Interpret `xlat' as an array of flags
    267  * print the entries whose bits are on in `flags'
    268  * return # of flags printed.
    269  */
    270 int
    271 addflags(xlat, flags)
    272 const struct xlat *xlat;
    273 int flags;
    274 {
    275 	int n;
    276 
    277 	for (n = 0; xlat->str; xlat++) {
    278 		if (xlat->val && (flags & xlat->val) == xlat->val) {
    279 			tprintf("|%s", xlat->str);
    280 			flags &= ~xlat->val;
    281 			n++;
    282 		}
    283 	}
    284 	if (flags) {
    285 		tprintf("|%#x", flags);
    286 		n++;
    287 	}
    288 	return n;
    289 }
    290 
    291 int
    292 printflags(xlat, flags, dflt)
    293 const struct xlat *xlat;
    294 int flags;
    295 const char *dflt;
    296 {
    297 	int n;
    298 	char *sep;
    299 
    300 	if (flags == 0 && xlat->val == 0) {
    301 		tprintf("%s", xlat->str);
    302 		return 1;
    303 	}
    304 
    305 	sep = "";
    306 	for (n = 0; xlat->str; xlat++) {
    307 		if (xlat->val && (flags & xlat->val) == xlat->val) {
    308 			tprintf("%s%s", sep, xlat->str);
    309 			flags &= ~xlat->val;
    310 			sep = "|";
    311 			n++;
    312 		}
    313 	}
    314 
    315 	if (n) {
    316 		if (flags) {
    317 			tprintf("%s%#x", sep, flags);
    318 			n++;
    319 		}
    320 	} else {
    321 		if (flags) {
    322 			tprintf("%#x", flags);
    323 			if (dflt)
    324 				tprintf(" /* %s */", dflt);
    325 		} else {
    326 			if (dflt)
    327 				tprintf("0");
    328 		}
    329 	}
    330 
    331 	return n;
    332 }
    333 
    334 void
    335 printnum(tcp, addr, fmt)
    336 struct tcb *tcp;
    337 long addr;
    338 char *fmt;
    339 {
    340 	long num;
    341 
    342 	if (!addr) {
    343 		tprintf("NULL");
    344 		return;
    345 	}
    346 	if (umove(tcp, addr, &num) < 0) {
    347 		tprintf("%#lx", addr);
    348 		return;
    349 	}
    350 	tprintf("[");
    351 	tprintf(fmt, num);
    352 	tprintf("]");
    353 }
    354 
    355 void
    356 printuid(text, uid)
    357 const char *text;
    358 unsigned long uid;
    359 {
    360 	tprintf("%s", text);
    361 	tprintf((uid == -1) ? "%ld" : "%lu", uid);
    362 }
    363 
    364 static char path[MAXPATHLEN + 1];
    365 
    366 static void
    367 string_quote(str)
    368 const char *str;
    369 {
    370 	char buf[2 * MAXPATHLEN + 1];
    371 	char *s;
    372 
    373 	if (!strpbrk(str, "\"\'\\")) {
    374 		tprintf("\"%s\"", str);
    375 		return;
    376 	}
    377 	for (s = buf; *str; str++) {
    378 		switch (*str) {
    379 		case '\"': case '\'': case '\\':
    380 			*s++ = '\\'; *s++ = *str; break;
    381 		default:
    382 			*s++ = *str; break;
    383 		}
    384 	}
    385 	*s = '\0';
    386 	tprintf("\"%s\"", buf);
    387 }
    388 
    389 void
    390 printpath(tcp, addr)
    391 struct tcb *tcp;
    392 long addr;
    393 {
    394 	if (addr == 0)
    395 		tprintf("NULL");
    396 	else if (umovestr(tcp, addr, MAXPATHLEN, path) < 0)
    397 		tprintf("%#lx", addr);
    398 	else
    399 		string_quote(path);
    400 	return;
    401 }
    402 
    403 void
    404 printpathn(tcp, addr, n)
    405 struct tcb *tcp;
    406 long addr;
    407 int n;
    408 {
    409 	if (addr == 0)
    410 		tprintf("NULL");
    411 	else 	if (umovestr(tcp, addr, n, path) < 0)
    412 		tprintf("%#lx", addr);
    413 	else {
    414 		path[n] = '\0';
    415 		string_quote(path);
    416 	}
    417 }
    418 
    419 void
    420 printstr(tcp, addr, len)
    421 struct tcb *tcp;
    422 long addr;
    423 int len;
    424 {
    425 	static unsigned char *str = NULL;
    426 	static char *outstr;
    427 	int i, n, c, usehex;
    428 	char *s, *outend;
    429 
    430 	if (!addr) {
    431 		tprintf("NULL");
    432 		return;
    433 	}
    434 	if (!str) {
    435 		if ((str = malloc(max_strlen)) == NULL
    436 		    || (outstr = malloc(2*max_strlen)) == NULL) {
    437 			fprintf(stderr, "out of memory\n");
    438 			tprintf("%#lx", addr);
    439 			return;
    440 		}
    441 	}
    442 	outend = outstr + max_strlen * 2 - 10;
    443 	if (len < 0) {
    444 		n = max_strlen;
    445 		if (umovestr(tcp, addr, n, (char *) str) < 0) {
    446 			tprintf("%#lx", addr);
    447 			return;
    448 		}
    449 	}
    450 	else {
    451 		n = MIN(len, max_strlen);
    452 		if (umoven(tcp, addr, n, (char *) str) < 0) {
    453 			tprintf("%#lx", addr);
    454 			return;
    455 		}
    456 	}
    457 
    458 	usehex = 0;
    459 	if (xflag > 1)
    460 		usehex = 1;
    461 	else if (xflag) {
    462 		for (i = 0; i < n; i++) {
    463 			c = str[i];
    464 			if (len < 0 && c == '\0')
    465 				break;
    466 			if (!isprint(c) && !isspace(c)) {
    467 				usehex = 1;
    468 				break;
    469 			}
    470 		}
    471 	}
    472 
    473 	s = outstr;
    474 	*s++ = '\"';
    475 
    476 	if (usehex) {
    477 		for (i = 0; i < n; i++) {
    478 			c = str[i];
    479 			if (len < 0 && c == '\0')
    480 				break;
    481 			sprintf(s, "\\x%02x", c);
    482 			s += 4;
    483 			if (s > outend)
    484 				break;
    485 		}
    486 	}
    487 	else {
    488 		for (i = 0; i < n; i++) {
    489 			c = str[i];
    490 			if (len < 0 && c == '\0')
    491 				break;
    492 			switch (c) {
    493 			case '\"': case '\'': case '\\':
    494 				*s++ = '\\'; *s++ = c; break;
    495 			case '\f':
    496 				*s++ = '\\'; *s++ = 'f'; break;
    497 			case '\n':
    498 				*s++ = '\\'; *s++ = 'n'; break;
    499 			case '\r':
    500 				*s++ = '\\'; *s++ = 'r'; break;
    501 			case '\t':
    502 				*s++ = '\\'; *s++ = 't'; break;
    503 			case '\v':
    504 				*s++ = '\\'; *s++ = 'v'; break;
    505 			default:
    506 				if (isprint(c))
    507 					*s++ = c;
    508 				else if (i < n - 1 && isdigit(str[i + 1])) {
    509 					sprintf(s, "\\%03o", c);
    510 					s += 4;
    511 				}
    512 				else {
    513 					sprintf(s, "\\%o", c);
    514 					s += strlen(s);
    515 				}
    516 				break;
    517 			}
    518 			if (s > outend)
    519 				break;
    520 		}
    521 	}
    522 
    523 	*s++ = '\"';
    524 	if (i < len || (len < 0 && (i == n || s > outend))) {
    525 		*s++ = '.'; *s++ = '.'; *s++ = '.';
    526 	}
    527 	*s = '\0';
    528 	tprintf("%s", outstr);
    529 }
    530 
    531 #if HAVE_SYS_UIO_H
    532 void
    533 dumpiov(tcp, len, addr)
    534 struct tcb * tcp;
    535 int len;
    536 long addr;
    537 {
    538 	struct iovec *iov;
    539 	int i;
    540 	unsigned long size;
    541 
    542 	size = sizeof(*iov) * (unsigned long) len;
    543 	if (size / sizeof(*iov) != len
    544 	    || (iov = (struct iovec *) malloc(size)) == NULL) {
    545 		fprintf(stderr, "out of memory\n");
    546 		return;
    547 	}
    548 	if (umoven(tcp, addr, size, (char *) iov) >= 0) {
    549 		for (i = 0; i < len; i++) {
    550                         /* include the buffer number to make it easy to
    551                          * match up the trace with the source */
    552                         tprintf(" * %lu bytes in buffer %d\n",
    553                                 (unsigned long)iov[i].iov_len, i);
    554                         dumpstr(tcp, (long) iov[i].iov_base,
    555                                 iov[i].iov_len);
    556                 }
    557 	}
    558 	free((char *) iov);
    559 
    560 }
    561 #endif
    562 
    563 void
    564 dumpstr(tcp, addr, len)
    565 struct tcb *tcp;
    566 long addr;
    567 int len;
    568 {
    569 	static int strsize = -1;
    570 	static unsigned char *str;
    571 	static char outstr[80];
    572 	char *s;
    573 	int i, j;
    574 
    575 	if (strsize < len) {
    576 		if (str)
    577 			free(str);
    578 		if ((str = malloc(len)) == NULL) {
    579 			fprintf(stderr, "out of memory\n");
    580 			return;
    581 		}
    582 		strsize = len;
    583 	}
    584 
    585 	if (umoven(tcp, addr, len, (char *) str) < 0)
    586 		return;
    587 
    588 	for (i = 0; i < len; i += 16) {
    589 		s = outstr;
    590 		sprintf(s, " | %05x ", i);
    591 		s += 9;
    592 		for (j = 0; j < 16; j++) {
    593 			if (j == 8)
    594 				*s++ = ' ';
    595 			if (i + j < len) {
    596 				sprintf(s, " %02x", str[i + j]);
    597 				s += 3;
    598 			}
    599 			else {
    600 				*s++ = ' '; *s++ = ' '; *s++ = ' ';
    601 			}
    602 		}
    603 		*s++ = ' '; *s++ = ' ';
    604 		for (j = 0; j < 16; j++) {
    605 			if (j == 8)
    606 				*s++ = ' ';
    607 			if (i + j < len) {
    608 				if (isprint(str[i + j]))
    609 					*s++ = str[i + j];
    610 				else
    611 					*s++ = '.';
    612 			}
    613 			else
    614 				*s++ = ' ';
    615 		}
    616 		tprintf("%s |\n", outstr);
    617 	}
    618 }
    619 
    620 #define PAGMASK	(~(PAGSIZ - 1))
    621 /*
    622  * move `len' bytes of data from process `pid'
    623  * at address `addr' to our space at `laddr'
    624  */
    625 int
    626 umoven(tcp, addr, len, laddr)
    627 struct tcb *tcp;
    628 long addr;
    629 int len;
    630 char *laddr;
    631 {
    632 
    633 #ifdef LINUX
    634 	int pid = tcp->pid;
    635 	int n, m;
    636 	int started = 0;
    637 	union {
    638 		long val;
    639 		char x[sizeof(long)];
    640 	} u;
    641 
    642 	if (addr & (sizeof(long) - 1)) {
    643 		/* addr not a multiple of sizeof(long) */
    644 		n = addr - (addr & -sizeof(long)); /* residue */
    645 		addr &= -sizeof(long); /* residue */
    646 		errno = 0;
    647 		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
    648 		if (errno) {
    649 			if (started && (errno==EPERM || errno==EIO)) {
    650 				/* Ran into 'end of memory' - stupid "printpath" */
    651 				return 0;
    652 			}
    653 			/* But if not started, we had a bogus address. */
    654 			perror("ptrace: umoven");
    655 			return -1;
    656 		}
    657 		started = 1;
    658 		memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
    659 		addr += sizeof(long), laddr += m, len -= m;
    660 	}
    661 	while (len) {
    662 		errno = 0;
    663 		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
    664 		if (errno) {
    665 			if (started && (errno==EPERM || errno==EIO)) {
    666 				/* Ran into 'end of memory' - stupid "printpath" */
    667 				return 0;
    668 			}
    669 			if (addr != 0)
    670 				perror("ptrace: umoven");
    671 			return -1;
    672 		}
    673 		started = 1;
    674 		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
    675 		addr += sizeof(long), laddr += m, len -= m;
    676 	}
    677 #endif /* LINUX */
    678 
    679 #ifdef SUNOS4
    680 	int pid = tcp->pid;
    681 #if 0
    682 	int n, m;
    683 	union {
    684 		long val;
    685 		char x[sizeof(long)];
    686 	} u;
    687 
    688 	if (addr & (sizeof(long) - 1)) {
    689 		/* addr not a multiple of sizeof(long) */
    690 		n = addr - (addr & -sizeof(long)); /* residue */
    691 		addr &= -sizeof(long); /* residue */
    692 		errno = 0;
    693 		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
    694 		if (errno) {
    695 			perror("umoven");
    696 			return -1;
    697 		}
    698 		memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
    699 		addr += sizeof(long), laddr += m, len -= m;
    700 	}
    701 	while (len) {
    702 		errno = 0;
    703 		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
    704 		if (errno) {
    705 			perror("umoven");
    706 			return -1;
    707 		}
    708 		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
    709 		addr += sizeof(long), laddr += m, len -= m;
    710 	}
    711 #else /* !oldway */
    712 	int n;
    713 
    714 	while (len) {
    715 		n = MIN(len, PAGSIZ);
    716 		n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
    717 		if (ptrace(PTRACE_READDATA, pid,
    718 			   (char *) addr, len, laddr) < 0) {
    719 			perror("umoven: ptrace(PTRACE_READDATA, ...)");
    720 			abort();
    721 			return -1;
    722 		}
    723 		len -= n;
    724 		addr += n;
    725 		laddr += n;
    726 	}
    727 #endif /* !oldway */
    728 #endif /* SUNOS4 */
    729 
    730 #ifdef USE_PROCFS
    731 #ifdef HAVE_MP_PROCFS
    732 	int fd = tcp->pfd_as;
    733 #else
    734 	int fd = tcp->pfd;
    735 #endif
    736 	lseek(fd, addr, SEEK_SET);
    737 	if (read(fd, laddr, len) == -1)
    738 		return -1;
    739 #endif /* USE_PROCFS */
    740 
    741 	return 0;
    742 }
    743 
    744 /*
    745  * like `umove' but make the additional effort of looking
    746  * for a terminating zero byte.
    747  */
    748 int
    749 umovestr(tcp, addr, len, laddr)
    750 struct tcb *tcp;
    751 long addr;
    752 int len;
    753 char *laddr;
    754 {
    755 #ifdef USE_PROCFS
    756 #ifdef HAVE_MP_PROCFS
    757 	int fd = tcp->pfd_as;
    758 #else
    759 	int fd = tcp->pfd;
    760 #endif
    761 	/* Some systems (e.g. FreeBSD) can be upset if we read off the
    762 	   end of valid memory,  avoid this by trying to read up
    763 	   to page boundaries.  But we don't know what a page is (and
    764 	   getpagesize(2) (if it exists) doesn't necessarily return
    765 	   hardware page size).  Assume all pages >= 1024 (a-historical
    766 	   I know) */
    767 
    768 	int page = 1024; 	/* How to find this? */
    769 	int move = page - (addr & (page - 1));
    770 	int left = len;
    771 
    772 	lseek(fd, addr, SEEK_SET);
    773 
    774 	while (left) {
    775 		if (move > left) move = left;
    776 		if ((move = read(fd, laddr, move)) <= 0)
    777 			return left != len ? 0 : -1;
    778 		if (memchr (laddr, 0, move)) break;
    779 		left -= move;
    780 		laddr += move;
    781 		addr += move;
    782 		move = page;
    783 	}
    784 #else /* !USE_PROCFS */
    785 	int started = 0;
    786 	int pid = tcp->pid;
    787 	int i, n, m;
    788 	union {
    789 		long val;
    790 		char x[sizeof(long)];
    791 	} u;
    792 
    793 	if (addr & (sizeof(long) - 1)) {
    794 		/* addr not a multiple of sizeof(long) */
    795 		n = addr - (addr & -sizeof(long)); /* residue */
    796 		addr &= -sizeof(long); /* residue */
    797 		errno = 0;
    798 		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
    799 		if (errno) {
    800 			if (started && (errno==EPERM || errno==EIO)) {
    801 				/* Ran into 'end of memory' - stupid "printpath" */
    802 				return 0;
    803 			}
    804 			perror("umovestr");
    805 			return -1;
    806 		}
    807 		started = 1;
    808 		memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len));
    809 		while (n & (sizeof(long) - 1))
    810 			if (u.x[n++] == '\0')
    811 				return 0;
    812 		addr += sizeof(long), laddr += m, len -= m;
    813 	}
    814 	while (len) {
    815 		errno = 0;
    816 		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
    817 		if (errno) {
    818 			if (started && (errno==EPERM || errno==EIO)) {
    819 				/* Ran into 'end of memory' - stupid "printpath" */
    820 				return 0;
    821 			}
    822 			perror("umovestr");
    823 			return -1;
    824 		}
    825 		started = 1;
    826 		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
    827 		for (i = 0; i < sizeof(long); i++)
    828 			if (u.x[i] == '\0')
    829 				return 0;
    830 
    831 		addr += sizeof(long), laddr += m, len -= m;
    832 	}
    833 #endif /* !USE_PROCFS */
    834 	return 0;
    835 }
    836 
    837 #ifdef LINUX
    838 #if !defined (SPARC) && !defined(SPARC64)
    839 #define PTRACE_WRITETEXT	101
    840 #define PTRACE_WRITEDATA	102
    841 #endif /* !SPARC && !SPARC64 */
    842 #endif /* LINUX */
    843 
    844 #ifdef SUNOS4
    845 
    846 static int
    847 uload(cmd, pid, addr, len, laddr)
    848 int cmd;
    849 int pid;
    850 long addr;
    851 int len;
    852 char *laddr;
    853 {
    854 #if 0
    855 	int n;
    856 
    857 	while (len) {
    858 		n = MIN(len, PAGSIZ);
    859 		n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
    860 		if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) {
    861 			perror("uload: ptrace(PTRACE_WRITE, ...)");
    862 			return -1;
    863 		}
    864 		len -= n;
    865 		addr += n;
    866 		laddr += n;
    867 	}
    868 #else
    869 	int peek, poke;
    870 	int n, m;
    871 	union {
    872 		long val;
    873 		char x[sizeof(long)];
    874 	} u;
    875 
    876 	if (cmd == PTRACE_WRITETEXT) {
    877 		peek = PTRACE_PEEKTEXT;
    878 		poke = PTRACE_POKETEXT;
    879 	}
    880 	else {
    881 		peek = PTRACE_PEEKDATA;
    882 		poke = PTRACE_POKEDATA;
    883 	}
    884 	if (addr & (sizeof(long) - 1)) {
    885 		/* addr not a multiple of sizeof(long) */
    886 		n = addr - (addr & -sizeof(long)); /* residue */
    887 		addr &= -sizeof(long);
    888 		errno = 0;
    889 		u.val = ptrace(peek, pid, (char *) addr, 0);
    890 		if (errno) {
    891 			perror("uload: POKE");
    892 			return -1;
    893 		}
    894 		memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len));
    895 		if (ptrace(poke, pid, (char *)addr, u.val) < 0) {
    896 			perror("uload: POKE");
    897 			return -1;
    898 		}
    899 		addr += sizeof(long), laddr += m, len -= m;
    900 	}
    901 	while (len) {
    902 		if (len < sizeof(long))
    903 			u.val = ptrace(peek, pid, (char *) addr, 0);
    904 		memcpy(u.x, laddr, m = MIN(sizeof(long), len));
    905 		if (ptrace(poke, pid, (char *) addr, u.val) < 0) {
    906 			perror("uload: POKE");
    907 			return -1;
    908 		}
    909 		addr += sizeof(long), laddr += m, len -= m;
    910 	}
    911 #endif
    912 	return 0;
    913 }
    914 
    915 int
    916 tload(pid, addr, len, laddr)
    917 int pid;
    918 int addr, len;
    919 char *laddr;
    920 {
    921 	return uload(PTRACE_WRITETEXT, pid, addr, len, laddr);
    922 }
    923 
    924 int
    925 dload(pid, addr, len, laddr)
    926 int pid;
    927 int addr;
    928 int len;
    929 char *laddr;
    930 {
    931 	return uload(PTRACE_WRITEDATA, pid, addr, len, laddr);
    932 }
    933 
    934 #endif /* SUNOS4 */
    935 
    936 #ifndef USE_PROCFS
    937 
    938 int
    939 upeek(pid, off, res)
    940 int pid;
    941 long off;
    942 long *res;
    943 {
    944 	long val;
    945 
    946 #ifdef SUNOS4_KERNEL_ARCH_KLUDGE
    947 	{
    948 		static int is_sun4m = -1;
    949 		struct utsname name;
    950 
    951 		/* Round up the usual suspects. */
    952 		if (is_sun4m == -1) {
    953 			if (uname(&name) < 0) {
    954 				perror("upeek: uname?");
    955 				exit(1);
    956 			}
    957 			is_sun4m = strcmp(name.machine, "sun4m") == 0;
    958 			if (is_sun4m) {
    959 				extern const struct xlat struct_user_offsets[];
    960 				const struct xlat *x;
    961 
    962 				for (x = struct_user_offsets; x->str; x++)
    963 					x->val += 1024;
    964 			}
    965 		}
    966 		if (is_sun4m)
    967 			off += 1024;
    968 	}
    969 #endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
    970 	errno = 0;
    971 	val = ptrace(PTRACE_PEEKUSER, pid, (char *) off, 0);
    972 	if (val == -1 && errno) {
    973 		char buf[60];
    974 		sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)",pid,off);
    975 		perror(buf);
    976 		return -1;
    977 	}
    978 	*res = val;
    979 	return 0;
    980 }
    981 
    982 #endif /* !USE_PROCFS */
    983 
    984 #if 0
    985 long
    986 getpc(tcp)
    987 struct tcb *tcp;
    988 {
    989 
    990 #ifdef LINUX
    991 	long pc;
    992 #if defined(I386)
    993 	if (upeek(tcp->pid, 4*EIP, &pc) < 0)
    994 		return -1;
    995 #elif defined(X86_64)
    996 	if (upeek(tcp->pid, 8*RIP, &pc) < 0)
    997 		return -1;
    998 #elif defined(IA64)
    999 	if (upeek(tcp->pid, PT_B0, &pc) < 0)
   1000 		return -1;
   1001 #elif defined(ARM)
   1002 	if (upeek(tcp->pid, 4*15, &pc) < 0)
   1003 		return -1;
   1004 #elif defined(POWERPC)
   1005 	if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0)
   1006 		return -1;
   1007 #elif defined(M68K)
   1008 	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
   1009 		return -1;
   1010 #elif defined(ALPHA)
   1011 	if (upeek(tcp->pid, REG_PC, &pc) < 0)
   1012 		return -1;
   1013 #elif defined(MIPS)
   1014  	if (upeek(tcp->pid, REG_EPC, &pc) < 0)
   1015  		return -1;
   1016 #elif defined(SPARC) || defined(SPARC64)
   1017 	struct regs regs;
   1018 	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
   1019 		return -1;
   1020 	pc = regs.r_pc;
   1021 #elif defined(S390) || defined(S390X)
   1022 	if(upeek(tcp->pid,PT_PSWADDR,&pc) < 0)
   1023 		return -1;
   1024 #elif defined(HPPA)
   1025 	if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0)
   1026 		return -1;
   1027 #elif defined(SH)
   1028        if (upeek(tcp->pid, 4*REG_PC ,&pc) < 0)
   1029                return -1;
   1030 #elif defined(SH64)
   1031        if (upeek(tcp->pid, REG_PC ,&pc) < 0)
   1032                return -1;
   1033 #endif
   1034 	return pc;
   1035 #endif /* LINUX */
   1036 
   1037 #ifdef SUNOS4
   1038 	/*
   1039 	 * Return current program counter for `pid'
   1040 	 * Assumes PC is never 0xffffffff
   1041 	 */
   1042 	struct regs regs;
   1043 
   1044 	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
   1045 		perror("getpc: ptrace(PTRACE_GETREGS, ...)");
   1046 		return -1;
   1047 	}
   1048 	return regs.r_pc;
   1049 #endif /* SUNOS4 */
   1050 
   1051 #ifdef SVR4
   1052 	/* XXX */
   1053 	return 0;
   1054 #endif /* SVR4 */
   1055 
   1056 #ifdef FREEBSD
   1057 	struct reg regs;
   1058 	pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
   1059 	return regs.r_eip;
   1060 #endif /* FREEBSD */
   1061 }
   1062 #endif
   1063 
   1064 void
   1065 printcall(tcp)
   1066 struct tcb *tcp;
   1067 {
   1068 #define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \
   1069 			   sizeof(long) == 8 ? "[????????????????] " : \
   1070 			   NULL /* crash */)
   1071 
   1072 #ifdef LINUX
   1073 #ifdef I386
   1074 	long eip;
   1075 
   1076 	if (upeek(tcp->pid, 4*EIP, &eip) < 0) {
   1077 		PRINTBADPC;
   1078 		return;
   1079 	}
   1080 	tprintf("[%08lx] ", eip);
   1081 
   1082 #elif defined(S390) || defined(S390X)
   1083          long psw;
   1084          if(upeek(tcp->pid,PT_PSWADDR,&psw) < 0) {
   1085                  PRINTBADPC;
   1086                  return;
   1087          }
   1088 #ifdef S390
   1089          tprintf("[%08lx] ", psw);
   1090 #elif S390X
   1091        tprintf("[%16lx] ", psw);
   1092 #endif
   1093 
   1094 #elif defined(X86_64)
   1095 	long rip;
   1096 
   1097 	if (upeek(tcp->pid, 8*RIP, &rip) < 0) {
   1098 		PRINTBADPC;
   1099 		return;
   1100 	}
   1101 	tprintf("[%16lx] ", rip);
   1102 #elif defined(IA64)
   1103 	long ip;
   1104 
   1105 	if (upeek(tcp->pid, PT_B0, &ip) < 0) {
   1106 		PRINTBADPC;
   1107 		return;
   1108 	}
   1109 	tprintf("[%08lx] ", ip);
   1110 #elif defined(POWERPC)
   1111 	long pc;
   1112 
   1113 	if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) {
   1114 		tprintf ("[????????] ");
   1115 		return;
   1116 	}
   1117 	tprintf("[%08lx] ", pc);
   1118 #elif defined(M68K)
   1119 	long pc;
   1120 
   1121 	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) {
   1122 		tprintf ("[????????] ");
   1123 		return;
   1124 	}
   1125 	tprintf("[%08lx] ", pc);
   1126 #elif defined(ALPHA)
   1127 	long pc;
   1128 
   1129 	if (upeek(tcp->pid, REG_PC, &pc) < 0) {
   1130 		tprintf ("[????????????????] ");
   1131 		return;
   1132 	}
   1133 	tprintf("[%08lx] ", pc);
   1134 #elif defined(SPARC) || defined(SPARC64)
   1135 	struct regs regs;
   1136 	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0) {
   1137 		PRINTBADPC;
   1138 		return;
   1139 	}
   1140 	tprintf("[%08lx] ", regs.r_pc);
   1141 #elif defined(HPPA)
   1142 	long pc;
   1143 
   1144 	if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) {
   1145 		tprintf ("[????????] ");
   1146 		return;
   1147 	}
   1148 	tprintf("[%08lx] ", pc);
   1149 #elif defined(MIPS)
   1150 	long pc;
   1151 
   1152 	if (upeek(tcp->pid, REG_EPC, &pc) < 0) {
   1153 		tprintf ("[????????] ");
   1154 		return;
   1155 	}
   1156 	tprintf("[%08lx] ", pc);
   1157 #elif defined(SH)
   1158        long pc;
   1159 
   1160        if (upeek(tcp->pid, 4*REG_PC, &pc) < 0) {
   1161                tprintf ("[????????] ");
   1162                return;
   1163        }
   1164        tprintf("[%08lx] ", pc);
   1165 #elif defined(SH64)
   1166 	long pc;
   1167 
   1168 	if (upeek(tcp->pid, REG_PC, &pc) < 0) {
   1169 		tprintf ("[????????????????] ");
   1170 		return;
   1171 	}
   1172 	tprintf("[%08lx] ", pc);
   1173 #elif defined(ARM)
   1174 	long pc;
   1175 
   1176 	if (upeek(tcp->pid, 4*15, &pc) < 0) {
   1177 		PRINTBADPC;
   1178 		return;
   1179 	}
   1180 	tprintf("[%08lx] ", pc);
   1181 #endif /* !architecture */
   1182 #endif /* LINUX */
   1183 
   1184 #ifdef SUNOS4
   1185 	struct regs regs;
   1186 
   1187 	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
   1188 		perror("printcall: ptrace(PTRACE_GETREGS, ...)");
   1189 		PRINTBADPC;
   1190 		return;
   1191 	}
   1192 	tprintf("[%08x] ", regs.r_o7);
   1193 #endif /* SUNOS4 */
   1194 
   1195 #ifdef SVR4
   1196 	/* XXX */
   1197 	PRINTBADPC;
   1198 #endif
   1199 
   1200 #ifdef FREEBSD
   1201 	struct reg regs;
   1202 	pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
   1203 	tprintf("[%08x] ", regs.r_eip);
   1204 #endif /* FREEBSD */
   1205 }
   1206 
   1207 #ifndef USE_PROCFS
   1208 
   1209 #if defined LINUX
   1210 
   1211 #include <sys/syscall.h>
   1212 #ifndef CLONE_PTRACE
   1213 # define CLONE_PTRACE    0x00002000
   1214 #endif
   1215 #ifndef CLONE_STOPPED
   1216 # define CLONE_STOPPED   0x02000000
   1217 #endif
   1218 
   1219 #ifdef IA64
   1220 
   1221 /* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32
   1222    subsystem has them for x86... */
   1223 #define SYS_fork	2
   1224 #define SYS_vfork	190
   1225 
   1226 typedef unsigned long *arg_setup_state;
   1227 
   1228 static int
   1229 arg_setup(struct tcb *tcp, arg_setup_state *state)
   1230 {
   1231 	unsigned long *bsp, cfm, sof, sol;
   1232 
   1233 	if (ia32)
   1234 		return 0;
   1235 
   1236 	if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) < 0)
   1237 		return -1;
   1238 	if (upeek(tcp->pid, PT_CFM, (long *) &cfm) < 0)
   1239 		return -1;
   1240 
   1241 	sof = (cfm >> 0) & 0x7f;
   1242 	sol = (cfm >> 7) & 0x7f;
   1243 	bsp = ia64_rse_skip_regs(bsp, -sof + sol);
   1244 
   1245 	*state = bsp;
   1246 	return 0;
   1247 }
   1248 
   1249 # define arg_finish_change(tcp, state)	0
   1250 
   1251 #ifdef SYS_fork
   1252 static int
   1253 get_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp)
   1254 {
   1255 	int ret;
   1256 
   1257 	if (ia32)
   1258 		ret = upeek (tcp->pid, PT_R11, valp);
   1259 	else
   1260 		ret = umoven (tcp,
   1261 			      (unsigned long) ia64_rse_skip_regs(*state, 0),
   1262 			      sizeof(long), (void *) valp);
   1263 	return ret;
   1264 }
   1265 
   1266 static int
   1267 get_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp)
   1268 {
   1269 	int ret;
   1270 
   1271 	if (ia32)
   1272 		ret = upeek (tcp->pid, PT_R9, valp);
   1273 	else
   1274 		ret = umoven (tcp,
   1275 			      (unsigned long) ia64_rse_skip_regs(*state, 1),
   1276 			      sizeof(long), (void *) valp);
   1277 	return ret;
   1278 }
   1279 #endif
   1280 
   1281 static int
   1282 set_arg0 (struct tcb *tcp, arg_setup_state *state, long val)
   1283 {
   1284 	int req = PTRACE_POKEDATA;
   1285 	void *ap;
   1286 
   1287 	if (ia32) {
   1288 		ap = (void *) (intptr_t) PT_R11;	 /* r11 == EBX */
   1289 		req = PTRACE_POKEUSER;
   1290 	} else
   1291 		ap = ia64_rse_skip_regs(*state, 0);
   1292 	errno = 0;
   1293 	ptrace(req, tcp->pid, ap, val);
   1294 	return errno ? -1 : 0;
   1295 }
   1296 
   1297 static int
   1298 set_arg1 (struct tcb *tcp, arg_setup_state *state, long val)
   1299 {
   1300 	int req = PTRACE_POKEDATA;
   1301 	void *ap;
   1302 
   1303 	if (ia32) {
   1304 		ap = (void *) (intptr_t) PT_R9;		/* r9 == ECX */
   1305 		req = PTRACE_POKEUSER;
   1306 	} else
   1307 		ap = ia64_rse_skip_regs(*state, 1);
   1308 	errno = 0;
   1309 	ptrace(req, tcp->pid, ap, val);
   1310 	return errno ? -1 : 0;
   1311 }
   1312 
   1313 #elif defined (SPARC) || defined (SPARC64)
   1314 
   1315 typedef struct regs arg_setup_state;
   1316 
   1317 # define arg_setup(tcp, state) \
   1318   (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0))
   1319 # define arg_finish_change(tcp, state) \
   1320   (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0))
   1321 
   1322 # define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0)
   1323 # define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0)
   1324 # define set_arg0(tcp, state, val) ((state)->r_o0 = (val), 0)
   1325 # define set_arg1(tcp, state, val) ((state)->r_o1 = (val), 0)
   1326 # define restore_arg0(tcp, state, val) 0
   1327 
   1328 #else
   1329 
   1330 # if defined S390 || defined S390X
   1331 /* Note: this is only true for the `clone' system call, which handles
   1332    arguments specially.  We could as well say that its first two arguments
   1333    are swapped relative to other architectures, but that would just be
   1334    another #ifdef in the calls.  */
   1335 #  define arg0_offset	PT_GPR3
   1336 #  define arg1_offset	PT_ORIGGPR2
   1337 #  define restore_arg0(tcp, state, val) ((void) (state), 0)
   1338 #  define restore_arg1(tcp, state, val) ((void) (state), 0)
   1339 #  define arg0_index	1
   1340 #  define arg1_index	0
   1341 # elif defined (ALPHA) || defined (MIPS)
   1342 #  define arg0_offset	REG_A0
   1343 #  define arg1_offset	(REG_A0+1)
   1344 # elif defined (POWERPC)
   1345 #  define arg0_offset	(sizeof(unsigned long)*PT_R3)
   1346 #  define arg1_offset	(sizeof(unsigned long)*PT_R4)
   1347 #  define restore_arg0(tcp, state, val) ((void) (state), 0)
   1348 # elif defined (HPPA)
   1349 #  define arg0_offset	 PT_GR26
   1350 #  define arg1_offset	 (PT_GR26-4)
   1351 # elif defined (X86_64)
   1352 #  define arg0_offset	((long)(8*(current_personality ? RBX : RDI)))
   1353 #  define arg1_offset	((long)(8*(current_personality ? RCX : RSI)))
   1354 # elif defined (SH)
   1355 #  define arg0_offset	(4*(REG_REG0+4))
   1356 #  define arg1_offset	(4*(REG_REG0+5))
   1357 # elif defined (SH64)
   1358    /* ABI defines arg0 & 1 in r2 & r3 */
   1359 #  define arg0_offset   (REG_OFFSET+16)
   1360 #  define arg1_offset   (REG_OFFSET+24)
   1361 #  define restore_arg0(tcp, state, val) 0
   1362 # else
   1363 #  define arg0_offset	0
   1364 #  define arg1_offset	4
   1365 #  if defined ARM
   1366 #   define restore_arg0(tcp, state, val) 0
   1367 #  endif
   1368 # endif
   1369 
   1370 typedef int arg_setup_state;
   1371 
   1372 # define arg_setup(tcp, state) (0)
   1373 # define arg_finish_change(tcp, state)	0
   1374 # define get_arg0(tcp, cookie, valp) \
   1375   (upeek ((tcp)->pid, arg0_offset, (valp)))
   1376 # define get_arg1(tcp, cookie, valp) \
   1377   (upeek ((tcp)->pid, arg1_offset, (valp)))
   1378 
   1379 static int
   1380 set_arg0 (struct tcb *tcp, void *cookie, long val)
   1381 {
   1382 	return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val);
   1383 }
   1384 
   1385 static int
   1386 set_arg1 (struct tcb *tcp, void *cookie, long val)
   1387 {
   1388 	return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val);
   1389 }
   1390 
   1391 #endif
   1392 
   1393 #ifndef restore_arg0
   1394 # define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val))
   1395 #endif
   1396 #ifndef restore_arg1
   1397 # define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val))
   1398 #endif
   1399 
   1400 #ifndef arg0_index
   1401 # define arg0_index 0
   1402 # define arg1_index 1
   1403 #endif
   1404 
   1405 int
   1406 setbpt(tcp)
   1407 struct tcb *tcp;
   1408 {
   1409 	extern int change_syscall(struct tcb *, int);
   1410 	arg_setup_state state;
   1411 
   1412 	if (tcp->flags & TCB_BPTSET) {
   1413 		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
   1414 		return -1;
   1415 	}
   1416 
   1417 	switch (known_scno(tcp)) {
   1418 #ifdef SYS_vfork
   1419 	case SYS_vfork:
   1420 #endif
   1421 #ifdef SYS_fork
   1422 	case SYS_fork:
   1423 #endif
   1424 #if defined SYS_fork || defined SYS_vfork
   1425 		if (arg_setup (tcp, &state) < 0
   1426 		    || get_arg0 (tcp, &state, &tcp->inst[0]) < 0
   1427 		    || get_arg1 (tcp, &state, &tcp->inst[1]) < 0
   1428 		    || change_syscall(tcp, SYS_clone) < 0
   1429 		    || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0
   1430 		    || set_arg1 (tcp, &state, 0) < 0
   1431 		    || arg_finish_change (tcp, &state) < 0)
   1432 			return -1;
   1433 		tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD;
   1434 		tcp->u_arg[arg1_index] = 0;
   1435 		tcp->flags |= TCB_BPTSET;
   1436 		return 0;
   1437 #endif
   1438 
   1439 	case SYS_clone:
   1440 #ifdef SYS_clone2
   1441 	case SYS_clone2:
   1442 #endif
   1443 		if ((tcp->u_arg[arg0_index] & CLONE_PTRACE) == 0
   1444 		    && (arg_setup (tcp, &state) < 0
   1445 			|| set_arg0 (tcp, &state,
   1446 				     tcp->u_arg[arg0_index] | CLONE_PTRACE) < 0
   1447 			|| arg_finish_change (tcp, &state) < 0))
   1448 			return -1;
   1449 		tcp->flags |= TCB_BPTSET;
   1450 		tcp->inst[0] = tcp->u_arg[arg0_index];
   1451 		tcp->inst[1] = tcp->u_arg[arg1_index];
   1452 		return 0;
   1453 
   1454 	default:
   1455 		fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n",
   1456 			tcp->scno, tcp->pid);
   1457 		break;
   1458 	}
   1459 
   1460 	return -1;
   1461 }
   1462 
   1463 int
   1464 clearbpt(tcp)
   1465 struct tcb *tcp;
   1466 {
   1467 	arg_setup_state state;
   1468 	if (arg_setup (tcp, &state) < 0
   1469 	    || restore_arg0 (tcp, &state, tcp->inst[0]) < 0
   1470 	    || restore_arg1 (tcp, &state, tcp->inst[1]) < 0
   1471 	    || arg_finish_change (tcp, &state))
   1472 		return -1;
   1473 	tcp->flags &= ~TCB_BPTSET;
   1474 	return 0;
   1475 }
   1476 
   1477 #else
   1478 
   1479 int
   1480 setbpt(tcp)
   1481 struct tcb *tcp;
   1482 {
   1483 
   1484 #ifdef LINUX
   1485 #if defined (SPARC) || defined (SPARC64)
   1486 	/* We simply use the SunOS breakpoint code. */
   1487 
   1488 	struct regs regs;
   1489 	unsigned long inst;
   1490 #define LOOPA	0x30800000	/* ba,a	0 */
   1491 
   1492 	if (tcp->flags & TCB_BPTSET) {
   1493 		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
   1494 		return -1;
   1495 	}
   1496 	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
   1497 		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
   1498 		return -1;
   1499 	}
   1500 	tcp->baddr = regs.r_o7 + 8;
   1501 	errno = 0;
   1502 	tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0);
   1503 	if(errno) {
   1504 		perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
   1505 		return -1;
   1506 	}
   1507 
   1508 	/*
   1509 	 * XXX - BRUTAL MODE ON
   1510 	 * We cannot set a real BPT in the child, since it will not be
   1511 	 * traced at the moment it will reach the trap and would probably
   1512 	 * die with a core dump.
   1513 	 * Thus, we are force our way in by taking out two instructions
   1514 	 * and insert an eternal loop instead, in expectance of the SIGSTOP
   1515 	 * generated by out PTRACE_ATTACH.
   1516 	 * Of cause, if we evaporate ourselves in the middle of all this...
   1517 	 */
   1518 	errno = 0;
   1519 	inst = LOOPA;
   1520 #if defined (SPARC64)
   1521 	inst <<= 32;
   1522 	inst |= (tcp->inst[0] & 0xffffffffUL);
   1523 #endif
   1524 	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, inst);
   1525 	if(errno) {
   1526 		perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
   1527 		return -1;
   1528 	}
   1529 	tcp->flags |= TCB_BPTSET;
   1530 
   1531 #else /* !SPARC && !SPARC64 */
   1532 #ifdef IA64
   1533 	if (ia32) {
   1534 #		define LOOP	0x0000feeb
   1535 		if (tcp->flags & TCB_BPTSET) {
   1536 			fprintf(stderr, "PANIC: bpt already set in pid %u\n",
   1537 				tcp->pid);
   1538 			return -1;
   1539 		}
   1540 		if (upeek(tcp->pid, PT_CR_IIP, &tcp->baddr) < 0)
   1541 			return -1;
   1542 		if (debug)
   1543 			fprintf(stderr, "[%d] setting bpt at %lx\n",
   1544 				tcp->pid, tcp->baddr);
   1545 		tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid,
   1546 				      (char *) tcp->baddr, 0);
   1547 		if (errno) {
   1548 			perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
   1549 			return -1;
   1550 		}
   1551 		ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
   1552 		if (errno) {
   1553 			perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
   1554 			return -1;
   1555 		}
   1556 		tcp->flags |= TCB_BPTSET;
   1557 	} else {
   1558 		/*
   1559 		 * Our strategy here is to replace the bundle that
   1560 		 * contained the clone() syscall with a bundle of the
   1561 		 * form:
   1562 		 *
   1563 		 *	{ 1: br 1b; br 1b; br 1b }
   1564 		 *
   1565 		 * This ensures that the newly forked child will loop
   1566 		 * endlessly until we've got a chance to attach to it.
   1567 		 */
   1568 #		define LOOP0	0x0000100000000017
   1569 #		define LOOP1	0x4000000000200000
   1570 		unsigned long addr, ipsr;
   1571 		pid_t pid;
   1572 
   1573 		pid = tcp->pid;
   1574 		if (upeek(pid, PT_CR_IPSR, &ipsr) < 0)
   1575 			return -1;
   1576 		if (upeek(pid, PT_CR_IIP, &addr) < 0)
   1577 			return -1;
   1578 		/* store "ri" in low two bits */
   1579 		tcp->baddr = addr | ((ipsr >> 41) & 0x3);
   1580 
   1581 		errno = 0;
   1582 		tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0,
   1583 				      0);
   1584 		tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8,
   1585 				      0);
   1586 		if (errno) {
   1587 			perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
   1588 			return -1;
   1589 		}
   1590 
   1591 		errno = 0;
   1592 		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0);
   1593 		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1);
   1594 		if (errno) {
   1595 			perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
   1596 			return -1;
   1597 		}
   1598 		tcp->flags |= TCB_BPTSET;
   1599 	}
   1600 #else /* !IA64 */
   1601 
   1602 #if defined (I386) || defined(X86_64)
   1603 #define LOOP	0x0000feeb
   1604 #elif defined (M68K)
   1605 #define LOOP	0x60fe0000
   1606 #elif defined (ALPHA)
   1607 #define LOOP	0xc3ffffff
   1608 #elif defined (POWERPC)
   1609 #define LOOP	0x48000000
   1610 #elif defined(ARM)
   1611 #define LOOP	0xEAFFFFFE
   1612 #elif defined(MIPS)
   1613 #define LOOP	0x1000ffff
   1614 #elif defined(S390)
   1615 #define LOOP	0xa7f40000	/* BRC 15,0 */
   1616 #elif defined(S390X)
   1617 #define LOOP   0xa7f4000000000000UL /* BRC 15,0 */
   1618 #elif defined(HPPA)
   1619 #define LOOP	0xe81f1ff7	/* b,l,n <loc>,r0 */
   1620 #elif defined(SH)
   1621 #ifdef __LITTLE_ENDIAN__
   1622 #define LOOP   0x0000affe
   1623 #else
   1624 #define LOOP   0xfeaf0000
   1625 #endif
   1626 #else
   1627 #error unknown architecture
   1628 #endif
   1629 
   1630 	if (tcp->flags & TCB_BPTSET) {
   1631 		fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid);
   1632 		return -1;
   1633 	}
   1634 #if defined (I386)
   1635 	if (upeek(tcp->pid, 4*EIP, &tcp->baddr) < 0)
   1636 		return -1;
   1637 #elif defined (X86_64)
   1638 	if (upeek(tcp->pid, 8*RIP, &tcp->baddr) < 0)
   1639 		return -1;
   1640 #elif defined (M68K)
   1641 	if (upeek(tcp->pid, 4*PT_PC, &tcp->baddr) < 0)
   1642 	  return -1;
   1643 #elif defined (ALPHA)
   1644 	return -1;
   1645 #elif defined (ARM)
   1646 	return -1;
   1647 #elif defined (MIPS)
   1648 	return -1;		/* FIXME: I do not know what i do - Flo */
   1649 #elif defined (POWERPC)
   1650 	if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &tcp->baddr) < 0)
   1651 		return -1;
   1652 #elif defined(S390) || defined(S390X)
   1653 	if (upeek(tcp->pid,PT_PSWADDR, &tcp->baddr) < 0)
   1654 		return -1;
   1655 #elif defined(HPPA)
   1656 	if (upeek(tcp->pid, PT_IAOQ0, &tcp->baddr) < 0)
   1657 		return -1;
   1658 	tcp->baddr &= ~0x03;
   1659 #elif defined(SH)
   1660        if (upeek(tcp->pid, 4*REG_PC, &tcp->baddr) < 0)
   1661                return -1;
   1662 #else
   1663 #error unknown architecture
   1664 #endif
   1665 	if (debug)
   1666 		fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr);
   1667 	tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0);
   1668 	if (errno) {
   1669 		perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
   1670 		return -1;
   1671 	}
   1672 	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
   1673 	if (errno) {
   1674 		perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
   1675 		return -1;
   1676 	}
   1677 	tcp->flags |= TCB_BPTSET;
   1678 
   1679 #endif /* !IA64 */
   1680 #endif /* SPARC || SPARC64 */
   1681 #endif /* LINUX */
   1682 
   1683 #ifdef SUNOS4
   1684 #ifdef SPARC	/* This code is slightly sparc specific */
   1685 
   1686 	struct regs regs;
   1687 #define BPT	0x91d02001	/* ta	1 */
   1688 #define LOOP	0x10800000	/* ba	0 */
   1689 #define LOOPA	0x30800000	/* ba,a	0 */
   1690 #define NOP	0x01000000
   1691 #if LOOPA
   1692 	static int loopdeloop[1] = {LOOPA};
   1693 #else
   1694 	static int loopdeloop[2] = {LOOP, NOP};
   1695 #endif
   1696 
   1697 	if (tcp->flags & TCB_BPTSET) {
   1698 		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
   1699 		return -1;
   1700 	}
   1701 	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
   1702 		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
   1703 		return -1;
   1704 	}
   1705 	tcp->baddr = regs.r_o7 + 8;
   1706 	if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr,
   1707 				sizeof tcp->inst, (char *)tcp->inst) < 0) {
   1708 		perror("setbpt: ptrace(PTRACE_READTEXT, ...)");
   1709 		return -1;
   1710 	}
   1711 
   1712 	/*
   1713 	 * XXX - BRUTAL MODE ON
   1714 	 * We cannot set a real BPT in the child, since it will not be
   1715 	 * traced at the moment it will reach the trap and would probably
   1716 	 * die with a core dump.
   1717 	 * Thus, we are force our way in by taking out two instructions
   1718 	 * and insert an eternal loop in stead, in expectance of the SIGSTOP
   1719 	 * generated by out PTRACE_ATTACH.
   1720 	 * Of cause, if we evaporate ourselves in the middle of all this...
   1721 	 */
   1722 	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
   1723 			sizeof loopdeloop, (char *) loopdeloop) < 0) {
   1724 		perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)");
   1725 		return -1;
   1726 	}
   1727 	tcp->flags |= TCB_BPTSET;
   1728 
   1729 #endif /* SPARC */
   1730 #endif /* SUNOS4 */
   1731 
   1732 	return 0;
   1733 }
   1734 
   1735 int
   1736 clearbpt(tcp)
   1737 struct tcb *tcp;
   1738 {
   1739 
   1740 #ifdef LINUX
   1741 #if defined(I386) || defined(X86_64)
   1742 	long eip;
   1743 #elif defined(POWERPC)
   1744 	long pc;
   1745 #elif defined(M68K)
   1746 	long pc;
   1747 #elif defined(ALPHA)
   1748 	long pc;
   1749 #elif defined(HPPA)
   1750 	long iaoq;
   1751 #elif defined(SH)
   1752        long pc;
   1753 #endif /* architecture */
   1754 
   1755 #if defined (SPARC) || defined (SPARC64)
   1756 	/* Again, we borrow the SunOS breakpoint code. */
   1757 	if (!(tcp->flags & TCB_BPTSET)) {
   1758 		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
   1759 		return -1;
   1760 	}
   1761 	errno = 0;
   1762 	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
   1763 	if(errno) {
   1764 		perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
   1765 		return -1;
   1766 	}
   1767 	tcp->flags &= ~TCB_BPTSET;
   1768 #elif defined(IA64)
   1769 	if (ia32) {
   1770 		unsigned long addr;
   1771 
   1772 		if (debug)
   1773 			fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
   1774 		if (!(tcp->flags & TCB_BPTSET)) {
   1775 			fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
   1776 			return -1;
   1777 		}
   1778 		errno = 0;
   1779 		ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
   1780 		if (errno) {
   1781 			perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
   1782 			return -1;
   1783 		}
   1784 		tcp->flags &= ~TCB_BPTSET;
   1785 
   1786 		if (upeek(tcp->pid, PT_CR_IIP, &addr) < 0)
   1787 			return -1;
   1788 		if (addr != tcp->baddr) {
   1789 			/* The breakpoint has not been reached yet.  */
   1790 			if (debug)
   1791 				fprintf(stderr,
   1792 					"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
   1793 						addr, tcp->baddr);
   1794 			return 0;
   1795 		}
   1796 	} else {
   1797 		unsigned long addr, ipsr;
   1798 		pid_t pid;
   1799 
   1800 		pid = tcp->pid;
   1801 
   1802 		if (upeek(pid, PT_CR_IPSR, &ipsr) < 0)
   1803 			return -1;
   1804 		if (upeek(pid, PT_CR_IIP, &addr) < 0)
   1805 			return -1;
   1806 
   1807 		/* restore original bundle: */
   1808 		errno = 0;
   1809 		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]);
   1810 		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]);
   1811 		if (errno) {
   1812 			perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)");
   1813 			return -1;
   1814 		}
   1815 
   1816 		/* restore original "ri" in ipsr: */
   1817 		ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41);
   1818 		errno = 0;
   1819 		ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr);
   1820 		if (errno) {
   1821 			perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)");
   1822 			return -1;
   1823 		}
   1824 
   1825 		tcp->flags &= ~TCB_BPTSET;
   1826 
   1827 		if (addr != (tcp->baddr & ~0x3)) {
   1828 			/* the breakpoint has not been reached yet.  */
   1829 			if (debug)
   1830 				fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
   1831 					addr, tcp->baddr);
   1832 			return 0;
   1833 		}
   1834 	}
   1835 #else /* !IA64  && !SPARC && !SPARC64 */
   1836 
   1837 	if (debug)
   1838 		fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
   1839 	if (!(tcp->flags & TCB_BPTSET)) {
   1840 		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
   1841 		return -1;
   1842 	}
   1843 	errno = 0;
   1844 	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
   1845 	if (errno) {
   1846 		perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
   1847 		return -1;
   1848 	}
   1849 	tcp->flags &= ~TCB_BPTSET;
   1850 
   1851 #ifdef I386
   1852 	if (upeek(tcp->pid, 4*EIP, &eip) < 0)
   1853 		return -1;
   1854 	if (eip != tcp->baddr) {
   1855 		/* The breakpoint has not been reached yet.  */
   1856 		if (debug)
   1857 			fprintf(stderr,
   1858 				"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
   1859 					eip, tcp->baddr);
   1860 		return 0;
   1861 	}
   1862 #elif defined(X86_64)
   1863 	if (upeek(tcp->pid, 8*RIP, &eip) < 0)
   1864 		return -1;
   1865 	if (eip != tcp->baddr) {
   1866 		/* The breakpoint has not been reached yet.  */
   1867 		if (debug)
   1868 			fprintf(stderr,
   1869 				"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
   1870 					eip, tcp->baddr);
   1871 		return 0;
   1872 	}
   1873 #elif defined(POWERPC)
   1874 	if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0)
   1875 		return -1;
   1876 	if (pc != tcp->baddr) {
   1877 		/* The breakpoint has not been reached yet.  */
   1878 		if (debug)
   1879 			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
   1880 				pc, tcp->baddr);
   1881 		return 0;
   1882 	}
   1883 #elif defined(M68K)
   1884 	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
   1885 		return -1;
   1886 	if (pc != tcp->baddr) {
   1887 		/* The breakpoint has not been reached yet.  */
   1888 		if (debug)
   1889 			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
   1890 				pc, tcp->baddr);
   1891 		return 0;
   1892 	}
   1893 #elif defined(ALPHA)
   1894 	if (upeek(tcp->pid, REG_PC, &pc) < 0)
   1895 		return -1;
   1896 	if (pc != tcp->baddr) {
   1897 		/* The breakpoint has not been reached yet.  */
   1898 		if (debug)
   1899 			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
   1900 				pc, tcp->baddr);
   1901 		return 0;
   1902 	}
   1903 #elif defined(HPPA)
   1904 	if (upeek(tcp->pid, PT_IAOQ0, &iaoq) < 0)
   1905 		return -1;
   1906 	iaoq &= ~0x03;
   1907 	if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) {
   1908 		/* The breakpoint has not been reached yet.  */
   1909 		if (debug)
   1910 			fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n",
   1911 				iaoq, tcp->baddr);
   1912 		return 0;
   1913 	}
   1914 	iaoq = tcp->baddr | 3;
   1915 	/* We should be pointing at a 'ldi -1000,r1' in glibc, so it is
   1916 	 * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit
   1917 	 * has no significant effect.
   1918 	 */
   1919 	ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq);
   1920 	ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq);
   1921 #elif defined(SH)
   1922        if (upeek(tcp->pid, 4*REG_PC, &pc) < 0)
   1923                return -1;
   1924         if (pc != tcp->baddr) {
   1925                 /* The breakpoint has not been reached yet.  */
   1926                 if (debug)
   1927                         fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
   1928                                 pc, tcp->baddr);
   1929                 return 0;
   1930         }
   1931 
   1932 #endif /* arch */
   1933 #endif /* !SPARC && !SPARC64 && !IA64 */
   1934 #endif /* LINUX */
   1935 
   1936 #ifdef SUNOS4
   1937 #ifdef SPARC
   1938 
   1939 #if !LOOPA
   1940 	struct regs regs;
   1941 #endif
   1942 
   1943 	if (!(tcp->flags & TCB_BPTSET)) {
   1944 		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
   1945 		return -1;
   1946 	}
   1947 	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
   1948 				sizeof tcp->inst, (char *) tcp->inst) < 0) {
   1949 		perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)");
   1950 		return -1;
   1951 	}
   1952 	tcp->flags &= ~TCB_BPTSET;
   1953 
   1954 #if !LOOPA
   1955 	/*
   1956 	 * Since we don't have a single instruction breakpoint, we may have
   1957 	 * to adjust the program counter after removing the our `breakpoint'.
   1958 	 */
   1959 	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
   1960 		perror("clearbpt: ptrace(PTRACE_GETREGS, ...)");
   1961 		return -1;
   1962 	}
   1963 	if ((regs.r_pc < tcp->baddr) ||
   1964 				(regs.r_pc > tcp->baddr + 4)) {
   1965 		/* The breakpoint has not been reached yet */
   1966 		if (debug)
   1967 			fprintf(stderr,
   1968 				"NOTE: PC not at bpt (pc %#x baddr %#x)\n",
   1969 					regs.r_pc, tcp->parent->baddr);
   1970 		return 0;
   1971 	}
   1972 	if (regs.r_pc != tcp->baddr)
   1973 		if (debug)
   1974 			fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n",
   1975 				regs.r_pc, tcp->baddr);
   1976 
   1977 	regs.r_pc = tcp->baddr;
   1978 	if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0) {
   1979 		perror("clearbpt: ptrace(PTRACE_SETREGS, ...)");
   1980 		return -1;
   1981 	}
   1982 #endif /* LOOPA */
   1983 #endif /* SPARC */
   1984 #endif /* SUNOS4 */
   1985 
   1986 	return 0;
   1987 }
   1988 
   1989 #endif
   1990 
   1991 #endif /* !USE_PROCFS */
   1992 
   1993 #ifdef SUNOS4
   1994 
   1995 static int
   1996 getex(pid, hdr)
   1997 int pid;
   1998 struct exec *hdr;
   1999 {
   2000 	int n;
   2001 
   2002 	for (n = 0; n < sizeof *hdr; n += 4) {
   2003 		long res;
   2004 		if (upeek(pid, uoff(u_exdata) + n, &res) < 0)
   2005 			return -1;
   2006 		memcpy(((char *) hdr) + n, &res, 4);
   2007 	}
   2008 	if (debug) {
   2009 		fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n",
   2010 			hdr->a_magic, hdr->a_toolversion, hdr->a_machtype);
   2011 		fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n",
   2012 			hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry);
   2013 	}
   2014 	return 0;
   2015 }
   2016 
   2017 int
   2018 fixvfork(tcp)
   2019 struct tcb *tcp;
   2020 {
   2021 	int pid = tcp->pid;
   2022 	/*
   2023 	 * Change `vfork' in a freshly exec'ed dynamically linked
   2024 	 * executable's (internal) symbol table to plain old `fork'
   2025 	 */
   2026 
   2027 	struct exec hdr;
   2028 	struct link_dynamic dyn;
   2029 	struct link_dynamic_2 ld;
   2030 	char *strtab, *cp;
   2031 
   2032 	if (getex(pid, &hdr) < 0)
   2033 		return -1;
   2034 	if (!hdr.a_dynamic)
   2035 		return -1;
   2036 
   2037 	if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) {
   2038 		fprintf(stderr, "Cannot read DYNAMIC\n");
   2039 		return -1;
   2040 	}
   2041 	if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) {
   2042 		fprintf(stderr, "Cannot read link_dynamic_2\n");
   2043 		return -1;
   2044 	}
   2045 	if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) {
   2046 		fprintf(stderr, "out of memory\n");
   2047 		return -1;
   2048 	}
   2049 	if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
   2050 					(int)ld.ld_symb_size, strtab) < 0)
   2051 		goto err;
   2052 
   2053 #if 0
   2054 	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
   2055 		fprintf(stderr, "[symbol: %s]\n", cp);
   2056 		cp += strlen(cp)+1;
   2057 	}
   2058 	return 0;
   2059 #endif
   2060 	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
   2061 		if (strcmp(cp, "_vfork") == 0) {
   2062 			if (debug)
   2063 				fprintf(stderr, "fixvfork: FOUND _vfork\n");
   2064 			strcpy(cp, "_fork");
   2065 			break;
   2066 		}
   2067 		cp += strlen(cp)+1;
   2068 	}
   2069 	if (cp < strtab + ld.ld_symb_size)
   2070 		/*
   2071 		 * Write entire symbol table back to avoid
   2072 		 * memory alignment bugs in ptrace
   2073 		 */
   2074 		if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
   2075 					(int)ld.ld_symb_size, strtab) < 0)
   2076 			goto err;
   2077 
   2078 	free(strtab);
   2079 	return 0;
   2080 
   2081 err:
   2082 	free(strtab);
   2083 	return -1;
   2084 }
   2085 
   2086 #endif /* SUNOS4 */
   2087