util.c revision 114aefd6183b8c073453f8def73270c42255f974
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
442d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# include <sys/uio.h>
451d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif
4636915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman
478470374cba7df0e70653d95c4f336a4082c68d82Denys Vlasenko#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1)
4876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <linux/ptrace.h>
491e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath#endif
5036915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman
518470374cba7df0e70653d95c4f336a4082c68d82Denys Vlasenko#if defined(IA64)
52d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# include <asm/ptrace_offsets.h>
53d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# include <asm/rse.h>
548b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#endif
558b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
5636915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#ifdef HAVE_SYS_REG_H
578470374cba7df0e70653d95c4f336a4082c68d82Denys Vlasenko# include <sys/reg.h>
5836915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman# define PTRACE_PEEKUSR PTRACE_PEEKUSER
59faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(HAVE_LINUX_PTRACE_H)
608470374cba7df0e70653d95c4f336a4082c68d82Denys Vlasenko# undef PTRACE_SYSCALL
61ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# ifdef HAVE_STRUCT_IA64_FPREG
62ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath#  define ia64_fpreg XXX_ia64_fpreg
63ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# endif
64ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# ifdef HAVE_STRUCT_PT_ALL_USER_REGS
65ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath#  define pt_all_user_regs XXX_pt_all_user_regs
66ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# endif
678470374cba7df0e70653d95c4f336a4082c68d82Denys Vlasenko# include <linux/ptrace.h>
68ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# undef ia64_fpreg
69ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# undef pt_all_user_regs
702e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#endif
712e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman
722d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#if defined(SPARC64)
736d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# undef PTRACE_GETREGS
746d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# define PTRACE_GETREGS PTRACE_GETREGS64
756d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# undef PTRACE_SETREGS
766d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# define PTRACE_SETREGS PTRACE_SETREGS64
779ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif
789ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman
7976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* macros */
8076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MAX
812d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define MAX(a,b)		(((a) > (b)) ? (a) : (b))
8276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
8376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MIN
842d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define MIN(a,b)		(((a) < (b)) ? (a) : (b))
8576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif
8676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
8776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
881201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_nz(struct timeval *a)
8976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
9076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return a->tv_sec || a->tv_usec;
9176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
9276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
9376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
941201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_cmp(struct timeval *a, struct timeval *b)
9576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
9676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (a->tv_sec < b->tv_sec
9776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	    || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
9876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
9976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (a->tv_sec > b->tv_sec
10076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	    || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
10176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 1;
10276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
10376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
10476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
10576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandouble
1061201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_float(struct timeval *tv)
10776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
10876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return tv->tv_sec + tv->tv_usec/1000000.0;
10976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
11076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
11176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
1121201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_add(struct timeval *tv, struct timeval *a, struct timeval *b)
11376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
11476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec + b->tv_sec;
11576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = a->tv_usec + b->tv_usec;
11658372f52ac5f824be687c01bfc1db1ffb963f91eRoland McGrath	if (tv->tv_usec >= 1000000) {
11776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_sec++;
11876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_usec -= 1000000;
11976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
12176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
12276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
1231201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_sub(struct timeval *tv, struct timeval *a, struct timeval *b)
12476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
12576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec - b->tv_sec;
12676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = a->tv_usec - b->tv_usec;
12776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (((long) tv->tv_usec) < 0) {
12876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_sec--;
12976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tv->tv_usec += 1000000;
13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
13176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
13276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
13376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
1341201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_div(struct timeval *tv, struct timeval *a, int n)
13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
13876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec %= 1000000;
13976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
14076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
14176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
1421201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_mul(struct timeval *tv, struct timeval *a, int n)
14376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec = a->tv_usec * n;
145fefdd97156bb2f86c5b6596dc7e28d954516b3edDmitry V. Levin	tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000;
14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tv->tv_usec %= 1000000;
14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
14876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
149ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinconst char *
150ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinxlookup(const struct xlat *xlat, int val)
15176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
15276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (; xlat->str != NULL; xlat++)
15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val == val)
15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return xlat->str;
15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return NULL;
15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
15776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1580a295bc97fd2ba9e6dc02f382dc87bc8705dc4d0Denys Vlasenko#if !defined HAVE_STPCPY
1595284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenkochar *
1605284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenkostpcpy(char *dst, const char *src)
1615284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko{
1625284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko	while ((*dst = *src++) != '\0')
1635284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko		dst++;
1645284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko	return dst;
1655284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko}
1660a295bc97fd2ba9e6dc02f382dc87bc8705dc4d0Denys Vlasenko#endif
1675284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko
16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
169732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Used when we want to unblock stopped traced process.
170732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL.
171732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Returns 0 on success or if error was ESRCH
172732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * (presumably process was killed while we talk to it).
173732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Otherwise prints error message and returns -1.
174732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko */
175732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenkoint
176eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathptrace_restart(int op, struct tcb *tcp, int sig)
177732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko{
178732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko	int err;
179eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	const char *msg;
180732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko
181732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko	errno = 0;
182114aefd6183b8c073453f8def73270c42255f974Denys Vlasenko	ptrace(op, tcp->pid, (void *) 0, (long) sig);
183732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko	err = errno;
184732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko	if (!err || err == ESRCH)
185732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko		return 0;
186732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko
187732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko	tcp->ptrace_errno = err;
188eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	msg = "SYSCALL";
189eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (op == PTRACE_CONT)
190eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		msg = "CONT";
191eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (op == PTRACE_DETACH)
192eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		msg = "DETACH";
19331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#ifdef PTRACE_LISTEN
19431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	if (op == PTRACE_LISTEN)
19531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		msg = "LISTEN";
19631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif
197114aefd6183b8c073453f8def73270c42255f974Denys Vlasenko	perror_msg("ptrace(PTRACE_%s,pid:%d,sig:%d)", msg, tcp->pid, sig);
198732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko	return -1;
199732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko}
200732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko
201732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko/*
20276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Print entry in struct xlat table, if there.
20376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
20476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
205ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinprintxval(const struct xlat *xlat, int val, const char *dflt)
20676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
207ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levin	const char *str = xlookup(xlat, val);
20876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
20976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (str)
2105940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko		tprints(str);
21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else
21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#x /* %s */", val, dflt);
21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
215b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab#if HAVE_LONG_LONG
216b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab/*
217b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab * Print 64bit argument at position llarg and return the index of the next
218b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab * argument.
219b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab */
220b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwabint
221b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwabprintllval(struct tcb *tcp, const char *format, int llarg)
222b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab{
223aa925db23634fe6a2c1d4b47accb3649daf1b781Denys Vlasenko# if defined(X86_64) || defined(POWERPC64)
224b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab	if (current_personality == 0) {
225b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab		tprintf(format, tcp->u_arg[llarg]);
226b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab		llarg++;
227b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab	} else {
228d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab#  ifdef POWERPC64
229d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab		/* Align 64bit argument to 64bit boundary.  */
2304b08df42ff069dcf44b8ed206ae33a2904c366baDenys Vlasenko		llarg = (llarg + 1) & 0x1e;
231d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab#  endif
232b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab		tprintf(format, LONG_LONG(tcp->u_arg[llarg], tcp->u_arg[llarg + 1]));
233b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab		llarg += 2;
234b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab	}
235d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab# elif defined IA64 || defined ALPHA
236b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab	tprintf(format, tcp->u_arg[llarg]);
237b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab	llarg++;
238b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# elif defined LINUX_MIPSN32
239b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab	tprintf(format, tcp->ext_arg[llarg]);
240b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab	llarg++;
241b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# else
242b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab	tprintf(format, LONG_LONG(tcp->u_arg[llarg], tcp->u_arg[llarg + 1]));
243b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab	llarg += 2;
244b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# endif
245b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab	return llarg;
246b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab}
247b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab#endif
248b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab
24976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
25076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interpret `xlat' as an array of flags
25176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * print the entries whose bits are on in `flags'
25276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * return # of flags printed.
25376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
2544924dbd6d750665cf383b20ab4fd67e48219ab91Denys Vlasenkovoid
2551201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoaddflags(const struct xlat *xlat, int flags)
25676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
2574924dbd6d750665cf383b20ab4fd67e48219ab91Denys Vlasenko	for (; xlat->str; xlat++) {
25876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val && (flags & xlat->val) == xlat->val) {
25976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("|%s", xlat->str);
26076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			flags &= ~xlat->val;
26176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
26276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
26376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (flags) {
26476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("|%#x", flags);
26576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
26676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
26776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
268a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath/*
2694924dbd6d750665cf383b20ab4fd67e48219ab91Denys Vlasenko * Interpret `xlat' as an array of flags.
270a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Print to static string the entries whose bits are on in `flags'
271a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Return static string.
272a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath */
273a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrathconst char *
274a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrathsprintflags(const char *prefix, const struct xlat *xlat, int flags)
275a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath{
276a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath	static char outstr[1024];
2775284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko	char *outptr;
278a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath	int found = 0;
279a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath
2805284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko	outptr = stpcpy(outstr, prefix);
281a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath
282a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath	for (; xlat->str; xlat++) {
283a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath		if ((flags & xlat->val) == xlat->val) {
284a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath			if (found)
2855284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko				*outptr++ = '|';
2865284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko			outptr = stpcpy(outptr, xlat->str);
287a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath			found = 1;
2884f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko			flags &= ~xlat->val;
2894f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko			if (!flags)
2904f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko				break;
291a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath		}
292a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath	}
293a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath	if (flags) {
294a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath		if (found)
2955284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko			*outptr++ = '|';
2965284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko		outptr += sprintf(outptr, "%#x", flags);
297a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath	}
298a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath
299a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath	return outstr;
300a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath}
301a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath
30276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
30330145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levinprintflags(const struct xlat *xlat, int flags, const char *dflt)
30476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n;
30630145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levin	const char *sep;
30776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
30876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (flags == 0 && xlat->val == 0) {
3095940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko		tprints(xlat->str);
31076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return 1;
31176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
31276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
31376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	sep = "";
31476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (n = 0; xlat->str; xlat++) {
31576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (xlat->val && (flags & xlat->val) == xlat->val) {
31676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%s%s", sep, xlat->str);
31776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			flags &= ~xlat->val;
31876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			sep = "|";
31976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			n++;
32076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
32176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
322b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath
323b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath	if (n) {
324b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath		if (flags) {
325b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath			tprintf("%s%#x", sep, flags);
326b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath			n++;
327b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath		}
328b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath	} else {
329b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath		if (flags) {
330b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath			tprintf("%#x", flags);
331b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath			if (dflt)
332b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath				tprintf(" /* %s */", dflt);
333b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath		} else {
334b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath			if (dflt)
33560fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko				tprints("0");
336b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath		}
33776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
338b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath
33976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return n;
34076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
34176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
34276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
34330145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levinprintnum(struct tcb *tcp, long addr, const char *fmt)
34476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
345eb285359906700f46b22cf4f9911695034313736Roland McGrath	long num;
34676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
34776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!addr) {
34860fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko		tprints("NULL");
34976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
35076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
35176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umove(tcp, addr, &num) < 0) {
35276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#lx", addr);
35376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
35476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
35560fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko	tprints("[");
35676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf(fmt, num);
35760fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko	tprints("]");
35876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
35976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
3606bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathvoid
36130145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levinprintnum_int(struct tcb *tcp, long addr, const char *fmt)
3629814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath{
3639814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	int num;
3649814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath
3659814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	if (!addr) {
36660fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko		tprints("NULL");
3679814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath		return;
3689814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	}
3699814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	if (umove(tcp, addr, &num) < 0) {
3709814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath		tprintf("%#lx", addr);
3719814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath		return;
3729814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	}
37360fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko	tprints("[");
3749814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath	tprintf(fmt, num);
37560fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko	tprints("]");
3769814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath}
3779814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath
3789814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathvoid
3793138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levinprintfd(struct tcb *tcp, int fd)
3803138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levin{
3818a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards	const char *p;
3828a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards
3838a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards	if (show_fd_path && (p = getfdpath(tcp, fd)))
3848a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards		tprintf("%d<%s>", fd, p);
3858a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards	else
3868a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards		tprintf("%d", fd);
3873138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levin}
3883138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levin
3893138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levinvoid
3901201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoprintuid(const char *text, unsigned long uid)
3916bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath{
3925940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko	tprintf((uid == -1) ? "%s%ld" : "%s%lu", text, uid);
3936bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath}
3946bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath
395a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/*
396a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Quote string `instr' of length `size'
397a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
398a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If `len' < 0, treat `instr' as a NUL-terminated string
399a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * and quote at most (`size' - 1) bytes.
4006cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko *
4016cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * Returns 0 if len < 0 and NUL was seen, 1 otherwise.
4026cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * Note that if len >= 0, always returns 1.
403a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */
4046d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrathstatic int
405bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinstring_quote(const char *instr, char *outstr, int len, int size)
40676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
407bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	const unsigned char *ustr = (const unsigned char *) instr;
408bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	char *s = outstr;
4098778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko	int usehex, c, i, eol;
41076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
4118778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko	eol = 0x100; /* this can never match a char */
4128778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko	if (len < 0) {
4138778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko		size--;
4148778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko		eol = '\0';
4158778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko	}
4168778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko
4178778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko	usehex = 0;
418bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	if (xflag > 1)
419bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		usehex = 1;
420bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	else if (xflag) {
421a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		/* Check for presence of symbol which require
422a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		   to hex-quote the whole string. */
423bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		for (i = 0; i < size; ++i) {
424bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			c = ustr[i];
425a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin			/* Check for NUL-terminated string. */
4268778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko			if (c == eol)
4278778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko				break;
428bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			if (!isprint(c) && !isspace(c)) {
429bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				usehex = 1;
430bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				break;
431bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			}
432bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		}
43376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
434bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin
435bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	*s++ = '\"';
436bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin
437bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	if (usehex) {
438a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		/* Hex-quote the whole string. */
439bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		for (i = 0; i < size; ++i) {
440bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			c = ustr[i];
441a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin			/* Check for NUL-terminated string. */
4428778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko			if (c == eol)
4438778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko				goto asciz_ended;
4448778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko			*s++ = '\\';
4458778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko			*s++ = 'x';
4468778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko			*s++ = "0123456789abcdef"[c >> 4];
4478778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko			*s++ = "0123456789abcdef"[c & 0xf];
448bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		}
449bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	} else {
450bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		for (i = 0; i < size; ++i) {
451bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			c = ustr[i];
452a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin			/* Check for NUL-terminated string. */
4538778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko			if (c == eol)
4548778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko				goto asciz_ended;
455bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			switch (c) {
456bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				case '\"': case '\\':
457bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = '\\';
458bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = c;
459bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					break;
460bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				case '\f':
461bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = '\\';
462bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = 'f';
463bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					break;
464bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				case '\n':
465bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = '\\';
466bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = 'n';
467bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					break;
468bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				case '\r':
469bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = '\\';
470bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = 'r';
471bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					break;
472bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				case '\t':
473bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = '\\';
474bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = 't';
475bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					break;
476bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				case '\v':
477bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = '\\';
478bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					*s++ = 'v';
479bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					break;
480bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin				default:
481bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					if (isprint(c))
482bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin						*s++ = c;
4838778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko					else {
4848778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko						/* Print \octal */
4858778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko						*s++ = '\\';
4868778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko						if (i + 1 < size
4878778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko						    && ustr[i + 1] >= '0'
4888778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko						    && ustr[i + 1] <= '9'
4898778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko						) {
4908778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko							/* Print \ooo */
4918778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko							*s++ = '0' + (c >> 6);
4928778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko							*s++ = '0' + ((c >> 3) & 0x7);
4938778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko						} else {
4948778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko							/* Print \[[o]o]o */
4958778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko							if ((c >> 3) != 0) {
4968778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko								if ((c >> 6) != 0)
4978778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko									*s++ = '0' + (c >> 6);
4988778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko								*s++ = '0' + ((c >> 3) & 0x7);
4998778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko							}
5008778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko						}
5018778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko						*s++ = '0' + (c & 0x7);
502bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					}
503bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin					break;
504bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin			}
50576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
50676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
50776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
508bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	*s++ = '\"';
509bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	*s = '\0';
5106d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath
5118778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko	/* Return zero if we printed entire ASCIZ string (didn't truncate it) */
5128778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko	if (len < 0 && ustr[i] == '\0') {
5138778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko		/* We didn't see NUL yet (otherwise we'd jump to 'asciz_ended')
5148778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko		 * but next char is NUL.
5158778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko		 */
5168778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko		return 0;
5178778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko	}
5188778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko
5198778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko	return 1;
5208778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko
5218778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko asciz_ended:
5228778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko	*s++ = '\"';
5238778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko	*s = '\0';
5248778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko	/* Return zero: we printed entire ASCIZ string (didn't truncate it) */
5258778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko	return 0;
52676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
52776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
528a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/*
529a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Print path string specified by address `addr' and length `n'.
530a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If path length exceeds `n', append `...' to the output.
531a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */
53276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
533bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintpathn(struct tcb *tcp, long addr, int n)
53476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
535b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko	char path[MAXPATHLEN + 1];
5366cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko	int nul_seen;
537b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko
538a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin	if (!addr) {
53960fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko		tprints("NULL");
540bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		return;
541bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	}
542bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin
5436cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko	/* Cap path length to the path buffer size */
544a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin	if (n > sizeof path - 1)
545a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		n = sizeof path - 1;
546a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin
547a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin	/* Fetch one byte more to find out whether path length > n. */
5486cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko	nul_seen = umovestr(tcp, addr, n + 1, path);
5496cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko	if (nul_seen < 0)
55076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%#lx", addr);
55176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
552b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko		char *outstr;
553bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin
5546cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko		path[n] = '\0';
555b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko		n++;
5566cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko		outstr = alloca(4 * n); /* 4*(n-1) + 3 for quotes and NUL */
557b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko		string_quote(path, outstr, -1, n);
558b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko		tprints(outstr);
5596cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko		if (!nul_seen)
560b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko			tprints("...");
56176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
56276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
56376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
56476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
565bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintpath(struct tcb *tcp, long addr)
566bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin{
567b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko	/* Size must correspond to char path[] size in printpathn */
568b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko	printpathn(tcp, addr, MAXPATHLEN);
569bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin}
570bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin
571a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/*
572a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Print string specified by address `addr' and length `len'.
573a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If `len' < 0, treat the string as a NUL-terminated string.
574a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If string length exceeds `max_strlen', append `...' to the output.
575a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */
576bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinvoid
577bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintstr(struct tcb *tcp, long addr, int len)
57876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
579bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin	static char *str = NULL;
58076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static char *outstr;
5816d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath	int size;
582b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko	int ellipsis;
58376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
58476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (!addr) {
58560fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko		tprints("NULL");
58676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
58776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
588a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin	/* Allocate static buffers if they are not allocated yet. */
5891d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko	if (!str) {
590a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		str = malloc(max_strlen + 1);
5911d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko		if (!str)
5921d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko			die_out_of_memory();
5936cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko		outstr = malloc(4 * max_strlen + /*for quotes and NUL:*/ 3);
5941d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko		if (!outstr)
5951d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko			die_out_of_memory();
59676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
597bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin
59876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (len < 0) {
599a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		/*
600a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		 * Treat as a NUL-terminated string: fetch one byte more
601a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		 * because string_quote() quotes one byte less.
602a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		 */
603bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		size = max_strlen + 1;
604bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		if (umovestr(tcp, addr, size, str) < 0) {
60576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%#lx", addr);
60676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
60776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
60876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
60976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
610a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin		size = MIN(len, max_strlen);
611bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin		if (umoven(tcp, addr, size, str) < 0) {
61276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tprintf("%#lx", addr);
61376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return;
61476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
61576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
61676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
6176cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko	/* If string_quote didn't see NUL and (it was supposed to be ASCIZ str
6186cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko	 * or we were requested to print more than -s NUM chars)...
6196cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko	 */
620b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko	ellipsis = (string_quote(str, outstr, len, size) &&
621b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko			(len < 0 || len > max_strlen));
62276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
623b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko	tprints(outstr);
624b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko	if (ellipsis)
625b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko		tprints("...");
62676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
6281d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H
6291d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesvoid
6301201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkodumpiov(struct tcb *tcp, int len, long addr)
6311d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes{
6328470374cba7df0e70653d95c4f336a4082c68d82Denys Vlasenko#if SUPPORTED_PERSONALITIES > 1
6334ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin	union {
6344ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin		struct { u_int32_t base; u_int32_t len; } *iov32;
6354ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin		struct { u_int64_t base; u_int64_t len; } *iov64;
6364ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin	} iovu;
6374ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov iovu.iov64
6384ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define sizeof_iov \
6394ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin  (personality_wordsize[current_personality] == 4 \
6404ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin   ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64))
6414ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_base(i) \
6424ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin  (personality_wordsize[current_personality] == 4 \
6434ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin   ? (u_int64_t) iovu.iov32[i].base : iovu.iov64[i].base)
6444ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_len(i) \
6454ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin  (personality_wordsize[current_personality] == 4 \
6464ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin   ? (u_int64_t) iovu.iov32[i].len : iovu.iov64[i].len)
6474ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#else
6481d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	struct iovec *iov;
6494ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define sizeof_iov sizeof(*iov)
6504ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_base(i) iov[i].iov_base
6514ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_len(i) iov[i].iov_len
6524ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#endif
6531d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	int i;
65479a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko	unsigned size;
6551d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes
65679a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko	size = sizeof_iov * len;
65779a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko	/* Assuming no sane program has millions of iovs */
65879a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko	if ((unsigned)len > 1024*1024 /* insane or negative size? */
6594ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin	    || (iov = malloc(size)) == NULL) {
66079a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko		fprintf(stderr, "Out of memory\n");
66179a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko		return;
6621d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	}
663aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath	if (umoven(tcp, addr, size, (char *) iov) >= 0) {
6641d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes		for (i = 0; i < len; i++) {
665adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko			/* include the buffer number to make it easy to
666adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko			 * match up the trace with the source */
667adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko			tprintf(" * %lu bytes in buffer %d\n",
668adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko				(unsigned long)iov_iov_len(i), i);
669adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko			dumpstr(tcp, (long) iov_iov_base(i),
670adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko				iov_iov_len(i));
671adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko		}
6721d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes	}
67379a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko	free(iov);
6744ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef sizeof_iov
6754ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov_iov_base
6764ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov_iov_len
6774ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov
6781d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes}
6791d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif
6801d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes
68176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
6821201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkodumpstr(struct tcb *tcp, long addr, int len)
68376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
68476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static int strsize = -1;
68576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	static unsigned char *str;
68676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	char *s;
68776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i, j;
68876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
68976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (strsize < len) {
6905d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko		free(str);
6915d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko		str = malloc(len);
69279a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko		if (!str) {
69379a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko			strsize = -1;
69479a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko			fprintf(stderr, "Out of memory\n");
69579a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko			return;
69679a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko		}
69776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		strsize = len;
69876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
69976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
70076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (umoven(tcp, addr, len, (char *) str) < 0)
70176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
70276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
70376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	for (i = 0; i < len; i += 16) {
7041d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko		char outstr[80];
7051d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko
70676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		s = outstr;
70776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		sprintf(s, " | %05x ", i);
70876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		s += 9;
70976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (j = 0; j < 16; j++) {
71076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (j == 8)
71176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
71276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (i + j < len) {
71376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				sprintf(s, " %02x", str[i + j]);
71476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				s += 3;
71576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
71676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			else {
71776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' '; *s++ = ' '; *s++ = ' ';
71876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
71976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
72076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		*s++ = ' '; *s++ = ' ';
72176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (j = 0; j < 16; j++) {
72276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (j == 8)
72376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
72476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (i + j < len) {
72576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				if (isprint(str[i + j]))
72676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					*s++ = str[i + j];
72776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				else
72876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					*s++ = '.';
72976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
73076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			else
73176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				*s++ = ' ';
73276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
73376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		tprintf("%s |\n", outstr);
73476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
73576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
73676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
737612659e41e2f41490ea5ae2926f5e002bb398334Mike Frysinger#ifdef HAVE_PROCESS_VM_READV
738612659e41e2f41490ea5ae2926f5e002bb398334Mike Frysinger/* C library supports this, but the kernel might not. */
739612659e41e2f41490ea5ae2926f5e002bb398334Mike Frysingerstatic bool process_vm_readv_not_supported = 0;
740612659e41e2f41490ea5ae2926f5e002bb398334Mike Frysinger#else
741612659e41e2f41490ea5ae2926f5e002bb398334Mike Frysinger
7423af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko/* Need to do this since process_vm_readv() is not yet available in libc.
7433af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko * When libc is be updated, only "static bool process_vm_readv_not_supported"
7443af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko * line should remain.
7453af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko */
7463af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko#if !defined(__NR_process_vm_readv)
7473af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko# if defined(I386)
7483af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko#  define __NR_process_vm_readv  347
7493af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko# elif defined(X86_64)
7503af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko#  define __NR_process_vm_readv  310
7513af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko# elif defined(POWERPC)
7523af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko#  define __NR_process_vm_readv  351
7533af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko# endif
7543af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko#endif
7553af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko
7563af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko#if defined(__NR_process_vm_readv)
7573af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenkostatic bool process_vm_readv_not_supported = 0;
7583af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenkostatic ssize_t process_vm_readv(pid_t pid,
7593af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		 const struct iovec *lvec,
7603af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		 unsigned long liovcnt,
7613af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		 const struct iovec *rvec,
7623af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		 unsigned long riovcnt,
7633af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		 unsigned long flags)
7643af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko{
7653af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko	return syscall(__NR_process_vm_readv, (long)pid, lvec, liovcnt, rvec, riovcnt, flags);
7663af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko}
7673af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko#else
7683af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenkostatic bool process_vm_readv_not_supported = 1;
7693af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko# define process_vm_readv(...) (errno = ENOSYS, -1)
7703af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko#endif
771612659e41e2f41490ea5ae2926f5e002bb398334Mike Frysinger
772612659e41e2f41490ea5ae2926f5e002bb398334Mike Frysinger#endif /* end of hack */
7733af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko
77476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PAGMASK	(~(PAGSIZ - 1))
77576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
77676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * move `len' bytes of data from process `pid'
77776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * at address `addr' to our space at `laddr'
77876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
77976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
780ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoumoven(struct tcb *tcp, long addr, int len, char *laddr)
78176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
782eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	int pid = tcp->pid;
78376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int n, m;
784a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko	int started;
78576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
78676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
78776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
78876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
78976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
790d2a660f534d98169f60d50706cbb2ec15fa13cf8Denys Vlasenko#if SUPPORTED_PERSONALITIES > 1
791d2a660f534d98169f60d50706cbb2ec15fa13cf8Denys Vlasenko	if (personality_wordsize[current_personality] < sizeof(addr))
792d2a660f534d98169f60d50706cbb2ec15fa13cf8Denys Vlasenko		addr &= (1ul << 8 * personality_wordsize[current_personality]) - 1;
793d2a660f534d98169f60d50706cbb2ec15fa13cf8Denys Vlasenko#endif
794d2a660f534d98169f60d50706cbb2ec15fa13cf8Denys Vlasenko
7953af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko	if (!process_vm_readv_not_supported) {
7963af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		struct iovec local[1], remote[1];
7973af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		int r;
7983af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko
7993af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		local[0].iov_base = laddr;
8003af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		remote[0].iov_base = (void*)addr;
8013af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		local[0].iov_len = remote[0].iov_len = len;
8023af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		r = process_vm_readv(pid,
8033af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko				local, 1,
8043af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko				remote, 1,
8053af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko				/*flags:*/ 0
8063af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		);
8073af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		if (r < 0) {
8083af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			if (errno == ENOSYS)
8093af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko				process_vm_readv_not_supported = 1;
8102945639eb854598dbbdc98c4f7e965a0a99492ddDenys Vlasenko			else if (errno != EINVAL) /* EINVAL is seen if process is gone */
8112945639eb854598dbbdc98c4f7e965a0a99492ddDenys Vlasenko				/* strange... */
8123af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko				perror("process_vm_readv");
8133af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			goto vm_readv_didnt_work;
8143af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		}
8153af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		return r;
8163af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko	}
8173af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko vm_readv_didnt_work:
8183af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko
819a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko	started = 0;
82076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
82176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
82276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
82376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
824eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		errno = 0;
825eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
826eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
827eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			/* But if not started, we had a bogus address. */
828eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (addr != 0 && errno != EIO && errno != ESRCH)
8294c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko				perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%lx", pid, addr);
830eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			return -1;
831eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		}
8325daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
833a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko		m = MIN(sizeof(long) - n, len);
834a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko		memcpy(laddr, &u.x[n], m);
83576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
83676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
83776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
838eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		errno = 0;
839eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
840eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
841eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (started && (errno==EPERM || errno==EIO)) {
842eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				/* Ran into 'end of memory' - stupid "printpath" */
843eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				return 0;
844eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			}
845eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (addr != 0 && errno != EIO && errno != ESRCH)
8464c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko				perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%lx", pid, addr);
847eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			return -1;
848eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		}
8495daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
850a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko		m = MIN(sizeof(long), len);
851a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko		memcpy(laddr, u.x, m);
85276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
85376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
85476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
85576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
85676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
85776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
85876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
8596cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * Like `umove' but make the additional effort of looking
86076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * for a terminating zero byte.
8616cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko *
8626cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * Returns < 0 on error, > 0 if NUL was seen,
8636cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * (TODO if useful: return count of bytes including NUL),
8646cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * else 0 if len bytes were read but no NUL byte seen.
8656cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko *
8666cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * Note: there is no guarantee we won't overwrite some bytes
8676cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * in laddr[] _after_ terminating NUL (but, of course,
8686cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * we never write past laddr[len-1]).
86976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
87076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
871ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoumovestr(struct tcb *tcp, long addr, int len, char *laddr)
87276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
873a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko	int started;
874eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	int pid = tcp->pid;
87576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i, n, m;
87676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	union {
87776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		long val;
87876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		char x[sizeof(long)];
87976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	} u;
88076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
881856c7ed97bce524ade99bb1fc41e746973d45accDmitry V. Levin#if SUPPORTED_PERSONALITIES > 1
882856c7ed97bce524ade99bb1fc41e746973d45accDmitry V. Levin	if (personality_wordsize[current_personality] < sizeof(addr))
883856c7ed97bce524ade99bb1fc41e746973d45accDmitry V. Levin		addr &= (1ul << 8 * personality_wordsize[current_personality]) - 1;
884856c7ed97bce524ade99bb1fc41e746973d45accDmitry V. Levin#endif
885856c7ed97bce524ade99bb1fc41e746973d45accDmitry V. Levin
8863af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko	if (!process_vm_readv_not_supported) {
8873af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		struct iovec local[1], remote[1];
8883af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko
8893af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		local[0].iov_base = laddr;
8903af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		remote[0].iov_base = (void*)addr;
8913af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko
8923af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		while (len > 0) {
8933af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			int end_in_page;
8943af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			int r;
8953af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			int chunk_len;
8963af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko
8973af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			/* Don't read kilobytes: most strings are short */
8983af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			chunk_len = len;
8993af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			if (chunk_len > 256)
9003af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko				chunk_len = 256;
9013af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			/* Don't cross pages. I guess otherwise we can get EFAULT
9023af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			 * and fail to notice that terminating NUL lies
9033af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			 * in the existing (first) page.
9043af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			 * (I hope there aren't arches with pages < 4K)
9053af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			 */
9063af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			end_in_page = ((addr + chunk_len) & 4095);
9073af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			r = chunk_len - end_in_page;
9083af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			if (r > 0) /* if chunk_len > end_in_page */
9093af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko				chunk_len = r; /* chunk_len -= end_in_page */
9103af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko
9113af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			local[0].iov_len = remote[0].iov_len = chunk_len;
9123af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			r = process_vm_readv(pid,
9133af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko					local, 1,
9143af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko					remote, 1,
9153af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko					/*flags:*/ 0
9163af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			);
9173af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			if (r < 0) {
9183af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko				if (errno == ENOSYS)
9193af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko					process_vm_readv_not_supported = 1;
9202945639eb854598dbbdc98c4f7e965a0a99492ddDenys Vlasenko				else if (errno != EINVAL) /* EINVAL is seen if process is gone */
9212945639eb854598dbbdc98c4f7e965a0a99492ddDenys Vlasenko					/* strange... */
9223af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko					perror("process_vm_readv");
9233af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko				goto vm_readv_didnt_work;
9243af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			}
9253af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			if (memchr(local[0].iov_base, '\0', r))
9263af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko				return 1;
9273af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			local[0].iov_base += r;
9283af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			remote[0].iov_base += r;
9293af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko			len -= r;
9303af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		}
9313af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko		return 0;
9323af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko	}
9333af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko vm_readv_didnt_work:
9343af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko
935a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko	started = 0;
93676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (addr & (sizeof(long) - 1)) {
93776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		/* addr not a multiple of sizeof(long) */
93876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		n = addr - (addr & -sizeof(long)); /* residue */
93976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr &= -sizeof(long); /* residue */
940eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		errno = 0;
941eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
942eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
943eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (addr != 0 && errno != EIO && errno != ESRCH)
9444c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko				perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%lx", pid, addr);
945eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			return -1;
946eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		}
9475daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
948a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko		m = MIN(sizeof(long) - n, len);
949a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko		memcpy(laddr, &u.x[n], m);
95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		while (n & (sizeof(long) - 1))
95176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (u.x[n++] == '\0')
9526cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko				return 1;
95376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
95476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
95576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while (len) {
956eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		errno = 0;
957eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
958eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno) {
959eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (started && (errno==EPERM || errno==EIO)) {
960eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				/* Ran into 'end of memory' - stupid "printpath" */
961eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath				return 0;
962eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			}
963eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			if (addr != 0 && errno != EIO && errno != ESRCH)
9644c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko				perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%lx", pid, addr);
965eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			return -1;
966eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		}
9675daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman		started = 1;
968a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko		m = MIN(sizeof(long), len);
969a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko		memcpy(laddr, u.x, m);
97076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		for (i = 0; i < sizeof(long); i++)
97176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			if (u.x[i] == '\0')
9726cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko				return 1;
97376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		addr += sizeof(long), laddr += m, len -= m;
97476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
975aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes	return 0;
97676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
97776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
9782d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#if !defined(SPARC) && !defined(SPARC64)
9792d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define PTRACE_WRITETEXT	101
9802d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define PTRACE_WRITEDATA	102
9812d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif /* !SPARC && !SPARC64 */
98276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
98376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint
9841201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoupeek(struct tcb *tcp, long off, long *res)
98576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
98676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long val;
98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
988eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	errno = 0;
989114aefd6183b8c073453f8def73270c42255f974Denys Vlasenko	val = ptrace(PTRACE_PEEKUSER, tcp->pid, (char *) off, 0);
990eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	if (val == -1 && errno) {
991eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (errno != ESRCH) {
9924c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko			perror_msg("upeek: PTRACE_PEEKUSER pid:%d @0x%lx)", tcp->pid, off);
993eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		}
99476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return -1;
995eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	}
99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	*res = val;
99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
99876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
99976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
100076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid
1001ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenkoprintcall(struct tcb *tcp)
100276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
10037a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath#define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \
10047a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath			   sizeof(long) == 8 ? "[????????????????] " : \
10057a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath			   NULL /* crash */)
100676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
10072d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#if defined(I386)
100876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long eip;
100976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1010932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 4*EIP, &eip) < 0) {
10117a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
101276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
101376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
101476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", eip);
1015eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath
10162d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#elif defined(S390) || defined(S390X)
1017adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	long psw;
1018b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko	if (upeek(tcp, PT_PSWADDR, &psw) < 0) {
1019adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko		PRINTBADPC;
1020adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko		return;
1021adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	}
10222d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# ifdef S390
1023adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	tprintf("[%08lx] ", psw);
10242d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# elif S390X
1025adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	tprintf("[%16lx] ", psw);
10262d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# endif
1027eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath
10282d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#elif defined(X86_64)
10290e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	long rip;
10300e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig
1031932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 8*RIP, &rip) < 0) {
10327a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
10330e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig		return;
10340e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	}
10350e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig	tprintf("[%16lx] ", rip);
10362d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#elif defined(IA64)
10378b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	long ip;
10388b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman
1039932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, PT_B0, &ip) < 0) {
10407a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
10418b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman		return;
10428b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	}
10438b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman	tprintf("[%08lx] ", ip);
10442d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#elif defined(POWERPC)
104576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
104676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1047932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) {
1048d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab		PRINTBADPC;
104976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
105076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
10512d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# ifdef POWERPC64
1052d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab	tprintf("[%016lx] ", pc);
10532d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# else
105476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
10552d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# endif
10562d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#elif defined(M68K)
105776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
105876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1059932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 4*PT_PC, &pc) < 0) {
106060fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko		tprints("[????????] ");
106176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
106276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
106376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
10642d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#elif defined(ALPHA)
106576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	long pc;
106676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1067932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, REG_PC, &pc) < 0) {
106860fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko		tprints("[????????????????] ");
106976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
107076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
107176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	tprintf("[%08lx] ", pc);
10722d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#elif defined(SPARC) || defined(SPARC64)
10738566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger	struct pt_regs regs;
1074b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
10757a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
107676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return;
107776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
10782d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# if defined(SPARC64)
10798566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger	tprintf("[%08lx] ", regs.tpc);
10802d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# else
10818566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger	tprintf("[%08lx] ", regs.pc);
10822d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# endif
10832d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#elif defined(HPPA)
1084c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	long pc;
1085c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman
1086b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko	if (upeek(tcp, PT_IAOQ0, &pc) < 0) {
108760fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko		tprints("[????????] ");
1088c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman		return;
1089c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	}
1090c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman	tprintf("[%08lx] ", pc);
10912d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#elif defined(MIPS)
109275c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	long pc;
109375c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman
1094932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, REG_EPC, &pc) < 0) {
109560fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko		tprints("[????????] ");
109675c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman		return;
109775c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	}
109875c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman	tprintf("[%08lx] ", pc);
10992d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#elif defined(SH)
1100adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	long pc;
1101ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman
1102adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	if (upeek(tcp, 4*REG_PC, &pc) < 0) {
110360fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko		tprints("[????????] ");
1104adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko		return;
1105adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	}
1106adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko	tprintf("[%08lx] ", pc);
11072d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#elif defined(SH64)
1108e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath	long pc;
1109e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath
1110932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, REG_PC, &pc) < 0) {
111160fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko		tprints("[????????????????] ");
1112e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath		return;
1113e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath	}
1114e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath	tprintf("[%08lx] ", pc);
11152d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#elif defined(ARM)
1116ef388689610fa17df1d3001face8057b411a2e26Roland McGrath	long pc;
1117e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath
1118932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, 4*15, &pc) < 0) {
11197a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath		PRINTBADPC;
1120ef388689610fa17df1d3001face8057b411a2e26Roland McGrath		return;
1121ef388689610fa17df1d3001face8057b411a2e26Roland McGrath	}
1122ef388689610fa17df1d3001face8057b411a2e26Roland McGrath	tprintf("[%08lx] ", pc);
11232d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#elif defined(AVR32)
11245ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko	long pc;
11255ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko
11265ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko	if (upeek(tcp, REG_PC, &pc) < 0) {
112760fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko		tprints("[????????] ");
11285ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko		return;
11295ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko	}
11305ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko	tprintf("[%08lx] ", pc);
11312d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#elif defined(BFIN)
113287ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin	long pc;
113387ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin
1134932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, PT_PC, &pc) < 0) {
113587ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin		PRINTBADPC;
113687ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin		return;
113787ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin	}
113887ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin	tprintf("[%08lx] ", pc);
1139ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#elif defined(CRISV10)
1140ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko	long pc;
1141ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko
1142eeb9ce3895f1ca0920d50696ef8b48124cef9da6Edgar E. Iglesias	if (upeek(tcp, 4*PT_IRP, &pc) < 0) {
1143ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko		PRINTBADPC;
1144ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko		return;
1145ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko	}
1146ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko	tprintf("[%08lx] ", pc);
1147ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#elif defined(CRISV32)
1148ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko	long pc;
1149ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko
1150eeb9ce3895f1ca0920d50696ef8b48124cef9da6Edgar E. Iglesias	if (upeek(tcp, 4*PT_ERP, &pc) < 0) {
1151ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko		PRINTBADPC;
1152ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko		return;
1153ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko	}
1154ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko	tprintf("[%08lx] ", pc);
11552d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif /* architecture */
115676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
115776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
11583bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko/*
11593bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * These #if's are huge, please indent them correctly.
11603bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * It's easy to get confused otherwise.
11613bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko */
116276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
11632d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#include "syscall.h"
11643291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath
11652d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#include <sys/syscall.h>
11662d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#ifndef CLONE_PTRACE
11672d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define CLONE_PTRACE    0x00002000
11682d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif
11692d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#ifndef CLONE_VFORK
11702d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define CLONE_VFORK     0x00004000
11712d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif
11722d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#ifndef CLONE_VM
11732d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define CLONE_VM        0x00000100
11742d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif
11752d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#ifndef CLONE_STOPPED
11762d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define CLONE_STOPPED   0x02000000
11772d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif
1178d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
11792d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#ifdef IA64
1180d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1181d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef unsigned long *arg_setup_state;
1182d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1183d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
1184d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGratharg_setup(struct tcb *tcp, arg_setup_state *state)
1185d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
11861f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil	unsigned long cfm, sof, sol;
11871f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil	long bsp;
1188d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
11891f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil	if (ia32) {
11901f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil		/* Satisfy a false GCC warning.  */
11911f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil		*state = NULL;
119208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		return 0;
11931f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil	}
119408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
1195932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, PT_AR_BSP, &bsp) < 0)
1196d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return -1;
1197932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko	if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
1198d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return -1;
1199d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1200d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	sof = (cfm >> 0) & 0x7f;
1201d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	sol = (cfm >> 7) & 0x7f;
12021f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil	bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol);
1203d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
12041f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil	*state = (unsigned long *) bsp;
1205d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return 0;
1206d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1207d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
12082d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg_finish_change(tcp, state)	0
1209d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1210d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
12111201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoget_arg0(struct tcb *tcp, arg_setup_state *state, long *valp)
1212d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
121308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	int ret;
121408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
121508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	if (ia32)
1216b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko		ret = upeek(tcp, PT_R11, valp);
121708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	else
1218b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko		ret = umoven(tcp,
121908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath			      (unsigned long) ia64_rse_skip_regs(*state, 0),
122008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath			      sizeof(long), (void *) valp);
122108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	return ret;
1222d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1223d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1224d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
12251201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoget_arg1(struct tcb *tcp, arg_setup_state *state, long *valp)
1226d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
122708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	int ret;
122808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
122908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	if (ia32)
1230b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko		ret = upeek(tcp, PT_R9, valp);
123108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	else
1232b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko		ret = umoven(tcp,
123308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath			      (unsigned long) ia64_rse_skip_regs(*state, 1),
123408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath			      sizeof(long), (void *) valp);
123508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	return ret;
1236d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1237d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1238d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
12391201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoset_arg0(struct tcb *tcp, arg_setup_state *state, long val)
1240d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
124108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	int req = PTRACE_POKEDATA;
124208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	void *ap;
124308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
124408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	if (ia32) {
124508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ap = (void *) (intptr_t) PT_R11;	 /* r11 == EBX */
124608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		req = PTRACE_POKEUSER;
124708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	} else
124808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ap = ia64_rse_skip_regs(*state, 0);
1249eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	errno = 0;
1250eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	ptrace(req, tcp->pid, ap, val);
1251eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	return errno ? -1 : 0;
1252d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1253d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1254d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
12551201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoset_arg1(struct tcb *tcp, arg_setup_state *state, long val)
1256d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
125708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	int req = PTRACE_POKEDATA;
125808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	void *ap;
125908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath
126008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	if (ia32) {
126108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ap = (void *) (intptr_t) PT_R9;		/* r9 == ECX */
126208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		req = PTRACE_POKEUSER;
126308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath	} else
126408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath		ap = ia64_rse_skip_regs(*state, 1);
1265eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	errno = 0;
1266eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	ptrace(req, tcp->pid, ap, val);
1267eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath	return errno ? -1 : 0;
1268d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1269d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1270b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath/* ia64 does not return the input arguments from functions (and syscalls)
1271b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath   according to ia64 RSE (Register Stack Engine) behavior.  */
1272b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath
12732d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg0(tcp, state, val) ((void) (state), 0)
12742d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg1(tcp, state, val) ((void) (state), 0)
1275b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath
12762d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#elif defined(SPARC) || defined(SPARC64)
1277d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
12788566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysingertypedef struct pt_regs arg_setup_state;
1279d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
12802d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg_setup(tcp, state) \
12812d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko    (ptrace(PTRACE_GETREGS, (tcp)->pid, (char *) (state), 0))
12822d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg_finish_change(tcp, state) \
12832d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko    (ptrace(PTRACE_SETREGS, (tcp)->pid, (char *) (state), 0))
1284d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
12852d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define get_arg0(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O0], 0)
12862d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define get_arg1(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O1], 0)
12872d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define set_arg0(tcp, state, val)  ((state)->u_regs[U_REG_O0] = (val), 0)
12882d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define set_arg1(tcp, state, val)  ((state)->u_regs[U_REG_O1] = (val), 0)
12892d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg0(tcp, state, val) 0
1290d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
12912d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#else /* other architectures */
1292d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
12932d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# if defined S390 || defined S390X
12947b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath/* Note: this is only true for the `clone' system call, which handles
12957b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath   arguments specially.  We could as well say that its first two arguments
12967b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath   are swapped relative to other architectures, but that would just be
12977b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath   another #ifdef in the calls.  */
12982d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg0_offset	PT_GPR3
12992d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg1_offset	PT_ORIGGPR2
13002d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define restore_arg0(tcp, state, val) ((void) (state), 0)
13012d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define restore_arg1(tcp, state, val) ((void) (state), 0)
13022d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg0_index	1
13032d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg1_index	0
13042d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# elif defined(ALPHA) || defined(MIPS)
13052d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg0_offset	REG_A0
13062d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg1_offset	(REG_A0+1)
13072d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# elif defined(AVR32)
13082d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg0_offset	(REG_R12)
13092d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg1_offset	(REG_R11)
13102d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# elif defined(POWERPC)
13112d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg0_offset	(sizeof(unsigned long)*PT_R3)
13122d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg1_offset	(sizeof(unsigned long)*PT_R4)
13132d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define restore_arg0(tcp, state, val) ((void) (state), 0)
13142d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# elif defined(HPPA)
13152d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg0_offset	PT_GR26
13162d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg1_offset	(PT_GR26-4)
13172d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# elif defined(X86_64)
13182d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg0_offset	((long)(8*(current_personality ? RBX : RDI)))
13192d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg1_offset	((long)(8*(current_personality ? RCX : RSI)))
13202d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# elif defined(SH)
13212d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg0_offset	(4*(REG_REG0+4))
13222d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg1_offset	(4*(REG_REG0+5))
13232d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# elif defined(SH64)
13242d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko   /* ABI defines arg0 & 1 in r2 & r3 */
13252d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg0_offset	(REG_OFFSET+16)
13262d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg1_offset	(REG_OFFSET+24)
13272d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define restore_arg0(tcp, state, val) 0
13282d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# elif defined CRISV10 || defined CRISV32
13292d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg0_offset	(4*PT_R11)
13302d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg1_offset	(4*PT_ORIG_R10)
13312d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define restore_arg0(tcp, state, val) 0
13322d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define restore_arg1(tcp, state, val) 0
13332d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg0_index	1
13342d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg1_index	0
13352d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# else
13362d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg0_offset	0
13372d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  define arg1_offset	4
13382d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  if defined ARM
13392d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#   define restore_arg0(tcp, state, val) 0
13402d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#  endif
13412d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# endif
1342d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1343d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef int arg_setup_state;
1344d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
13452d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg_setup(tcp, state)         (0)
13462d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg_finish_change(tcp, state) 0
13472d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define get_arg0(tcp, cookie, valp)   (upeek((tcp), arg0_offset, (valp)))
13482d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define get_arg1(tcp, cookie, valp)   (upeek((tcp), arg1_offset, (valp)))
1349d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1350d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
13511201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoset_arg0(struct tcb *tcp, void *cookie, long val)
1352d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1353b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko	return ptrace(PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val);
1354d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1355d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1356d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int
13571201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoset_arg1(struct tcb *tcp, void *cookie, long val)
1358d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1359b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko	return ptrace(PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val);
1360d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1361d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
13622d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif /* architectures */
1363d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
13642d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#ifndef restore_arg0
13652d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val))
13662d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif
13672d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#ifndef restore_arg1
13682d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val))
13692d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif
1370d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
13712d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#ifndef arg0_index
13722d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg0_index 0
13732d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg1_index 1
13742d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif
137590d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath
1376d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint
1377418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkosetbpt(struct tcb *tcp)
1378d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
13793291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath	static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone };
1380d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	arg_setup_state state;
1381d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1382d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	if (tcp->flags & TCB_BPTSET) {
1383d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1384d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return -1;
1385d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	}
1386d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
13873291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath	/*
13883291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath	 * It's a silly kludge to initialize this with a search at runtime.
13893291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath	 * But it's better than maintaining another magic thing in the
13903291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath	 * godforsaken tables.
13913291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath	 */
13923291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath	if (clone_scno[current_personality] == 0) {
13933291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath		int i;
13943291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath		for (i = 0; i < nsyscalls; ++i)
13953291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath			if (sysent[i].sys_func == sys_clone) {
13963291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath				clone_scno[current_personality] = i;
13973291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath				break;
13983291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath			}
13993291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath	}
14003291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath
14010c661513e5a4594cfae98042018ed549b1e26b8dDmitry V. Levin	if (sysent[tcp->scno].sys_func == sys_fork ||
14020c661513e5a4594cfae98042018ed549b1e26b8dDmitry V. Levin	    sysent[tcp->scno].sys_func == sys_vfork) {
1403b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko		if (arg_setup(tcp, &state) < 0
1404b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko		    || get_arg0(tcp, &state, &tcp->inst[0]) < 0
1405b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko		    || get_arg1(tcp, &state, &tcp->inst[1]) < 0
14063291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath		    || change_syscall(tcp, clone_scno[current_personality]) < 0
1407b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko		    || set_arg0(tcp, &state, CLONE_PTRACE|SIGCHLD) < 0
1408b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko		    || set_arg1(tcp, &state, 0) < 0
1409b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko		    || arg_finish_change(tcp, &state) < 0)
1410d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath			return -1;
1411c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath		tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD;
1412c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath		tcp->u_arg[arg1_index] = 0;
1413d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		tcp->flags |= TCB_BPTSET;
1414d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return 0;
14150c661513e5a4594cfae98042018ed549b1e26b8dDmitry V. Levin	}
1416d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
14170c661513e5a4594cfae98042018ed549b1e26b8dDmitry V. Levin	if (sysent[tcp->scno].sys_func == sys_clone) {
14188fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil		/* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)'
14190c661513e5a4594cfae98042018ed549b1e26b8dDmitry V. Levin		   contrary to x86 vfork above.  Even on x86 we turn the
14208fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil		   vfork semantics into plain fork - each application must not
14218fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil		   depend on the vfork specifics according to POSIX.  We would
14228fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil		   hang waiting for the parent resume otherwise.  We need to
14238fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil		   clear also CLONE_VM but only in the CLONE_VFORK case as
14248fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil		   otherwise we would break pthread_create.  */
14258fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil
1426c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko		long new_arg0 = (tcp->u_arg[arg0_index] | CLONE_PTRACE);
1427c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko		if (new_arg0 & CLONE_VFORK)
1428c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko			new_arg0 &= ~(unsigned long)(CLONE_VFORK | CLONE_VM);
1429c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko		if (arg_setup(tcp, &state) < 0
1430c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko		 || set_arg0(tcp, &state, new_arg0) < 0
1431c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko		 || arg_finish_change(tcp, &state) < 0)
14325ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko			return -1;
1433d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		tcp->flags |= TCB_BPTSET;
1434c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath		tcp->inst[0] = tcp->u_arg[arg0_index];
1435c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath		tcp->inst[1] = tcp->u_arg[arg1_index];
1436d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath		return 0;
1437d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	}
1438d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
14390c661513e5a4594cfae98042018ed549b1e26b8dDmitry V. Levin	fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n",
14400c661513e5a4594cfae98042018ed549b1e26b8dDmitry V. Levin		tcp->scno, tcp->pid);
1441d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return -1;
1442d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1443d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath
1444d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint
14451201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoclearbpt(struct tcb *tcp)
1446d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{
1447d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	arg_setup_state state;
1448b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko	if (arg_setup(tcp, &state) < 0
1449b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko	    || restore_arg0(tcp, &state, tcp->inst[0]) < 0
1450b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko	    || restore_arg1(tcp, &state, tcp->inst[1]) < 0
1451b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko	    || arg_finish_change(tcp, &state))
1452c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko		if (errno != ESRCH)
1453c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko			return -1;
1454d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	tcp->flags &= ~TCB_BPTSET;
1455d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath	return 0;
1456d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath}
1457