util.c revision b15c4e47ff5b2b0dd71fa10472eafb1d5abf4c5f
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
66ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# ifdef HAVE_STRUCT_IA64_FPREG
67ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath#  define ia64_fpreg XXX_ia64_fpreg
68ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# endif
69ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# ifdef HAVE_STRUCT_PT_ALL_USER_REGS
70ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath#  define pt_all_user_regs XXX_pt_all_user_regs
71ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# endif
72faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#include <linux/ptrace.h>
73ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# undef ia64_fpreg
74ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# undef pt_all_user_regs
752e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#endif
762e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman
7776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE
7876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/utsname.h>
7976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
8076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
816d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if defined(LINUXSPARC)
829ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman
834db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# define fpq kernel_fpq
844db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# define fq kernel_fq
854db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# define fpu kernel_fpu
864db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# include <asm/reg.h>
874db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# undef fpq
884db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# undef fq
894db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# undef fpu
909ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman
916d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if defined (SPARC64)
926d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# define r_pc r_tpc
936d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# undef PTRACE_GETREGS
946d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# define PTRACE_GETREGS PTRACE_GETREGS64
956d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# undef PTRACE_SETREGS
966d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# define PTRACE_SETREGS PTRACE_SETREGS64
976d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#endif /* SPARC64 */
986d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath
999ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#if !defined(__GLIBC__)
10076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
10176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <linux/unistd.h>
10276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
10376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define _hack_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\
10476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman          type5,arg5,syscall) \
10576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantype name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
10676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ \
10776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman      long __res; \
10876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman\
10976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman__asm__ volatile ("or %%g0, %1, %%o0\n\t" \
11076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %2, %%o1\n\t" \
11176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %3, %%o2\n\t" \
11276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %4, %%o3\n\t" \
11376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %5, %%o4\n\t" \
11476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %6, %%g1\n\t" \
1156d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if defined (SPARC64)
1166d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath                  "t 0x6d\n\t" \
1176d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#else
11876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "t 0x10\n\t" \
1196d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#endif
12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "bcc 1f\n\t" \
12176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "or %%g0, %%o0, %0\n\t" \
12276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "sub %%g0, %%o0, %0\n\t" \
12376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  "1:\n\t" \
12476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  : "=r" (__res) \
12576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  : "0" ((long)(arg1)),"1" ((long)(arg2)), \
12676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                    "2" ((long)(arg3)),"3" ((long)(arg4)),"4" ((long)(arg5)), \
12776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                    "i" (__NR_##syscall)  \
12876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman                  : "g1", "o0", "o1", "o2", "o3", "o4"); \
12976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanif (__res>=0) \
13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman        return (type) __res; \
13176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerrno = -__res; \
13276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanreturn -1; \
13376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
13476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,int,__addr2,ptrace)
13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define _ptrace
13876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
13976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
14076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1419ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif
1429ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman
14376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* macros */
14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MAX
14576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MAX(a,b)		(((a) > (b)) ? (a) : (b))
14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MIN
14876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MIN(a,b)		(((a) < (b)) ? (a) : (b))
14976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
15076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
151a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrath#if 0
15276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_tv(tv, a, b)
15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv;
15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint a;
15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint b;
15776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
15876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a;
15976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = b;
16076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
161a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrath#endif
16276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
16376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
16476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_nz(a)
16576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a;
16676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
16776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return a->tv_sec || a->tv_usec;
16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
16976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
17176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_cmp(a, b)
17276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a, *b;
17376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
17476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (a->tv_sec < b->tv_sec
17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	    || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
17676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
17776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (a->tv_sec > b->tv_sec
17876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	    || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
17976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 1;
18076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
18176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
18276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
18376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandouble
18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_float(tv)
18576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv;
18676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
18776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return tv->tv_sec + tv->tv_usec/1000000.0;
18876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
18976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
19076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
19176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_add(tv, a, b)
19276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b;
19376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
19476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec + b->tv_sec;
19576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = a->tv_usec + b->tv_usec;
19676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tv->tv_usec > 1000000) {
19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_sec++;
19876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_usec -= 1000000;
19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
20076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
20176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
20276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
20376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_sub(tv, a, b)
20476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b;
20576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
20676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec - b->tv_sec;
20776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = a->tv_usec - b->tv_usec;
20876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (((long) tv->tv_usec) < 0) {
20976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_sec--;
21076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_usec += 1000000;
21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
21576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_div(tv, a, n)
21676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a;
21776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n;
21876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
21976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
22076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
22176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec %= 1000000;
22276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
22376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
22476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
22576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_mul(tv, a, n)
22676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a;
22776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n;
22876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
22976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = a->tv_usec * n;
23076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec * n + a->tv_usec / 1000000;
23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec %= 1000000;
23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *
23576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanxlookup(xlat, val)
236d9f816f60457930af27349fac3d23b3b78338036Roland McGrathconst struct xlat *xlat;
23776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint val;
23876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
23976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (; xlat->str != NULL; xlat++)
24076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val == val)
24176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return xlat->str;
24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return NULL;
24376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
24476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
24576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
24676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Print entry in struct xlat table, if there.
24776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
24876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
24976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintxval(xlat, val, dflt)
250d9f816f60457930af27349fac3d23b3b78338036Roland McGrathconst struct xlat *xlat;
25176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint val;
252b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrathconst char *dflt;
25376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
25476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *str = xlookup(xlat, val);
25576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
25676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (str)
25776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s", str);
25876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else
25976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#x /* %s */", val, dflt);
26076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
26176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
26276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
26376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interpret `xlat' as an array of flags
26476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * print the entries whose bits are on in `flags'
26576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * return # of flags printed.
26676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
26776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
26876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanaddflags(xlat, flags)
269d9f816f60457930af27349fac3d23b3b78338036Roland McGrathconst struct xlat *xlat;
27076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags;
27176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
27276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
27376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
27476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (n = 0; xlat->str; xlat++) {
27576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val && (flags & xlat->val) == xlat->val) {
27676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("|%s", xlat->str);
27776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			flags &= ~xlat->val;
27876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			n++;
27976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
28076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
28176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (flags) {
28276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("|%#x", flags);
28376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n++;
28476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
28576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return n;
28676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
28776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
28876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
289b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrathprintflags(xlat, flags, dflt)
290d9f816f60457930af27349fac3d23b3b78338036Roland McGrathconst struct xlat *xlat;
29176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags;
292b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrathconst char *dflt;
29376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
29476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
29576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *sep;
29676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
29776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (flags == 0 && xlat->val == 0) {
29876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s", xlat->str);
29976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 1;
30076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
30176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
30276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	sep = "";
30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (n = 0; xlat->str; xlat++) {
30476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val && (flags & xlat->val) == xlat->val) {
30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%s%s", sep, xlat->str);
30676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			flags &= ~xlat->val;
30776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			sep = "|";
30876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			n++;
30976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
31076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
311b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath
312b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath	if (n) {
313b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath		if (flags) {
314b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath			tprintf("%s%#x", sep, flags);
315b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath			n++;
316b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath		}
317b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath	} else {
318b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath		if (flags) {
319b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath			tprintf("%#x", flags);
320b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath			if (dflt)
321b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath				tprintf(" /* %s */", dflt);
322b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath		} else {
323b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath			if (dflt)
324b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath				tprintf("0");
325b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath		}
32676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
327b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath
32876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return n;
32976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
33076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
33176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
33276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintnum(tcp, addr, fmt)
33376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *fmt;
33676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
337eb285359906700f46b22cf4f9911695034313736Roland McGrath	long num;
33876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
33976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!addr) {
34076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("NULL");
34176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
34276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
34376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umove(tcp, addr, &num) < 0) {
34476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#lx", addr);
34576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
34676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
34776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[");
34876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf(fmt, num);
34976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("]");
35076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
35176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
3526bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathvoid
3539814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathprintnum_int(tcp, addr, fmt)
3549814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathstruct tcb *tcp;
3559814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathlong addr;
3569814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathchar *fmt;
3579814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath{
3589814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	int num;
3599814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath
3609814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	if (!addr) {
3619814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath		tprintf("NULL");
3629814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath		return;
3639814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	}
3649814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	if (umove(tcp, addr, &num) < 0) {
3659814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath		tprintf("%#lx", addr);
3669814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath		return;
3679814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	}
3689814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	tprintf("[");
3699814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	tprintf(fmt, num);
3709814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	tprintf("]");
3719814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath}
3729814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath
3739814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathvoid
3746bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathprintuid(text, uid)
3756bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathconst char *text;
3766bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathunsigned long uid;
3776bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath{
3786bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath	tprintf("%s", text);
3796bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath	tprintf((uid == -1) ? "%ld" : "%lu", uid);
3806bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath}
3816bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath
38276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic char path[MAXPATHLEN + 1];
38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
384a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrathstatic void
38576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstring_quote(str)
386a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrathconst char *str;
38776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
38876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char buf[2 * MAXPATHLEN + 1];
38976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *s;
39076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
39176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!strpbrk(str, "\"\'\\")) {
39276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("\"%s\"", str);
39376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
39476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
39576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (s = buf; *str; str++) {
39676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		switch (*str) {
39776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case '\"': case '\'': case '\\':
39876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			*s++ = '\\'; *s++ = *str; break;
39976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		default:
40076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			*s++ = *str; break;
40176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
40276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
40376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*s = '\0';
40476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("\"%s\"", buf);
40576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
40676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
40776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
40876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpath(tcp, addr)
40976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
41076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
41176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
412371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath	if (addr == 0)
413371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath		tprintf("NULL");
414371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath	else if (umovestr(tcp, addr, MAXPATHLEN, path) < 0)
41576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#lx", addr);
41676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else
41776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		string_quote(path);
41876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return;
41976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
42076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
42176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
42276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpathn(tcp, addr, n)
42376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
42476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
42576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n;
42676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
427b15c4e47ff5b2b0dd71fa10472eafb1d5abf4c5fRoland McGrath	if (n >= sizeof path)
428b15c4e47ff5b2b0dd71fa10472eafb1d5abf4c5fRoland McGrath		n = sizeof path - 1;
429b15c4e47ff5b2b0dd71fa10472eafb1d5abf4c5fRoland McGrath
430371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath	if (addr == 0)
431371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath		tprintf("NULL");
432371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath	else 	if (umovestr(tcp, addr, n, path) < 0)
43376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#lx", addr);
43476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
43576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		path[n] = '\0';
43676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		string_quote(path);
43776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
43876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
43976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
44076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
44176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintstr(tcp, addr, len)
44276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
44376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
44476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
44576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
44676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static unsigned char *str = NULL;
44776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static char *outstr;
44876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i, n, c, usehex;
44976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *s, *outend;
45076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
45176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!addr) {
45276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("NULL");
45376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
45476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
45576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!str) {
45676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if ((str = malloc(max_strlen)) == NULL
45776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		    || (outstr = malloc(2*max_strlen)) == NULL) {
45846100d07257824da2ae1147da0324b5788c95501Roland McGrath			fprintf(stderr, "out of memory\n");
45976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%#lx", addr);
46076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
46176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
46276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
4632e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman	outend = outstr + max_strlen * 2 - 10;
46476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (len < 0) {
46576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = max_strlen;
46676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (umovestr(tcp, addr, n, (char *) str) < 0) {
46776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%#lx", addr);
46876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
46976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
47076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
47176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
47276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(len, max_strlen);
47376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (umoven(tcp, addr, n, (char *) str) < 0) {
47476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%#lx", addr);
47576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
47676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
47776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
47876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
47976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	usehex = 0;
48076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (xflag > 1)
48176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		usehex = 1;
48276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else if (xflag) {
48376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < n; i++) {
48476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			c = str[i];
48576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (len < 0 && c == '\0')
48676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
48776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (!isprint(c) && !isspace(c)) {
48876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				usehex = 1;
48976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
49076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
49176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
49276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
49376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
49476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	s = outstr;
49576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*s++ = '\"';
49676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
49776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (usehex) {
49876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < n; i++) {
49976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			c = str[i];
50076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (len < 0 && c == '\0')
50176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
50276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			sprintf(s, "\\x%02x", c);
50376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			s += 4;
50476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (s > outend)
50576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
50676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
50776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
50876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
50976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < n; i++) {
51076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			c = str[i];
51176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (len < 0 && c == '\0')
51276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
51376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			switch (c) {
51476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\"': case '\'': case '\\':
51576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = c; break;
51676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\f':
51776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 'f'; break;
51876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\n':
51976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 'n'; break;
52076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\r':
52176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 'r'; break;
52276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\t':
52376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 't'; break;
52476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			case '\v':
52576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = '\\'; *s++ = 'v'; break;
52676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			default:
52776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				if (isprint(c))
52876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					*s++ = c;
52976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				else if (i < n - 1 && isdigit(str[i + 1])) {
53076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					sprintf(s, "\\%03o", c);
53176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					s += 4;
53276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				}
53376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				else {
53476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					sprintf(s, "\\%o", c);
53576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					s += strlen(s);
53676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				}
53776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
53876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
53976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (s > outend)
54076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				break;
54176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
54276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
54376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
54476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*s++ = '\"';
54576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (i < len || (len < 0 && (i == n || s > outend))) {
54676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		*s++ = '.'; *s++ = '.'; *s++ = '.';
54776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
54876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*s = '\0';
54976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("%s", outstr);
55076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
55176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
5521d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H
5531d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesvoid
5541d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesdumpiov(tcp, len, addr)
5551d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesstruct tcb * tcp;
5561d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesint len;
5571d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hugheslong addr;
5581d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes{
5591d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	struct iovec *iov;
5601d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	int i;
561aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath	unsigned long size;
5621d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes
563aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath	size = sizeof(*iov) * (unsigned long) len;
564aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath	if (size / sizeof(*iov) != len
565aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath	    || (iov = (struct iovec *) malloc(size)) == NULL) {
566aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath		fprintf(stderr, "out of memory\n");
5671d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes		return;
5681d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	}
569aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath	if (umoven(tcp, addr, size, (char *) iov) >= 0) {
5701d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes		for (i = 0; i < len; i++) {
5711d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                        /* include the buffer number to make it easy to
5721d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                         * match up the trace with the source */
5731d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                        tprintf(" * %lu bytes in buffer %d\n",
5741d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                                (unsigned long)iov[i].iov_len, i);
5751d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                        dumpstr(tcp, (long) iov[i].iov_base,
5761d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                                iov[i].iov_len);
5771d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes                }
5781d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	}
5791d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	free((char *) iov);
5801e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath
5811d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes}
5821d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif
5831d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes
58476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
58576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandumpstr(tcp, addr, len)
58676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
58776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
58876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
58976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
59076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static int strsize = -1;
59176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static unsigned char *str;
59276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static char outstr[80];
59376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *s;
59476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i, j;
59576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
59676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (strsize < len) {
59776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (str)
59876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			free(str);
59976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if ((str = malloc(len)) == NULL) {
60046100d07257824da2ae1147da0324b5788c95501Roland McGrath			fprintf(stderr, "out of memory\n");
60176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
60276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
60376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		strsize = len;
60476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
60576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
60676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umoven(tcp, addr, len, (char *) str) < 0)
60776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
60876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
60976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (i = 0; i < len; i += 16) {
61076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		s = outstr;
61176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		sprintf(s, " | %05x ", i);
61276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		s += 9;
61376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (j = 0; j < 16; j++) {
61476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (j == 8)
61576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
61676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (i + j < len) {
61776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				sprintf(s, " %02x", str[i + j]);
61876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				s += 3;
61976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
62076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			else {
62176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' '; *s++ = ' '; *s++ = ' ';
62276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
62376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
62476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		*s++ = ' '; *s++ = ' ';
62576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (j = 0; j < 16; j++) {
62676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (j == 8)
62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
62876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (i + j < len) {
62976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				if (isprint(str[i + j]))
63076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					*s++ = str[i + j];
63176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				else
63276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					*s++ = '.';
63376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
63476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			else
63576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
63676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
63776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s |\n", outstr);
63876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
63976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
64076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
64176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PAGMASK	(~(PAGSIZ - 1))
64276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
64376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * move `len' bytes of data from process `pid'
64476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * at address `addr' to our space at `laddr'
64576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
64676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
64776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumoven(tcp, addr, len, laddr)
64876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
64976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
65076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
65176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
65276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
65376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
65476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
65576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
65676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n, m;
6575daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman	int started = 0;
65876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
65976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
66076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
66176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
66276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
66376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
66476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
66576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
66676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
66776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
66876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
66976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
6705daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			if (started && (errno==EPERM || errno==EIO)) {
67176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/* Ran into 'end of memory' - stupid "printpath" */
67276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
67376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
6745daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			/* But if not started, we had a bogus address. */
67576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("ptrace: umoven");
67676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
67776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
6785daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
67976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
68076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
68176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
68276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
68376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
68476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
68576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
6865daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			if (started && (errno==EPERM || errno==EIO)) {
68776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/* Ran into 'end of memory' - stupid "printpath" */
68876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
68976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
6904db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath			if (addr != 0)
6914db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath				perror("ptrace: umoven");
69276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
69376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
6945daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
69576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
69676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
69776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
69876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
69976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
70076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
70176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
70276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0
70376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n, m;
70476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
70576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
70676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
70776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
70876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
70976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
71076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
71176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
71276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
71376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
71476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
71576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
71676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umoven");
71776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
71876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
71976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
72076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
72176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
72276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
72376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
72476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
72576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
72676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umoven");
72776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
72876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
72976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
73076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
73176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
73276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !oldway */
73376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
73476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
73576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
73676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(len, PAGSIZ);
73776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
73876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (ptrace(PTRACE_READDATA, pid,
73976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			   (char *) addr, len, laddr) < 0) {
74076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umoven: ptrace(PTRACE_READDATA, ...)");
74176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			abort();
74276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
74376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		len -= n;
74576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += n;
74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		laddr += n;
74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
74876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !oldway */
74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
751bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS
752ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS
753aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int fd = tcp->pfd_as;
7549ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else
755aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int fd = tcp->pfd;
75676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
757aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	lseek(fd, addr, SEEK_SET);
758aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	if (read(fd, laddr, len) == -1)
75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
760bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */
76176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
76276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
76376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
76476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
76576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
76676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * like `umove' but make the additional effort of looking
76776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * for a terminating zero byte.
76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
77076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumovestr(tcp, addr, len, laddr)
77176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
77276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
77376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
77476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
77576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
776bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS
777aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#ifdef HAVE_MP_PROCFS
778aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int fd = tcp->pfd_as;
779aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#else
780aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int fd = tcp->pfd;
781aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#endif
782aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	/* Some systems (e.g. FreeBSD) can be upset if we read off the
783aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   end of valid memory,  avoid this by trying to read up
784aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   to page boundaries.  But we don't know what a page is (and
785aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   getpagesize(2) (if it exists) doesn't necessarily return
786aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   hardware page size).  Assume all pages >= 1024 (a-historical
787aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   I know) */
788aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes
789aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int page = 1024; 	/* How to find this? */
790aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int move = page - (addr & (page - 1));
791aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int left = len;
792aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes
793aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	lseek(fd, addr, SEEK_SET);
794aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes
795aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	while (left) {
796aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		if (move > left) move = left;
7979cecf7f8d6115a247be7186013857270b2d588d5John Hughes		if ((move = read(fd, laddr, move)) <= 0)
798aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes			return left != len ? 0 : -1;
799aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		if (memchr (laddr, 0, move)) break;
800aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		left -= move;
801aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		laddr += move;
802aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		addr += move;
803aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		move = page;
804aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	}
805bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */
8065daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman	int started = 0;
80776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
80876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i, n, m;
80976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
81076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
81176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
81276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
81376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
81476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
81576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
81676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
81776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
81876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
81976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
82076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
8215daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			if (started && (errno==EPERM || errno==EIO)) {
82276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/* Ran into 'end of memory' - stupid "printpath" */
82376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
82476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
82576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umovestr");
82676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
82776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
8285daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
82976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len));
83076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		while (n & (sizeof(long) - 1))
83176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (u.x[n++] == '\0')
83276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
83376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
83476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
83576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
83676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
83776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
83876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
8395daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman			if (started && (errno==EPERM || errno==EIO)) {
84076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/* Ran into 'end of memory' - stupid "printpath" */
84176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
84276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
84376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("umovestr");
84476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
84576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
8465daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
84776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
84876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < sizeof(long); i++)
84976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (u.x[i] == '\0')
85076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
85176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
85276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
85376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
854bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */
855aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	return 0;
85676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
85776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
85876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
8596d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if !defined (SPARC) && !defined(SPARC64)
86076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITETEXT	101
86176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITEDATA	102
8626d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#endif /* !SPARC && !SPARC64 */
86376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
86476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
86576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
86676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
86776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int
86876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanuload(cmd, pid, addr, len, laddr)
86976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint cmd;
87076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
87176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
87276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
87376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
87476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
87576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0
87676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
87776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
87876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
87976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(len, PAGSIZ);
88076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
88176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) {
88276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("uload: ptrace(PTRACE_WRITE, ...)");
88376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
88476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
88576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		len -= n;
88676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += n;
88776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		laddr += n;
88876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
88976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else
89076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int peek, poke;
89176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n, m;
89276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
89376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
89476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
89576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
89676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
89776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (cmd == PTRACE_WRITETEXT) {
89876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		peek = PTRACE_PEEKTEXT;
89976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		poke = PTRACE_POKETEXT;
90076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
90176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
90276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		peek = PTRACE_PEEKDATA;
90376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		poke = PTRACE_POKEDATA;
90476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
90576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
90676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
90776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
90876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long);
90976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		errno = 0;
91076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		u.val = ptrace(peek, pid, (char *) addr, 0);
91176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (errno) {
91276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("uload: POKE");
91376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
91476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
91576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len));
91676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (ptrace(poke, pid, (char *)addr, u.val) < 0) {
91776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("uload: POKE");
91876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
91976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
92076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
92176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
92276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
92376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (len < sizeof(long))
92476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			u.val = ptrace(peek, pid, (char *) addr, 0);
92576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(u.x, laddr, m = MIN(sizeof(long), len));
92676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (ptrace(poke, pid, (char *) addr, u.val) < 0) {
92776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			perror("uload: POKE");
92876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
92976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
93076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
93176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
93276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
93376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
93476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
93576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
93676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
93776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantload(pid, addr, len, laddr)
93876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
93976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr, len;
94076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
94176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
94276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return uload(PTRACE_WRITETEXT, pid, addr, len, laddr);
94376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
94476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
94576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
94676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandload(pid, addr, len, laddr)
94776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
94876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr;
94976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr;
95176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
95276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return uload(PTRACE_WRITEDATA, pid, addr, len, laddr);
95376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
95476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
95576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
95676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
957bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS
95876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
95976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
96076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanupeek(pid, off, res)
96176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
96276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong off;
96376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong *res;
96476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
96576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long val;
96676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
96776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE
96876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	{
96976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		static int is_sun4m = -1;
97076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		struct utsname name;
97176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
97276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* Round up the usual suspects. */
97376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (is_sun4m == -1) {
97476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (uname(&name) < 0) {
97576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				perror("upeek: uname?");
97676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				exit(1);
97776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
97876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			is_sun4m = strcmp(name.machine, "sun4m") == 0;
97976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (is_sun4m) {
980d9f816f60457930af27349fac3d23b3b78338036Roland McGrath				extern const struct xlat struct_user_offsets[];
981d9f816f60457930af27349fac3d23b3b78338036Roland McGrath				const struct xlat *x;
98276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
98376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				for (x = struct_user_offsets; x->str; x++)
98476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					x->val += 1024;
98576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
98676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (is_sun4m)
98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			off += 1024;
98976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
99076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	val = ptrace(PTRACE_PEEKUSER, pid, (char *) off, 0);
99376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (val == -1 && errno) {
9941e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath		char buf[60];
9950e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)",pid,off);
9961e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath		perror(buf);
99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
99876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
99976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*res = val;
100076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
100176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
100276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1003bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */
100476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1005a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrath#if 0
100676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong
100776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetpc(tcp)
100876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
100976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
101076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
101176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
101276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
1013f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#if defined(I386)
101476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*EIP, &pc) < 0)
101576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
10160e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined(X86_64)
10170e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	if (upeek(tcp->pid, 8*RIP, &pc) < 0)
10180e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		return -1;
10198b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#elif defined(IA64)
10208b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	if (upeek(tcp->pid, PT_B0, &pc) < 0)
10218b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		return -1;
1022f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ARM)
102376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*15, &pc) < 0)
102476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
1025f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(POWERPC)
1026eb285359906700f46b22cf4f9911695034313736Roland McGrath	if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0)
102776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
102884fa923c15aa537b666d26694549091e9b9a5ddbRoland McGrath#elif defined(M68K)
102976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
103076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
1031f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ALPHA)
103276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, REG_PC, &pc) < 0)
103376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
1034f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS)
1035f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman 	if (upeek(tcp->pid, REG_EPC, &pc) < 0)
1036f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman 		return -1;
10376d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#elif defined(SPARC) || defined(SPARC64)
10389ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	struct regs regs;
103976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
104076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
10419ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	pc = regs.r_pc;
104210a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#elif defined(S390) || defined(S390X)
10434dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman	if(upeek(tcp->pid,PT_PSWADDR,&pc) < 0)
104410a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig		return -1;
1045c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
1046c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0)
1047c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return -1;
1048ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH)
1049ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman       if (upeek(tcp->pid, 4*REG_PC ,&pc) < 0)
1050ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman               return -1;
1051f5a477788ed49d3c15e2080c03d30d4beaeefee3Roland McGrath#elif defined(SH64)
1052e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath       if (upeek(tcp->pid, REG_PC ,&pc) < 0)
1053e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath               return -1;
10547a0b649aeace5c1e1efe4a1d7b1ae6e3a87e0d44Wichert Akkerman#endif
105576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return pc;
105676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
105776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
105876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
105976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
106076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Return current program counter for `pid'
106176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Assumes PC is never 0xffffffff
106276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
106376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct regs regs;
106476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
106576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
106676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("getpc: ptrace(PTRACE_GETREGS, ...)");
106776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
106876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
106976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return regs.r_pc;
107076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
107176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
107276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4
107376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* XXX */
107476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
107576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */
107676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1077bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD
1078bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	struct reg regs;
1079bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
1080bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	return regs.r_eip;
1081bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */
108276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
1083a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrath#endif
108476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
108576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
108676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintcall(tcp)
108776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
108876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
10897a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath#define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \
10907a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath			   sizeof(long) == 8 ? "[????????????????] " : \
10917a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath			   NULL /* crash */)
109276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
109376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
109476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386
109576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long eip;
109676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
109776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*EIP, &eip) < 0) {
10987a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
109976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
110076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
110176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", eip);
1102eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath
1103eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath#elif defined(S390) || defined(S390X)
1104eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath         long psw;
1105eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath         if(upeek(tcp->pid,PT_PSWADDR,&psw) < 0) {
11067a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath                 PRINTBADPC;
1107eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath                 return;
1108eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath         }
1109eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath#ifdef S390
1110eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath         tprintf("[%08lx] ", psw);
1111eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath#elif S390X
1112eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath       tprintf("[%16lx] ", psw);
1113eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath#endif
1114eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath
11150e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined(X86_64)
11160e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	long rip;
11170e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig
11180e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	if (upeek(tcp->pid, 8*RIP, &rip) < 0) {
11197a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
11200e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		return;
11210e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	}
11220e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	tprintf("[%16lx] ", rip);
1123ef388689610fa17df1d3001face8057b411a2e26Roland McGrath#elif defined(IA64)
11248b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	long ip;
11258b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
11268b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	if (upeek(tcp->pid, PT_B0, &ip) < 0) {
11277a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
11288b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		return;
11298b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	}
11308b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	tprintf("[%08lx] ", ip);
1131faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(POWERPC)
113276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
113376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1134eb285359906700f46b22cf4f9911695034313736Roland McGrath	if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) {
113576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf ("[????????] ");
113676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
113776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
113876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
113984fa923c15aa537b666d26694549091e9b9a5ddbRoland McGrath#elif defined(M68K)
114076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
114176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
114276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) {
114376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf ("[????????] ");
114476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
114576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
114676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
1147faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA)
114876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
114976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
115076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, REG_PC, &pc) < 0) {
11517a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		tprintf ("[????????????????] ");
115276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
115376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
115476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
11556d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#elif defined(SPARC) || defined(SPARC64)
11569ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	struct regs regs;
115776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0) {
11587a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
115976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
116076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
11619ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	tprintf("[%08lx] ", regs.r_pc);
1162c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
1163c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	long pc;
1164c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman
1165c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) {
1166c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		tprintf ("[????????] ");
1167c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return;
1168c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	}
1169c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	tprintf("[%08lx] ", pc);
117075c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman#elif defined(MIPS)
117175c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	long pc;
117275c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman
117375c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	if (upeek(tcp->pid, REG_EPC, &pc) < 0) {
117475c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman		tprintf ("[????????] ");
117575c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman		return;
117675c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	}
117775c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	tprintf("[%08lx] ", pc);
1178ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH)
1179ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman       long pc;
1180ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman
1181ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman       if (upeek(tcp->pid, 4*REG_PC, &pc) < 0) {
1182ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman               tprintf ("[????????] ");
1183ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman               return;
1184ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman       }
1185ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman       tprintf("[%08lx] ", pc);
1186f5a477788ed49d3c15e2080c03d30d4beaeefee3Roland McGrath#elif defined(SH64)
1187e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath	long pc;
1188e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath
1189e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath	if (upeek(tcp->pid, REG_PC, &pc) < 0) {
11907a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		tprintf ("[????????????????] ");
1191e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath		return;
1192e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath	}
1193e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath	tprintf("[%08lx] ", pc);
1194ef388689610fa17df1d3001face8057b411a2e26Roland McGrath#elif defined(ARM)
1195ef388689610fa17df1d3001face8057b411a2e26Roland McGrath	long pc;
1196e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath
1197ef388689610fa17df1d3001face8057b411a2e26Roland McGrath	if (upeek(tcp->pid, 4*15, &pc) < 0) {
11987a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
1199ef388689610fa17df1d3001face8057b411a2e26Roland McGrath		return;
1200ef388689610fa17df1d3001face8057b411a2e26Roland McGrath	}
1201ef388689610fa17df1d3001face8057b411a2e26Roland McGrath	tprintf("[%08lx] ", pc);
1202faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* !architecture */
120376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
120476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
120576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
120676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct regs regs;
120776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
120876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
120976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("printcall: ptrace(PTRACE_GETREGS, ...)");
12107a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
121176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
121276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
121376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08x] ", regs.r_o7);
121476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
121576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
121676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4
121776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* XXX */
12187a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath	PRINTBADPC;
121976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
122076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1221bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD
1222bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	struct reg regs;
1223bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
1224bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	tprintf("[%08x] ", regs.r_eip);
1225bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */
122676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
122776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1228bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS
122976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1230d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#if defined LINUX
1231d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1232d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#include <sys/syscall.h>
1233d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifndef CLONE_PTRACE
1234d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define CLONE_PTRACE    0x00002000
1235d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif
123676989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath#ifndef CLONE_STOPPED
123776989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath# define CLONE_STOPPED   0x02000000
123876989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath#endif
1239d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1240d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef IA64
1241d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
124208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath/* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32
124308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath   subsystem has them for x86... */
124408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath#define SYS_fork	2
124508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath#define SYS_vfork	190
124608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
1247d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef unsigned long *arg_setup_state;
1248d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1249d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1250d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGratharg_setup(struct tcb *tcp, arg_setup_state *state)
1251d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1252d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	unsigned long *bsp, cfm, sof, sol;
1253d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
125408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	if (ia32)
125508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		return 0;
125608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
1257d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) < 0)
1258d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return -1;
1259d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	if (upeek(tcp->pid, PT_CFM, (long *) &cfm) < 0)
1260d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return -1;
1261d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1262d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	sof = (cfm >> 0) & 0x7f;
1263d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	sol = (cfm >> 7) & 0x7f;
1264d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	bsp = ia64_rse_skip_regs(bsp, -sof + sol);
1265d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1266d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	*state = bsp;
1267d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return 0;
1268d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1269d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1270d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_finish_change(tcp, state)	0
1271d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1272d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef SYS_fork
1273d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1274d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathget_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp)
1275d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
127608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	int ret;
127708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
127808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	if (ia32)
127908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ret = upeek (tcp->pid, PT_R11, valp);
128008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	else
128108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ret = umoven (tcp,
128208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath			      (unsigned long) ia64_rse_skip_regs(*state, 0),
128308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath			      sizeof(long), (void *) valp);
128408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	return ret;
1285d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1286d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1287d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1288d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathget_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp)
1289d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
129008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	int ret;
129108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
129208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	if (ia32)
129308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ret = upeek (tcp->pid, PT_R9, valp);
129408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	else
129508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ret = umoven (tcp,
129608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath			      (unsigned long) ia64_rse_skip_regs(*state, 1),
129708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath			      sizeof(long), (void *) valp);
129808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	return ret;
1299d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1300d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif
1301d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1302d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1303d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg0 (struct tcb *tcp, arg_setup_state *state, long val)
1304d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
130508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	int req = PTRACE_POKEDATA;
130608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	void *ap;
130708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
130808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	if (ia32) {
130908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ap = (void *) (intptr_t) PT_R11;	 /* r11 == EBX */
131008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		req = PTRACE_POKEUSER;
131108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	} else
131208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ap = ia64_rse_skip_regs(*state, 0);
1313d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	errno = 0;
131408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	ptrace(req, tcp->pid, ap, val);
1315d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return errno ? -1 : 0;
1316d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1317d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1318d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1319d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg1 (struct tcb *tcp, arg_setup_state *state, long val)
1320d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
132108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	int req = PTRACE_POKEDATA;
132208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	void *ap;
132308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
132408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	if (ia32) {
132508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ap = (void *) (intptr_t) PT_R9;		/* r9 == ECX */
132608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		req = PTRACE_POKEUSER;
132708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	} else
132808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ap = ia64_rse_skip_regs(*state, 1);
1329d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	errno = 0;
133008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	ptrace(req, tcp->pid, ap, val);
1331d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return errno ? -1 : 0;
1332d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1333d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
13346d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#elif defined (SPARC) || defined (SPARC64)
1335d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1336d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef struct regs arg_setup_state;
1337d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1338d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_setup(tcp, state) \
1339d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath  (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0))
1340d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_finish_change(tcp, state) \
1341d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath  (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0))
1342d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1343d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0)
1344d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0)
1345d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define set_arg0(tcp, state, val) ((state)->r_o0 = (val), 0)
1346d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define set_arg1(tcp, state, val) ((state)->r_o1 = (val), 0)
1347e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg0(tcp, state, val) 0
1348d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1349d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#else
1350d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1351d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# if defined S390 || defined S390X
13527b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath/* Note: this is only true for the `clone' system call, which handles
13537b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath   arguments specially.  We could as well say that its first two arguments
13547b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath   are swapped relative to other architectures, but that would just be
13557b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath   another #ifdef in the calls.  */
13567b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath#  define arg0_offset	PT_GPR3
13577b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath#  define arg1_offset	PT_ORIGGPR2
13587b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath#  define restore_arg0(tcp, state, val) ((void) (state), 0)
13597b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath#  define restore_arg1(tcp, state, val) ((void) (state), 0)
1360c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath#  define arg0_index	1
1361c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath#  define arg1_index	0
1362d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# elif defined (ALPHA) || defined (MIPS)
1363d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#  define arg0_offset	REG_A0
1364d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#  define arg1_offset	(REG_A0+1)
1365d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# elif defined (POWERPC)
1366eb285359906700f46b22cf4f9911695034313736Roland McGrath#  define arg0_offset	(sizeof(unsigned long)*PT_R3)
1367eb285359906700f46b22cf4f9911695034313736Roland McGrath#  define arg1_offset	(sizeof(unsigned long)*PT_R4)
13687b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath#  define restore_arg0(tcp, state, val) ((void) (state), 0)
1369d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# elif defined (HPPA)
1370d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#  define arg0_offset	 PT_GR26
1371d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#  define arg1_offset	 (PT_GR26-4)
13727f33cc3eb5ead7a79cae8c586e40d2f8b573eec1Roland McGrath# elif defined (X86_64)
13737f33cc3eb5ead7a79cae8c586e40d2f8b573eec1Roland McGrath#  define arg0_offset	((long)(8*(current_personality ? RBX : RDI)))
13747f33cc3eb5ead7a79cae8c586e40d2f8b573eec1Roland McGrath#  define arg1_offset	((long)(8*(current_personality ? RCX : RSI)))
1375ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath# elif defined (SH)
1376ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath#  define arg0_offset	(4*(REG_REG0+4))
1377ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath#  define arg1_offset	(4*(REG_REG0+5))
1378f5a477788ed49d3c15e2080c03d30d4beaeefee3Roland McGrath# elif defined (SH64)
1379e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath   /* ABI defines arg0 & 1 in r2 & r3 */
1380e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath#  define arg0_offset   (REG_OFFSET+16)
1381e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath#  define arg1_offset   (REG_OFFSET+24)
1382e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath#  define restore_arg0(tcp, state, val) 0
1383d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# else
1384d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#  define arg0_offset	0
1385d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#  define arg1_offset	4
1386ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath#  if defined ARM
1387e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#   define restore_arg0(tcp, state, val) 0
1388e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#  endif
1389d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# endif
1390d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1391d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef int arg_setup_state;
1392d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1393d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_setup(tcp, state) (0)
1394d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_finish_change(tcp, state)	0
1395d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg0(tcp, cookie, valp) \
1396d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath  (upeek ((tcp)->pid, arg0_offset, (valp)))
1397d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg1(tcp, cookie, valp) \
1398d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath  (upeek ((tcp)->pid, arg1_offset, (valp)))
1399d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1400d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1401d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg0 (struct tcb *tcp, void *cookie, long val)
1402d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1403ca85b97c9cea63db45e59a345218b902936b693dRoland McGrath	return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val);
1404d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1405d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1406d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1407d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg1 (struct tcb *tcp, void *cookie, long val)
1408d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1409d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val);
1410d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1411d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1412d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif
1413d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1414e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#ifndef restore_arg0
1415e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val))
1416e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#endif
1417e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#ifndef restore_arg1
1418e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val))
1419e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#endif
1420d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
142190d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath#ifndef arg0_index
142290d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath# define arg0_index 0
142390d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath# define arg1_index 1
142490d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath#endif
142590d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath
1426d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint
1427d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathsetbpt(tcp)
1428d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstruct tcb *tcp;
1429d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1430d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	extern int change_syscall(struct tcb *, int);
1431d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	arg_setup_state state;
1432d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1433d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	if (tcp->flags & TCB_BPTSET) {
1434d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1435d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return -1;
1436d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	}
1437d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
143876989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath	switch (known_scno(tcp)) {
14399383c6c539af09303efe0a16dea55363b095f66eRoland McGrath#ifdef SYS_vfork
14409383c6c539af09303efe0a16dea55363b095f66eRoland McGrath	case SYS_vfork:
14419383c6c539af09303efe0a16dea55363b095f66eRoland McGrath#endif
1442d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef SYS_fork
1443d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	case SYS_fork:
14449b0982b5d3b84c845192ad8b7ad822f81cf4743aRoland McGrath#endif
14459b0982b5d3b84c845192ad8b7ad822f81cf4743aRoland McGrath#if defined SYS_fork || defined SYS_vfork
1446d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		if (arg_setup (tcp, &state) < 0
1447d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || get_arg0 (tcp, &state, &tcp->inst[0]) < 0
1448d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || get_arg1 (tcp, &state, &tcp->inst[1]) < 0
1449d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || change_syscall(tcp, SYS_clone) < 0
1450d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0
1451d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || set_arg1 (tcp, &state, 0) < 0
1452d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || arg_finish_change (tcp, &state) < 0)
1453d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath			return -1;
1454c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath		tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD;
1455c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath		tcp->u_arg[arg1_index] = 0;
1456d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		tcp->flags |= TCB_BPTSET;
1457d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return 0;
1458d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif
1459d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1460d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	case SYS_clone:
1461d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef SYS_clone2
1462d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	case SYS_clone2:
1463d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif
146402cee8d5cbcb0aaaf64d4f4d0916e3d4dbd8ee01Roland McGrath		if ((tcp->u_arg[arg0_index] & CLONE_PTRACE) == 0
1465d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    && (arg_setup (tcp, &state) < 0
1466c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath			|| set_arg0 (tcp, &state,
1467c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath				     tcp->u_arg[arg0_index] | CLONE_PTRACE) < 0
1468d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath			|| arg_finish_change (tcp, &state) < 0))
1469d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath			return -1;
1470d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		tcp->flags |= TCB_BPTSET;
1471c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath		tcp->inst[0] = tcp->u_arg[arg0_index];
1472c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath		tcp->inst[1] = tcp->u_arg[arg1_index];
1473d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return 0;
1474d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1475d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	default:
1476d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n",
1477d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath			tcp->scno, tcp->pid);
1478d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		break;
1479d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	}
1480d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1481d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return -1;
1482d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1483d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1484d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint
1485d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathclearbpt(tcp)
1486d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstruct tcb *tcp;
1487d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1488d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	arg_setup_state state;
1489d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	if (arg_setup (tcp, &state) < 0
1490e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath	    || restore_arg0 (tcp, &state, tcp->inst[0]) < 0
1491e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath	    || restore_arg1 (tcp, &state, tcp->inst[1]) < 0
1492d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	    || arg_finish_change (tcp, &state))
1493d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return -1;
1494d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	tcp->flags &= ~TCB_BPTSET;
1495d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return 0;
1496d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1497d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1498d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#else
1499d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
150076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
150176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermansetbpt(tcp)
150276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
150376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
150476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
150576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
15066d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if defined (SPARC) || defined (SPARC64)
150776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* We simply use the SunOS breakpoint code. */
150876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
15099ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	struct regs regs;
15106d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath	unsigned long inst;
151176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA	0x30800000	/* ba,a	0 */
151276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
151376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tcp->flags & TCB_BPTSET) {
151476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
151576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
151676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
151776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
151876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
151976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
152076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
15219ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	tcp->baddr = regs.r_o7 + 8;
152276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
152376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0);
152476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if(errno) {
152576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
152676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
152776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
152876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
152976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
153076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * XXX - BRUTAL MODE ON
153176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * We cannot set a real BPT in the child, since it will not be
153276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * traced at the moment it will reach the trap and would probably
153376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * die with a core dump.
153476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Thus, we are force our way in by taking out two instructions
153576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * and insert an eternal loop instead, in expectance of the SIGSTOP
153676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * generated by out PTRACE_ATTACH.
153776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Of cause, if we evaporate ourselves in the middle of all this...
153876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
153976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
15406d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath	inst = LOOPA;
15416d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if defined (SPARC64)
15426d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath	inst <<= 32;
15436d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath	inst |= (tcp->inst[0] & 0xffffffffUL);
15446d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#endif
15456d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, inst);
154676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if(errno) {
154776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
154876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
154976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
155076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags |= TCB_BPTSET;
155176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
15526d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#else /* !SPARC && !SPARC64 */
15538b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#ifdef IA64
15547b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman	if (ia32) {
15557b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#		define LOOP	0x0000feeb
15567b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (tcp->flags & TCB_BPTSET) {
15577b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			fprintf(stderr, "PANIC: bpt already set in pid %u\n",
15587b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				tcp->pid);
15597b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
15607b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
15617b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (upeek(tcp->pid, PT_CR_IIP, &tcp->baddr) < 0)
15627b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
15637b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (debug)
15647b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			fprintf(stderr, "[%d] setting bpt at %lx\n",
15657b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				tcp->pid, tcp->baddr);
15667b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid,
15677b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				      (char *) tcp->baddr, 0);
15687b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (errno) {
15697b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
15707b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
15717b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
15727b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
15737b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (errno) {
15747b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
15757b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
15767b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
15777b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->flags |= TCB_BPTSET;
15787b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman	} else {
15797b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		/*
15807b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * Our strategy here is to replace the bundle that
15817b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * contained the clone() syscall with a bundle of the
15827b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * form:
15837b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 *
15847b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 *	{ 1: br 1b; br 1b; br 1b }
15857b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 *
15867b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * This ensures that the newly forked child will loop
15877b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * endlessly until we've got a chance to attach to it.
15887b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 */
15898b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#		define LOOP0	0x0000100000000017
15908b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#		define LOOP1	0x4000000000200000
15918b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		unsigned long addr, ipsr;
15928b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		pid_t pid;
15938b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
15948b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		pid = tcp->pid;
15958b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (upeek(pid, PT_CR_IPSR, &ipsr) < 0)
15968b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
15978b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (upeek(pid, PT_CR_IIP, &addr) < 0)
15988b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
15997b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		/* store "ri" in low two bits */
16007b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->baddr = addr | ((ipsr >> 41) & 0x3);
16018b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
16028b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		errno = 0;
16037b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0,
16047b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				      0);
16057b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8,
16067b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				      0);
16078b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (errno) {
16088b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
16098b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
16108b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
16118b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
16128b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		errno = 0;
16138b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0);
16148b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1);
16158b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (errno) {
16168b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
16178b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
16188b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
16198b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		tcp->flags |= TCB_BPTSET;
16208b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	}
16218b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#else /* !IA64 */
162276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
16230e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#if defined (I386) || defined(X86_64)
162476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP	0x0000feeb
162576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K)
162676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP	0x60fe0000
162776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA)
16284dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP	0xc3ffffff
162976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC)
16301e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath#define LOOP	0x48000000
163176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined(ARM)
16329a8a37f2b28d1c0d3f57951fd5aeeb96ff7d2f16Wichert Akkerman#define LOOP	0xEAFFFFFE
1633f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS)
16344dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP	0x1000ffff
16354dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390)
16364dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP	0xa7f40000	/* BRC 15,0 */
163710a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#elif defined(S390X)
163810a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#define LOOP   0xa7f4000000000000UL /* BRC 15,0 */
1639c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
1640c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#define LOOP	0xe81f1ff7	/* b,l,n <loc>,r0 */
1641ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH)
1642ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#ifdef __LITTLE_ENDIAN__
1643ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#define LOOP   0x0000affe
1644ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#else
1645ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#define LOOP   0xfeaf0000
1646ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#endif
164776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else
164876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture
164976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
165076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
165176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tcp->flags & TCB_BPTSET) {
165276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid);
165376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
165476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
165576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined (I386)
165676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*EIP, &tcp->baddr) < 0)
165776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
16580e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined (X86_64)
16590e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	if (upeek(tcp->pid, 8*RIP, &tcp->baddr) < 0)
16600e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		return -1;
166176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K)
166276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_PC, &tcp->baddr) < 0)
166376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	  return -1;
166476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA)
166576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return -1;
166676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ARM)
166776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return -1;
1668f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined (MIPS)
1669f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman	return -1;		/* FIXME: I do not know what i do - Flo */
167076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC)
1671eb285359906700f46b22cf4f9911695034313736Roland McGrath	if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &tcp->baddr) < 0)
167276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
167310a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#elif defined(S390) || defined(S390X)
16744dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman	if (upeek(tcp->pid,PT_PSWADDR, &tcp->baddr) < 0)
16754dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman		return -1;
1676c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
1677c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	if (upeek(tcp->pid, PT_IAOQ0, &tcp->baddr) < 0)
1678c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return -1;
1679c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	tcp->baddr &= ~0x03;
1680ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH)
1681ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman       if (upeek(tcp->pid, 4*REG_PC, &tcp->baddr) < 0)
1682ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman               return -1;
168376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else
168476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture
168576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
168676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (debug)
168776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr);
168876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0);
168976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (errno) {
169076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
169176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
169276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
169376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
169476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (errno) {
169576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
169676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
169776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
169876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags |= TCB_BPTSET;
169976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
17008b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#endif /* !IA64 */
17016d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#endif /* SPARC || SPARC64 */
170276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
170376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
170476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
170576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC	/* This code is slightly sparc specific */
170676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1707e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman	struct regs regs;
170876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define BPT	0x91d02001	/* ta	1 */
170976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP	0x10800000	/* ba	0 */
171076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA	0x30800000	/* ba,a	0 */
171176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define NOP	0x01000000
171276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if LOOPA
171376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static int loopdeloop[1] = {LOOPA};
171476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else
171576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static int loopdeloop[2] = {LOOP, NOP};
171676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
171776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
171876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tcp->flags & TCB_BPTSET) {
171976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
172076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
172176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
172276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
172376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
172476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
172576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
172676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->baddr = regs.r_o7 + 8;
172776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr,
172876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				sizeof tcp->inst, (char *)tcp->inst) < 0) {
172976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_READTEXT, ...)");
173076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
173176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
173276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
173476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * XXX - BRUTAL MODE ON
173576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * We cannot set a real BPT in the child, since it will not be
173676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * traced at the moment it will reach the trap and would probably
173776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * die with a core dump.
173876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Thus, we are force our way in by taking out two instructions
173976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * and insert an eternal loop in stead, in expectance of the SIGSTOP
174076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * generated by out PTRACE_ATTACH.
174176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Of cause, if we evaporate ourselves in the middle of all this...
174276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
174376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
174476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			sizeof loopdeloop, (char *) loopdeloop) < 0) {
174576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)");
174676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
174776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
174876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags |= TCB_BPTSET;
174976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
175076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */
175176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
175276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
175376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
175476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
175576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
175676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
175776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanclearbpt(tcp)
175876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
175976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
176076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
176176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
17620e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#if defined(I386) || defined(X86_64)
176376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long eip;
1764faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(POWERPC)
176576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
1766faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68K)
176776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
1768faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA)
176976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
1770c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
1771c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	long iaoq;
1772ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH)
1773ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman       long pc;
1774faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* architecture */
177576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
17766d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if defined (SPARC) || defined (SPARC64)
177776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* Again, we borrow the SunOS breakpoint code. */
177876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!(tcp->flags & TCB_BPTSET)) {
177976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
178076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
178176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
178276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
178376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
178476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if(errno) {
178576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
178676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
178776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
178876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags &= ~TCB_BPTSET;
1789faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(IA64)
17907b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman	if (ia32) {
17917b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		unsigned long addr;
17927b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman
17937b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (debug)
17947b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
17957b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (!(tcp->flags & TCB_BPTSET)) {
17967b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
17977b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
17987b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
17997b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		errno = 0;
18007b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
18017b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (errno) {
18027b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
18037b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
18047b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
18057b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->flags &= ~TCB_BPTSET;
18067b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman
18077b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (upeek(tcp->pid, PT_CR_IIP, &addr) < 0)
18087b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
18097b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (addr != tcp->baddr) {
18107b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			/* The breakpoint has not been reached yet.  */
18117b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			if (debug)
18127b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				fprintf(stderr,
18137b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman					"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
18147b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman						addr, tcp->baddr);
18157b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return 0;
18167b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
18177b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman	} else {
18188b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		unsigned long addr, ipsr;
18198b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		pid_t pid;
18208b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
18218b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		pid = tcp->pid;
18228b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
18238b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (upeek(pid, PT_CR_IPSR, &ipsr) < 0)
18248b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
18258b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (upeek(pid, PT_CR_IIP, &addr) < 0)
18268b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
18278b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
18288b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		/* restore original bundle: */
18298b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		errno = 0;
18308b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]);
18318b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]);
18328b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (errno) {
18338b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)");
18348b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
18358b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
18368b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
18378b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		/* restore original "ri" in ipsr: */
18388b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41);
18398b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		errno = 0;
18408b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr);
18418b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (errno) {
18428b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)");
18438b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
18448b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
18458b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
18468b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		tcp->flags &= ~TCB_BPTSET;
18478b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
18488b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (addr != (tcp->baddr & ~0x3)) {
18498b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			/* the breakpoint has not been reached yet.  */
18508b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			if (debug)
18518b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman				fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
18528b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman					addr, tcp->baddr);
18538b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return 0;
18548b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
18558b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	}
18566d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#else /* !IA64  && !SPARC && !SPARC64 */
185776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
185876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (debug)
185976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
186076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!(tcp->flags & TCB_BPTSET)) {
186176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
186276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
186376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
186476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
186576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
186676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (errno) {
186776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
186876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
186976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
187076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags &= ~TCB_BPTSET;
187176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
187276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386
187376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*EIP, &eip) < 0)
187476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
187576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (eip != tcp->baddr) {
187676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
187776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
187876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr,
187976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
188076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					eip, tcp->baddr);
188176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
188276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
18830e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined(X86_64)
18840e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	if (upeek(tcp->pid, 8*RIP, &eip) < 0)
18850e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		return -1;
18860e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	if (eip != tcp->baddr) {
18870e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		/* The breakpoint has not been reached yet.  */
18880e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		if (debug)
18890e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig			fprintf(stderr,
18900e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig				"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
18910e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig					eip, tcp->baddr);
18920e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		return 0;
18930e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	}
1894c792698a99b640e7d256e8692c992bd967f0c5b2Wichert Akkerman#elif defined(POWERPC)
1895eb285359906700f46b22cf4f9911695034313736Roland McGrath	if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0)
189676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
189776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (pc != tcp->baddr) {
189876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
189976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
190076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
190176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				pc, tcp->baddr);
190276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
190376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
1904faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68K)
190576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
190676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
190776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (pc != tcp->baddr) {
190876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
190976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
191076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
191176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				pc, tcp->baddr);
191276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
191376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
1914faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA)
191576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (upeek(tcp->pid, REG_PC, &pc) < 0)
191676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
191776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (pc != tcp->baddr) {
191876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
191976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
192076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
192176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				pc, tcp->baddr);
192276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
192376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
1924c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA)
1925c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	if (upeek(tcp->pid, PT_IAOQ0, &iaoq) < 0)
1926c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return -1;
1927c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	iaoq &= ~0x03;
1928c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) {
1929c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		/* The breakpoint has not been reached yet.  */
1930c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		if (debug)
1931c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n",
1932c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman				iaoq, tcp->baddr);
1933c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return 0;
1934c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	}
1935c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	iaoq = tcp->baddr | 3;
1936c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	/* We should be pointing at a 'ldi -1000,r1' in glibc, so it is
1937c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	 * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit
1938c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	 * has no significant effect.
1939c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	 */
1940c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq);
1941c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq);
1942ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH)
1943ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman       if (upeek(tcp->pid, 4*REG_PC, &pc) < 0)
1944ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman               return -1;
1945ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman        if (pc != tcp->baddr) {
1946ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman                /* The breakpoint has not been reached yet.  */
1947ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman                if (debug)
1948ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman                        fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1949ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman                                pc, tcp->baddr);
1950ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman                return 0;
1951ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman        }
1952ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman
1953faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* arch */
19546d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#endif /* !SPARC && !SPARC64 && !IA64 */
195576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
195676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
195776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
195876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC
195976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
196076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA
1961e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman	struct regs regs;
196276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
196376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
196476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!(tcp->flags & TCB_BPTSET)) {
196576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
196676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
196776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
196876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
196976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				sizeof tcp->inst, (char *) tcp->inst) < 0) {
197076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)");
197176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
197276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
197376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags &= ~TCB_BPTSET;
197476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
197576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA
197676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
197776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Since we don't have a single instruction breakpoint, we may have
197876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * to adjust the program counter after removing the our `breakpoint'.
197976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
198076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
198176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbpt: ptrace(PTRACE_GETREGS, ...)");
198276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
198376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
198476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if ((regs.r_pc < tcp->baddr) ||
198576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				(regs.r_pc > tcp->baddr + 4)) {
198676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet */
198776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
198876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr,
198976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				"NOTE: PC not at bpt (pc %#x baddr %#x)\n",
199076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					regs.r_pc, tcp->parent->baddr);
199176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
199276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
199376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (regs.r_pc != tcp->baddr)
199476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
199576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n",
199676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				regs.r_pc, tcp->baddr);
199776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
199876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	regs.r_pc = tcp->baddr;
199976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0) {
200076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		perror("clearbpt: ptrace(PTRACE_SETREGS, ...)");
200176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
200276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
200376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LOOPA */
200476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */
200576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
200676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
200776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
200876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
200976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
2010d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif
2011d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
2012bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */
201376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
201476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
201576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
201676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int
201776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetex(pid, hdr)
201876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid;
201976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct exec *hdr;
202076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
202176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
202276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
202376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (n = 0; n < sizeof *hdr; n += 4) {
202476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long res;
202576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (upeek(pid, uoff(u_exdata) + n, &res) < 0)
202676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
202776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(((char *) hdr) + n, &res, 4);
202876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
202976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (debug) {
203076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n",
203176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			hdr->a_magic, hdr->a_toolversion, hdr->a_machtype);
203276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n",
203376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry);
203476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
203576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
203676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
203776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
203876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
203976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfixvfork(tcp)
204076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
204176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
204276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
204376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
204476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Change `vfork' in a freshly exec'ed dynamically linked
204576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * executable's (internal) symbol table to plain old `fork'
204676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
204776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
204876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct exec hdr;
204976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct link_dynamic dyn;
205076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct link_dynamic_2 ld;
205176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *strtab, *cp;
205276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
205376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (getex(pid, &hdr) < 0)
205476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
205576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!hdr.a_dynamic)
205676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
205776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
205876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) {
205976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "Cannot read DYNAMIC\n");
206076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
206176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
206276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) {
206376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "Cannot read link_dynamic_2\n");
206476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
206576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
206676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) {
206746100d07257824da2ae1147da0324b5788c95501Roland McGrath		fprintf(stderr, "out of memory\n");
206876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
206976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
207076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
207176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					(int)ld.ld_symb_size, strtab) < 0)
207276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		goto err;
207376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
207476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0
207576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
207676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[symbol: %s]\n", cp);
207776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		cp += strlen(cp)+1;
207876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
207976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
208076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
208176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
208276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (strcmp(cp, "_vfork") == 0) {
208376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (debug)
208476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				fprintf(stderr, "fixvfork: FOUND _vfork\n");
208576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			strcpy(cp, "_fork");
208676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
208776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
208876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		cp += strlen(cp)+1;
208976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
209076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (cp < strtab + ld.ld_symb_size)
209176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/*
209276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		 * Write entire symbol table back to avoid
209376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		 * memory alignment bugs in ptrace
209476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		 */
209576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
209676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					(int)ld.ld_symb_size, strtab) < 0)
209776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			goto err;
209876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
209976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	free(strtab);
210076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
210176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
210276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerr:
210376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	free(strtab);
210476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return -1;
210576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
210676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
210776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
2108