util.c revision 9a8a37f2b28d1c0d3f57951fd5aeeb96ff7d2f16
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>
4176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
4276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <machine/reg.h>
4376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <a.out.h>
4476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <link.h>
4576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
4636915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman
4715dea97f8a05b2b67f5752137fe93e3cc20db6ecWichert Akkerman#if defined(linux)
4876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <linux/ptrace.h>
4936915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#endif
5036915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman
5136915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#ifdef HAVE_SYS_REG_H
5236915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#include <sys/reg.h>
5336915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman# define PTRACE_PEEKUSR PTRACE_PEEKUSER
542e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#endif
5576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
562e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#ifdef HAVE_SYS_PTRACE_H
572e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#include <sys/ptrace.h>
582e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#endif
592e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman
6076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE
6176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/utsname.h>
6276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
6376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
649ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#if defined(LINUX) && defined(SPARC)
659ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman
669ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#include <asm/reg.h>
679ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman
689ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#if !defined(__GLIBC__)
6976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
7076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <linux/unistd.h>
7176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
7276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define _hack_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\
7376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman          type5,arg5,syscall) \
7476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantype name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
7576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ \
7676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman      long __res; \
7776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman\
7876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman__asm__ volatile ("or %%g0, %1, %%o0\n\t" \
7976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %2, %%o1\n\t" \
8076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %3, %%o2\n\t" \
8176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %4, %%o3\n\t" \
8276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %5, %%o4\n\t" \
8376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %6, %%g1\n\t" \
8476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "t 0x10\n\t" \
8576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "bcc 1f\n\t" \
8676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %%o0, %0\n\t" \
8776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "sub %%g0, %%o0, %0\n\t" \
8876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "1:\n\t" \
8976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  : "=r" (__res) \
9076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  : "0" ((long)(arg1)),"1" ((long)(arg2)), \
9176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                    "2" ((long)(arg3)),"3" ((long)(arg4)),"4" ((long)(arg5)), \
9276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                    "i" (__NR_##syscall)  \
9376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  : "g1", "o0", "o1", "o2", "o3", "o4"); \
9476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanif (__res>=0) \
9576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman        return (type) __res; \
9676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerrno = -__res; \
9776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanreturn -1; \
9876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
9976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
10076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,int,__addr2,ptrace)
10176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
10276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define _ptrace
10376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
10476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
10576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1069ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif
1079ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman
10876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* macros */
10976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MAX
11076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MAX(a,b)		(((a) > (b)) ? (a) : (b))
11176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
11276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MIN
11376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MIN(a,b)		(((a) < (b)) ? (a) : (b))
11476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
11576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
11676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
11776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_tv(tv, a, b)
11876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv;
11976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint a;
12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint b;
12176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
12276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a;
12376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = b;
12476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
12576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
12676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
12776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_nz(a)
12876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a;
12976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return a->tv_sec || a->tv_usec;
13176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
13276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
13376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
13476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_cmp(a, b)
13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a, *b;
13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (a->tv_sec < b->tv_sec
13876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	    || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
13976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
14076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (a->tv_sec > b->tv_sec
14176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	    || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
14276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 1;
14376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
14576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandouble
14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_float(tv)
14876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv;
14976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
15076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return tv->tv_sec + tv->tv_usec/1000000.0;
15176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
15276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_add(tv, a, b)
15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b;
15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
15776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec + b->tv_sec;
15876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = a->tv_usec + b->tv_usec;
15976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tv->tv_usec > 1000000) {
16076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_sec++;
16176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_usec -= 1000000;
16276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
16376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
16476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
16576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
16676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_sub(tv, a, b)
16776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b;
16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
16976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec - b->tv_sec;
17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = a->tv_usec - b->tv_usec;
17176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (((long) tv->tv_usec) < 0) {
17276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_sec--;
17376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_usec += 1000000;
17476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
17676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
17776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
17876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_div(tv, a, n)
17976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a;
18076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n;
18176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
18276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
18376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec %= 1000000;
18576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
18676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
18776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
18876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_mul(tv, a, n)
18976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a;
19076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n;
19176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
19276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = a->tv_usec * n;
19376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec * n + a->tv_usec / 1000000;
19476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec %= 1000000;
19576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
19676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *
19876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanxlookup(xlat, val)
19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat;
20076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint val;
20176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
20276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (; xlat->str != NULL; xlat++)
20376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val == val)
20476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return xlat->str;
20576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return NULL;
20676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
20776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
20876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
20976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Print entry in struct xlat table, if there.
21076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintxval(xlat, val, dflt)
21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat;
21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint val;
21576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *dflt;
21676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
21776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *str = xlookup(xlat, val);
21876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
21976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (str)
22076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s", str);
22176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else
22276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#x /* %s */", val, dflt);
22376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
22476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
22576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
22676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interpret `xlat' as an array of flags
22776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * print the entries whose bits are on in `flags'
22876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * return # of flags printed.
22976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
23076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanaddflags(xlat, flags)
23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat;
23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags;
23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
23576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
23676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
23776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (n = 0; xlat->str; xlat++) {
23876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val && (flags & xlat->val) == xlat->val) {
23976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("|%s", xlat->str);
24076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			flags &= ~xlat->val;
24176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			n++;
24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
24376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
24476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (flags) {
24576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("|%#x", flags);
24676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n++;
24776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
24876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return n;
24976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
25076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
25176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
25276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintflags(xlat, flags)
25376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat;
25476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags;
25576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
25676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
25776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *sep;
25876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
25976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (flags == 0 && xlat->val == 0) {
26076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s", xlat->str);
26176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 1;
26276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
26376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
26476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	sep = "";
26576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (n = 0; xlat->str; xlat++) {
26676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val && (flags & xlat->val) == xlat->val) {
26776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%s%s", sep, xlat->str);
26876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			flags &= ~xlat->val;
26976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			sep = "|";
27076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			n++;
27176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
27276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
27376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (flags) {
27476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s%#x", sep, flags);
27576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n++;
27676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
27776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return n;
27876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
27976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
28076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
28176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintnum(tcp, addr, fmt)
28276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
28376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
28476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *fmt;
28576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
28676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int num;
28776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
28876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!addr) {
28976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("NULL");
29076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
29176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
29276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umove(tcp, addr, &num) < 0) {
29376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#lx", addr);
29476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
29576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
29676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[");
29776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf(fmt, num);
29876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("]");
29976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
30076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
30176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic char path[MAXPATHLEN + 1];
30276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
30476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstring_quote(str)
30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *str;
30676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
30776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char buf[2 * MAXPATHLEN + 1];
30876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *s;
30976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
31076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!strpbrk(str, "\"\'\\")) {
31176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("\"%s\"", str);
31276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
31376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
31476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (s = buf; *str; str++) {
31576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		switch (*str) {
31676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case '\"': case '\'': case '\\':
31776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			*s++ = '\\'; *s++ = *str; break;
31876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		default:
31976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			*s++ = *str; break;
32076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
32176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
32276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*s = '\0';
32376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("\"%s\"", buf);
32476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
32576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
32676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
32776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpath(tcp, addr)
32876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
32976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
33076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
33176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umovestr(tcp, addr, MAXPATHLEN, path) < 0)
33276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#lx", addr);
33376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else
33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		string_quote(path);
33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return;
33676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
33776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
33876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
33976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpathn(tcp, addr, n)
34076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
34176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
34276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n;
34376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
34476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umovestr(tcp, addr, n, path) < 0)
34576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#lx", addr);
34676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
34776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		path[n] = '\0';
34876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		string_quote(path);
34976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
35076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
35176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
35276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
35376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintstr(tcp, addr, len)
35476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
35576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
35676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
35776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
35876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static unsigned char *str = NULL;
35976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static char *outstr;
36076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i, n, c, usehex;
36176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *s, *outend;
36276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
36376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!addr) {
36476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("NULL");
36576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
36676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
36776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!str) {
36876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if ((str = malloc(max_strlen)) == NULL
36976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		    || (outstr = malloc(2*max_strlen)) == NULL) {
37076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "printstr: no memory\n");
37176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%#lx", addr);
37276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
37376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
37476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
3752e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman	outend = outstr + max_strlen * 2 - 10;
37676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (len < 0) {
37776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = max_strlen;
37876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (umovestr(tcp, addr, n, (char *) str) < 0) {
37976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%#lx", addr);
38076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
38176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
38276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
38476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(len, max_strlen);
38576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (umoven(tcp, addr, n, (char *) str) < 0) {
38676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%#lx", addr);
38776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
38876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
38976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
39076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
39176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	usehex = 0;
39276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (xflag > 1)
39376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		usehex = 1;
39476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else if (xflag) {
39576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < n; i++) {
39676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			c = str[i];
39776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (len < 0 && c == '\0')
39876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
39976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (!isprint(c) && !isspace(c)) {
40076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				usehex = 1;
40176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
40276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
40376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
40476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
40576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
40676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	s = outstr;
40776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*s++ = '\"';
40876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
40976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (usehex) {
41076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < n; i++) {
41176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			c = str[i];
41276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (len < 0 && c == '\0')
41376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
41476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			sprintf(s, "\\x%02x", c);
41576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			s += 4;
41676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (s > outend)
41776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
41876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
41976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
42076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
42176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < n; i++) {
42276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			c = str[i];
42376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (len < 0 && c == '\0')
42476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
42576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			switch (c) {
42676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\"': case '\'': case '\\':
42776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = c; break;
42876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\f':
42976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 'f'; break;
43076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\n':
43176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 'n'; break;
43276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\r':
43376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 'r'; break;
43476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\t':
43576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 't'; break;
43676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\v':
43776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 'v'; break;
43876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			default:
43976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				if (isprint(c))
44076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					*s++ = c;
44176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				else if (i < n - 1 && isdigit(str[i + 1])) {
44276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					sprintf(s, "\\%03o", c);
44376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					s += 4;
44476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				}
44576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				else {
44676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					sprintf(s, "\\%o", c);
44776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					s += strlen(s);
44876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				}
44976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
45076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
45176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (s > outend)
45276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
45376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
45476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
45576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
45676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*s++ = '\"';
45776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (i < len || (len < 0 && (i == n || s > outend))) {
45876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		*s++ = '.'; *s++ = '.'; *s++ = '.';
45976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
46076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*s = '\0';
46176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("%s", outstr);
46276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
46376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
46476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
46576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandumpstr(tcp, addr, len)
46676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
46776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
46876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
46976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
47076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static int strsize = -1;
47176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static unsigned char *str;
47276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static char outstr[80];
47376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *s;
47476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i, j;
47576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
47676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (strsize < len) {
47776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (str)
47876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			free(str);
47976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if ((str = malloc(len)) == NULL) {
48076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "dump: no memory\n");
48176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
48276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
48376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		strsize = len;
48476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
48576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
48676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umoven(tcp, addr, len, (char *) str) < 0)
48776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
48876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
48976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (i = 0; i < len; i += 16) {
49076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		s = outstr;
49176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		sprintf(s, " | %05x ", i);
49276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		s += 9;
49376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (j = 0; j < 16; j++) {
49476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (j == 8)
49576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
49676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (i + j < len) {
49776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				sprintf(s, " %02x", str[i + j]);
49876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				s += 3;
49976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
50076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			else {
50176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' '; *s++ = ' '; *s++ = ' ';
50276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
50376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
50476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		*s++ = ' '; *s++ = ' ';
50576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (j = 0; j < 16; j++) {
50676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (j == 8)
50776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
50876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (i + j < len) {
50976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				if (isprint(str[i + j]))
51076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					*s++ = str[i + j];
51176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				else
51276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					*s++ = '.';
51376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
51476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			else
51576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
51676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
51776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s |\n", outstr);
51876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
51976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
52076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
52176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PAGMASK	(~(PAGSIZ - 1))
52276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
52376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * move `len' bytes of data from process `pid'
52476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * at address `addr' to our space at `laddr'
52576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
52676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
52776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumoven(tcp, addr, len, laddr)
52876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
52976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
53076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
53176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
53276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
53376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
53476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
53576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
53676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n, m;
5375daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman	int started = 0;
53876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
53976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
54076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
54176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
54276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
54376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
54476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
54576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
54676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
54776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
54876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
54976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
5505daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			if (started && (errno==EPERM || errno==EIO)) {
55176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/* Ran into 'end of memory' - stupid "printpath" */
55276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
55376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
5545daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			/* But if not started, we had a bogus address. */
55576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("ptrace: umoven");
55676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
55776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
5585daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
55976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
56076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
56176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
56276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
56376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
56476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
56576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
5665daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			if (started && (errno==EPERM || errno==EIO)) {
56776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/* Ran into 'end of memory' - stupid "printpath" */
56876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
56976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
57076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("ptrace: umoven");
57176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
57276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
5735daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
57476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
57576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
57676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
57776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
57876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
57976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
58076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
58176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0
58276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n, m;
58376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
58476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
58576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
58676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
58776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
58876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
58976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
59076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
59176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
59276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
59376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
59476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
59576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umoven");
59676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
59776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
59876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
59976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
60076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
60176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
60276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
60376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
60476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
60576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umoven");
60676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
60776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
60876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
60976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
61076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
61176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !oldway */
61276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
61376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
61476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
61576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(len, PAGSIZ);
61676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
61776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (ptrace(PTRACE_READDATA, pid,
61876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			   (char *) addr, len, laddr) < 0) {
61976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umoven: ptrace(PTRACE_READDATA, ...)");
62076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			abort();
62176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
62276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
62376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		len -= n;
62476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += n;
62576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		laddr += n;
62676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !oldway */
62876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
62976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
63076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4
631ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS
6329ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	if (pread(tcp->pfd_as, laddr, len, addr) == -1)
6339ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman		return -1;
6349ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else
63576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
63676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We would like to use pread preferentially for speed
63776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * but even though SGI has it in their library, it no longer works.
63876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
63976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef MIPS
64076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#undef HAVE_PREAD
64176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
64276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_PREAD
64376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (pread(tcp->pfd, laddr, len, addr) == -1)
64476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
64576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !HAVE_PREAD */
64676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	lseek(tcp->pfd, addr, SEEK_SET);
64776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (read(tcp->pfd, laddr, len) == -1)
64876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
64976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_PREAD */
650ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#endif /* HAVE_MP_PROCFS */
65176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */
65276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
65376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
65476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
65576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
65676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
65776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * like `umove' but make the additional effort of looking
65876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * for a terminating zero byte.
65976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
66076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
66176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumovestr(tcp, addr, len, laddr)
66276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
66376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
66476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
66576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
66676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
66771bdaff3b7009ce6d7fa9d8dda569b758ae238afWichert Akkerman#ifdef SVR4
66876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return umoven(tcp, addr, len, laddr);
66976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !SVR4 */
6705daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman	int started = 0;
67176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
67276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i, n, m;
67376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
67476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
67576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
67676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
67776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
67876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
67976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
68076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
68176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
68276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
68376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
68476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
6855daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			if (started && (errno==EPERM || errno==EIO)) {
68676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/* Ran into 'end of memory' - stupid "printpath" */
68776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
68876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
68976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umovestr");
69076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
69176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
6925daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
69376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len));
69476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		while (n & (sizeof(long) - 1))
69576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (u.x[n++] == '\0')
69676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
69776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
69876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
69976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
70076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
70176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
70276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
7035daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			if (started && (errno==EPERM || errno==EIO)) {
70476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/* Ran into 'end of memory' - stupid "printpath" */
70576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
70676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
70776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umovestr");
70876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
70976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
7105daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
71176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
71276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < sizeof(long); i++)
71376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (u.x[i] == '\0')
71476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
71576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
71676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
71776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
71876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
71976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !SVR4 */
72076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
72176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
72276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
72376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SPARC
72476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITETEXT	101
72576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITEDATA	102
72676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !SPARC */
72776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
72876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
72976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
73076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
73176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int
73276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanuload(cmd, pid, addr, len, laddr)
73376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint cmd;
73476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
73576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
73676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
73776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
73876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
73976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0
74076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
74176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
74276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
74376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(len, PAGSIZ);
74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
74576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) {
74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("uload: ptrace(PTRACE_WRITE, ...)");
74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
74876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		len -= n;
75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += n;
75176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		laddr += n;
75276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
75376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else
75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int peek, poke;
75576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n, m;
75676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
75776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
75876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
76076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
76176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (cmd == PTRACE_WRITETEXT) {
76276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		peek = PTRACE_PEEKTEXT;
76376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		poke = PTRACE_POKETEXT;
76476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
76576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
76676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		peek = PTRACE_PEEKDATA;
76776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		poke = PTRACE_POKEDATA;
76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
77076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
77176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
77276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long);
77376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
77476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(peek, pid, (char *) addr, 0);
77576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
77676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("uload: POKE");
77776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
77876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
77976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len));
78076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (ptrace(poke, pid, (char *)addr, u.val) < 0) {
78176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("uload: POKE");
78276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
78376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
78476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
78576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
78676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
78776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (len < sizeof(long))
78876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			u.val = ptrace(peek, pid, (char *) addr, 0);
78976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(u.x, laddr, m = MIN(sizeof(long), len));
79076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (ptrace(poke, pid, (char *) addr, u.val) < 0) {
79176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("uload: POKE");
79276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
79376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
79476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
79576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
79676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
79776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
79876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
79976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
80076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
80176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantload(pid, addr, len, laddr)
80276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
80376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr, len;
80476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
80576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
80676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return uload(PTRACE_WRITETEXT, pid, addr, len, laddr);
80776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
80876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
80976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
81076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandload(pid, addr, len, laddr)
81176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
81276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr;
81376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
81476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
81576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
81676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return uload(PTRACE_WRITEDATA, pid, addr, len, laddr);
81776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
81876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
81976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
82076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
82176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SVR4
82276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
82376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
82476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanupeek(pid, off, res)
82576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
82676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong off;
82776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong *res;
82876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
82976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long val;
83076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
83176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE
83276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	{
83376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		static int is_sun4m = -1;
83476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		struct utsname name;
83576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
83676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* Round up the usual suspects. */
83776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (is_sun4m == -1) {
83876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (uname(&name) < 0) {
83976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				perror("upeek: uname?");
84076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				exit(1);
84176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
84276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			is_sun4m = strcmp(name.machine, "sun4m") == 0;
84376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (is_sun4m) {
84476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				extern struct xlat struct_user_offsets[];
84576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				struct xlat *x;
84676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
84776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				for (x = struct_user_offsets; x->str; x++)
84876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					x->val += 1024;
84976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
85076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
85176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (is_sun4m)
85276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			off += 1024;
85376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
85476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
85576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
85676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	val = ptrace(PTRACE_PEEKUSER, pid, (char *) off, 0);
85776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (val == -1 && errno) {
85876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("upeek: ptrace(PTRACE_PEEKUSER, ... )");
85976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
86076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
86176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*res = val;
86276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
86376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
86476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
86576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !SVR4 */
86676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
86776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong
86876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetpc(tcp)
86976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
87076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
87176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
87276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
87376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
874f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#if defined(I386)
87576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*EIP, &pc) < 0)
87676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
877f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ARM)
87876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*15, &pc) < 0)
87976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
880f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(POWERPC)
88176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_NIP, &pc) < 0)
88276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
883f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(M68k)
88476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
88576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
886f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ALPHA)
88776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, REG_PC, &pc) < 0)
88876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
889f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS)
890f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman 	if (upeek(tcp->pid, REG_EPC, &pc) < 0)
891f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman 		return -1;
892f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(SPARC)
8939ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	struct regs regs;
89476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
89576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
8969ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	pc = regs.r_pc;
8974dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390)
8984dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman	if(upeek(tcp->pid,PT_PSWADDR,&pc) < 0)
8997a0b649aeace5c1e1efe4a1d7b1ae6e3a87e0d44Wichert Akkerman#endif
90076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return pc;
90176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
90276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
90376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
90476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
90576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Return current program counter for `pid'
90676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Assumes PC is never 0xffffffff
90776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
90876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct regs regs;
90976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
91076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
91176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("getpc: ptrace(PTRACE_GETREGS, ...)");
91276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
91376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
91476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return regs.r_pc;
91576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
91676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
91776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4
91876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* XXX */
91976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
92076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */
92176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
92276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
92376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
92476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
92576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintcall(tcp)
92676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
92776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
92876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
92976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
93076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386
93176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long eip;
93276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
93376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*EIP, &eip) < 0) {
93476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("[????????] ");
93576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
93676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
93776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", eip);
93876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !I386K */
93976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef POWERPC
94076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
94176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
94276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_NIP, &pc) < 0) {
94376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf ("[????????] ");
94476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
94576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
94676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
94776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !POWERPC */
94876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef M68K
94976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
95176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) {
95276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf ("[????????] ");
95376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
95476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
95576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
95676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !M68K */
95776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef ALPHA
95876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
95976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
96076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, REG_PC, &pc) < 0) {
96176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf ("[????????] ");
96276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
96376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
96476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
96576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !ALPHA */
96676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC
9679ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	struct regs regs;
96876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0) {
96976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("[????????] ");
97076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
97176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
9729ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	tprintf("[%08lx] ", regs.r_pc);
97376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */
97476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* ALPHA */
97576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !M68K */
97676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !POWERPC */
97776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !I386 */
97876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
97976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
98076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
98176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct regs regs;
98276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
98376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
98476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("printcall: ptrace(PTRACE_GETREGS, ...)");
98576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("[????????] ");
98676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08x] ", regs.r_o7);
98976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
99076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4
99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* XXX */
99376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[????????] ");
99476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
99576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
99876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SVR4
99976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
100076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
100176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermansetbpt(tcp)
100276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
100376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
100476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
100576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
100676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC
100776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* We simply use the SunOS breakpoint code. */
100876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
10099ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	struct regs regs;
101076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA	0x30800000	/* ba,a	0 */
101176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
101276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tcp->flags & TCB_BPTSET) {
101376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
101476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
101576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
101676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
101776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
101876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
101976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
10209ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	tcp->baddr = regs.r_o7 + 8;
102176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
102276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0);
102376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if(errno) {
102476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
102576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
102676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
102776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
102876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
102976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * XXX - BRUTAL MODE ON
103076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * We cannot set a real BPT in the child, since it will not be
103176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * traced at the moment it will reach the trap and would probably
103276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * die with a core dump.
103376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Thus, we are force our way in by taking out two instructions
103476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * and insert an eternal loop instead, in expectance of the SIGSTOP
103576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * generated by out PTRACE_ATTACH.
103676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Of cause, if we evaporate ourselves in the middle of all this...
103776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
103876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
103976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOPA);
104076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if(errno) {
104176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
104276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
104376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
104476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags |= TCB_BPTSET;
104576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
104676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !SPARC */
104776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
104876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined (I386)
104976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP	0x0000feeb
105076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K)
105176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP	0x60fe0000
105276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA)
10534dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP	0xc3ffffff
105476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC)
10554dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP	0x0000feeb
105676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined(ARM)
10579a8a37f2b28d1c0d3f57951fd5aeeb96ff7d2f16Wichert Akkerman#define LOOP	0xEAFFFFFE
1058f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS)
10594dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP	0x1000ffff
10604dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390)
10614dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP	0xa7f40000	/* BRC 15,0 */
106276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else
106376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture
106476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
106576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
106676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tcp->flags & TCB_BPTSET) {
106776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid);
106876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
106976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
107076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined (I386)
107176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*EIP, &tcp->baddr) < 0)
107276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
107376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K)
107476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_PC, &tcp->baddr) < 0)
107576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	  return -1;
107676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA)
107776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return -1;
107876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ARM)
107976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return -1;
1080f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined (MIPS)
1081f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman	return -1;		/* FIXME: I do not know what i do - Flo */
108276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC)
108376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_NIP, &tcp->baddr) < 0)
108476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
10854dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390)
10864dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman	if (upeek(tcp->pid,PT_PSWADDR, &tcp->baddr) < 0)
10874dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman		return -1;
108876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else
108976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture
109076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
109176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (debug)
109276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr);
109376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0);
109476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (errno) {
109576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
109676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
109776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
109876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
109976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (errno) {
110076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
110176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
110276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
110376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags |= TCB_BPTSET;
110476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
110576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */
110676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
110776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
110876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
110976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC	/* This code is slightly sparc specific */
111076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1111e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman	struct regs regs;
111276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define BPT	0x91d02001	/* ta	1 */
111376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP	0x10800000	/* ba	0 */
111476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA	0x30800000	/* ba,a	0 */
111576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define NOP	0x01000000
111676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if LOOPA
111776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static int loopdeloop[1] = {LOOPA};
111876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else
111976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static int loopdeloop[2] = {LOOP, NOP};
112076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
112176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
112276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tcp->flags & TCB_BPTSET) {
112376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
112476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
112576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
112676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
112776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
112876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
112976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
113076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->baddr = regs.r_o7 + 8;
113176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr,
113276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				sizeof tcp->inst, (char *)tcp->inst) < 0) {
113376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_READTEXT, ...)");
113476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
113576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
113676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
113776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
113876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * XXX - BRUTAL MODE ON
113976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * We cannot set a real BPT in the child, since it will not be
114076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * traced at the moment it will reach the trap and would probably
114176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * die with a core dump.
114276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Thus, we are force our way in by taking out two instructions
114376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * and insert an eternal loop in stead, in expectance of the SIGSTOP
114476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * generated by out PTRACE_ATTACH.
114576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Of cause, if we evaporate ourselves in the middle of all this...
114676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
114776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
114876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			sizeof loopdeloop, (char *) loopdeloop) < 0) {
114976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)");
115076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
115176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
115276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags |= TCB_BPTSET;
115376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
115476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */
115576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
115676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
115776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
115876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
115976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
116076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
116176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanclearbpt(tcp)
116276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
116376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
116476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
116576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
116676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386
116776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long eip;
116876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !I386 */
116976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef POWERPC
117076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
117176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !POWERPC */
117276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef M68K
117376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
117476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !M68K */
117576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef ALPHA
117676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
117776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* ALPHA */
117876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !M68K */
117976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !POWERPC */
118076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !I386 */
118176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
118276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC
118376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* Again, we borrow the SunOS breakpoint code. */
118476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!(tcp->flags & TCB_BPTSET)) {
118576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
118676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
118776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
118876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
118976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
119076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if(errno) {
119176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
119276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
119376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
119476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags &= ~TCB_BPTSET;
119576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !SPARC */
119676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
119776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (debug)
119876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
119976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!(tcp->flags & TCB_BPTSET)) {
120076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
120176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
120276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
120376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
120476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
120576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (errno) {
120676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
120776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
120876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
120976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags &= ~TCB_BPTSET;
121076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
121176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386
121276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*EIP, &eip) < 0)
121376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
121476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (eip != tcp->baddr) {
121576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
121676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
121776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr,
121876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
121976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					eip, tcp->baddr);
122076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
122176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
122276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !I386 */
122376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef POWERPC
122476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_NIP, &pc) < 0)
122576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
122676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (pc != tcp->baddr) {
122776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
122876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
122976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
123076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				pc, tcp->baddr);
123176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
123276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
123376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !POWERPC */
123476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef M68K
123576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
123676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
123776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (pc != tcp->baddr) {
123876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
123976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
124076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
124176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				pc, tcp->baddr);
124276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
124376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
124476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !M68K */
124576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef ALPHA
124676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, REG_PC, &pc) < 0)
124776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
124876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (pc != tcp->baddr) {
124976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
125076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
125176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
125276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				pc, tcp->baddr);
125376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
125476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
125576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* ALPHA */
125676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !M68K */
125776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !POWERPC */
125876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !I386 */
125976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !SPARC */
126076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
126176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
126276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
126376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC
126476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
126576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA
1266e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman	struct regs regs;
126776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
126876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
126976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!(tcp->flags & TCB_BPTSET)) {
127076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
127176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
127276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
127376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
127476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				sizeof tcp->inst, (char *) tcp->inst) < 0) {
127576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)");
127676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
127776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
127876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags &= ~TCB_BPTSET;
127976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
128076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA
128176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
128276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Since we don't have a single instruction breakpoint, we may have
128376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * to adjust the program counter after removing the our `breakpoint'.
128476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
128576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
128676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbpt: ptrace(PTRACE_GETREGS, ...)");
128776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
128876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
128976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if ((regs.r_pc < tcp->baddr) ||
129076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				(regs.r_pc > tcp->baddr + 4)) {
129176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet */
129276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
129376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr,
129476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				"NOTE: PC not at bpt (pc %#x baddr %#x)\n",
129576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					regs.r_pc, tcp->parent->baddr);
129676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
129776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
129876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (regs.r_pc != tcp->baddr)
129976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
130076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n",
130176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				regs.r_pc, tcp->baddr);
130276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
130376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	regs.r_pc = tcp->baddr;
130476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0) {
130576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbpt: ptrace(PTRACE_SETREGS, ...)");
130676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
130776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
130876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LOOPA */
130976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */
131076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
131176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
131276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
131376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
131476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
131576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !SVR4 */
131676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
131776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
131876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
131976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int
132076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetex(pid, hdr)
132176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
132276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct exec *hdr;
132376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
132476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
132576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
132676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (n = 0; n < sizeof *hdr; n += 4) {
132776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long res;
132876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (upeek(pid, uoff(u_exdata) + n, &res) < 0)
132976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
133076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(((char *) hdr) + n, &res, 4);
133176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
133276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (debug) {
133376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n",
133476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			hdr->a_magic, hdr->a_toolversion, hdr->a_machtype);
133576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n",
133676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry);
133776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
133876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
133976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
134076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
134176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
134276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfixvfork(tcp)
134376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
134476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
134576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
134676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
134776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Change `vfork' in a freshly exec'ed dynamically linked
134876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * executable's (internal) symbol table to plain old `fork'
134976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
135076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
135176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct exec hdr;
135276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct link_dynamic dyn;
135376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct link_dynamic_2 ld;
135476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *strtab, *cp;
135576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
135676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (getex(pid, &hdr) < 0)
135776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
135876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!hdr.a_dynamic)
135976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
136076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
136176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) {
136276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "Cannot read DYNAMIC\n");
136376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
136476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
136576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) {
136676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "Cannot read link_dynamic_2\n");
136776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
136876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
136976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) {
137076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "fixvfork: out of memory\n");
137176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
137276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
137376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
137476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					(int)ld.ld_symb_size, strtab) < 0)
137576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		goto err;
137676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
137776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0
137876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
137976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[symbol: %s]\n", cp);
138076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		cp += strlen(cp)+1;
138176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
138276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
138376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
138476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
138576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (strcmp(cp, "_vfork") == 0) {
138676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (debug)
138776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				fprintf(stderr, "fixvfork: FOUND _vfork\n");
138876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			strcpy(cp, "_fork");
138976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
139076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
139176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		cp += strlen(cp)+1;
139276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
139376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (cp < strtab + ld.ld_symb_size)
139476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/*
139576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		 * Write entire symbol table back to avoid
139676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		 * memory alignment bugs in ptrace
139776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		 */
139876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
139976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					(int)ld.ld_symb_size, strtab) < 0)
140076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			goto err;
140176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
140276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	free(strtab);
140376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
140476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
140576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerr:
140676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	free(strtab);
140776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return -1;
140876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
140976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
141076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
1411