util.c revision 09a13c2da736aa9a74e7de761062c82832f7cf04
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) \
130adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	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;
19658372f52ac5f824be687c01bfc1db1ffb963f91eRoland McGrath	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;
230fefdd97156bb2f86c5b6596dc7e28d954516b3edDmitry V. Levin	tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000;
23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec %= 1000000;
23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
234ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinconst char *
235ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinxlookup(const struct xlat *xlat, int val)
23676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
23776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (; xlat->str != NULL; xlat++)
23876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val == val)
23976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return xlat->str;
24076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return NULL;
24176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
24376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
244eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Generic ptrace wrapper which tracks ESRCH errors
245eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * by setting tcp->ptrace_errno to ESRCH.
246732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko *
247732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * We assume that ESRCH indicates likely process death (SIGKILL?),
248732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * modulo bugs where process somehow ended up not stopped.
249732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Unfortunately kernel uses ESRCH for that case too. Oh well.
250eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath *
251eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Currently used by upeek() only.
252eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * TODO: use this in all other ptrace() calls while decoding.
253732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko */
254732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenkolong
255eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathdo_ptrace(int request, struct tcb *tcp, void *addr, void *data)
256732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko{
257732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko	long l;
258732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko
259732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko	errno = 0;
26009a13c2da736aa9a74e7de761062c82832f7cf04Mike Frysinger	l = ptrace(request, tcp->pid, addr, (long) data);
261eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	/* Non-ESRCH errors might be our invalid reg/mem accesses,
262eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	 * we do not record them. */
263eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (errno == ESRCH)
264eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		tcp->ptrace_errno = ESRCH;
265732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko	return l;
266732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko}
267732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko
268732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko/*
269732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Used when we want to unblock stopped traced process.
270732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL.
271732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Returns 0 on success or if error was ESRCH
272732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * (presumably process was killed while we talk to it).
273732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Otherwise prints error message and returns -1.
274732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko */
275732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenkoint
276eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathptrace_restart(int op, struct tcb *tcp, int sig)
277732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko{
278732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko	int err;
279eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	const char *msg;
280732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko
281732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko	errno = 0;
28209a13c2da736aa9a74e7de761062c82832f7cf04Mike Frysinger	ptrace(op, tcp->pid, (void *) 1, (long) sig);
283732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko	err = errno;
284732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko	if (!err || err == ESRCH)
285732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko		return 0;
286732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko
287732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko	tcp->ptrace_errno = err;
288eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	msg = "SYSCALL";
289eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (op == PTRACE_CONT)
290eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		msg = "CONT";
291eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (op == PTRACE_DETACH)
292eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		msg = "DETACH";
293eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	fprintf(stderr, "strace: ptrace(PTRACE_%s,1,%d): %s\n",
294eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			msg, sig, strerror(err));
295732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko	return -1;
296732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko}
297732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko
298732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko/*
29976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Print entry in struct xlat table, if there.
30076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
30176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
302ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinprintxval(const struct xlat *xlat, int val, const char *dflt)
30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
304ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levin	const char *str = xlookup(xlat, val);
30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
30676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (str)
30776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s", str);
30876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else
30976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#x /* %s */", val, dflt);
31076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
31176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
31276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
31376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interpret `xlat' as an array of flags
31476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * print the entries whose bits are on in `flags'
31576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * return # of flags printed.
31676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
31776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
31876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanaddflags(xlat, flags)
319d9f816f60457930af27349fac3d23b3b78338036Roland McGrathconst struct xlat *xlat;
32076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags;
32176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
32276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
32376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
32476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (n = 0; xlat->str; xlat++) {
32576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val && (flags & xlat->val) == xlat->val) {
32676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("|%s", xlat->str);
32776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			flags &= ~xlat->val;
32876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			n++;
32976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
33076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
33176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (flags) {
33276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("|%#x", flags);
33376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n++;
33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return n;
33676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
33776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
338a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath/*
339a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Interpret `xlat' as an array of flags/
340a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Print to static string the entries whose bits are on in `flags'
341a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Return static string.
342a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath */
343a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrathconst char *
344a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrathsprintflags(const char *prefix, const struct xlat *xlat, int flags)
345a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath{
346a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath	static char outstr[1024];
347a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath	int found = 0;
348a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath
349a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath	strcpy(outstr, prefix);
350a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath
351a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath	for (; xlat->str; xlat++) {
352a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath		if ((flags & xlat->val) == xlat->val) {
353a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath			if (found)
354a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath				strcat(outstr, "|");
355a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath			strcat(outstr, xlat->str);
356a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath			flags &= ~xlat->val;
357a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath			found = 1;
358a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath		}
359a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath	}
360a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath	if (flags) {
361a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath		if (found)
362a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath			strcat(outstr, "|");
363a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath		sprintf(outstr + strlen(outstr), "%#x", flags);
364a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath	}
365a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath
366a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath	return outstr;
367a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath}
368a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath
36976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
370b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrathprintflags(xlat, flags, dflt)
371d9f816f60457930af27349fac3d23b3b78338036Roland McGrathconst struct xlat *xlat;
37276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags;
373b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrathconst char *dflt;
37476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
37576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
37676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *sep;
37776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
37876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (flags == 0 && xlat->val == 0) {
37976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s", xlat->str);
38076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 1;
38176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
38276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	sep = "";
38476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (n = 0; xlat->str; xlat++) {
38576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val && (flags & xlat->val) == xlat->val) {
38676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%s%s", sep, xlat->str);
38776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			flags &= ~xlat->val;
38876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			sep = "|";
38976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			n++;
39076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
39176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
392b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath
393b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath	if (n) {
394b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath		if (flags) {
395b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath			tprintf("%s%#x", sep, flags);
396b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath			n++;
397b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath		}
398b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath	} else {
399b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath		if (flags) {
400b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath			tprintf("%#x", flags);
401b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath			if (dflt)
402b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath				tprintf(" /* %s */", dflt);
403b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath		} else {
404b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath			if (dflt)
405b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath				tprintf("0");
406b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath		}
40776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
408b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath
40976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return n;
41076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
41176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
41276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
41376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintnum(tcp, addr, fmt)
41476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
41576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
41676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *fmt;
41776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
418eb285359906700f46b22cf4f9911695034313736Roland McGrath	long num;
41976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
42076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!addr) {
42176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("NULL");
42276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
42376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
42476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umove(tcp, addr, &num) < 0) {
42576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#lx", addr);
42676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
42776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
42876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[");
42976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf(fmt, num);
43076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("]");
43176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
43276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
4336bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathvoid
4349814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathprintnum_int(tcp, addr, fmt)
4359814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathstruct tcb *tcp;
4369814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathlong addr;
4379814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathchar *fmt;
4389814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath{
4399814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	int num;
4409814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath
4419814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	if (!addr) {
4429814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath		tprintf("NULL");
4439814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath		return;
4449814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	}
4459814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	if (umove(tcp, addr, &num) < 0) {
4469814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath		tprintf("%#lx", addr);
4479814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath		return;
4489814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	}
4499814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	tprintf("[");
4509814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	tprintf(fmt, num);
4519814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	tprintf("]");
4529814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath}
4539814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath
4549814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathvoid
4556bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathprintuid(text, uid)
4566bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathconst char *text;
4576bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathunsigned long uid;
4586bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath{
4596bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath	tprintf("%s", text);
4606bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath	tprintf((uid == -1) ? "%ld" : "%lu", uid);
4616bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath}
4626bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath
46376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic char path[MAXPATHLEN + 1];
46476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
465a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/*
466a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Quote string `instr' of length `size'
467a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
468a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If `len' < 0, treat `instr' as a NUL-terminated string
469a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * and quote at most (`size' - 1) bytes.
470a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */
4716d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrathstatic int
472bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinstring_quote(const char *instr, char *outstr, int len, int size)
47376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
474bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	const unsigned char *ustr = (const unsigned char *) instr;
475bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	char *s = outstr;
476bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	int usehex = 0, c, i;
47776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
478bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	if (xflag > 1)
479bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		usehex = 1;
480bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	else if (xflag) {
481a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		/* Check for presence of symbol which require
482a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		   to hex-quote the whole string. */
483bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		for (i = 0; i < size; ++i) {
484bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			c = ustr[i];
485a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin			/* Check for NUL-terminated string. */
486a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin			if (len < 0) {
487a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin				if (c == '\0')
488a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin					break;
489a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin				/* Quote at most size - 1 bytes. */
490a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin				if (i == size - 1)
491a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin					continue;
492a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin			}
493bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			if (!isprint(c) && !isspace(c)) {
494bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				usehex = 1;
495bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				break;
496bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			}
497bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		}
49876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
499bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin
500bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	*s++ = '\"';
501bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin
502bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	if (usehex) {
503a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		/* Hex-quote the whole string. */
504bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		for (i = 0; i < size; ++i) {
505bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			c = ustr[i];
506a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin			/* Check for NUL-terminated string. */
507a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin			if (len < 0) {
508a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin				if (c == '\0')
509a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin					break;
510a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin				/* Quote at most size - 1 bytes. */
511a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin				if (i == size - 1)
512a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin					continue;
513a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin			}
514bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			sprintf(s, "\\x%02x", c);
515bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			s += 4;
516bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		}
517bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	} else {
518bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		for (i = 0; i < size; ++i) {
519bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			c = ustr[i];
520a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin			/* Check for NUL-terminated string. */
521a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin			if (len < 0) {
522a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin				if (c == '\0')
523a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin					break;
524a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin				/* Quote at most size - 1 bytes. */
525a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin				if (i == size - 1)
526a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin					continue;
527a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin			}
528bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			switch (c) {
529bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				case '\"': case '\\':
530bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = '\\';
531bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = c;
532bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					break;
533bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				case '\f':
534bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = '\\';
535bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = 'f';
536bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					break;
537bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				case '\n':
538bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = '\\';
539bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = 'n';
540bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					break;
541bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				case '\r':
542bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = '\\';
543bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = 'r';
544bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					break;
545bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				case '\t':
546bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = '\\';
547bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = 't';
548bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					break;
549bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				case '\v':
550bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = '\\';
551bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = 'v';
552bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					break;
553bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				default:
554bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					if (isprint(c))
555bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin						*s++ = c;
556bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					else if (i + 1 < size
557bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin						 && isdigit(ustr[i + 1])) {
558bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin						sprintf(s, "\\%03o", c);
559bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin						s += 4;
560bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					} else {
561bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin						sprintf(s, "\\%o", c);
562bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin						s += strlen(s);
563bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					}
564bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					break;
565bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			}
56676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
56776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
56876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
569bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	*s++ = '\"';
570bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	*s = '\0';
5716d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath
5726d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath	/* Return nonzero if the string was unterminated.  */
5736d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath	return i == size;
57476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
57576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
576a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/*
577a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Print path string specified by address `addr' and length `n'.
578a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If path length exceeds `n', append `...' to the output.
579a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */
58076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
581bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintpathn(struct tcb *tcp, long addr, int n)
58276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
583a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin	if (!addr) {
584371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath		tprintf("NULL");
585bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		return;
586bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	}
587bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin
588a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin	/* Cap path length to the path buffer size,
589a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin	   and NUL-terminate the buffer. */
590a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin	if (n > sizeof path - 1)
591a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		n = sizeof path - 1;
592bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	path[n] = '\0';
593a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin
594a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin	/* Fetch one byte more to find out whether path length > n. */
595bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	if (umovestr(tcp, addr, n + 1, path) < 0)
59676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#lx", addr);
59776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
598bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		static char outstr[4*(sizeof path - 1) + sizeof "\"...\""];
599bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		int trunc = (path[n] != '\0');
600bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin
601bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		if (trunc)
602bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			path[n] = '\0';
603a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		(void) string_quote(path, outstr, -1, n + 1);
604a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		if (trunc)
605bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			strcat(outstr, "...");
606bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		tprintf("%s", outstr);
60776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
60876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
60976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
61076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
611bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintpath(struct tcb *tcp, long addr)
612bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin{
613bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	printpathn(tcp, addr, sizeof path - 1);
614bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin}
615bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin
616a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/*
617a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Print string specified by address `addr' and length `len'.
618a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If `len' < 0, treat the string as a NUL-terminated string.
619a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If string length exceeds `max_strlen', append `...' to the output.
620a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */
621bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinvoid
622bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintstr(struct tcb *tcp, long addr, int len)
62376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
624bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	static char *str = NULL;
62576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static char *outstr;
6266d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath	int size;
62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
62876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!addr) {
62976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("NULL");
63076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
63176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
632a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin	/* Allocate static buffers if they are not allocated yet. */
633a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin	if (!str)
634a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		str = malloc(max_strlen + 1);
635a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin	if (!outstr)
636a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		outstr = malloc(4 * max_strlen + sizeof "\"...\"");
637a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin	if (!str || !outstr) {
638a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		fprintf(stderr, "out of memory\n");
639a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		tprintf("%#lx", addr);
640a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		return;
64176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
642bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin
64376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (len < 0) {
644a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		/*
645a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		 * Treat as a NUL-terminated string: fetch one byte more
646a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		 * because string_quote() quotes one byte less.
647a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		 */
648bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		size = max_strlen + 1;
649a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		str[max_strlen] = '\0';
650bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		if (umovestr(tcp, addr, size, str) < 0) {
65176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%#lx", addr);
65276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
65376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
65476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
65576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
656a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		size = MIN(len, max_strlen);
657bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		if (umoven(tcp, addr, size, str) < 0) {
65876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%#lx", addr);
65976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
66076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
66176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
66276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
663a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin	if (string_quote(str, outstr, len, size) &&
664a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin	    (len < 0 || len > max_strlen))
665bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		strcat(outstr, "...");
66676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
66776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("%s", outstr);
66876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
66976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
6701d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H
6711d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesvoid
6721d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesdumpiov(tcp, len, addr)
6731d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesstruct tcb * tcp;
6741d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesint len;
6751d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hugheslong addr;
6761d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes{
6774ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
6784ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin	union {
6794ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin		struct { u_int32_t base; u_int32_t len; } *iov32;
6804ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin		struct { u_int64_t base; u_int64_t len; } *iov64;
6814ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin	} iovu;
6824ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov iovu.iov64
6834ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define sizeof_iov \
6844ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin  (personality_wordsize[current_personality] == 4 \
6854ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin   ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64))
6864ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_base(i) \
6874ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin  (personality_wordsize[current_personality] == 4 \
6884ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin   ? (u_int64_t) iovu.iov32[i].base : iovu.iov64[i].base)
6894ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_len(i) \
6904ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin  (personality_wordsize[current_personality] == 4 \
6914ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin   ? (u_int64_t) iovu.iov32[i].len : iovu.iov64[i].len)
6924ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#else
6931d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	struct iovec *iov;
6944ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define sizeof_iov sizeof(*iov)
6954ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_base(i) iov[i].iov_base
6964ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_len(i) iov[i].iov_len
6974ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#endif
6981d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	int i;
699aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath	unsigned long size;
7001d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes
7014ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin	size = sizeof_iov * (unsigned long) len;
7024ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin	if (size / sizeof_iov != len
7034ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin	    || (iov = malloc(size)) == NULL) {
704aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath		fprintf(stderr, "out of memory\n");
7051d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes		return;
7061d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	}
707aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath	if (umoven(tcp, addr, size, (char *) iov) >= 0) {
7081d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes		for (i = 0; i < len; i++) {
709adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko			/* include the buffer number to make it easy to
710adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko			 * match up the trace with the source */
711adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko			tprintf(" * %lu bytes in buffer %d\n",
712adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko				(unsigned long)iov_iov_len(i), i);
713adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko			dumpstr(tcp, (long) iov_iov_base(i),
714adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko				iov_iov_len(i));
715adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko		}
7161d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	}
7171d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	free((char *) iov);
7184ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef sizeof_iov
7194ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov_iov_base
7204ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov_iov_len
7214ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov
7221d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes}
7231d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif
7241d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes
72576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
72676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandumpstr(tcp, addr, len)
72776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
72876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr;
72976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len;
73076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
73176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static int strsize = -1;
73276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static unsigned char *str;
73376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static char outstr[80];
73476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *s;
73576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i, j;
73676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
73776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (strsize < len) {
73876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (str)
73976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			free(str);
74076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if ((str = malloc(len)) == NULL) {
74146100d07257824da2ae1147da0324b5788c95501Roland McGrath			fprintf(stderr, "out of memory\n");
74276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
74376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		strsize = len;
74576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umoven(tcp, addr, len, (char *) str) < 0)
74876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (i = 0; i < len; i += 16) {
75176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		s = outstr;
75276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		sprintf(s, " | %05x ", i);
75376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		s += 9;
75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (j = 0; j < 16; j++) {
75576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (j == 8)
75676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
75776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (i + j < len) {
75876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				sprintf(s, " %02x", str[i + j]);
75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				s += 3;
76076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
76176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			else {
76276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' '; *s++ = ' '; *s++ = ' ';
76376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
76476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
76576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		*s++ = ' '; *s++ = ' ';
76676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (j = 0; j < 16; j++) {
76776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (j == 8)
76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (i + j < len) {
77076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				if (isprint(str[i + j]))
77176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					*s++ = str[i + j];
77276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				else
77376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					*s++ = '.';
77476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
77576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			else
77676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
77776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
77876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s |\n", outstr);
77976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
78076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
78176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
78276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PAGMASK	(~(PAGSIZ - 1))
78376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
78476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * move `len' bytes of data from process `pid'
78576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * at address `addr' to our space at `laddr'
78676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
78776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
788ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoumoven(struct tcb *tcp, long addr, int len, char *laddr)
78976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
79076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
791eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	int pid = tcp->pid;
79276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n, m;
7935daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman	int started = 0;
79476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
79576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
79676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
79776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
79876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
79976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
80076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
80176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
80276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
803eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		errno = 0;
804eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
805eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
806eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (started && (errno==EPERM || errno==EIO)) {
807eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				/* Ran into 'end of memory' - stupid "printpath" */
808eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				return 0;
809eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			}
810eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			/* But if not started, we had a bogus address. */
811eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (addr != 0 && errno != EIO && errno != ESRCH)
812eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				perror("ptrace: umoven");
813eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			return -1;
814eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		}
8155daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
81676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
81776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
81876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
81976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
820eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		errno = 0;
821eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
822eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
823eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (started && (errno==EPERM || errno==EIO)) {
824eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				/* Ran into 'end of memory' - stupid "printpath" */
825eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				return 0;
826eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			}
827eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (addr != 0 && errno != EIO && errno != ESRCH)
828eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				perror("ptrace: umoven");
829eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			return -1;
830eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		}
8315daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
83276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
83376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
83476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
83576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
83676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
83776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
83876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
83976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0
84076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n, m;
84176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
84276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
84376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
84476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
84576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
84676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
84776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
84876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
84976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
850eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		errno = 0;
851eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
852eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
853eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (errno != ESRCH)
854eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				perror("umoven");
85576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
856eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		}
85776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
85876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
85976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
86076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
861eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		errno = 0;
862eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
863eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
864eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (errno != ESRCH)
865eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				perror("umoven");
86676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
867eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		}
86876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
86976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
87076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
87176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !oldway */
87276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
87376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
87476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
87576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(len, PAGSIZ);
87676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
877eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (ptrace(PTRACE_READDATA, pid,
878eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			   (char *) addr, len, laddr) < 0) {
879eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (errno != ESRCH) {
880eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				perror("umoven: ptrace(PTRACE_READDATA, ...)");
881eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				abort();
882eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			}
88376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
88476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
88576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		len -= n;
88676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += n;
88776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		laddr += n;
88876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
88976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !oldway */
89076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
89176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
892bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS
893ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS
894aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int fd = tcp->pfd_as;
8959ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else
896aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int fd = tcp->pfd;
89776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
898aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	lseek(fd, addr, SEEK_SET);
899aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	if (read(fd, laddr, len) == -1)
90076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
901bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */
90276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
90376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
90476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
90576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
90676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
90776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * like `umove' but make the additional effort of looking
90876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * for a terminating zero byte.
90976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
91076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
911ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoumovestr(struct tcb *tcp, long addr, int len, char *laddr)
91276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
913bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS
914aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#ifdef HAVE_MP_PROCFS
915aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int fd = tcp->pfd_as;
916aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#else
917aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int fd = tcp->pfd;
918aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#endif
919aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	/* Some systems (e.g. FreeBSD) can be upset if we read off the
920aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   end of valid memory,  avoid this by trying to read up
921aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   to page boundaries.  But we don't know what a page is (and
922aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   getpagesize(2) (if it exists) doesn't necessarily return
923aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   hardware page size).  Assume all pages >= 1024 (a-historical
924aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	   I know) */
925aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes
926aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int page = 1024; 	/* How to find this? */
927aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int move = page - (addr & (page - 1));
928aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	int left = len;
929aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes
930aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	lseek(fd, addr, SEEK_SET);
931aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes
932aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	while (left) {
933aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		if (move > left) move = left;
9349cecf7f8d6115a247be7186013857270b2d588d5John Hughes		if ((move = read(fd, laddr, move)) <= 0)
935aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes			return left != len ? 0 : -1;
936aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		if (memchr (laddr, 0, move)) break;
937aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		left -= move;
938aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		laddr += move;
939aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		addr += move;
940aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes		move = page;
941aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	}
942bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */
9435daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman	int started = 0;
944eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	int pid = tcp->pid;
94576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i, n, m;
94676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
94776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
94876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
94976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
95176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
95276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
95376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
95476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
955eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		errno = 0;
956eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
957eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
958eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (started && (errno==EPERM || errno==EIO)) {
959eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				/* Ran into 'end of memory' - stupid "printpath" */
960eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				return 0;
961eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			}
962eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (addr != 0 && errno != EIO && errno != ESRCH)
963eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				perror("umovestr");
964eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			return -1;
965eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		}
9665daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
96776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len));
96876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		while (n & (sizeof(long) - 1))
96976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (u.x[n++] == '\0')
97076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
97176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
97276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
97376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
974eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		errno = 0;
975eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
976eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
977eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (started && (errno==EPERM || errno==EIO)) {
978eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				/* Ran into 'end of memory' - stupid "printpath" */
979eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				return 0;
980eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			}
981eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (addr != 0 && errno != EIO && errno != ESRCH)
982eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				perror("umovestr");
983eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			return -1;
984eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		}
9855daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
98676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < sizeof(long); i++)
98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (u.x[i] == '\0')
98976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				return 0;
99076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
993bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */
994aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	return 0;
99576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
9983bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if !defined (SPARC) && !defined(SPARC64)
9993bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  define PTRACE_WRITETEXT	101
10003bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  define PTRACE_WRITEDATA	102
10013bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* !SPARC && !SPARC64 */
100276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
100376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
100476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
100576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
100676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int
1007eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathuload(cmd, pid, addr, len, laddr)
1008eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint cmd;
1009eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint pid;
1010eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathlong addr;
1011eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint len;
1012eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathchar *laddr;
101376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
10143bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if 0
101576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
101676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
101776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
101876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(len, PAGSIZ);
101976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
1020eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) {
1021eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			perror("uload: ptrace(PTRACE_WRITE, ...)");
102276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
102376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
102476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		len -= n;
102576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += n;
102676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		laddr += n;
102776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
10283bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else
102976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int peek, poke;
103076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n, m;
103176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
103276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
103376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
103476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
103576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
103676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (cmd == PTRACE_WRITETEXT) {
103776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		peek = PTRACE_PEEKTEXT;
103876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		poke = PTRACE_POKETEXT;
103976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
104076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
104176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		peek = PTRACE_PEEKDATA;
104276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		poke = PTRACE_POKEDATA;
104376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
104476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
104576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
104676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
104776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long);
1048eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		errno = 0;
1049eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		u.val = ptrace(peek, pid, (char *) addr, 0);
1050eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
1051eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			perror("uload: POKE");
105276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
1053eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		}
1054eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len));
1055eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (ptrace(poke, pid, (char *)addr, u.val) < 0) {
1056eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			perror("uload: POKE");
105776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
105876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
1059eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		addr += sizeof(long), laddr += m, len -= m;
106076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
106176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
106276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (len < sizeof(long))
1063eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			u.val = ptrace(peek, pid, (char *) addr, 0);
1064eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		memcpy(u.x, laddr, m = MIN(sizeof(long), len));
1065eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (ptrace(poke, pid, (char *) addr, u.val) < 0) {
1066eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			perror("uload: POKE");
106776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
106876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
1069eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		addr += sizeof(long), laddr += m, len -= m;
107076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
10713bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif
107276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
107376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
107476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1075eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint
1076eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathtload(pid, addr, len, laddr)
1077eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint pid;
1078eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint addr, len;
1079eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathchar *laddr;
1080eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath{
1081eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	return uload(PTRACE_WRITETEXT, pid, addr, len, laddr);
1082eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath}
1083eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath
1084eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint
1085eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathdload(pid, addr, len, laddr)
1086eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint pid;
1087eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint addr;
1088eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint len;
1089eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathchar *laddr;
109076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
1091eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	return uload(PTRACE_WRITEDATA, pid, addr, len, laddr);
109276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
109376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
109476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
109576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1096bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS
109776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
109876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
1099eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathupeek(tcp, off, res)
1100eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathstruct tcb *tcp;
1101eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathlong off;
1102eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathlong *res;
110376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
110476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long val;
110576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
11063bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SUNOS4_KERNEL_ARCH_KLUDGE
110776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	{
110876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		static int is_sun4m = -1;
110976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		struct utsname name;
111076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
111176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* Round up the usual suspects. */
111276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (is_sun4m == -1) {
111376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (uname(&name) < 0) {
111476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				perror("upeek: uname?");
111576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				exit(1);
111676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
111776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			is_sun4m = strcmp(name.machine, "sun4m") == 0;
111876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (is_sun4m) {
1119d9f816f60457930af27349fac3d23b3b78338036Roland McGrath				const struct xlat *x;
112076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
112176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				for (x = struct_user_offsets; x->str; x++)
112276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					x->val += 1024;
112376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
112476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
112576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (is_sun4m)
112676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			off += 1024;
112776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
11283bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
1129eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	errno = 0;
1130732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko	val = do_ptrace(PTRACE_PEEKUSER, tcp, (char *) off, 0);
1131eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (val == -1 && errno) {
1132eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno != ESRCH) {
1133eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			char buf[60];
1134eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)", tcp->pid, off);
1135eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			perror(buf);
1136eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		}
113776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
1138eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	}
113976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*res = val;
114076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
114176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
114276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1143bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */
114476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1145a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrath#if 0
114676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong
11475ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenkogetpc(struct tcb *tcp)
114876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
114976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
115076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
115176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
11523bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined(I386)
1153932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 4*EIP, &pc) < 0)
115476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
11553bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(X86_64)
1156932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 8*RIP, &pc) < 0)
11570e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		return -1;
11583bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(IA64)
1159932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, PT_B0, &pc) < 0)
11608b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		return -1;
11613bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ARM)
1162932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 4*15, &pc) < 0)
116376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
11645ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# elif defined(AVR32)
11655ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko	if (upeek(tcp, REG_PC, &pc) < 0)
11665ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko		return -1;
11673bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(BFIN)
1168932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, REG_PC, &pc) < 0)
116987ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin		return -1;
11703bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(POWERPC)
1171932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0)
117276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
11733bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(M68K)
1174932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 4*PT_PC, &pc) < 0)
117576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
11763bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ALPHA)
1177932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, REG_PC, &pc) < 0)
117876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
11793bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(MIPS)
11803bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko	if (upeek(tcp, REG_EPC, &pc) < 0)
11813bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko		return -1;
11823bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SPARC) || defined(SPARC64)
11839ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	struct regs regs;
1184eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
118576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
11869ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	pc = regs.r_pc;
11873bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(S390) || defined(S390X)
1188eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if(upeek(tcp,PT_PSWADDR,&pc) < 0)
118910a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig		return -1;
11903bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(HPPA)
1191eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if(upeek(tcp,PT_IAOQ0,&pc) < 0)
1192c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return -1;
11933bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH)
1194eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (upeek(tcp, 4*REG_PC ,&pc) < 0)
1195adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko		return -1;
11963bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH64)
1197adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	if (upeek(tcp, REG_PC ,&pc) < 0)
1198adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko		return -1;
11993bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif
120076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return pc;
120176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
120276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
120376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
120476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
120576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Return current program counter for `pid'
120676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Assumes PC is never 0xffffffff
120776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
120876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct regs regs;
120976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1210eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
1211eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		perror("getpc: ptrace(PTRACE_GETREGS, ...)");
121276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
1213eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	}
121476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return regs.r_pc;
121576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
121676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
121776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4
121876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* XXX */
121976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
122076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */
122176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1222bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD
1223bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	struct reg regs;
1224bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
1225bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	return regs.r_eip;
1226bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */
122776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
12283bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#endif /* 0 */
122976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
123076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
1231ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenkoprintcall(struct tcb *tcp)
123276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
12337a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath#define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \
12347a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath			   sizeof(long) == 8 ? "[????????????????] " : \
12357a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath			   NULL /* crash */)
123676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
123776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX
12383bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef I386
123976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long eip;
124076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1241932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 4*EIP, &eip) < 0) {
12427a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
124376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
124476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
124576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", eip);
1246eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath
12473bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(S390) || defined(S390X)
1248adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	long psw;
1249eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if(upeek(tcp,PT_PSWADDR,&psw) < 0) {
1250adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko		PRINTBADPC;
1251adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko		return;
1252adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	}
12533bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  ifdef S390
1254adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	tprintf("[%08lx] ", psw);
12553bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  elif S390X
1256adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	tprintf("[%16lx] ", psw);
12573bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif
1258eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath
12593bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(X86_64)
12600e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	long rip;
12610e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig
1262932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 8*RIP, &rip) < 0) {
12637a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
12640e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		return;
12650e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	}
12660e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	tprintf("[%16lx] ", rip);
12673bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(IA64)
12688b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	long ip;
12698b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
1270932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, PT_B0, &ip) < 0) {
12717a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
12728b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		return;
12738b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	}
12748b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	tprintf("[%08lx] ", ip);
12753bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(POWERPC)
127676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
127776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1278932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) {
127976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf ("[????????] ");
128076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
128176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
128276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
12833bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(M68K)
128476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
128576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1286932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 4*PT_PC, &pc) < 0) {
128776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf ("[????????] ");
128876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
128976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
129076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
12913bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ALPHA)
129276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
129376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1294932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, REG_PC, &pc) < 0) {
12957a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		tprintf ("[????????????????] ");
129676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
129776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
129876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
12993bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SPARC) || defined(SPARC64)
13009ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	struct regs regs;
1301eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0) {
13027a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
130376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
130476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
13059ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	tprintf("[%08lx] ", regs.r_pc);
13063bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(HPPA)
1307c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	long pc;
1308c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman
1309eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if(upeek(tcp,PT_IAOQ0,&pc) < 0) {
1310c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		tprintf ("[????????] ");
1311c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return;
1312c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	}
1313c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	tprintf("[%08lx] ", pc);
13143bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(MIPS)
131575c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	long pc;
131675c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman
1317932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, REG_EPC, &pc) < 0) {
131875c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman		tprintf ("[????????] ");
131975c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman		return;
132075c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	}
132175c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	tprintf("[%08lx] ", pc);
13223bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH)
1323adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	long pc;
1324ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman
1325adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	if (upeek(tcp, 4*REG_PC, &pc) < 0) {
1326adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko		tprintf ("[????????] ");
1327adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko		return;
1328adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	}
1329adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	tprintf("[%08lx] ", pc);
13303bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH64)
1331e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath	long pc;
1332e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath
1333932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, REG_PC, &pc) < 0) {
13347a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		tprintf ("[????????????????] ");
1335e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath		return;
1336e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath	}
1337e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath	tprintf("[%08lx] ", pc);
13383bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ARM)
1339ef388689610fa17df1d3001face8057b411a2e26Roland McGrath	long pc;
1340e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath
1341932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 4*15, &pc) < 0) {
13427a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
1343ef388689610fa17df1d3001face8057b411a2e26Roland McGrath		return;
1344ef388689610fa17df1d3001face8057b411a2e26Roland McGrath	}
1345ef388689610fa17df1d3001face8057b411a2e26Roland McGrath	tprintf("[%08lx] ", pc);
13465ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# elif defined(AVR32)
13475ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko	long pc;
13485ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko
13495ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko	if (upeek(tcp, REG_PC, &pc) < 0) {
13505ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko		tprintf("[????????] ");
13515ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko		return;
13525ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko	}
13535ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko	tprintf("[%08lx] ", pc);
13543bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(BFIN)
135587ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin	long pc;
135687ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin
1357932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, PT_PC, &pc) < 0) {
135887ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin		PRINTBADPC;
135987ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin		return;
136087ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin	}
136187ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin	tprintf("[%08lx] ", pc);
1362ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#elif defined(CRISV10)
1363ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko	long pc;
1364ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko
1365eeb9ce3895f1ca0920d50696ef8b48124cef9da6Edgar E. Iglesias	if (upeek(tcp, 4*PT_IRP, &pc) < 0) {
1366ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko		PRINTBADPC;
1367ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko		return;
1368ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko	}
1369ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko	tprintf("[%08lx] ", pc);
1370ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#elif defined(CRISV32)
1371ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko	long pc;
1372ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko
1373eeb9ce3895f1ca0920d50696ef8b48124cef9da6Edgar E. Iglesias	if (upeek(tcp, 4*PT_ERP, &pc) < 0) {
1374ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko		PRINTBADPC;
1375ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko		return;
1376ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko	}
1377ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko	tprintf("[%08lx] ", pc);
13783bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* architecture */
137976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */
138076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
138176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
138276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct regs regs;
138376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1384eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
1385eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		perror("printcall: ptrace(PTRACE_GETREGS, ...)");
13867a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
138776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
138876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
138976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08x] ", regs.r_o7);
139076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
139176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
139276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4
139376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* XXX */
13947a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath	PRINTBADPC;
139576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
139676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1397bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD
1398bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	struct reg regs;
1399bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
1400bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman	tprintf("[%08x] ", regs.r_eip);
1401bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */
140276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
140376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
14043bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko
14053bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko/*
14063bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * These #if's are huge, please indent them correctly.
14073bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * It's easy to get confused otherwise.
14083bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko */
1409bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS
141076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
14113bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined LINUX
1412d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
14133bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  include "syscall.h"
14143291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath
14153bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  include <sys/syscall.h>
14163bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  ifndef CLONE_PTRACE
14173bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define CLONE_PTRACE    0x00002000
14183bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif
14193bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  ifndef CLONE_VFORK
14203bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define CLONE_VFORK     0x00004000
14213bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif
14223bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  ifndef CLONE_VM
14233bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define CLONE_VM        0x00000100
14243bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif
14253bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  ifndef CLONE_STOPPED
14263bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define CLONE_STOPPED   0x02000000
14273bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif
1428d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
14293bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  ifdef IA64
1430d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
143108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath/* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32
143208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath   subsystem has them for x86... */
14333bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define SYS_fork	2
14343bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define SYS_vfork	190
143508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
1436d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef unsigned long *arg_setup_state;
1437d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1438d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1439d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGratharg_setup(struct tcb *tcp, arg_setup_state *state)
1440d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
14411f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil	unsigned long cfm, sof, sol;
14421f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil	long bsp;
1443d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
14441f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil	if (ia32) {
14451f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil		/* Satisfy a false GCC warning.  */
14461f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil		*state = NULL;
144708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		return 0;
14481f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil	}
144908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
1450932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, PT_AR_BSP, &bsp) < 0)
1451d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return -1;
1452932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
1453d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return -1;
1454d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1455d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	sof = (cfm >> 0) & 0x7f;
1456d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	sol = (cfm >> 7) & 0x7f;
14571f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil	bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol);
1458d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
14591f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil	*state = (unsigned long *) bsp;
1460d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return 0;
1461d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1462d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
14633bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define arg_finish_change(tcp, state)	0
1464d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
14653bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   ifdef SYS_fork
1466d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1467d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathget_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp)
1468d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
146908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	int ret;
147008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
147108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	if (ia32)
1472932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko		ret = upeek (tcp, PT_R11, valp);
147308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	else
147408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ret = umoven (tcp,
147508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath			      (unsigned long) ia64_rse_skip_regs(*state, 0),
147608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath			      sizeof(long), (void *) valp);
147708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	return ret;
1478d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1479d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1480d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1481d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathget_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp)
1482d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
148308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	int ret;
148408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
148508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	if (ia32)
1486932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko		ret = upeek (tcp, PT_R9, valp);
148708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	else
148808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ret = umoven (tcp,
148908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath			      (unsigned long) ia64_rse_skip_regs(*state, 1),
149008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath			      sizeof(long), (void *) valp);
149108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	return ret;
1492d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
14933bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   endif
1494d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1495d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1496d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg0 (struct tcb *tcp, arg_setup_state *state, long val)
1497d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
149808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	int req = PTRACE_POKEDATA;
149908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	void *ap;
150008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
150108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	if (ia32) {
150208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ap = (void *) (intptr_t) PT_R11;	 /* r11 == EBX */
150308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		req = PTRACE_POKEUSER;
150408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	} else
150508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ap = ia64_rse_skip_regs(*state, 0);
1506eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	errno = 0;
1507eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	ptrace(req, tcp->pid, ap, val);
1508eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	return errno ? -1 : 0;
1509d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1510d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1511d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1512d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg1 (struct tcb *tcp, arg_setup_state *state, long val)
1513d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
151408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	int req = PTRACE_POKEDATA;
151508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	void *ap;
151608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
151708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	if (ia32) {
151808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ap = (void *) (intptr_t) PT_R9;		/* r9 == ECX */
151908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		req = PTRACE_POKEUSER;
152008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	} else
152108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ap = ia64_rse_skip_regs(*state, 1);
1522eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	errno = 0;
1523eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	ptrace(req, tcp->pid, ap, val);
1524eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	return errno ? -1 : 0;
1525d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1526d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1527b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath/* ia64 does not return the input arguments from functions (and syscalls)
1528b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath   according to ia64 RSE (Register Stack Engine) behavior.  */
1529b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath
15303bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define restore_arg0(tcp, state, val) ((void) (state), 0)
15313bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define restore_arg1(tcp, state, val) ((void) (state), 0)
1532b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath
15333bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  elif defined (SPARC) || defined (SPARC64)
1534d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1535d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef struct regs arg_setup_state;
1536d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
15373bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define arg_setup(tcp, state) \
1538eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath    (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0))
15393bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define arg_finish_change(tcp, state) \
1540eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath    (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0))
1541d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
15423bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0)
15433bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0)
15443bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define set_arg0(tcp, state, val) ((state)->r_o0 = (val), 0)
15453bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define set_arg1(tcp, state, val) ((state)->r_o1 = (val), 0)
15463bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define restore_arg0(tcp, state, val) 0
1547d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
15483bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  else /* other architectures */
1549d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
15503bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   if defined S390 || defined S390X
15517b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath/* Note: this is only true for the `clone' system call, which handles
15527b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath   arguments specially.  We could as well say that its first two arguments
15537b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath   are swapped relative to other architectures, but that would just be
15547b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath   another #ifdef in the calls.  */
15553bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg0_offset	PT_GPR3
15563bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg1_offset	PT_ORIGGPR2
15573bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define restore_arg0(tcp, state, val) ((void) (state), 0)
15583bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define restore_arg1(tcp, state, val) ((void) (state), 0)
15593bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg0_index	1
15603bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg1_index	0
15613bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   elif defined (ALPHA) || defined (MIPS)
15623bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg0_offset	REG_A0
15633bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg1_offset	(REG_A0+1)
15645ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko#   elif defined (AVR32)
15655ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko#    define arg0_offset	(REG_R12)
15665ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko#    define arg1_offset	(REG_R11)
15673bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   elif defined (POWERPC)
15683bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg0_offset	(sizeof(unsigned long)*PT_R3)
15693bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg1_offset	(sizeof(unsigned long)*PT_R4)
15703bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define restore_arg0(tcp, state, val) ((void) (state), 0)
15713bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   elif defined (HPPA)
15723bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg0_offset	 PT_GR26
15733bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg1_offset	 (PT_GR26-4)
15743bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   elif defined (X86_64)
15753bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg0_offset	((long)(8*(current_personality ? RBX : RDI)))
15763bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg1_offset	((long)(8*(current_personality ? RCX : RSI)))
15773bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   elif defined (SH)
15783bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg0_offset	(4*(REG_REG0+4))
15793bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg1_offset	(4*(REG_REG0+5))
15803bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   elif defined (SH64)
15813bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko    /* ABI defines arg0 & 1 in r2 & r3 */
15823bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg0_offset   (REG_OFFSET+16)
15833bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg1_offset   (REG_OFFSET+24)
15843bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define restore_arg0(tcp, state, val) 0
1585ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#   elif defined CRISV10 || defined CRISV32
1586ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#    define arg0_offset   (4*PT_R11)
1587ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#    define arg1_offset   (4*PT_ORIG_R10)
1588ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#    define restore_arg0(tcp, state, val) 0
1589ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#    define restore_arg1(tcp, state, val) 0
1590ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#    define arg0_index   1
1591ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#    define arg1_index   0
15923bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   else
15933bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg0_offset	0
15943bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define arg1_offset	4
15953bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    if defined ARM
15963bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     define restore_arg0(tcp, state, val) 0
15973bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    endif
15983bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   endif
1599d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1600d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef int arg_setup_state;
1601d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
16023bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define arg_setup(tcp, state) (0)
16033bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define arg_finish_change(tcp, state)	0
16043bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define get_arg0(tcp, cookie, valp) \
16053bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko    (upeek ((tcp), arg0_offset, (valp)))
16063bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define get_arg1(tcp, cookie, valp) \
16073bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko    (upeek ((tcp), arg1_offset, (valp)))
1608d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1609d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1610eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathset_arg0 (struct tcb *tcp, void *cookie, long val)
1611d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1612eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val);
1613d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1614d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1615d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1616eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathset_arg1 (struct tcb *tcp, void *cookie, long val)
1617d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1618eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val);
1619d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1620d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
16213bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif /* architectures */
1622d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
16233bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  ifndef restore_arg0
16243bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val))
16253bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif
16263bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  ifndef restore_arg1
16273bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val))
16283bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif
1629d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
16303bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  ifndef arg0_index
16313bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define arg0_index 0
16323bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   define arg1_index 1
16333bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif
163490d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath
1635d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint
1636418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkosetbpt(struct tcb *tcp)
1637d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
16383291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath	static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone };
1639d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	arg_setup_state state;
1640d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1641d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	if (tcp->flags & TCB_BPTSET) {
1642d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1643d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return -1;
1644d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	}
1645d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
16463291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath	/*
16473291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath	 * It's a silly kludge to initialize this with a search at runtime.
16483291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath	 * But it's better than maintaining another magic thing in the
16493291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath	 * godforsaken tables.
16503291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath	 */
16513291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath	if (clone_scno[current_personality] == 0) {
16523291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath		int i;
16533291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath		for (i = 0; i < nsyscalls; ++i)
16543291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath			if (sysent[i].sys_func == sys_clone) {
16553291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath				clone_scno[current_personality] = i;
16563291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath				break;
16573291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath			}
16583291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath	}
16593291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath
166076989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath	switch (known_scno(tcp)) {
16613bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  ifdef SYS_vfork
16629383c6c539af09303efe0a16dea55363b095f66eRoland McGrath	case SYS_vfork:
16633bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif
16643bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  ifdef SYS_fork
1665d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	case SYS_fork:
16663bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif
16673bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  if defined SYS_fork || defined SYS_vfork
1668d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		if (arg_setup (tcp, &state) < 0
1669d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || get_arg0 (tcp, &state, &tcp->inst[0]) < 0
1670d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || get_arg1 (tcp, &state, &tcp->inst[1]) < 0
16713291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath		    || change_syscall(tcp, clone_scno[current_personality]) < 0
1672d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0
1673d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || set_arg1 (tcp, &state, 0) < 0
1674d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		    || arg_finish_change (tcp, &state) < 0)
1675d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath			return -1;
1676c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath		tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD;
1677c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath		tcp->u_arg[arg1_index] = 0;
1678d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		tcp->flags |= TCB_BPTSET;
1679d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return 0;
16803bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif
1681d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1682d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	case SYS_clone:
16833bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  ifdef SYS_clone2
1684d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	case SYS_clone2:
16853bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif
16868fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil		/* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)'
16878fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil		   contrary to x86 SYS_vfork above.  Even on x86 we turn the
16888fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil		   vfork semantics into plain fork - each application must not
16898fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil		   depend on the vfork specifics according to POSIX.  We would
16908fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil		   hang waiting for the parent resume otherwise.  We need to
16918fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil		   clear also CLONE_VM but only in the CLONE_VFORK case as
16928fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil		   otherwise we would break pthread_create.  */
16938fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil
1694d6ff0d520d4bd8dda1523ec57e8ba2bc0ab3cf69Roland McGrath		if ((arg_setup (tcp, &state) < 0
1695d6ff0d520d4bd8dda1523ec57e8ba2bc0ab3cf69Roland McGrath		    || set_arg0 (tcp, &state,
1696d6ff0d520d4bd8dda1523ec57e8ba2bc0ab3cf69Roland McGrath				 (tcp->u_arg[arg0_index] | CLONE_PTRACE)
16978fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil				 & ~(tcp->u_arg[arg0_index] & CLONE_VFORK
16988fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil				     ? CLONE_VFORK | CLONE_VM : 0)) < 0
1699d6ff0d520d4bd8dda1523ec57e8ba2bc0ab3cf69Roland McGrath		    || arg_finish_change (tcp, &state) < 0))
17005ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko			return -1;
1701d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		tcp->flags |= TCB_BPTSET;
1702c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath		tcp->inst[0] = tcp->u_arg[arg0_index];
1703c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath		tcp->inst[1] = tcp->u_arg[arg1_index];
1704d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return 0;
1705d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1706d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	default:
1707d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n",
1708d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath			tcp->scno, tcp->pid);
1709d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		break;
1710d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	}
1711d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1712d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return -1;
1713d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1714d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1715d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint
1716d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathclearbpt(tcp)
1717d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstruct tcb *tcp;
1718d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1719d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	arg_setup_state state;
1720d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	if (arg_setup (tcp, &state) < 0
1721e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath	    || restore_arg0 (tcp, &state, tcp->inst[0]) < 0
1722e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath	    || restore_arg1 (tcp, &state, tcp->inst[1]) < 0
1723d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	    || arg_finish_change (tcp, &state))
1724d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return -1;
1725d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	tcp->flags &= ~TCB_BPTSET;
1726d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return 0;
1727d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1728d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
17293bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else /* !defined LINUX */
1730d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
173176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
173276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermansetbpt(tcp)
173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
173476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
17353bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  ifdef LINUX
17363bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko	DEAD CODE HERE? WE ARE IN 'else !defined LINUX'
17373bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   if defined (SPARC) || defined (SPARC64)
173876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* We simply use the SunOS breakpoint code. */
173976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
17409ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	struct regs regs;
17416d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath	unsigned long inst;
17423bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define LOOPA	0x30800000	/* ba,a	0 */
174376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
174476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tcp->flags & TCB_BPTSET) {
174576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
174676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
174776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
1748eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1749eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
175076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
175176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
17529ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman	tcp->baddr = regs.r_o7 + 8;
1753eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	errno = 0;
1754eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0);
1755eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if(errno) {
1756eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
175776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
1758eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	}
175976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
176076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
176176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * XXX - BRUTAL MODE ON
176276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * We cannot set a real BPT in the child, since it will not be
176376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * traced at the moment it will reach the trap and would probably
176476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * die with a core dump.
176576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Thus, we are force our way in by taking out two instructions
176676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * and insert an eternal loop instead, in expectance of the SIGSTOP
17673bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko	 * generated by our PTRACE_ATTACH.
176876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Of cause, if we evaporate ourselves in the middle of all this...
176976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
177076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	errno = 0;
17716d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath	inst = LOOPA;
17723bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    if defined (SPARC64)
17736d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath	inst <<= 32;
17746d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath	inst |= (tcp->inst[0] & 0xffffffffUL);
17753bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    endif
1776eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, inst);
1777eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if(errno) {
1778eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
177976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
1780eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	}
178176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags |= TCB_BPTSET;
178276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
17833bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   else /* !SPARC && !SPARC64 */
17843bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    ifdef IA64
17857b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman	if (ia32) {
17867b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#		define LOOP	0x0000feeb
17877b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (tcp->flags & TCB_BPTSET) {
17887b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			fprintf(stderr, "PANIC: bpt already set in pid %u\n",
17897b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				tcp->pid);
17907b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
17917b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
1792932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko		if (upeek(tcp, PT_CR_IIP, &tcp->baddr) < 0)
17937b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
17947b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (debug)
17957b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			fprintf(stderr, "[%d] setting bpt at %lx\n",
17967b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				tcp->pid, tcp->baddr);
1797eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid,
1798eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				      (char *) tcp->baddr, 0);
1799eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
1800eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
18017b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
1802eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		}
1803eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
1804eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
1805eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
18067b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
1807eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		}
18087b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->flags |= TCB_BPTSET;
18097b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman	} else {
18107b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		/*
18117b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * Our strategy here is to replace the bundle that
18127b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * contained the clone() syscall with a bundle of the
18137b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * form:
18147b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 *
18157b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 *	{ 1: br 1b; br 1b; br 1b }
18167b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 *
18177b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * This ensures that the newly forked child will loop
18187b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 * endlessly until we've got a chance to attach to it.
18197b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		 */
18203bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# 			define LOOP0	0x0000100000000017
18213bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# 			define LOOP1	0x4000000000200000
18228b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		unsigned long addr, ipsr;
18238b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		pid_t pid;
18248b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
18258b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		pid = tcp->pid;
1826932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko		if (upeek(tcp, PT_CR_IPSR, &ipsr) < 0)
18278b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
1828932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko		if (upeek(tcp, PT_CR_IIP, &addr) < 0)
18298b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
18307b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		/* store "ri" in low two bits */
18317b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->baddr = addr | ((ipsr >> 41) & 0x3);
18328b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
1833eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		errno = 0;
1834eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0,
1835eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				      0);
1836eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8,
1837eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				      0);
1838eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
1839eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
18408b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
1841eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		}
18428b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
1843eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		errno = 0;
1844eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0);
1845eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1);
1846eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
1847eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
18488b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
18498b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
18508b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		tcp->flags |= TCB_BPTSET;
18518b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	}
18523bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    else /* !IA64 */
18533bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko
18543bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     if defined (I386) || defined(X86_64)
18553bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#      define LOOP	0x0000feeb
18563bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined (M68K)
18573bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#      define LOOP	0x60fe0000
18583bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined (ALPHA)
18593bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#      define LOOP	0xc3ffffff
18603bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined (POWERPC)
18613bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#      define LOOP	0x48000000
18623bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined(ARM)
18633bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#      define LOOP	0xEAFFFFFE
18643bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined(MIPS)
18653bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#      define LOOP	0x1000ffff
18663bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined(S390)
18673bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#      define LOOP	0xa7f40000	/* BRC 15,0 */
18683bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined(S390X)
18693bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#      define LOOP   0xa7f4000000000000UL /* BRC 15,0 */
18703bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined(HPPA)
18713bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#      define LOOP	0xe81f1ff7	/* b,l,n <loc>,r0 */
18723bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined(SH)
18733bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#      ifdef __LITTLE_ENDIAN__
18743bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#       define LOOP   0x0000affe
18753bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#      else
18763bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#       define LOOP   0xfeaf0000
18773bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#      endif
18783bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     else
18793bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#      error unknown architecture
18803bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     endif
188176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
188276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tcp->flags & TCB_BPTSET) {
188376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid);
188476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
188576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
18863bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     if defined (I386)
1887932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 4*EIP, &tcp->baddr) < 0)
188876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
18893bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined (X86_64)
1890932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 8*RIP, &tcp->baddr) < 0)
18910e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		return -1;
18923bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined (M68K)
1893932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 4*PT_PC, &tcp->baddr) < 0)
18945ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko		return -1;
18953bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined (ALPHA)
189676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return -1;
18973bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined (ARM)
189876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return -1;
18993bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined (MIPS)
1900f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman	return -1;		/* FIXME: I do not know what i do - Flo */
19013bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined (POWERPC)
1902932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &tcp->baddr) < 0)
190376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
19043bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined(S390) || defined(S390X)
1905932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp,PT_PSWADDR, &tcp->baddr) < 0)
19064dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman		return -1;
19073bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined(HPPA)
1908932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, PT_IAOQ0, &tcp->baddr) < 0)
1909c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return -1;
1910c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	tcp->baddr &= ~0x03;
19113bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     elif defined(SH)
1912adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	if (upeek(tcp, 4*REG_PC, &tcp->baddr) < 0)
1913adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko		return -1;
19143bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     else
19153bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#      error unknown architecture
19163bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#     endif
191776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (debug)
191876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr);
1919eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0);
1920eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (errno) {
1921eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
192276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
1923eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	}
1924eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
1925eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (errno) {
1926eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
192776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
192876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
192976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags |= TCB_BPTSET;
193076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
19313bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    endif /* !IA64 */
19323bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   endif /* !SPARC && !SPARC64 */
19333bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif /* LINUX */
193476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
19353bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  ifdef SUNOS4
19363bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   ifdef SPARC	/* This code is slightly sparc specific */
193776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1938e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman	struct regs regs;
19393bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define BPT	0x91d02001	/* ta	1 */
19403bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define LOOP	0x10800000	/* ba	0 */
19413bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define LOOPA	0x30800000	/* ba,a	0 */
19423bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    define NOP	0x01000000
19433bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    if LOOPA
194476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static int loopdeloop[1] = {LOOPA};
19453bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    else
194676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static int loopdeloop[2] = {LOOP, NOP};
19473bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    endif
194876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
194976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (tcp->flags & TCB_BPTSET) {
195076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
195176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
195276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
1953eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1954eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
195576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
195676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
195776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->baddr = regs.r_o7 + 8;
1958eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr,
1959eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				sizeof tcp->inst, (char *)tcp->inst) < 0) {
1960eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		perror("setbpt: ptrace(PTRACE_READTEXT, ...)");
196176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
196276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
196376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
196476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
196576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * XXX - BRUTAL MODE ON
196676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * We cannot set a real BPT in the child, since it will not be
196776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * traced at the moment it will reach the trap and would probably
196876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * die with a core dump.
196976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Thus, we are force our way in by taking out two instructions
197076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * and insert an eternal loop in stead, in expectance of the SIGSTOP
197176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * generated by out PTRACE_ATTACH.
197276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Of cause, if we evaporate ourselves in the middle of all this...
197376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
1974eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
197576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			sizeof loopdeloop, (char *) loopdeloop) < 0) {
1976eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)");
197776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
197876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
197976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags |= TCB_BPTSET;
198076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
19813bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   endif /* SPARC */
19823bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif /* SUNOS4 */
198376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
198476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
198576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
198676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
198776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
198876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanclearbpt(tcp)
198976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
199076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
199176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
19923bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  ifdef LINUX
19933bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko	DEAD CODE HERE? WE ARE IN 'else !defined LINUX'
19943bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   if defined(I386) || defined(X86_64)
199576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long eip;
19963bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   elif defined(POWERPC)
199776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
19983bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   elif defined(M68K)
199976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
20003bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   elif defined(ALPHA)
200176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
20023bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   elif defined(HPPA)
2003c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	long iaoq;
20043bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   elif defined(SH)
2005adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	long pc;
20063bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   endif /* architecture */
200776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
20083bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   if defined (SPARC) || defined (SPARC64)
200976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* Again, we borrow the SunOS breakpoint code. */
201076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!(tcp->flags & TCB_BPTSET)) {
201176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
201276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
201376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
2014eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	errno = 0;
2015eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
2016eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if(errno) {
2017eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
201876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
201976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
202076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags &= ~TCB_BPTSET;
20213bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   elif defined(IA64)
20227b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman	if (ia32) {
20237b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		unsigned long addr;
20247b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman
20257b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (debug)
20267b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
20277b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (!(tcp->flags & TCB_BPTSET)) {
20287b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
20297b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
20307b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
2031eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		errno = 0;
2032eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
2033eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
2034eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
20357b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
20367b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
20377b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		tcp->flags &= ~TCB_BPTSET;
20387b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman
2039932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko		if (upeek(tcp, PT_CR_IIP, &addr) < 0)
20407b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return -1;
20417b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		if (addr != tcp->baddr) {
20427b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			/* The breakpoint has not been reached yet.  */
20437b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			if (debug)
20447b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman				fprintf(stderr,
20457b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman					"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
20467b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman						addr, tcp->baddr);
20477b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman			return 0;
20487b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman		}
20497b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman	} else {
20508b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		unsigned long addr, ipsr;
20518b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		pid_t pid;
20528b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
20538b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		pid = tcp->pid;
20548b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
2055932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko		if (upeek(tcp, PT_CR_IPSR, &ipsr) < 0)
20568b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
2057932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko		if (upeek(tcp, PT_CR_IIP, &addr) < 0)
20588b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
20598b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
20608b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		/* restore original bundle: */
2061eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		errno = 0;
2062eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]);
2063eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]);
2064eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
2065eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)");
20668b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
20678b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
20688b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
20698b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		/* restore original "ri" in ipsr: */
20708b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41);
2071eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		errno = 0;
2072eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr);
2073eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
2074eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)");
20758b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return -1;
20768b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
20778b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
20788b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		tcp->flags &= ~TCB_BPTSET;
20798b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
20808b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		if (addr != (tcp->baddr & ~0x3)) {
20818b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			/* the breakpoint has not been reached yet.  */
20828b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			if (debug)
20838b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman				fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
20848b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman					addr, tcp->baddr);
20858b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman			return 0;
20868b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		}
20878b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	}
20883bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   else /* !IA64 && !SPARC && !SPARC64 */
208976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
209076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (debug)
209176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
209276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!(tcp->flags & TCB_BPTSET)) {
209376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
209476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
209576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
2096eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	errno = 0;
2097eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
2098eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (errno) {
2099eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
210076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
210176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
210276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags &= ~TCB_BPTSET;
210376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
21043bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    ifdef I386
2105932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 4*EIP, &eip) < 0)
210676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
210776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (eip != tcp->baddr) {
210876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
210976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
211076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr,
211176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
211276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					eip, tcp->baddr);
211376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
211476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
21153bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    elif defined(X86_64)
2116932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 8*RIP, &eip) < 0)
21170e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		return -1;
21180e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	if (eip != tcp->baddr) {
21190e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		/* The breakpoint has not been reached yet.  */
21200e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		if (debug)
21210e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig			fprintf(stderr,
21220e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig				"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
21230e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig					eip, tcp->baddr);
21240e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		return 0;
21250e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	}
21263bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    elif defined(POWERPC)
2127932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0)
212876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
212976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (pc != tcp->baddr) {
213076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
213176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
213276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
213376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				pc, tcp->baddr);
213476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
213576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
21363bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    elif defined(M68K)
2137932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 4*PT_PC, &pc) < 0)
213876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
213976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (pc != tcp->baddr) {
214076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
214176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
214276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
214376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				pc, tcp->baddr);
214476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
214576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
21463bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    elif defined(ALPHA)
2147932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, REG_PC, &pc) < 0)
214876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
214976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (pc != tcp->baddr) {
215076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet.  */
215176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
215276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
215376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				pc, tcp->baddr);
215476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
215576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
21563bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    elif defined(HPPA)
2157932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, PT_IAOQ0, &iaoq) < 0)
2158c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return -1;
2159c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	iaoq &= ~0x03;
2160c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) {
2161c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		/* The breakpoint has not been reached yet.  */
2162c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		if (debug)
2163c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman			fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n",
2164c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman				iaoq, tcp->baddr);
2165c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return 0;
2166c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	}
2167c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	iaoq = tcp->baddr | 3;
2168c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	/* We should be pointing at a 'ldi -1000,r1' in glibc, so it is
2169c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	 * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit
2170c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	 * has no significant effect.
2171c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	 */
2172eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq);
2173eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq);
21743bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    elif defined(SH)
2175adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	if (upeek(tcp, 4*REG_PC, &pc) < 0)
2176adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko		return -1;
2177adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	if (pc != tcp->baddr) {
2178adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko		/* The breakpoint has not been reached yet.  */
2179adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko		if (debug)
2180adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2181adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko				pc, tcp->baddr);
2182adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko		return 0;
2183adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	}
2184ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman
21853bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    endif /* arch */
21863bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   endif /* !SPARC && !SPARC64 && !IA64 */
21873bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif /* LINUX */
218876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
21893bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  ifdef SUNOS4
21903bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   ifdef SPARC
219176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
21923bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    if !LOOPA
2193e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman	struct regs regs;
21943bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    endif
219576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
219676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!(tcp->flags & TCB_BPTSET)) {
219776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
219876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
219976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
2200eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
220176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				sizeof tcp->inst, (char *) tcp->inst) < 0) {
2202eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)");
220376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
220476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
220576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tcp->flags &= ~TCB_BPTSET;
220676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
22073bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    if !LOOPA
220876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
220976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Since we don't have a single instruction breakpoint, we may have
22103bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko	 * to adjust the program counter after removing our `breakpoint'.
221176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
2212eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
2213eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		perror("clearbpt: ptrace(PTRACE_GETREGS, ...)");
221476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
221576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
2216eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if ((regs.r_pc < tcp->baddr) ||
2217eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				(regs.r_pc > tcp->baddr + 4)) {
221876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* The breakpoint has not been reached yet */
221976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
222076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr,
222176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				"NOTE: PC not at bpt (pc %#x baddr %#x)\n",
22223bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko					regs.r_pc, tcp->baddr);
222376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 0;
222476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
222576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (regs.r_pc != tcp->baddr)
222676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (debug)
222776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n",
222876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				regs.r_pc, tcp->baddr);
222976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
223076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	regs.r_pc = tcp->baddr;
2231eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0) {
2232eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		perror("clearbpt: ptrace(PTRACE_SETREGS, ...)");
223376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
223476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
22353bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#    endif /* LOOPA */
22363bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#   endif /* SPARC */
22373bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#  endif /* SUNOS4 */
223876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
223976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
224076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
224176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
22423bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* !defined LINUX */
2243d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
2244bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */
224576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
22463bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko
224776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4
224876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
224976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int
2250932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenkogetex(tcp, hdr)
2251932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenkostruct tcb *tcp;
225276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct exec *hdr;
225376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
225476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
225576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
225676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (n = 0; n < sizeof *hdr; n += 4) {
225776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long res;
2258932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko		if (upeek(tcp, uoff(u_exdata) + n, &res) < 0)
225976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return -1;
226076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		memcpy(((char *) hdr) + n, &res, 4);
226176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
226276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (debug) {
226376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n",
226476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			hdr->a_magic, hdr->a_toolversion, hdr->a_machtype);
226576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n",
226676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry);
226776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
226876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
226976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
227076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
227176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
227276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfixvfork(tcp)
227376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp;
227476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
227576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int pid = tcp->pid;
227676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/*
227776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * Change `vfork' in a freshly exec'ed dynamically linked
227876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 * executable's (internal) symbol table to plain old `fork'
227976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	 */
228076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
228176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct exec hdr;
228276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct link_dynamic dyn;
228376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct link_dynamic_2 ld;
228476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *strtab, *cp;
228576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
2286932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (getex(tcp, &hdr) < 0)
228776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
228876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!hdr.a_dynamic)
228976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
229076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
229176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) {
229276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "Cannot read DYNAMIC\n");
229376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
229476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
229576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) {
229676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "Cannot read link_dynamic_2\n");
229776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
229876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
229976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) {
230046100d07257824da2ae1147da0324b5788c95501Roland McGrath		fprintf(stderr, "out of memory\n");
230176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
230276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
2303eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
230476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					(int)ld.ld_symb_size, strtab) < 0)
230576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		goto err;
230676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
23073bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if 0
230876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
230976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		fprintf(stderr, "[symbol: %s]\n", cp);
231076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		cp += strlen(cp)+1;
231176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
231276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
23133bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif
231476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
231576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (strcmp(cp, "_vfork") == 0) {
231676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (debug)
231776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				fprintf(stderr, "fixvfork: FOUND _vfork\n");
231876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			strcpy(cp, "_fork");
231976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
232076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
232176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		cp += strlen(cp)+1;
232276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
232376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (cp < strtab + ld.ld_symb_size)
232476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/*
232576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		 * Write entire symbol table back to avoid
232676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		 * memory alignment bugs in ptrace
232776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		 */
2328eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
232976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					(int)ld.ld_symb_size, strtab) < 0)
233076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			goto err;
233176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
233276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	free(strtab);
233376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
233476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
233576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerr:
233676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	free(strtab);
233776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return -1;
233876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
233976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
234076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */
2341