util.c revision 7b3346be42d6a1f539e95d385ee498f8b3c529f8
176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
54dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
64dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
74dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman *                     Linux for s390 port by D.J. Barrow
84dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman *                    <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * All rights reserved.
1076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *
1176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Redistribution and use in source and binary forms, with or without
1276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * modification, are permitted provided that the following conditions
1376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * are met:
1476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 1. Redistributions of source code must retain the above copyright
1576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *    notice, this list of conditions and the following disclaimer.
1676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 2. Redistributions in binary form must reproduce the above copyright
1776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *    notice, this list of conditions and the following disclaimer in the
1876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *    documentation and/or other materials provided with the distribution.
1976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 3. The name of the author may not be used to endorse or promote products
2076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *    derived from this software without specific prior written permission.
2176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *
2276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *
3376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *	$Id$
3476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
3576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
3676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "defs.h"
3776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
3876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/user.h>
3976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/param.h>
4076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <fcntl.h>
411d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H
421d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#include <sys/uio.h>
431d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif
4476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
4576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <machine/reg.h>
4676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <a.out.h>
4776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <link.h>
4876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
4936915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman
5043a7482edbc7142b91e95d7aedeb9d121fc4880fWichert Akkerman#if defined(linux) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1))
5176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <linux/ptrace.h>
5236915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#endif
5336915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman
548b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#if defined(LINUX) && defined(IA64)
558b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#include <asm/ptrace_offsets.h>
568b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#endif
578b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
5836915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#ifdef HAVE_SYS_REG_H
5936915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#include <sys/reg.h>
6036915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman# define PTRACE_PEEKUSR PTRACE_PEEKUSER
61faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(HAVE_LINUX_PTRACE_H)
62faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#undef PTRACE_SYSCALL
63faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#include <linux/ptrace.h>
642e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#endif
652e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman
6676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE
6776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/utsname.h>
6876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
6976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
709ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#if defined(LINUX) && defined(SPARC)
719ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman
729ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#include <asm/reg.h>
739ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman
749ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#if !defined(__GLIBC__)
7576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
7676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <linux/unistd.h>
7776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
7876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define _hack_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\
7976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman          type5,arg5,syscall) \
8076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantype name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
8176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ \
8276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman      long __res; \
8376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman\
8476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman__asm__ volatile ("or %%g0, %1, %%o0\n\t" \
8576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %2, %%o1\n\t" \
8676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %3, %%o2\n\t" \
8776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %4, %%o3\n\t" \
8876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %5, %%o4\n\t" \
8976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %6, %%g1\n\t" \
9076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "t 0x10\n\t" \
9176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "bcc 1f\n\t" \
9276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %%o0, %0\n\t" \
9376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "sub %%g0, %%o0, %0\n\t" \
9476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "1:\n\t" \
9576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  : "=r" (__res) \
9676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  : "0" ((long)(arg1)),"1" ((long)(arg2)), \
9776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                    "2" ((long)(arg3)),"3" ((long)(arg4)),"4" ((long)(arg5)), \
9876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                    "i" (__NR_##syscall)  \
9976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  : "g1", "o0", "o1", "o2", "o3", "o4"); \
10076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanif (__res>=0) \
10176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman        return (type) __res; \
10276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerrno = -__res; \
10376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanreturn -1; \
10476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
10576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
10676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,int,__addr2,ptrace)
10776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
10876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define _ptrace
10976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
11076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
11176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1129ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif
1139ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman
11476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* macros */
11576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MAX
11676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MAX(a,b)		(((a) > (b)) ? (a) : (b))
11776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
11876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MIN
11976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MIN(a,b)		(((a) < (b)) ? (a) : (b))
12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
12176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
12276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
12376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_tv(tv, a, b)
12476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv;
12576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint a;
12676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint b;
12776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
12876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a;
12976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = b;
13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
13176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
13276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
13376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_nz(a)
13476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a;
13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return a->tv_sec || a->tv_usec;
13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
13876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
13976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
14076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_cmp(a, b)
14176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a, *b;
14276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
14376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (a->tv_sec < b->tv_sec
14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	    || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
14576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (a->tv_sec > b->tv_sec
14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	    || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
14876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 1;
14976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
15076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
15176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
15276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandouble
15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_float(tv)
15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv;
15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return tv->tv_sec + tv->tv_usec/1000000.0;
15776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
15876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
15976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
16076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_add(tv, a, b)
16176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b;
16276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
16376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec + b->tv_sec;
16476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = a->tv_usec + b->tv_usec;
16576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tv->tv_usec > 1000000) {
16676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_sec++;
16776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_usec -= 1000000;
16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
16976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
17176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
17276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_sub(tv, a, b)
17376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b;
17476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec - b->tv_sec;
17676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = a->tv_usec - b->tv_usec;
17776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (((long) tv->tv_usec) < 0) {
17876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_sec--;
17976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_usec += 1000000;
18076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
18176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
18276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
18376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_div(tv, a, n)
18576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a;
18676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n;
18776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
18876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
18976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
19076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec %= 1000000;
19176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
19276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
19376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
19476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_mul(tv, a, n)
19576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a;
19676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n;
19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
19876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = a->tv_usec * n;
19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec * n + a->tv_usec / 1000000;
20076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec %= 1000000;
20176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
20276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
20376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *
20476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanxlookup(xlat, val)
20576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat;
20676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint val;
20776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
20876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (; xlat->str != NULL; xlat++)
20976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val == val)
21076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return xlat->str;
21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return NULL;
21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
21576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Print entry in struct xlat table, if there.
21676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
21776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
21876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintxval(xlat, val, dflt)
21976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat;
22076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint val;
22176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *dflt;
22276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
22376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *str = xlookup(xlat, val);
22476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
22576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (str)
22676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s", str);
22776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else
22876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#x /* %s */", val, dflt);
22976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
23076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interpret `xlat' as an array of flags
23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * print the entries whose bits are on in `flags'
23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * return # of flags printed.
23576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
23676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
23776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanaddflags(xlat, flags)
23876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat;
23976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags;
24076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
24176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
24376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (n = 0; xlat->str; xlat++) {
24476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val && (flags & xlat->val) == xlat->val) {
24576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("|%s", xlat->str);
24676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			flags &= ~xlat->val;
24776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			n++;
24876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
24976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
25076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (flags) {
25176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("|%#x", flags);
25276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n++;
25376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
25476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return n;
25576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
25676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
25776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
25876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintflags(xlat, flags)
25976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat;
26076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags;
26176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
26276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
26376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *sep;
26476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
26576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (flags == 0 && xlat->val == 0) {
26676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s", xlat->str);
26776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 1;
26876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
26976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
27076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	sep = "";
27176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (n = 0; xlat->str; xlat++) {
27276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val && (flags & xlat->val) == xlat->val) {
27376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%s%s", sep, xlat->str);
27476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			flags &= ~xlat->val;
27576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			sep = "|";
27676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			n++;
27776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
27876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
27976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (flags) {
28076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s%#x", sep, flags);
28176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n++;
28276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
28376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return n;
28476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
28576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
28676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
28776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintnum(tcp, addr, fmt)
28876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
28976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
29076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *fmt;
29176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
29276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int num;
29376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
29476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!addr) {
29576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("NULL");
29676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
29776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
29876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umove(tcp, addr, &num) < 0) {
29976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#lx", addr);
30076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
30176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
30276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[");
30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf(fmt, num);
30476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("]");
30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
30676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
30776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic char path[MAXPATHLEN + 1];
30876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
30976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
31076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstring_quote(str)
31176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *str;
31276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
31376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char buf[2 * MAXPATHLEN + 1];
31476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *s;
31576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
31676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!strpbrk(str, "\"\'\\")) {
31776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("\"%s\"", str);
31876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
31976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
32076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (s = buf; *str; str++) {
32176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		switch (*str) {
32276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case '\"': case '\'': case '\\':
32376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			*s++ = '\\'; *s++ = *str; break;
32476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		default:
32576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			*s++ = *str; break;
32676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
32776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
32876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*s = '\0';
32976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("\"%s\"", buf);
33076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
33176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
33276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
33376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpath(tcp, addr)
33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
33676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
33776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umovestr(tcp, addr, MAXPATHLEN, path) < 0)
33876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#lx", addr);
33976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else
34076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		string_quote(path);
34176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return;
34276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
34376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
34476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
34576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpathn(tcp, addr, n)
34676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
34776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
34876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n;
34976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
35076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umovestr(tcp, addr, n, path) < 0)
35176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#lx", addr);
35276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
35376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		path[n] = '\0';
35476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		string_quote(path);
35576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
35676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
35776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
35876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
35976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintstr(tcp, addr, len)
36076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
36176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
36276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
36376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
36476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static unsigned char *str = NULL;
36576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static char *outstr;
36676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i, n, c, usehex;
36776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *s, *outend;
36876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
36976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!addr) {
37076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("NULL");
37176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
37276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
37376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!str) {
37476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if ((str = malloc(max_strlen)) == NULL
37576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		    || (outstr = malloc(2*max_strlen)) == NULL) {
37676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "printstr: no memory\n");
37776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%#lx", addr);
37876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
37976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
38076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
3812e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman	outend = outstr + max_strlen * 2 - 10;
38276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (len < 0) {
38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = max_strlen;
38476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (umovestr(tcp, addr, n, (char *) str) < 0) {
38576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%#lx", addr);
38676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
38776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
38876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
38976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
39076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(len, max_strlen);
39176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (umoven(tcp, addr, n, (char *) str) < 0) {
39276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%#lx", addr);
39376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
39476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
39576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
39676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
39776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	usehex = 0;
39876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (xflag > 1)
39976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		usehex = 1;
40076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else if (xflag) {
40176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < n; i++) {
40276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			c = str[i];
40376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (len < 0 && c == '\0')
40476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
40576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (!isprint(c) && !isspace(c)) {
40676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				usehex = 1;
40776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
40876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
40976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
41076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
41176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
41276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	s = outstr;
41376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*s++ = '\"';
41476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
41576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (usehex) {
41676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < n; i++) {
41776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			c = str[i];
41876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (len < 0 && c == '\0')
41976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
42076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			sprintf(s, "\\x%02x", c);
42176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			s += 4;
42276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (s > outend)
42376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
42476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
42576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
42676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
42776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < n; i++) {
42876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			c = str[i];
42976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (len < 0 && c == '\0')
43076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
43176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			switch (c) {
43276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\"': case '\'': case '\\':
43376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = c; break;
43476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\f':
43576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 'f'; break;
43676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\n':
43776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 'n'; break;
43876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\r':
43976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 'r'; break;
44076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\t':
44176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 't'; break;
44276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\v':
44376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 'v'; break;
44476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			default:
44576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				if (isprint(c))
44676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					*s++ = c;
44776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				else if (i < n - 1 && isdigit(str[i + 1])) {
44876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					sprintf(s, "\\%03o", c);
44976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					s += 4;
45076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				}
45176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				else {
45276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					sprintf(s, "\\%o", c);
45376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					s += strlen(s);
45476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				}
45576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
45676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
45776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (s > outend)
45876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
45976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
46076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
46176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
46276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*s++ = '\"';
46376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (i < len || (len < 0 && (i == n || s > outend))) {
46476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		*s++ = '.'; *s++ = '.'; *s++ = '.';
46576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
46676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*s = '\0';
46776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("%s", outstr);
46876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
46976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
4701d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H
4711d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesvoid
4721d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesdumpiov(tcp, len, addr)
4731d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesstruct tcb * tcp;
4741d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesint len;
4751d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hugheslong addr;
4761d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes{
4771d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	struct iovec *iov;
4781d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	int i;
4791d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes
4801d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes
4811d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	if ((iov = (struct iovec *) malloc(len * sizeof *iov)) == NULL) {
4821d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes		fprintf(stderr, "dump: No memory");
4831d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes		return;
4841d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	}
4851d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	if (umoven(tcp, addr,
4861d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes		   len * sizeof *iov, (char *) iov) >= 0) {
4871d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes
4881d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes		for (i = 0; i < len; i++) {
4891d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                        /* include the buffer number to make it easy to
4901d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                         * match up the trace with the source */
4911d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                        tprintf(" * %lu bytes in buffer %d\n",
4921d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                                (unsigned long)iov[i].iov_len, i);
4931d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                        dumpstr(tcp, (long) iov[i].iov_base,
4941d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                                iov[i].iov_len);
4951d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                }
4961d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	}
4971d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	free((char *) iov);
4981d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes
4991d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes}
5001d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif
5011d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes
50276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
50376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandumpstr(tcp, addr, len)
50476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
50576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
50676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
50776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
50876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static int strsize = -1;
50976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static unsigned char *str;
51076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static char outstr[80];
51176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *s;
51276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i, j;
51376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
51476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (strsize < len) {
51576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (str)
51676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			free(str);
51776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if ((str = malloc(len)) == NULL) {
51876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "dump: no memory\n");
51976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
52076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
52176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		strsize = len;
52276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
52376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
52476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umoven(tcp, addr, len, (char *) str) < 0)
52576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
52676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
52776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (i = 0; i < len; i += 16) {
52876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		s = outstr;
52976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		sprintf(s, " | %05x ", i);
53076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		s += 9;
53176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (j = 0; j < 16; j++) {
53276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (j == 8)
53376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
53476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (i + j < len) {
53576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				sprintf(s, " %02x", str[i + j]);
53676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				s += 3;
53776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
53876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			else {
53976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' '; *s++ = ' '; *s++ = ' ';
54076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
54176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
54276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		*s++ = ' '; *s++ = ' ';
54376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (j = 0; j < 16; j++) {
54476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (j == 8)
54576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
54676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (i + j < len) {
54776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				if (isprint(str[i + j]))
54876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					*s++ = str[i + j];
54976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				else
55076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					*s++ = '.';
55176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
55276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			else
55376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
55476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
55576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s |\n", outstr);
55676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
55776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
55876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
55976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PAGMASK	(~(PAGSIZ - 1))
56076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
56176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * move `len' bytes of data from process `pid'
56276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * at address `addr' to our space at `laddr'
56376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
56476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
56576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumoven(tcp, addr, len, laddr)
56676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
56776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
56876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
56976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
57076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
57176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
57276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
57376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
57476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n, m;
5755daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman	int started = 0;
57676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
57776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
57876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
57976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
58076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
58176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
58276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
58376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
58476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
58576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
58676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
58776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
5885daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			if (started && (errno==EPERM || errno==EIO)) {
58976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/* Ran into 'end of memory' - stupid "printpath" */
59076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
59176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
5925daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			/* But if not started, we had a bogus address. */
59376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("ptrace: umoven");
59476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
59576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
5965daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
59776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
59876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
59976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
60076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
60176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
60276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
60376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
6045daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			if (started && (errno==EPERM || errno==EIO)) {
60576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/* Ran into 'end of memory' - stupid "printpath" */
60676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
60776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
60876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("ptrace: umoven");
60976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
61076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
6115daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
61276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
61376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
61476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
61576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
61676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
61776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
61876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
61976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0
62076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n, m;
62176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
62276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
62376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
62476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
62576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
62676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
62876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
62976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
63076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
63176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
63276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
63376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umoven");
63476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
63576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
63676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
63776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
63876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
63976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
64076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
64176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
64276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
64376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umoven");
64476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
64576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
64676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
64776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
64876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
64976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !oldway */
65076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
65176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
65276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
65376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(len, PAGSIZ);
65476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
65576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (ptrace(PTRACE_READDATA, pid,
65676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			   (char *) addr, len, laddr) < 0) {
65776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umoven: ptrace(PTRACE_READDATA, ...)");
65876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			abort();
65976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
66076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
66176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		len -= n;
66276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += n;
66376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		laddr += n;
66476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
66576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !oldway */
66676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
66776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
668bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS
669ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS
670aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int fd = tcp->pfd_as;
6719ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else
672aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int fd = tcp->pfd;
67376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
674aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	lseek(fd, addr, SEEK_SET);
675aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	if (read(fd, laddr, len) == -1)
67676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
677bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */
67876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
67976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
68076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
68176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
68276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
68376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * like `umove' but make the additional effort of looking
68476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * for a terminating zero byte.
68576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
68676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
68776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumovestr(tcp, addr, len, laddr)
68876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
68976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
69076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
69176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
69276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
693bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS
694aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#ifdef HAVE_MP_PROCFS
695aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int fd = tcp->pfd_as;
696aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#else
697aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int fd = tcp->pfd;
698aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#endif
699aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	/* Some systems (e.g. FreeBSD) can be upset if we read off the
700aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   end of valid memory,  avoid this by trying to read up
701aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   to page boundaries.  But we don't know what a page is (and
702aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   getpagesize(2) (if it exists) doesn't necessarily return
703aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   hardware page size).  Assume all pages >= 1024 (a-historical
704aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   I know) */
705aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes
706aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int page = 1024; 	/* How to find this? */
707aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int move = page - (addr & (page - 1));
708aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int left = len;
709aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes
710aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	lseek(fd, addr, SEEK_SET);
711aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes
712aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	while (left) {
713aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		if (move > left) move = left;
714aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		if ((move = read(fd, laddr, move)) == -1)
715aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes			return left != len ? 0 : -1;
716aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		if (memchr (laddr, 0, move)) break;
717aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		left -= move;
718aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		laddr += move;
719aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		addr += move;
720aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		move = page;
721aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	}
722bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */
7235daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman	int started = 0;
72476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
72576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i, n, m;
72676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
72776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
72876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
72976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
73076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
73176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
73276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
73376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
73476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
73576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
73676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
73776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
7385daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			if (started && (errno==EPERM || errno==EIO)) {
73976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/* Ran into 'end of memory' - stupid "printpath" */
74076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
74176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
74276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umovestr");
74376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
7455daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len));
74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		while (n & (sizeof(long) - 1))
74876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (u.x[n++] == '\0')
74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
75176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
75276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
75376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
75576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
7565daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			if (started && (errno==EPERM || errno==EIO)) {
75776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/* Ran into 'end of memory' - stupid "printpath" */
75876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
76076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umovestr");
76176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
76276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
7635daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
76476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
76576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < sizeof(long); i++)
76676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (u.x[i] == '\0')
76776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
77076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
771bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */
772aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	return 0;
77376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
77476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
77576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
77676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SPARC
77776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITETEXT	101
77876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITEDATA	102
77976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !SPARC */
78076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
78176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
78276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
78376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
78476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int
78576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanuload(cmd, pid, addr, len, laddr)
78676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint cmd;
78776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
78876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
78976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
79076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
79176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
79276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0
79376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
79476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
79576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
79676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(len, PAGSIZ);
79776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
79876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) {
79976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("uload: ptrace(PTRACE_WRITE, ...)");
80076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
80176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
80276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		len -= n;
80376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += n;
80476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		laddr += n;
80576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
80676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else
80776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int peek, poke;
80876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n, m;
80976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
81076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
81176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
81276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
81376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
81476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (cmd == PTRACE_WRITETEXT) {
81576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		peek = PTRACE_PEEKTEXT;
81676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		poke = PTRACE_POKETEXT;
81776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
81876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
81976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		peek = PTRACE_PEEKDATA;
82076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		poke = PTRACE_POKEDATA;
82176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
82276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
82376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
82476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
82576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long);
82676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
82776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(peek, pid, (char *) addr, 0);
82876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
82976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("uload: POKE");
83076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
83176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
83276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len));
83376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (ptrace(poke, pid, (char *)addr, u.val) < 0) {
83476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("uload: POKE");
83576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
83676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
83776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
83876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
83976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
84076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (len < sizeof(long))
84176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			u.val = ptrace(peek, pid, (char *) addr, 0);
84276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(u.x, laddr, m = MIN(sizeof(long), len));
84376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (ptrace(poke, pid, (char *) addr, u.val) < 0) {
84476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("uload: POKE");
84576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
84676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
84776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
84876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
84976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
85076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
85176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
85276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
85376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
85476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantload(pid, addr, len, laddr)
85576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
85676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr, len;
85776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
85876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
85976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return uload(PTRACE_WRITETEXT, pid, addr, len, laddr);
86076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
86176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
86276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
86376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandload(pid, addr, len, laddr)
86476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
86576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr;
86676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
86776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
86876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
86976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return uload(PTRACE_WRITEDATA, pid, addr, len, laddr);
87076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
87176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
87276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
87376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
874bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS
87576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
87676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
87776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanupeek(pid, off, res)
87876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
87976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong off;
88076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong *res;
88176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
88276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long val;
88376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
88476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE
88576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	{
88676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		static int is_sun4m = -1;
88776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		struct utsname name;
88876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
88976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* Round up the usual suspects. */
89076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (is_sun4m == -1) {
89176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (uname(&name) < 0) {
89276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				perror("upeek: uname?");
89376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				exit(1);
89476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
89576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			is_sun4m = strcmp(name.machine, "sun4m") == 0;
89676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (is_sun4m) {
89776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				extern struct xlat struct_user_offsets[];
89876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				struct xlat *x;
89976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
90076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				for (x = struct_user_offsets; x->str; x++)
90176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					x->val += 1024;
90276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
90376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
90476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (is_sun4m)
90576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			off += 1024;
90676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
90776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
90876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
90976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	val = ptrace(PTRACE_PEEKUSER, pid, (char *) off, 0);
91076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (val == -1 && errno) {
91176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("upeek: ptrace(PTRACE_PEEKUSER, ... )");
91276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
91376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
91476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*res = val;
91576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
91676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
91776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
918bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */
91976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
92076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong
92176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetpc(tcp)
92276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
92376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
92476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
92576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
92676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
927f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#if defined(I386)
92876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*EIP, &pc) < 0)
92976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
9308b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#elif defined(IA64)
9318b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	if (upeek(tcp->pid, PT_B0, &pc) < 0)
9328b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		return -1;
933f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ARM)
93476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*15, &pc) < 0)
93576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
936f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(POWERPC)
93776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_NIP, &pc) < 0)
93876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
939f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(M68k)
94076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
94176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
942f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ALPHA)
94376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, REG_PC, &pc) < 0)
94476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
945f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS)
946f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman 	if (upeek(tcp->pid, REG_EPC, &pc) < 0)
947f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman 		return -1;
948f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(SPARC)
9499ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	struct regs regs;
95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
95176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
9529ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	pc = regs.r_pc;
9534dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390)
9544dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman	if(upeek(tcp->pid,PT_PSWADDR,&pc) < 0)
955c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
956c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0)
957c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return -1;
9587a0b649aeace5c1e1efe4a1d7b1ae6e3a87e0d44Wichert Akkerman#endif
95976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return pc;
96076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
96176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
96276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
96376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
96476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Return current program counter for `pid'
96576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Assumes PC is never 0xffffffff
96676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
96776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct regs regs;
96876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
96976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
97076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("getpc: ptrace(PTRACE_GETREGS, ...)");
97176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
97276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
97376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return regs.r_pc;
97476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
97576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
97676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4
97776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* XXX */
97876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
97976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */
98076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
981bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD
982bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	struct reg regs;
983bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
984bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	return regs.r_eip;
985bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */
98676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
98976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintcall(tcp)
99076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
99376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
99476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386
99576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long eip;
99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*EIP, &eip) < 0) {
99876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("[????????] ");
99976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
100076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
100176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", eip);
1002faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(IA62)
10038b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	long ip;
10048b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
10058b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	if (upeek(tcp->pid, PT_B0, &ip) < 0) {
10068b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		tprintf("[????????] ");
10078b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		return;
10088b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	}
10098b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	tprintf("[%08lx] ", ip);
1010faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(POWERPC)
101176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
101276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
101376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_NIP, &pc) < 0) {
101476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf ("[????????] ");
101576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
101676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
101776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
1018faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68k)
101976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
102076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
102176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) {
102276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf ("[????????] ");
102376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
102476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
102576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
1026faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA)
102776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
102876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
102976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, REG_PC, &pc) < 0) {
103076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf ("[????????] ");
103176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
103276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
103376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
1034faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(SPARC)
10359ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	struct regs regs;
103676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0) {
103776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("[????????] ");
103876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
103976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
10409ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	tprintf("[%08lx] ", regs.r_pc);
1041c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
1042c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	long pc;
1043c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman
1044c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) {
1045c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		tprintf ("[????????] ");
1046c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return;
1047c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	}
1048c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	tprintf("[%08lx] ", pc);
104975c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman#elif defined(MIPS)
105075c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	long pc;
105175c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman
105275c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	if (upeek(tcp->pid, REG_EPC, &pc) < 0) {
105375c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman		tprintf ("[????????] ");
105475c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman		return;
105575c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	}
105675c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	tprintf("[%08lx] ", pc);
1057faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* !architecture */
105876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
105976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
106076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
106176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct regs regs;
106276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
106376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
106476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("printcall: ptrace(PTRACE_GETREGS, ...)");
106576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("[????????] ");
106676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
106776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
106876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08x] ", regs.r_o7);
106976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
107076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
107176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4
107276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* XXX */
107376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[????????] ");
107476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
107576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1076bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD
1077bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	struct reg regs;
1078bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
1079bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	tprintf("[%08x] ", regs.r_eip);
1080bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */
108176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
108276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1083bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS
108476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
108576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
108676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermansetbpt(tcp)
108776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
108876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
108976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
109076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
109176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC
109276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* We simply use the SunOS breakpoint code. */
109376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
10949ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	struct regs regs;
109576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA	0x30800000	/* ba,a	0 */
109676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
109776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tcp->flags & TCB_BPTSET) {
109876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
109976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
110076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
110176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
110276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
110376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
110476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
11059ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	tcp->baddr = regs.r_o7 + 8;
110676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
110776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0);
110876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if(errno) {
110976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
111076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
111176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
111276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
111376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
111476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * XXX - BRUTAL MODE ON
111576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * We cannot set a real BPT in the child, since it will not be
111676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * traced at the moment it will reach the trap and would probably
111776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * die with a core dump.
111876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Thus, we are force our way in by taking out two instructions
111976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * and insert an eternal loop instead, in expectance of the SIGSTOP
112076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * generated by out PTRACE_ATTACH.
112176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Of cause, if we evaporate ourselves in the middle of all this...
112276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
112376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
112476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOPA);
112576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if(errno) {
112676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
112776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
112876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
112976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags |= TCB_BPTSET;
113076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
113176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !SPARC */
11328b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#ifdef IA64
11337b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman	if (ia32) {
11347b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#		define LOOP	0x0000feeb
11357b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (tcp->flags & TCB_BPTSET) {
11367b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			fprintf(stderr, "PANIC: bpt already set in pid %u\n",
11377b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				tcp->pid);
11387b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
11397b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
11407b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (upeek(tcp->pid, PT_CR_IIP, &tcp->baddr) < 0)
11417b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
11427b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (debug)
11437b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			fprintf(stderr, "[%d] setting bpt at %lx\n",
11447b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				tcp->pid, tcp->baddr);
11457b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid,
11467b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				      (char *) tcp->baddr, 0);
11477b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (errno) {
11487b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
11497b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
11507b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
11517b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
11527b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (errno) {
11537b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
11547b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
11557b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
11567b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->flags |= TCB_BPTSET;
11577b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman	} else {
11587b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		/*
11597b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * XXX Use break instead!
11607b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 *
11617b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * Our strategy here is to replace the bundle that
11627b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * contained the clone() syscall with a bundle of the
11637b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * form:
11647b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 *
11657b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 *	{ 1: br 1b; br 1b; br 1b }
11667b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 *
11677b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * This ensures that the newly forked child will loop
11687b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * endlessly until we've got a chance to attach to it.
11697b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 */
11708b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#		define LOOP0	0x0000100000000017
11718b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#		define LOOP1	0x4000000000200000
11728b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		unsigned long addr, ipsr;
11738b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		pid_t pid;
11748b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
11758b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		pid = tcp->pid;
11768b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (upeek(pid, PT_CR_IPSR, &ipsr) < 0)
11778b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
11788b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (upeek(pid, PT_CR_IIP, &addr) < 0)
11798b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
11807b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		/* store "ri" in low two bits */
11817b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->baddr = addr | ((ipsr >> 41) & 0x3);
11828b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
11838b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		errno = 0;
11847b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0,
11857b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				      0);
11867b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8,
11877b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				      0);
11888b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (errno) {
11898b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
11908b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
11918b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
11928b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
11938b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		errno = 0;
11948b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0);
11958b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1);
11968b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (errno) {
11978b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
11988b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
11998b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
12008b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		tcp->flags |= TCB_BPTSET;
12018b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	}
12028b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#else /* !IA64 */
120376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
120476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined (I386)
120576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP	0x0000feeb
120676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K)
120776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP	0x60fe0000
120876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA)
12094dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP	0xc3ffffff
121076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC)
12114dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP	0x0000feeb
121276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined(ARM)
12139a8a37f2b28d1c0d3f57951fd5aeeb96ff7d2f16Wichert Akkerman#define LOOP	0xEAFFFFFE
1214f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS)
12154dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP	0x1000ffff
12164dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390)
12174dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP	0xa7f40000	/* BRC 15,0 */
1218c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
1219c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#define LOOP	0xe81f1ff7	/* b,l,n <loc>,r0 */
122076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else
122176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture
122276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
122376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
122476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tcp->flags & TCB_BPTSET) {
122576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid);
122676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
122776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
122876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined (I386)
122976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*EIP, &tcp->baddr) < 0)
123076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
123176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K)
123276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_PC, &tcp->baddr) < 0)
123376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	  return -1;
123476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA)
123576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return -1;
123676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ARM)
123776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return -1;
1238f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined (MIPS)
1239f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman	return -1;		/* FIXME: I do not know what i do - Flo */
124076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC)
124176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_NIP, &tcp->baddr) < 0)
124276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
12434dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390)
12444dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman	if (upeek(tcp->pid,PT_PSWADDR, &tcp->baddr) < 0)
12454dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman		return -1;
1246c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
1247c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	if (upeek(tcp->pid, PT_IAOQ0, &tcp->baddr) < 0)
1248c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return -1;
1249c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	tcp->baddr &= ~0x03;
125076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else
125176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture
125276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
125376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (debug)
125476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr);
125576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0);
125676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (errno) {
125776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
125876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
125976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
126076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
126176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (errno) {
126276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
126376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
126476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
126576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags |= TCB_BPTSET;
126676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
12678b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#endif /* !IA64 */
126876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */
126976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
127076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
127176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
127276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC	/* This code is slightly sparc specific */
127376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1274e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman	struct regs regs;
127576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define BPT	0x91d02001	/* ta	1 */
127676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP	0x10800000	/* ba	0 */
127776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA	0x30800000	/* ba,a	0 */
127876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define NOP	0x01000000
127976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if LOOPA
128076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static int loopdeloop[1] = {LOOPA};
128176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else
128276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static int loopdeloop[2] = {LOOP, NOP};
128376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
128476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
128576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tcp->flags & TCB_BPTSET) {
128676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
128776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
128876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
128976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
129076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
129176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
129276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
129376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->baddr = regs.r_o7 + 8;
129476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr,
129576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				sizeof tcp->inst, (char *)tcp->inst) < 0) {
129676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_READTEXT, ...)");
129776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
129876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
129976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
130076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
130176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * XXX - BRUTAL MODE ON
130276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * We cannot set a real BPT in the child, since it will not be
130376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * traced at the moment it will reach the trap and would probably
130476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * die with a core dump.
130576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Thus, we are force our way in by taking out two instructions
130676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * and insert an eternal loop in stead, in expectance of the SIGSTOP
130776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * generated by out PTRACE_ATTACH.
130876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Of cause, if we evaporate ourselves in the middle of all this...
130976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
131076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
131176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			sizeof loopdeloop, (char *) loopdeloop) < 0) {
131276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)");
131376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
131476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
131576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags |= TCB_BPTSET;
131676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
131776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */
131876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
131976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
132076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
132176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
132276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
132376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
132476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanclearbpt(tcp)
132576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
132676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
132776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
132876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
1329faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#if defined(I386)
133076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long eip;
1331faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(POWERPC)
133276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
1333faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68K)
133476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
1335faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA)
133676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
1337c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
1338c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	long iaoq;
1339faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* architecture */
134076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
134176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC
134276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* Again, we borrow the SunOS breakpoint code. */
134376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!(tcp->flags & TCB_BPTSET)) {
134476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
134576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
134676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
134776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
134876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
134976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if(errno) {
135076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
135176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
135276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
135376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags &= ~TCB_BPTSET;
1354faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(IA64)
13557b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman	if (ia32) {
13567b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		unsigned long addr;
13577b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman
13587b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (debug)
13597b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
13607b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (!(tcp->flags & TCB_BPTSET)) {
13617b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
13627b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
13637b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
13647b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		errno = 0;
13657b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
13667b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (errno) {
13677b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
13687b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
13697b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
13707b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->flags &= ~TCB_BPTSET;
13717b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman
13727b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (upeek(tcp->pid, PT_CR_IIP, &addr) < 0)
13737b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
13747b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (addr != tcp->baddr) {
13757b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			/* The breakpoint has not been reached yet.  */
13767b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			if (debug)
13777b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				fprintf(stderr,
13787b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman					"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
13797b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman						addr, tcp->baddr);
13807b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return 0;
13817b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
13827b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman	} else {
13838b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		unsigned long addr, ipsr;
13848b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		pid_t pid;
13858b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
13868b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		pid = tcp->pid;
13878b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
13888b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (upeek(pid, PT_CR_IPSR, &ipsr) < 0)
13898b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
13908b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (upeek(pid, PT_CR_IIP, &addr) < 0)
13918b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
13928b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
13938b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		/* restore original bundle: */
13948b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		errno = 0;
13958b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]);
13968b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]);
13978b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (errno) {
13988b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)");
13998b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
14008b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
14018b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
14028b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		/* restore original "ri" in ipsr: */
14038b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41);
14048b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		errno = 0;
14058b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr);
14068b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (errno) {
14078b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)");
14088b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
14098b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
14108b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
14118b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		tcp->flags &= ~TCB_BPTSET;
14128b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
14138b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (addr != (tcp->baddr & ~0x3)) {
14148b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			/* the breakpoint has not been reached yet.  */
14158b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			if (debug)
14168b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman				fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
14178b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman					addr, tcp->baddr);
14188b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return 0;
14198b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
14208b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	}
1421faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#else /* !IA64  && ! SPARC */
142276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
142376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (debug)
142476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
142576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!(tcp->flags & TCB_BPTSET)) {
142676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
142776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
142876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
142976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
143076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
143176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (errno) {
143276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
143376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
143476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
143576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags &= ~TCB_BPTSET;
143676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
143776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386
143876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*EIP, &eip) < 0)
143976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
144076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (eip != tcp->baddr) {
144176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
144276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
144376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr,
144476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
144576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					eip, tcp->baddr);
144676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
144776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
1448c792698a99b640e7d256e8692c992bd967f0c5b2Wichert Akkerman#elif defined(POWERPC)
144976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_NIP, &pc) < 0)
145076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
145176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (pc != tcp->baddr) {
145276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
145376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
145476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
145576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				pc, tcp->baddr);
145676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
145776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
1458faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68K)
145976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
146076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
146176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (pc != tcp->baddr) {
146276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
146376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
146476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
146576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				pc, tcp->baddr);
146676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
146776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
1468faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA)
146976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, REG_PC, &pc) < 0)
147076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
147176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (pc != tcp->baddr) {
147276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
147376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
147476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
147576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				pc, tcp->baddr);
147676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
147776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
1478c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
1479c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	if (upeek(tcp->pid, PT_IAOQ0, &iaoq) < 0)
1480c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return -1;
1481c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	iaoq &= ~0x03;
1482c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) {
1483c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		/* The breakpoint has not been reached yet.  */
1484c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		if (debug)
1485c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n",
1486c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman				iaoq, tcp->baddr);
1487c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return 0;
1488c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	}
1489c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	iaoq = tcp->baddr | 3;
1490c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	/* We should be pointing at a 'ldi -1000,r1' in glibc, so it is
1491c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	 * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit
1492c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	 * has no significant effect.
1493c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	 */
1494c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq);
1495c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq);
1496faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* arch */
1497faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* !SPARC && !IA64 */
149876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
149976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
150076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
150176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC
150276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
150376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA
1504e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman	struct regs regs;
150576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
150676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
150776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!(tcp->flags & TCB_BPTSET)) {
150876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
150976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
151076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
151176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
151276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				sizeof tcp->inst, (char *) tcp->inst) < 0) {
151376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)");
151476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
151576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
151676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags &= ~TCB_BPTSET;
151776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
151876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA
151976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
152076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Since we don't have a single instruction breakpoint, we may have
152176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * to adjust the program counter after removing the our `breakpoint'.
152276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
152376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
152476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbpt: ptrace(PTRACE_GETREGS, ...)");
152576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
152676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
152776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if ((regs.r_pc < tcp->baddr) ||
152876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				(regs.r_pc > tcp->baddr + 4)) {
152976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet */
153076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
153176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr,
153276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				"NOTE: PC not at bpt (pc %#x baddr %#x)\n",
153376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					regs.r_pc, tcp->parent->baddr);
153476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
153576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
153676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (regs.r_pc != tcp->baddr)
153776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
153876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n",
153976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				regs.r_pc, tcp->baddr);
154076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
154176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	regs.r_pc = tcp->baddr;
154276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0) {
154376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbpt: ptrace(PTRACE_SETREGS, ...)");
154476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
154576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
154676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LOOPA */
154776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */
154876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
154976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
155076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
155176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
155276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1553bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */
155476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
155576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
155676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
155776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int
155876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetex(pid, hdr)
155976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
156076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct exec *hdr;
156176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
156276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
156376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
156476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (n = 0; n < sizeof *hdr; n += 4) {
156576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long res;
156676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (upeek(pid, uoff(u_exdata) + n, &res) < 0)
156776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
156876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(((char *) hdr) + n, &res, 4);
156976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
157076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (debug) {
157176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n",
157276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			hdr->a_magic, hdr->a_toolversion, hdr->a_machtype);
157376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n",
157476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry);
157576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
157676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
157776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
157876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
157976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
158076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfixvfork(tcp)
158176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
158276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
158376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
158476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
158576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Change `vfork' in a freshly exec'ed dynamically linked
158676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * executable's (internal) symbol table to plain old `fork'
158776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
158876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
158976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct exec hdr;
159076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct link_dynamic dyn;
159176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct link_dynamic_2 ld;
159276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *strtab, *cp;
159376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
159476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (getex(pid, &hdr) < 0)
159576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
159676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!hdr.a_dynamic)
159776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
159876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
159976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) {
160076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "Cannot read DYNAMIC\n");
160176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
160276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
160376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) {
160476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "Cannot read link_dynamic_2\n");
160576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
160676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
160776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) {
160876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "fixvfork: out of memory\n");
160976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
161076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
161176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
161276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					(int)ld.ld_symb_size, strtab) < 0)
161376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		goto err;
161476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
161576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0
161676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
161776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[symbol: %s]\n", cp);
161876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		cp += strlen(cp)+1;
161976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
162076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
162176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
162276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
162376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (strcmp(cp, "_vfork") == 0) {
162476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (debug)
162576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				fprintf(stderr, "fixvfork: FOUND _vfork\n");
162676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			strcpy(cp, "_fork");
162776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
162876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
162976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		cp += strlen(cp)+1;
163076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
163176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (cp < strtab + ld.ld_symb_size)
163276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/*
163376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		 * Write entire symbol table back to avoid
163476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		 * memory alignment bugs in ptrace
163576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		 */
163676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
163776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					(int)ld.ld_symb_size, strtab) < 0)
163876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			goto err;
163976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
164076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	free(strtab);
164176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
164276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
164376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerr:
164476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	free(strtab);
164576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return -1;
164676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
164776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
164876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
1649