util.c revision ac971c27278e1d45bf12c1ba522c7507ba778144
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
38d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#include <signal.h>
39d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#include <sys/syscall.h>
4076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/user.h>
4176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/param.h>
4276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <fcntl.h>
431d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H
441d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#include <sys/uio.h>
451d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif
4676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
4776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <machine/reg.h>
4876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <a.out.h>
4976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <link.h>
5076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
5136915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman
5243a7482edbc7142b91e95d7aedeb9d121fc4880fWichert Akkerman#if defined(linux) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1))
5376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <linux/ptrace.h>
541e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath#endif
5536915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman
568b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#if defined(LINUX) && defined(IA64)
57d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# include <asm/ptrace_offsets.h>
58d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# include <asm/rse.h>
598b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#endif
608b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
6136915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#ifdef HAVE_SYS_REG_H
6236915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#include <sys/reg.h>
6336915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman# define PTRACE_PEEKUSR PTRACE_PEEKUSER
64faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(HAVE_LINUX_PTRACE_H)
65faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#undef PTRACE_SYSCALL
66faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#include <linux/ptrace.h>
672e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#endif
682e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman
6976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE
7076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/utsname.h>
7176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
7276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
739ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#if defined(LINUX) && defined(SPARC)
749ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman
754db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# define fpq kernel_fpq
764db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# define fq kernel_fq
774db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# define fpu kernel_fpu
784db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# include <asm/reg.h>
794db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# undef fpq
804db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# undef fq
814db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# undef fpu
829ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman
839ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#if !defined(__GLIBC__)
8476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
8576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <linux/unistd.h>
8676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
8776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define _hack_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\
8876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman          type5,arg5,syscall) \
8976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantype name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
9076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ \
9176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman      long __res; \
9276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman\
9376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman__asm__ volatile ("or %%g0, %1, %%o0\n\t" \
9476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %2, %%o1\n\t" \
9576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %3, %%o2\n\t" \
9676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %4, %%o3\n\t" \
9776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %5, %%o4\n\t" \
9876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %6, %%g1\n\t" \
9976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "t 0x10\n\t" \
10076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "bcc 1f\n\t" \
10176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %%o0, %0\n\t" \
10276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "sub %%g0, %%o0, %0\n\t" \
10376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "1:\n\t" \
10476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  : "=r" (__res) \
10576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  : "0" ((long)(arg1)),"1" ((long)(arg2)), \
10676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                    "2" ((long)(arg3)),"3" ((long)(arg4)),"4" ((long)(arg5)), \
10776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                    "i" (__NR_##syscall)  \
10876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  : "g1", "o0", "o1", "o2", "o3", "o4"); \
10976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanif (__res>=0) \
11076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman        return (type) __res; \
11176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerrno = -__res; \
11276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanreturn -1; \
11376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
11476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
11576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,int,__addr2,ptrace)
11676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
11776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define _ptrace
11876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
11976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1219ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif
1229ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman
12376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* macros */
12476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MAX
12576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MAX(a,b)		(((a) > (b)) ? (a) : (b))
12676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
12776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MIN
12876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MIN(a,b)		(((a) < (b)) ? (a) : (b))
12976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
13176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
13276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_tv(tv, a, b)
13376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv;
13476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint a;
13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint b;
13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a;
13876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = b;
13976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
14076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
14176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
14276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_nz(a)
14376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a;
14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
14576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return a->tv_sec || a->tv_usec;
14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
14876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
14976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_cmp(a, b)
15076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a, *b;
15176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
15276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (a->tv_sec < b->tv_sec
15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	    || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (a->tv_sec > b->tv_sec
15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	    || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
15776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 1;
15876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
15976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
16076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
16176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandouble
16276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_float(tv)
16376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv;
16476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
16576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return tv->tv_sec + tv->tv_usec/1000000.0;
16676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
16776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
16976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_add(tv, a, b)
17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b;
17176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
17276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec + b->tv_sec;
17376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = a->tv_usec + b->tv_usec;
17476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tv->tv_usec > 1000000) {
17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_sec++;
17676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_usec -= 1000000;
17776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
17876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
17976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
18076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
18176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_sub(tv, a, b)
18276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b;
18376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec - b->tv_sec;
18576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = a->tv_usec - b->tv_usec;
18676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (((long) tv->tv_usec) < 0) {
18776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_sec--;
18876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_usec += 1000000;
18976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
19076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
19176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
19276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
19376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_div(tv, a, n)
19476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a;
19576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n;
19676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
19876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec %= 1000000;
20076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
20176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
20276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
20376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_mul(tv, a, n)
20476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a;
20576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n;
20676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
20776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = a->tv_usec * n;
20876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec * n + a->tv_usec / 1000000;
20976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec %= 1000000;
21076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *
21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanxlookup(xlat, val)
21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat;
21576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint val;
21676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
21776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (; xlat->str != NULL; xlat++)
21876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val == val)
21976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return xlat->str;
22076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return NULL;
22176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
22276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
22376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
22476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Print entry in struct xlat table, if there.
22576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
22676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
22776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintxval(xlat, val, dflt)
22876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat;
22976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint val;
23076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *dflt;
23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *str = xlookup(xlat, val);
23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (str)
23576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s", str);
23676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else
23776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#x /* %s */", val, dflt);
23876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
23976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
24076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
24176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interpret `xlat' as an array of flags
24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * print the entries whose bits are on in `flags'
24376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * return # of flags printed.
24476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
24576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
24676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanaddflags(xlat, flags)
24776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat;
24876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags;
24976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
25076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
25176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
25276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (n = 0; xlat->str; xlat++) {
25376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val && (flags & xlat->val) == xlat->val) {
25476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("|%s", xlat->str);
25576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			flags &= ~xlat->val;
25676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			n++;
25776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
25876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
25976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (flags) {
26076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("|%#x", flags);
26176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n++;
26276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
26376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return n;
26476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
26576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
26676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
26776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintflags(xlat, flags)
26876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat;
26976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags;
27076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
27176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
27276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *sep;
27376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
27476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (flags == 0 && xlat->val == 0) {
27576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s", xlat->str);
27676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 1;
27776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
27876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
27976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	sep = "";
28076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (n = 0; xlat->str; xlat++) {
28176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val && (flags & xlat->val) == xlat->val) {
28276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%s%s", sep, xlat->str);
28376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			flags &= ~xlat->val;
28476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			sep = "|";
28576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			n++;
28676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
28776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
28876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (flags) {
28976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s%#x", sep, flags);
29076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n++;
29176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
29276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return n;
29376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
29476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
29576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
29676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintnum(tcp, addr, fmt)
29776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
29876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
29976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *fmt;
30076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
301eb285359906700f46b22cf4f9911695034313736Roland McGrath	long num;
30276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!addr) {
30476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("NULL");
30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
30676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
30776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umove(tcp, addr, &num) < 0) {
30876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#lx", addr);
30976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
31076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
31176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[");
31276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf(fmt, num);
31376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("]");
31476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
31576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
31676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic char path[MAXPATHLEN + 1];
31776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
31876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
31976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstring_quote(str)
32076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *str;
32176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
32276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char buf[2 * MAXPATHLEN + 1];
32376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *s;
32476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
32576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!strpbrk(str, "\"\'\\")) {
32676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("\"%s\"", str);
32776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
32876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
32976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (s = buf; *str; str++) {
33076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		switch (*str) {
33176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case '\"': case '\'': case '\\':
33276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			*s++ = '\\'; *s++ = *str; break;
33376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		default:
33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			*s++ = *str; break;
33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
33676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
33776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*s = '\0';
33876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("\"%s\"", buf);
33976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
34076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
34176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
34276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpath(tcp, addr)
34376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
34476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
34576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
34676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umovestr(tcp, addr, MAXPATHLEN, path) < 0)
34776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#lx", addr);
34876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else
34976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		string_quote(path);
35076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return;
35176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
35276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
35376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
35476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpathn(tcp, addr, n)
35576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
35676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
35776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n;
35876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
35976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umovestr(tcp, addr, n, path) < 0)
36076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#lx", addr);
36176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
36276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		path[n] = '\0';
36376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		string_quote(path);
36476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
36576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
36676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
36776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
36876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintstr(tcp, addr, len)
36976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
37076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
37176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
37276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
37376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static unsigned char *str = NULL;
37476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static char *outstr;
37576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i, n, c, usehex;
37676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *s, *outend;
37776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
37876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!addr) {
37976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("NULL");
38076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
38176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
38276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!str) {
38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if ((str = malloc(max_strlen)) == NULL
38476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		    || (outstr = malloc(2*max_strlen)) == NULL) {
38576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "printstr: no memory\n");
38676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%#lx", addr);
38776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
38876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
38976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
3902e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman	outend = outstr + max_strlen * 2 - 10;
39176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (len < 0) {
39276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = max_strlen;
39376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (umovestr(tcp, addr, n, (char *) str) < 0) {
39476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%#lx", addr);
39576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
39676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
39776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
39876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
39976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(len, max_strlen);
40076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (umoven(tcp, addr, n, (char *) str) < 0) {
40176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%#lx", addr);
40276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
40376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
40476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
40576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
40676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	usehex = 0;
40776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (xflag > 1)
40876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		usehex = 1;
40976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else if (xflag) {
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			if (!isprint(c) && !isspace(c)) {
41576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				usehex = 1;
41676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
41776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
41876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
41976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
42076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
42176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	s = outstr;
42276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*s++ = '\"';
42376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
42476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (usehex) {
42576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < n; i++) {
42676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			c = str[i];
42776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (len < 0 && c == '\0')
42876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
42976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			sprintf(s, "\\x%02x", c);
43076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			s += 4;
43176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (s > outend)
43276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
43376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
43476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
43576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
43676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < n; i++) {
43776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			c = str[i];
43876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (len < 0 && c == '\0')
43976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
44076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			switch (c) {
44176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\"': case '\'': case '\\':
44276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = c; break;
44376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\f':
44476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 'f'; break;
44576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\n':
44676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 'n'; break;
44776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\r':
44876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 'r'; break;
44976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\t':
45076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 't'; break;
45176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\v':
45276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 'v'; break;
45376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			default:
45476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				if (isprint(c))
45576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					*s++ = c;
45676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				else if (i < n - 1 && isdigit(str[i + 1])) {
45776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					sprintf(s, "\\%03o", c);
45876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					s += 4;
45976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				}
46076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				else {
46176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					sprintf(s, "\\%o", c);
46276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					s += strlen(s);
46376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				}
46476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
46576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
46676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (s > outend)
46776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
46876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
46976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
47076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
47176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*s++ = '\"';
47276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (i < len || (len < 0 && (i == n || s > outend))) {
47376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		*s++ = '.'; *s++ = '.'; *s++ = '.';
47476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
47576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*s = '\0';
47676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("%s", outstr);
47776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
47876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
4791d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H
4801d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesvoid
4811d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesdumpiov(tcp, len, addr)
4821d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesstruct tcb * tcp;
4831d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesint len;
4841d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hugheslong addr;
4851d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes{
4861d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	struct iovec *iov;
4871d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	int i;
4881d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes
4891e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath
4901d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	if ((iov = (struct iovec *) malloc(len * sizeof *iov)) == NULL) {
4911d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes		fprintf(stderr, "dump: No memory");
4921d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes		return;
4931d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	}
4941d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	if (umoven(tcp, addr,
4951d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes		   len * sizeof *iov, (char *) iov) >= 0) {
4961e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath
4971d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes		for (i = 0; i < len; i++) {
4981d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                        /* include the buffer number to make it easy to
4991d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                         * match up the trace with the source */
5001d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                        tprintf(" * %lu bytes in buffer %d\n",
5011d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                                (unsigned long)iov[i].iov_len, i);
5021d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                        dumpstr(tcp, (long) iov[i].iov_base,
5031d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                                iov[i].iov_len);
5041d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                }
5051d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	}
5061d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	free((char *) iov);
5071e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath
5081d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes}
5091d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif
5101d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes
51176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
51276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandumpstr(tcp, addr, len)
51376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
51476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
51576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
51676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
51776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static int strsize = -1;
51876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static unsigned char *str;
51976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static char outstr[80];
52076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *s;
52176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i, j;
52276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
52376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (strsize < len) {
52476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (str)
52576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			free(str);
52676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if ((str = malloc(len)) == NULL) {
52776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "dump: no memory\n");
52876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
52976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
53076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		strsize = len;
53176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
53276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
53376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umoven(tcp, addr, len, (char *) str) < 0)
53476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
53576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
53676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (i = 0; i < len; i += 16) {
53776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		s = outstr;
53876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		sprintf(s, " | %05x ", i);
53976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		s += 9;
54076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (j = 0; j < 16; j++) {
54176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (j == 8)
54276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
54376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (i + j < len) {
54476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				sprintf(s, " %02x", str[i + j]);
54576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				s += 3;
54676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
54776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			else {
54876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' '; *s++ = ' '; *s++ = ' ';
54976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
55076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
55176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		*s++ = ' '; *s++ = ' ';
55276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (j = 0; j < 16; j++) {
55376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (j == 8)
55476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
55576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (i + j < len) {
55676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				if (isprint(str[i + j]))
55776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					*s++ = str[i + j];
55876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				else
55976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					*s++ = '.';
56076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
56176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			else
56276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
56376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
56476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s |\n", outstr);
56576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
56676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
56776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
56876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PAGMASK	(~(PAGSIZ - 1))
56976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
57076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * move `len' bytes of data from process `pid'
57176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * at address `addr' to our space at `laddr'
57276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
57376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
57476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumoven(tcp, addr, len, laddr)
57576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
57676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
57776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
57876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
57976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
58076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
58176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
58276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
58376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n, m;
5845daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman	int started = 0;
58576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
58676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
58776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
58876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
58976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
59076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
59176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
59276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
59376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
59476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
59576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
59676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
5975daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			if (started && (errno==EPERM || errno==EIO)) {
59876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/* Ran into 'end of memory' - stupid "printpath" */
59976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
60076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
6015daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			/* But if not started, we had a bogus address. */
60276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("ptrace: umoven");
60376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
60476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
6055daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
60676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
60776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
60876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
60976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
61076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
61176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
61276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
6135daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			if (started && (errno==EPERM || errno==EIO)) {
61476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/* Ran into 'end of memory' - stupid "printpath" */
61576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
61676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
6174db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath			if (addr != 0)
6184db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath				perror("ptrace: umoven");
61976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
62076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
6215daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
62276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
62376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
62476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
62576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
62676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
62876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
62976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0
63076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n, m;
63176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
63276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
63376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
63476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
63576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
63676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
63776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
63876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
63976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
64076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
64176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
64276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
64376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umoven");
64476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
64576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
64676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
64776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
64876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
64976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
65076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
65176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
65276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
65376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umoven");
65476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
65576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
65676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
65776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
65876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
65976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !oldway */
66076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
66176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
66276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
66376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(len, PAGSIZ);
66476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
66576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (ptrace(PTRACE_READDATA, pid,
66676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			   (char *) addr, len, laddr) < 0) {
66776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umoven: ptrace(PTRACE_READDATA, ...)");
66876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			abort();
66976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
67076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
67176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		len -= n;
67276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += n;
67376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		laddr += n;
67476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
67576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !oldway */
67676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
67776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
678bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS
679ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS
680aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int fd = tcp->pfd_as;
6819ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else
682aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int fd = tcp->pfd;
68376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
684aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	lseek(fd, addr, SEEK_SET);
685aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	if (read(fd, laddr, len) == -1)
68676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
687bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */
68876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
68976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
69076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
69176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
69276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
69376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * like `umove' but make the additional effort of looking
69476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * for a terminating zero byte.
69576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
69676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
69776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumovestr(tcp, addr, len, laddr)
69876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
69976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
70076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
70176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
70276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
703bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS
704aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#ifdef HAVE_MP_PROCFS
705aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int fd = tcp->pfd_as;
706aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#else
707aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int fd = tcp->pfd;
708aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#endif
709aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	/* Some systems (e.g. FreeBSD) can be upset if we read off the
710aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   end of valid memory,  avoid this by trying to read up
711aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   to page boundaries.  But we don't know what a page is (and
712aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   getpagesize(2) (if it exists) doesn't necessarily return
713aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   hardware page size).  Assume all pages >= 1024 (a-historical
714aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   I know) */
715aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes
716aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int page = 1024; 	/* How to find this? */
717aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int move = page - (addr & (page - 1));
718aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int left = len;
719aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes
720aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	lseek(fd, addr, SEEK_SET);
721aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes
722aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	while (left) {
723aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		if (move > left) move = left;
7249cecf7f8d6115a247be7186013857270b2d588d5John Hughes		if ((move = read(fd, laddr, move)) <= 0)
725aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes			return left != len ? 0 : -1;
726aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		if (memchr (laddr, 0, move)) break;
727aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		left -= move;
728aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		laddr += move;
729aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		addr += move;
730aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		move = page;
731aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	}
732bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */
7335daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman	int started = 0;
73476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
73576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i, n, m;
73676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
73776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
73876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
73976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
74076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
74176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
74276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
74376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
74576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
7485daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			if (started && (errno==EPERM || errno==EIO)) {
74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/* Ran into 'end of memory' - stupid "printpath" */
75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
75176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
75276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umovestr");
75376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
7555daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
75676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len));
75776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		while (n & (sizeof(long) - 1))
75876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (u.x[n++] == '\0')
75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
76076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
76176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
76276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
76376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
76476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
76576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
7665daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			if (started && (errno==EPERM || errno==EIO)) {
76776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/* Ran into 'end of memory' - stupid "printpath" */
76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
77076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umovestr");
77176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
77276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
7735daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
77476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
77576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < sizeof(long); i++)
77676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (u.x[i] == '\0')
77776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
77876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
77976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
78076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
781bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */
782aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	return 0;
78376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
78476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
78576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
78676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SPARC
78776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITETEXT	101
78876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITEDATA	102
78976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !SPARC */
79076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
79176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
79276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
79376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
79476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int
79576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanuload(cmd, pid, addr, len, laddr)
79676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint cmd;
79776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
79876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
79976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
80076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
80176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
80276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0
80376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
80476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
80576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
80676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(len, PAGSIZ);
80776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
80876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) {
80976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("uload: ptrace(PTRACE_WRITE, ...)");
81076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
81176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
81276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		len -= n;
81376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += n;
81476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		laddr += n;
81576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
81676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else
81776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int peek, poke;
81876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n, m;
81976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
82076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
82176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
82276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
82376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
82476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (cmd == PTRACE_WRITETEXT) {
82576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		peek = PTRACE_PEEKTEXT;
82676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		poke = PTRACE_POKETEXT;
82776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
82876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
82976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		peek = PTRACE_PEEKDATA;
83076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		poke = PTRACE_POKEDATA;
83176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
83276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
83376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
83476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
83576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long);
83676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
83776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(peek, pid, (char *) addr, 0);
83876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
83976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("uload: POKE");
84076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
84176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
84276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len));
84376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (ptrace(poke, pid, (char *)addr, u.val) < 0) {
84476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("uload: POKE");
84576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
84676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
84776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
84876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
84976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
85076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (len < sizeof(long))
85176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			u.val = ptrace(peek, pid, (char *) addr, 0);
85276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(u.x, laddr, m = MIN(sizeof(long), len));
85376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (ptrace(poke, pid, (char *) addr, u.val) < 0) {
85476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("uload: POKE");
85576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
85676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
85776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
85876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
85976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
86076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
86176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
86276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
86376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
86476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantload(pid, addr, len, laddr)
86576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
86676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr, len;
86776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
86876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
86976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return uload(PTRACE_WRITETEXT, pid, addr, len, laddr);
87076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
87176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
87276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
87376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandload(pid, addr, len, laddr)
87476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
87576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr;
87676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
87776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
87876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
87976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return uload(PTRACE_WRITEDATA, pid, addr, len, laddr);
88076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
88176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
88276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
88376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
884bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS
88576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
88676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
88776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanupeek(pid, off, res)
88876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
88976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong off;
89076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong *res;
89176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
89276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long val;
89376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
89476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE
89576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	{
89676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		static int is_sun4m = -1;
89776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		struct utsname name;
89876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
89976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* Round up the usual suspects. */
90076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (is_sun4m == -1) {
90176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (uname(&name) < 0) {
90276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				perror("upeek: uname?");
90376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				exit(1);
90476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
90576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			is_sun4m = strcmp(name.machine, "sun4m") == 0;
90676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (is_sun4m) {
90776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				extern struct xlat struct_user_offsets[];
90876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				struct xlat *x;
90976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
91076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				for (x = struct_user_offsets; x->str; x++)
91176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					x->val += 1024;
91276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
91376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
91476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (is_sun4m)
91576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			off += 1024;
91676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
91776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
91876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
91976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	val = ptrace(PTRACE_PEEKUSER, pid, (char *) off, 0);
92076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (val == -1 && errno) {
9211e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath		char buf[60];
9220e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)",pid,off);
9231e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath		perror(buf);
92476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
92576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
92676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*res = val;
92776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
92876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
92976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
930bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */
93176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
93276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong
93376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetpc(tcp)
93476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
93576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
93676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
93776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
93876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
939f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#if defined(I386)
94076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*EIP, &pc) < 0)
94176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
9420e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined(X86_64)
9430e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	if (upeek(tcp->pid, 8*RIP, &pc) < 0)
9440e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		return -1;
9458b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#elif defined(IA64)
9468b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	if (upeek(tcp->pid, PT_B0, &pc) < 0)
9478b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		return -1;
948f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ARM)
94976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*15, &pc) < 0)
95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
951f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(POWERPC)
952eb285359906700f46b22cf4f9911695034313736Roland McGrath	if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0)
95376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
954f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(M68k)
95576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
95676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
957f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ALPHA)
95876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, REG_PC, &pc) < 0)
95976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
960f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS)
961f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman 	if (upeek(tcp->pid, REG_EPC, &pc) < 0)
962f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman 		return -1;
963f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(SPARC)
9649ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	struct regs regs;
96576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
96676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
9679ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	pc = regs.r_pc;
96810a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#elif defined(S390) || defined(S390X)
9694dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman	if(upeek(tcp->pid,PT_PSWADDR,&pc) < 0)
97010a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig		return -1;
971c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
972c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0)
973c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return -1;
974ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH)
975ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman       if (upeek(tcp->pid, 4*REG_PC ,&pc) < 0)
976ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman               return -1;
9777a0b649aeace5c1e1efe4a1d7b1ae6e3a87e0d44Wichert Akkerman#endif
97876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return pc;
97976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
98076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
98176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
98276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
98376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Return current program counter for `pid'
98476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Assumes PC is never 0xffffffff
98576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
98676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct regs regs;
98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
98976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("getpc: ptrace(PTRACE_GETREGS, ...)");
99076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return regs.r_pc;
99376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
99476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
99576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4
99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* XXX */
99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
99876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */
99976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1000bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD
1001bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	struct reg regs;
1002bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
1003bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	return regs.r_eip;
1004bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */
100576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
100676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
100776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
100876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintcall(tcp)
100976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
101076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
101176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
101276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
101376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386
101476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long eip;
101576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
101676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*EIP, &eip) < 0) {
101776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("[????????] ");
101876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
101976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
102076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", eip);
10210e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined(X86_64)
10220e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	long rip;
10230e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig
10240e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	if (upeek(tcp->pid, 8*RIP, &rip) < 0) {
10250e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		tprintf("[????????] ");
10260e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		return;
10270e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	}
10280e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	tprintf("[%16lx] ", rip);
1029faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(IA62)
10308b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	long ip;
10318b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
10328b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	if (upeek(tcp->pid, PT_B0, &ip) < 0) {
10338b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		tprintf("[????????] ");
10348b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		return;
10358b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	}
10368b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	tprintf("[%08lx] ", ip);
1037faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(POWERPC)
103876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
103976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1040eb285359906700f46b22cf4f9911695034313736Roland McGrath	if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) {
104176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf ("[????????] ");
104276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
104376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
104476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
1045faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68k)
104676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
104776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
104876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) {
104976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf ("[????????] ");
105076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
105176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
105276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
1053faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA)
105476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
105576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
105676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, REG_PC, &pc) < 0) {
105776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf ("[????????] ");
105876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
105976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
106076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
1061faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(SPARC)
10629ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	struct regs regs;
106376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0) {
106476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("[????????] ");
106576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
106676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
10679ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	tprintf("[%08lx] ", regs.r_pc);
1068c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
1069c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	long pc;
1070c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman
1071c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) {
1072c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		tprintf ("[????????] ");
1073c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return;
1074c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	}
1075c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	tprintf("[%08lx] ", pc);
107675c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman#elif defined(MIPS)
107775c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	long pc;
107875c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman
107975c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	if (upeek(tcp->pid, REG_EPC, &pc) < 0) {
108075c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman		tprintf ("[????????] ");
108175c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman		return;
108275c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	}
108375c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	tprintf("[%08lx] ", pc);
1084ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH)
1085ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman       long pc;
1086ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman
1087ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman       if (upeek(tcp->pid, 4*REG_PC, &pc) < 0) {
1088ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman               tprintf ("[????????] ");
1089ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman               return;
1090ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman       }
1091ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman       tprintf("[%08lx] ", pc);
1092faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* !architecture */
109376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
109476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
109576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
109676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct regs regs;
109776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
109876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
109976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("printcall: ptrace(PTRACE_GETREGS, ...)");
110076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("[????????] ");
110176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
110276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
110376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08x] ", regs.r_o7);
110476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
110576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
110676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4
110776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* XXX */
110876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[????????] ");
110976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
111076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1111bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD
1112bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	struct reg regs;
1113bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
1114bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	tprintf("[%08x] ", regs.r_eip);
1115bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */
111676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
111776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1118bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS
111976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1120d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#if defined LINUX
1121d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1122d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#include <sys/syscall.h>
1123d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifndef CLONE_PTRACE
1124d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define CLONE_PTRACE    0x00002000
1125d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif
1126d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1127d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef IA64
1128d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1129d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef unsigned long *arg_setup_state;
1130d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1131d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1132d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGratharg_setup(struct tcb *tcp, arg_setup_state *state)
1133d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1134d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	unsigned long *bsp, cfm, sof, sol;
1135d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1136d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) < 0)
1137d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return -1;
1138d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	if (upeek(tcp->pid, PT_CFM, (long *) &cfm) < 0)
1139d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return -1;
1140d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1141d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	sof = (cfm >> 0) & 0x7f;
1142d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	sol = (cfm >> 7) & 0x7f;
1143d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	bsp = ia64_rse_skip_regs(bsp, -sof + sol);
1144d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1145d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	*state = bsp;
1146d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return 0;
1147d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1148d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1149d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_finish_change(tcp, state)	0
1150d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1151d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef SYS_fork
1152d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1153d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathget_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp)
1154d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1155d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return umoven (tcp, (unsigned long) ia64_rse_skip_regs(*state, 0),
1156d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		       sizeof(long), (void *) valp);
1157d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1158d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1159d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1160d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathget_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp)
1161d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1162d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return umoven (tcp, (unsigned long) ia64_rse_skip_regs(*state, 1),
1163d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		       sizeof(long), (void *) valp);
1164d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1165d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif
1166d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1167d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1168d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg0 (struct tcb *tcp, arg_setup_state *state, long val)
1169d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1170d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	unsigned long *ap;
1171d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	ap = ia64_rse_skip_regs(*state, 0);
1172d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	errno = 0;
1173d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	ptrace(PTRACE_POKEDATA, tcp->pid, (void *) ap, val);
1174d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return errno ? -1 : 0;
1175d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1176d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1177d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1178d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg1 (struct tcb *tcp, arg_setup_state *state, long val)
1179d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1180d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	unsigned long *ap;
1181d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	ap = ia64_rse_skip_regs(*state, 1);
1182d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	errno = 0;
1183d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	ptrace(PTRACE_POKEDATA, tcp->pid, (void *) ap, val);
1184d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return errno ? -1 : 0;
1185d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1186d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1187d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#elif defined (SPARC)
1188d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1189d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef struct regs arg_setup_state;
1190d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1191d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_setup(tcp, state) \
1192d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath  (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0))
1193d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_finish_change(tcp, state) \
1194d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath  (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0))
1195d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1196d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0)
1197d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0)
1198d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define set_arg0(tcp, state, val) ((state)->r_o0 = (val), 0)
1199d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define set_arg1(tcp, state, val) ((state)->r_o1 = (val), 0)
1200e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg0(tcp, state, val) 0
1201d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1202d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#else
1203d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1204d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# if defined S390 || defined S390X
12057b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath/* Note: this is only true for the `clone' system call, which handles
12067b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath   arguments specially.  We could as well say that its first two arguments
12077b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath   are swapped relative to other architectures, but that would just be
12087b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath   another #ifdef in the calls.  */
12097b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath#  define arg0_offset	PT_GPR3
12107b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath#  define arg1_offset	PT_ORIGGPR2
12117b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath#  define restore_arg0(tcp, state, val) ((void) (state), 0)
12127b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath#  define restore_arg1(tcp, state, val) ((void) (state), 0)
1213d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# elif defined (ALPHA) || defined (MIPS)
1214d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#  define arg0_offset	REG_A0
1215d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#  define arg1_offset	(REG_A0+1)
1216d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# elif defined (POWERPC)
1217eb285359906700f46b22cf4f9911695034313736Roland McGrath#  define arg0_offset	(sizeof(unsigned long)*PT_R3)
1218eb285359906700f46b22cf4f9911695034313736Roland McGrath#  define arg1_offset	(sizeof(unsigned long)*PT_R4)
12197b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath#  define restore_arg0(tcp, state, val) ((void) (state), 0)
1220d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# elif defined (HPPA)
1221d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#  define arg0_offset	 PT_GR26
1222d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#  define arg1_offset	 (PT_GR26-4)
12237f33cc3eb5ead7a79cae8c586e40d2f8b573eec1Roland McGrath# elif defined (X86_64)
12247f33cc3eb5ead7a79cae8c586e40d2f8b573eec1Roland McGrath#  define arg0_offset	((long)(8*(current_personality ? RBX : RDI)))
12257f33cc3eb5ead7a79cae8c586e40d2f8b573eec1Roland McGrath#  define arg1_offset	((long)(8*(current_personality ? RCX : RSI)))
1226ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath# elif defined (SH)
1227ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath#  define arg0_offset	(4*(REG_REG0+4))
1228ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath#  define arg1_offset	(4*(REG_REG0+5))
1229d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# else
1230d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#  define arg0_offset	0
1231d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#  define arg1_offset	4
1232ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath#  if defined ARM
1233e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#   define restore_arg0(tcp, state, val) 0
1234e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#  endif
1235d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# endif
1236d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1237d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef int arg_setup_state;
1238d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1239d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_setup(tcp, state) (0)
1240d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_finish_change(tcp, state)	0
1241d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg0(tcp, cookie, valp) \
1242d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath  (upeek ((tcp)->pid, arg0_offset, (valp)))
1243d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg1(tcp, cookie, valp) \
1244d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath  (upeek ((tcp)->pid, arg1_offset, (valp)))
1245d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1246d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1247d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg0 (struct tcb *tcp, void *cookie, long val)
1248d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1249d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val);
1250d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1251d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1252d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1253d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg1 (struct tcb *tcp, void *cookie, long val)
1254d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1255d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val);
1256d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1257d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1258d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif
1259d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1260e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#ifndef restore_arg0
1261e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val))
1262e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#endif
1263e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#ifndef restore_arg1
1264e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val))
1265e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#endif
1266d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1267d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint
1268d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathsetbpt(tcp)
1269d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstruct tcb *tcp;
1270d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1271d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	extern int change_syscall(struct tcb *, int);
1272d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	arg_setup_state state;
1273d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1274d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	if (tcp->flags & TCB_BPTSET) {
1275d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1276d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return -1;
1277d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	}
1278d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1279d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	switch (tcp->scno) {
12809383c6c539af09303efe0a16dea55363b095f66eRoland McGrath#ifdef SYS_vfork
12819383c6c539af09303efe0a16dea55363b095f66eRoland McGrath	case SYS_vfork:
12829383c6c539af09303efe0a16dea55363b095f66eRoland McGrath#endif
1283d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef SYS_fork
1284d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	case SYS_fork:
12859b0982b5d3b84c845192ad8b7ad822f81cf4743aRoland McGrath#endif
12869b0982b5d3b84c845192ad8b7ad822f81cf4743aRoland McGrath#if defined SYS_fork || defined SYS_vfork
1287d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		if (arg_setup (tcp, &state) < 0
1288d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || get_arg0 (tcp, &state, &tcp->inst[0]) < 0
1289d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || get_arg1 (tcp, &state, &tcp->inst[1]) < 0
1290d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || change_syscall(tcp, SYS_clone) < 0
1291d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0
1292d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || set_arg1 (tcp, &state, 0) < 0
1293d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || arg_finish_change (tcp, &state) < 0)
1294d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath			return -1;
1295d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		tcp->u_arg[0] = CLONE_PTRACE|SIGCHLD;
1296d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		tcp->u_arg[1] = 0;
1297d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		tcp->flags |= TCB_BPTSET;
1298d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return 0;
1299d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif
1300d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1301d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	case SYS_clone:
1302d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef SYS_clone2
1303d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	case SYS_clone2:
1304d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif
1305d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		if ((tcp->u_arg[0] & CLONE_PTRACE) == 0
1306d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    && (arg_setup (tcp, &state) < 0
1307d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath			|| set_arg0 (tcp, &state, tcp->u_arg[0] | CLONE_PTRACE) < 0
1308d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath			|| arg_finish_change (tcp, &state) < 0))
1309d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath			return -1;
1310d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		tcp->flags |= TCB_BPTSET;
1311d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		tcp->inst[0] = tcp->u_arg[0];
1312d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		tcp->inst[1] = tcp->u_arg[1];
1313d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return 0;
1314d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1315d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	default:
1316d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n",
1317d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath			tcp->scno, tcp->pid);
1318d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		break;
1319d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	}
1320d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1321d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return -1;
1322d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1323d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1324d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint
1325d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathclearbpt(tcp)
1326d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstruct tcb *tcp;
1327d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1328d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	arg_setup_state state;
1329d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	if (arg_setup (tcp, &state) < 0
1330e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath	    || restore_arg0 (tcp, &state, tcp->inst[0]) < 0
1331e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath	    || restore_arg1 (tcp, &state, tcp->inst[1]) < 0
1332d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	    || arg_finish_change (tcp, &state))
1333d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return -1;
1334d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	tcp->flags &= ~TCB_BPTSET;
1335d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return 0;
1336d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1337d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1338d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#else
1339d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
134076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
134176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermansetbpt(tcp)
134276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
134376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
134476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
134576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
134676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC
134776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* We simply use the SunOS breakpoint code. */
134876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
13499ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	struct regs regs;
135076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA	0x30800000	/* ba,a	0 */
135176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
135276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tcp->flags & TCB_BPTSET) {
135376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
135476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
135576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
135676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
135776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
135876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
135976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
13609ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	tcp->baddr = regs.r_o7 + 8;
136176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
136276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0);
136376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if(errno) {
136476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
136576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
136676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
136776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
136876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
136976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * XXX - BRUTAL MODE ON
137076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * We cannot set a real BPT in the child, since it will not be
137176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * traced at the moment it will reach the trap and would probably
137276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * die with a core dump.
137376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Thus, we are force our way in by taking out two instructions
137476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * and insert an eternal loop instead, in expectance of the SIGSTOP
137576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * generated by out PTRACE_ATTACH.
137676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Of cause, if we evaporate ourselves in the middle of all this...
137776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
137876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
137976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOPA);
138076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if(errno) {
138176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
138276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
138376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
138476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags |= TCB_BPTSET;
138576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
138676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !SPARC */
13878b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#ifdef IA64
13887b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman	if (ia32) {
13897b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#		define LOOP	0x0000feeb
13907b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (tcp->flags & TCB_BPTSET) {
13917b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			fprintf(stderr, "PANIC: bpt already set in pid %u\n",
13927b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				tcp->pid);
13937b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
13947b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
13957b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (upeek(tcp->pid, PT_CR_IIP, &tcp->baddr) < 0)
13967b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
13977b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (debug)
13987b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			fprintf(stderr, "[%d] setting bpt at %lx\n",
13997b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				tcp->pid, tcp->baddr);
14007b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid,
14017b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				      (char *) tcp->baddr, 0);
14027b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (errno) {
14037b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
14047b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
14057b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
14067b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
14077b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (errno) {
14087b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
14097b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
14107b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
14117b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->flags |= TCB_BPTSET;
14127b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman	} else {
14137b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		/*
14147b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * Our strategy here is to replace the bundle that
14157b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * contained the clone() syscall with a bundle of the
14167b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * form:
14177b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 *
14187b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 *	{ 1: br 1b; br 1b; br 1b }
14197b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 *
14207b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * This ensures that the newly forked child will loop
14217b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * endlessly until we've got a chance to attach to it.
14227b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 */
14238b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#		define LOOP0	0x0000100000000017
14248b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#		define LOOP1	0x4000000000200000
14258b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		unsigned long addr, ipsr;
14268b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		pid_t pid;
14278b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
14288b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		pid = tcp->pid;
14298b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (upeek(pid, PT_CR_IPSR, &ipsr) < 0)
14308b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
14318b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (upeek(pid, PT_CR_IIP, &addr) < 0)
14328b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
14337b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		/* store "ri" in low two bits */
14347b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->baddr = addr | ((ipsr >> 41) & 0x3);
14358b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
14368b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		errno = 0;
14377b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0,
14387b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				      0);
14397b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8,
14407b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				      0);
14418b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (errno) {
14428b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
14438b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
14448b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
14458b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
14468b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		errno = 0;
14478b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0);
14488b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1);
14498b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (errno) {
14508b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
14518b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
14528b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
14538b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		tcp->flags |= TCB_BPTSET;
14548b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	}
14558b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#else /* !IA64 */
145676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
14570e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#if defined (I386) || defined(X86_64)
145876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP	0x0000feeb
145976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K)
146076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP	0x60fe0000
146176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA)
14624dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP	0xc3ffffff
146376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC)
14641e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath#define LOOP	0x48000000
146576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined(ARM)
14669a8a37f2b28d1c0d3f57951fd5aeeb96ff7d2f16Wichert Akkerman#define LOOP	0xEAFFFFFE
1467f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS)
14684dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP	0x1000ffff
14694dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390)
14704dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP	0xa7f40000	/* BRC 15,0 */
147110a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#elif defined(S390X)
147210a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#define LOOP   0xa7f4000000000000UL /* BRC 15,0 */
1473c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
1474c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#define LOOP	0xe81f1ff7	/* b,l,n <loc>,r0 */
1475ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH)
1476ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#ifdef __LITTLE_ENDIAN__
1477ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#define LOOP   0x0000affe
1478ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#else
1479ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#define LOOP   0xfeaf0000
1480ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#endif
148176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else
148276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture
148376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
148476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
148576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tcp->flags & TCB_BPTSET) {
148676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid);
148776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
148876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
148976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined (I386)
149076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*EIP, &tcp->baddr) < 0)
149176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
14920e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined (X86_64)
14930e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	if (upeek(tcp->pid, 8*RIP, &tcp->baddr) < 0)
14940e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		return -1;
149576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K)
149676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_PC, &tcp->baddr) < 0)
149776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	  return -1;
149876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA)
149976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return -1;
150076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ARM)
150176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return -1;
1502f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined (MIPS)
1503f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman	return -1;		/* FIXME: I do not know what i do - Flo */
150476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC)
1505eb285359906700f46b22cf4f9911695034313736Roland McGrath	if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &tcp->baddr) < 0)
150676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
150710a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#elif defined(S390) || defined(S390X)
15084dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman	if (upeek(tcp->pid,PT_PSWADDR, &tcp->baddr) < 0)
15094dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman		return -1;
1510c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
1511c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	if (upeek(tcp->pid, PT_IAOQ0, &tcp->baddr) < 0)
1512c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return -1;
1513c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	tcp->baddr &= ~0x03;
1514ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH)
1515ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman       if (upeek(tcp->pid, 4*REG_PC, &tcp->baddr) < 0)
1516ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman               return -1;
151776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else
151876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture
151976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
152076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (debug)
152176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr);
152276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0);
152376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (errno) {
152476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
152576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
152676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
152776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
152876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (errno) {
152976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
153076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
153176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
153276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags |= TCB_BPTSET;
153376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
15348b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#endif /* !IA64 */
153576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */
153676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
153776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
153876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
153976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC	/* This code is slightly sparc specific */
154076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1541e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman	struct regs regs;
154276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define BPT	0x91d02001	/* ta	1 */
154376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP	0x10800000	/* ba	0 */
154476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA	0x30800000	/* ba,a	0 */
154576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define NOP	0x01000000
154676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if LOOPA
154776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static int loopdeloop[1] = {LOOPA};
154876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else
154976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static int loopdeloop[2] = {LOOP, NOP};
155076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
155176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
155276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tcp->flags & TCB_BPTSET) {
155376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
155476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
155576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
155676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
155776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
155876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
155976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
156076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->baddr = regs.r_o7 + 8;
156176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr,
156276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				sizeof tcp->inst, (char *)tcp->inst) < 0) {
156376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_READTEXT, ...)");
156476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
156576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
156676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
156776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
156876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * XXX - BRUTAL MODE ON
156976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * We cannot set a real BPT in the child, since it will not be
157076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * traced at the moment it will reach the trap and would probably
157176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * die with a core dump.
157276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Thus, we are force our way in by taking out two instructions
157376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * and insert an eternal loop in stead, in expectance of the SIGSTOP
157476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * generated by out PTRACE_ATTACH.
157576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Of cause, if we evaporate ourselves in the middle of all this...
157676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
157776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
157876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			sizeof loopdeloop, (char *) loopdeloop) < 0) {
157976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)");
158076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
158176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
158276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags |= TCB_BPTSET;
158376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
158476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */
158576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
158676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
158776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
158876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
158976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
159076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
159176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanclearbpt(tcp)
159276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
159376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
159476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
159576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
15960e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#if defined(I386) || defined(X86_64)
159776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long eip;
1598faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(POWERPC)
159976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
1600faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68K)
160176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
1602faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA)
160376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
1604c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
1605c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	long iaoq;
1606ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH)
1607ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman       long pc;
1608faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* architecture */
160976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
161076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC
161176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* Again, we borrow the SunOS breakpoint code. */
161276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!(tcp->flags & TCB_BPTSET)) {
161376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
161476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
161576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
161676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
161776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
161876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if(errno) {
161976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
162076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
162176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
162276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags &= ~TCB_BPTSET;
1623faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(IA64)
16247b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman	if (ia32) {
16257b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		unsigned long addr;
16267b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman
16277b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (debug)
16287b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
16297b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (!(tcp->flags & TCB_BPTSET)) {
16307b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
16317b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
16327b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
16337b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		errno = 0;
16347b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
16357b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (errno) {
16367b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
16377b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
16387b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
16397b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->flags &= ~TCB_BPTSET;
16407b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman
16417b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (upeek(tcp->pid, PT_CR_IIP, &addr) < 0)
16427b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
16437b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (addr != tcp->baddr) {
16447b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			/* The breakpoint has not been reached yet.  */
16457b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			if (debug)
16467b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				fprintf(stderr,
16477b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman					"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
16487b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman						addr, tcp->baddr);
16497b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return 0;
16507b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
16517b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman	} else {
16528b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		unsigned long addr, ipsr;
16538b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		pid_t pid;
16548b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
16558b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		pid = tcp->pid;
16568b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
16578b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (upeek(pid, PT_CR_IPSR, &ipsr) < 0)
16588b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
16598b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (upeek(pid, PT_CR_IIP, &addr) < 0)
16608b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
16618b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
16628b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		/* restore original bundle: */
16638b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		errno = 0;
16648b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]);
16658b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]);
16668b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (errno) {
16678b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)");
16688b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
16698b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
16708b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
16718b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		/* restore original "ri" in ipsr: */
16728b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41);
16738b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		errno = 0;
16748b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr);
16758b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (errno) {
16768b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)");
16778b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
16788b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
16798b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
16808b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		tcp->flags &= ~TCB_BPTSET;
16818b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
16828b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (addr != (tcp->baddr & ~0x3)) {
16838b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			/* the breakpoint has not been reached yet.  */
16848b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			if (debug)
16858b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman				fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
16868b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman					addr, tcp->baddr);
16878b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return 0;
16888b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
16898b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	}
1690faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#else /* !IA64  && ! SPARC */
169176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
169276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (debug)
169376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
169476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!(tcp->flags & TCB_BPTSET)) {
169576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
169676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
169776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
169876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
169976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
170076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (errno) {
170176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
170276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
170376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
170476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags &= ~TCB_BPTSET;
170576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
170676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386
170776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*EIP, &eip) < 0)
170876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
170976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (eip != tcp->baddr) {
171076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
171176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
171276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr,
171376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
171476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					eip, tcp->baddr);
171576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
171676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
17170e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined(X86_64)
17180e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	if (upeek(tcp->pid, 8*RIP, &eip) < 0)
17190e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		return -1;
17200e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	if (eip != tcp->baddr) {
17210e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		/* The breakpoint has not been reached yet.  */
17220e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		if (debug)
17230e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig			fprintf(stderr,
17240e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig				"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
17250e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig					eip, tcp->baddr);
17260e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		return 0;
17270e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	}
1728c792698a99b640e7d256e8692c992bd967f0c5b2Wichert Akkerman#elif defined(POWERPC)
1729eb285359906700f46b22cf4f9911695034313736Roland McGrath	if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0)
173076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
173176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (pc != tcp->baddr) {
173276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
173476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
173576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				pc, tcp->baddr);
173676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
173776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
1738faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68K)
173976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
174076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
174176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (pc != tcp->baddr) {
174276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
174376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
174476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
174576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				pc, tcp->baddr);
174676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
174776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
1748faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA)
174976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, REG_PC, &pc) < 0)
175076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
175176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (pc != tcp->baddr) {
175276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
175376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
175476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
175576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				pc, tcp->baddr);
175676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
175776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
1758c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
1759c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	if (upeek(tcp->pid, PT_IAOQ0, &iaoq) < 0)
1760c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return -1;
1761c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	iaoq &= ~0x03;
1762c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) {
1763c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		/* The breakpoint has not been reached yet.  */
1764c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		if (debug)
1765c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n",
1766c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman				iaoq, tcp->baddr);
1767c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return 0;
1768c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	}
1769c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	iaoq = tcp->baddr | 3;
1770c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	/* We should be pointing at a 'ldi -1000,r1' in glibc, so it is
1771c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	 * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit
1772c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	 * has no significant effect.
1773c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	 */
1774c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq);
1775c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq);
1776ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH)
1777ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman       if (upeek(tcp->pid, 4*REG_PC, &pc) < 0)
1778ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman               return -1;
1779ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman        if (pc != tcp->baddr) {
1780ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman                /* The breakpoint has not been reached yet.  */
1781ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman                if (debug)
1782ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman                        fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1783ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman                                pc, tcp->baddr);
1784ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman                return 0;
1785ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman        }
1786ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman
1787faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* arch */
1788faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* !SPARC && !IA64 */
178976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
179076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
179176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
179276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC
179376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
179476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA
1795e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman	struct regs regs;
179676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
179776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
179876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!(tcp->flags & TCB_BPTSET)) {
179976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
180076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
180176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
180276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
180376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				sizeof tcp->inst, (char *) tcp->inst) < 0) {
180476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)");
180576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
180676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
180776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags &= ~TCB_BPTSET;
180876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
180976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA
181076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
181176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Since we don't have a single instruction breakpoint, we may have
181276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * to adjust the program counter after removing the our `breakpoint'.
181376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
181476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
181576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbpt: ptrace(PTRACE_GETREGS, ...)");
181676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
181776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
181876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if ((regs.r_pc < tcp->baddr) ||
181976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				(regs.r_pc > tcp->baddr + 4)) {
182076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet */
182176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
182276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr,
182376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				"NOTE: PC not at bpt (pc %#x baddr %#x)\n",
182476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					regs.r_pc, tcp->parent->baddr);
182576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
182676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
182776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (regs.r_pc != tcp->baddr)
182876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
182976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n",
183076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				regs.r_pc, tcp->baddr);
183176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
183276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	regs.r_pc = tcp->baddr;
183376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0) {
183476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbpt: ptrace(PTRACE_SETREGS, ...)");
183576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
183676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
183776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LOOPA */
183876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */
183976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
184076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
184176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
184276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
184376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1844d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif
1845d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1846bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */
184776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
184876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
184976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
185076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int
185176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetex(pid, hdr)
185276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
185376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct exec *hdr;
185476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
185576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
185676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
185776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (n = 0; n < sizeof *hdr; n += 4) {
185876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long res;
185976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (upeek(pid, uoff(u_exdata) + n, &res) < 0)
186076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
186176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(((char *) hdr) + n, &res, 4);
186276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
186376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (debug) {
186476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n",
186576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			hdr->a_magic, hdr->a_toolversion, hdr->a_machtype);
186676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n",
186776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry);
186876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
186976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
187076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
187176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
187276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
187376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfixvfork(tcp)
187476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
187576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
187676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
187776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
187876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Change `vfork' in a freshly exec'ed dynamically linked
187976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * executable's (internal) symbol table to plain old `fork'
188076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
188176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
188276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct exec hdr;
188376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct link_dynamic dyn;
188476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct link_dynamic_2 ld;
188576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *strtab, *cp;
188676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
188776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (getex(pid, &hdr) < 0)
188876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
188976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!hdr.a_dynamic)
189076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
189176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
189276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) {
189376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "Cannot read DYNAMIC\n");
189476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
189576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
189676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) {
189776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "Cannot read link_dynamic_2\n");
189876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
189976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
190076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) {
190176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "fixvfork: out of memory\n");
190276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
190376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
190476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
190576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					(int)ld.ld_symb_size, strtab) < 0)
190676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		goto err;
190776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
190876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0
190976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
191076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[symbol: %s]\n", cp);
191176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		cp += strlen(cp)+1;
191276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
191376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
191476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
191576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
191676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (strcmp(cp, "_vfork") == 0) {
191776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (debug)
191876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				fprintf(stderr, "fixvfork: FOUND _vfork\n");
191976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			strcpy(cp, "_fork");
192076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
192176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
192276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		cp += strlen(cp)+1;
192376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
192476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (cp < strtab + ld.ld_symb_size)
192576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/*
192676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		 * Write entire symbol table back to avoid
192776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		 * memory alignment bugs in ptrace
192876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		 */
192976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
193076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					(int)ld.ld_symb_size, strtab) < 0)
193176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			goto err;
193276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
193376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	free(strtab);
193476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
193576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
193676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerr:
193776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	free(strtab);
193876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return -1;
193976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
194076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
194176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
1942