util.c revision e5e60858063f214fcd7860f50f8bcb46f951f9ab
176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> 376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> 476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> 54dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> 64dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 74dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman * Linux for s390 port by D.J. Barrow 84dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com> 976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * All rights reserved. 1076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 1176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Redistribution and use in source and binary forms, with or without 1276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * modification, are permitted provided that the following conditions 1376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * are met: 1476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 1. Redistributions of source code must retain the above copyright 1576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * notice, this list of conditions and the following disclaimer. 1676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 2. Redistributions in binary form must reproduce the above copyright 1776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * notice, this list of conditions and the following disclaimer in the 1876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * documentation and/or other materials provided with the distribution. 1976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 3. The name of the author may not be used to endorse or promote products 2076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * derived from this software without specific prior written permission. 2176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 2276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 3376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * $Id$ 3476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 3576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 3676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "defs.h" 3776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 38d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#include <signal.h> 39d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#include <sys/syscall.h> 4076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/user.h> 4176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/param.h> 4276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <fcntl.h> 431d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H 441d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#include <sys/uio.h> 451d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 4676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 4776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <machine/reg.h> 4876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <a.out.h> 4976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <link.h> 5076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 5136915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman 5243a7482edbc7142b91e95d7aedeb9d121fc4880fWichert Akkerman#if defined(linux) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1)) 5376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <linux/ptrace.h> 541e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath#endif 5536915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman 568b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#if defined(LINUX) && defined(IA64) 57d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# include <asm/ptrace_offsets.h> 58d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# include <asm/rse.h> 598b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#endif 608b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 6136915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#ifdef HAVE_SYS_REG_H 6236915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#include <sys/reg.h> 6336915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman# define PTRACE_PEEKUSR PTRACE_PEEKUSER 64faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(HAVE_LINUX_PTRACE_H) 65faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#undef PTRACE_SYSCALL 66ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# ifdef HAVE_STRUCT_IA64_FPREG 67ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# define ia64_fpreg XXX_ia64_fpreg 68ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# endif 69ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# ifdef HAVE_STRUCT_PT_ALL_USER_REGS 70ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# define pt_all_user_regs XXX_pt_all_user_regs 71ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# endif 72faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#include <linux/ptrace.h> 73ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# undef ia64_fpreg 74ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# undef pt_all_user_regs 752e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#endif 762e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman 7776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE 7876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/utsname.h> 7976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 8076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 818566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger#if defined(LINUXSPARC) && defined (SPARC64) 826d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# undef PTRACE_GETREGS 836d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# define PTRACE_GETREGS PTRACE_GETREGS64 846d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# undef PTRACE_SETREGS 856d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# define PTRACE_SETREGS PTRACE_SETREGS64 869ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 879ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 8876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* macros */ 8976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MAX 9076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MAX(a,b) (((a) > (b)) ? (a) : (b)) 9176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 9276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MIN 9376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MIN(a,b) (((a) < (b)) ? (a) : (b)) 9476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 9576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 9676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 9776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_nz(a) 9876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a; 9976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 10076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return a->tv_sec || a->tv_usec; 10176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 10276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 10476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_cmp(a, b) 10576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a, *b; 10676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 10776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (a->tv_sec < b->tv_sec 10876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec)) 10976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 11076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (a->tv_sec > b->tv_sec 11176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec)) 11276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 11376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 11476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 11576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandouble 11776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_float(tv) 11876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv; 11976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tv->tv_sec + tv->tv_usec/1000000.0; 12176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 12276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 12476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_add(tv, a, b) 12576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b; 12676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 12776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec + b->tv_sec; 12876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec + b->tv_usec; 12958372f52ac5f824be687c01bfc1db1ffb963f91eRoland McGrath if (tv->tv_usec >= 1000000) { 13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec++; 13176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec -= 1000000; 13276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 13376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 13476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_sub(tv, a, b) 13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b; 13876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 13976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec - b->tv_sec; 14076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec - b->tv_usec; 14176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (((long) tv->tv_usec) < 0) { 14276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec--; 14376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec += 1000000; 14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 14576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 14876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_div(tv, a, n) 14976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a; 15076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 15176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 15276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n; 15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000; 15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 15876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_mul(tv, a, n) 15976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a; 16076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 16176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 16276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec * n; 163fefdd97156bb2f86c5b6596dc7e28d954516b3edDmitry V. Levin tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000; 16476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 16576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 16676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 167ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinconst char * 168ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinxlookup(const struct xlat *xlat, int val) 16976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (; xlat->str != NULL; xlat++) 17176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val == val) 17276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return xlat->str; 17376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 17476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 177eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Generic ptrace wrapper which tracks ESRCH errors 178eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * by setting tcp->ptrace_errno to ESRCH. 179732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * 180732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * We assume that ESRCH indicates likely process death (SIGKILL?), 181732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * modulo bugs where process somehow ended up not stopped. 182732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Unfortunately kernel uses ESRCH for that case too. Oh well. 183eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * 184eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Currently used by upeek() only. 185eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * TODO: use this in all other ptrace() calls while decoding. 186732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko */ 187732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenkolong 188eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathdo_ptrace(int request, struct tcb *tcp, void *addr, void *data) 189732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko{ 190732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko long l; 191732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko 192732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko errno = 0; 19309a13c2da736aa9a74e7de761062c82832f7cf04Mike Frysinger l = ptrace(request, tcp->pid, addr, (long) data); 194eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Non-ESRCH errors might be our invalid reg/mem accesses, 195eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * we do not record them. */ 196eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno == ESRCH) 197eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tcp->ptrace_errno = ESRCH; 198732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko return l; 199732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko} 200732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko 201732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko/* 202732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Used when we want to unblock stopped traced process. 203732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL. 204732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Returns 0 on success or if error was ESRCH 205732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * (presumably process was killed while we talk to it). 206732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Otherwise prints error message and returns -1. 207732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko */ 208732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenkoint 209eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathptrace_restart(int op, struct tcb *tcp, int sig) 210732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko{ 211732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko int err; 212eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath const char *msg; 213732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko 214732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko errno = 0; 21509a13c2da736aa9a74e7de761062c82832f7cf04Mike Frysinger ptrace(op, tcp->pid, (void *) 1, (long) sig); 216732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko err = errno; 217732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko if (!err || err == ESRCH) 218732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko return 0; 219732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko 220732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko tcp->ptrace_errno = err; 221eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath msg = "SYSCALL"; 222eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (op == PTRACE_CONT) 223eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath msg = "CONT"; 224eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (op == PTRACE_DETACH) 225eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath msg = "DETACH"; 226eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath fprintf(stderr, "strace: ptrace(PTRACE_%s,1,%d): %s\n", 227eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath msg, sig, strerror(err)); 228732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko return -1; 229732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko} 230732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko 231732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko/* 23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Print entry in struct xlat table, if there. 23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 235ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinprintxval(const struct xlat *xlat, int val, const char *dflt) 23676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 237ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levin const char *str = xlookup(xlat, val); 23876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 23976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 24076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", str); 24176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#x /* %s */", val, dflt); 24376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 24476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 245b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab#if HAVE_LONG_LONG 246b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab/* 247b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab * Print 64bit argument at position llarg and return the index of the next 248b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab * argument. 249b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab */ 250b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwabint 251b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwabprintllval(struct tcb *tcp, const char *format, int llarg) 252b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab{ 253b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# if defined(FREEBSD) \ 254b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab || (defined(LINUX) && defined(POWERPC) && !defined(__powerpc64__)) \ 255b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab || defined (LINUX_MIPSO32) 256b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab /* Align 64bit argument to 64bit boundary. */ 257b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab if (llarg % 2) llarg++; 258b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# endif 259b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# if defined LINUX && defined X86_64 260b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab if (current_personality == 0) { 261b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab tprintf(format, tcp->u_arg[llarg]); 262b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab llarg++; 263b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab } else { 264b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab tprintf(format, LONG_LONG(tcp->u_arg[llarg], tcp->u_arg[llarg + 1])); 265b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab llarg += 2; 266b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab } 267b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# elif defined IA64 || defined ALPHA || (defined POWERPC && defined __powerpc64__) 268b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab tprintf(format, tcp->u_arg[llarg]); 269b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab llarg++; 270b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# elif defined LINUX_MIPSN32 271b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab tprintf(format, tcp->ext_arg[llarg]); 272b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab llarg++; 273b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# else 274b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab tprintf(format, LONG_LONG(tcp->u_arg[llarg], tcp->u_arg[llarg + 1])); 275b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab llarg += 2; 276b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# endif 277b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab return llarg; 278b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab} 279b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab#endif 280b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab 28176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 28276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interpret `xlat' as an array of flags 28376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * print the entries whose bits are on in `flags' 28476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * return # of flags printed. 28576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 28676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 28776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanaddflags(xlat, flags) 288d9f816f60457930af27349fac3d23b3b78338036Roland McGrathconst struct xlat *xlat; 28976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags; 29076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 29176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 29276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 29376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 29476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 29576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%s", xlat->str); 29676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 29776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 29876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 29976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 30076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags) { 30176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%#x", flags); 30276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 30476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 30676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 307a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath/* 308a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Interpret `xlat' as an array of flags/ 309a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Print to static string the entries whose bits are on in `flags' 310a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Return static string. 311a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath */ 312a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrathconst char * 313a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrathsprintflags(const char *prefix, const struct xlat *xlat, int flags) 314a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath{ 315a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath static char outstr[1024]; 316a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath int found = 0; 317a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 318a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath strcpy(outstr, prefix); 319a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 320a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath for (; xlat->str; xlat++) { 321a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if ((flags & xlat->val) == xlat->val) { 322a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if (found) 323a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath strcat(outstr, "|"); 324a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath strcat(outstr, xlat->str); 325a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath flags &= ~xlat->val; 326a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath found = 1; 327a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath } 328a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath } 329a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if (flags) { 330a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if (found) 331a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath strcat(outstr, "|"); 332a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath sprintf(outstr + strlen(outstr), "%#x", flags); 333a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath } 334a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 335a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath return outstr; 336a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath} 337a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 33876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 339b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrathprintflags(xlat, flags, dflt) 340d9f816f60457930af27349fac3d23b3b78338036Roland McGrathconst struct xlat *xlat; 34176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags; 342b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrathconst char *dflt; 34376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 34476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 34576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *sep; 34676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 34776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags == 0 && xlat->val == 0) { 34876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", xlat->str); 34976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 35076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 35176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 35276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = ""; 35376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 35476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 35576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s%s", sep, xlat->str); 35676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 35776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = "|"; 35876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 35976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 36076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 361b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath 362b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (n) { 363b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (flags) { 364b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("%s%#x", sep, flags); 365b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath n++; 366b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } 367b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } else { 368b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (flags) { 369b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("%#x", flags); 370b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (dflt) 371b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf(" /* %s */", dflt); 372b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } else { 373b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (dflt) 374b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("0"); 375b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } 37676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 377b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath 37876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 37976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 38076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 38176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 38276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintnum(tcp, addr, fmt) 38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 38476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 38576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *fmt; 38676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 387eb285359906700f46b22cf4f9911695034313736Roland McGrath long num; 38876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 38976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 39076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 39176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 39276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 39376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, addr, &num) < 0) { 39476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 39576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 39676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 39776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("["); 39876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf(fmt, num); 39976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("]"); 40076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 40176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 4026bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathvoid 4039814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathprintnum_int(tcp, addr, fmt) 4049814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathstruct tcb *tcp; 4059814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathlong addr; 4069814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathchar *fmt; 4079814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath{ 4089814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath int num; 4099814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath 4109814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath if (!addr) { 4119814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("NULL"); 4129814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath return; 4139814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath } 4149814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath if (umove(tcp, addr, &num) < 0) { 4159814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("%#lx", addr); 4169814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath return; 4179814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath } 4189814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("["); 4199814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf(fmt, num); 4209814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("]"); 4219814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath} 4229814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath 4239814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathvoid 4246bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathprintuid(text, uid) 4256bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathconst char *text; 4266bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathunsigned long uid; 4276bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath{ 4286bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath tprintf("%s", text); 4296bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath tprintf((uid == -1) ? "%ld" : "%lu", uid); 4306bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath} 4316bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath 43276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic char path[MAXPATHLEN + 1]; 43376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 434a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/* 435a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Quote string `instr' of length `size' 436a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Write up to (3 + `size' * 4) bytes to `outstr' buffer. 437a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If `len' < 0, treat `instr' as a NUL-terminated string 438a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * and quote at most (`size' - 1) bytes. 439a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 4406d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrathstatic int 441bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinstring_quote(const char *instr, char *outstr, int len, int size) 44276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 443bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin const unsigned char *ustr = (const unsigned char *) instr; 444bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin char *s = outstr; 445bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin int usehex = 0, c, i; 44676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 447bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (xflag > 1) 448bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin usehex = 1; 449bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin else if (xflag) { 450a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for presence of symbol which require 451a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin to hex-quote the whole string. */ 452bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin for (i = 0; i < size; ++i) { 453bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin c = ustr[i]; 454a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for NUL-terminated string. */ 455a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (len < 0) { 456a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (c == '\0') 457a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin break; 458a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Quote at most size - 1 bytes. */ 459a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (i == size - 1) 460a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin continue; 461a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin } 462bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (!isprint(c) && !isspace(c)) { 463bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin usehex = 1; 464bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 465bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 466bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 46776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 468bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 469bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\"'; 470bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 471bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (usehex) { 472a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Hex-quote the whole string. */ 473bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin for (i = 0; i < size; ++i) { 474bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin c = ustr[i]; 475a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for NUL-terminated string. */ 476a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (len < 0) { 477a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (c == '\0') 478a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin break; 479a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Quote at most size - 1 bytes. */ 480a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (i == size - 1) 481a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin continue; 482a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin } 483bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin sprintf(s, "\\x%02x", c); 484bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin s += 4; 485bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 486bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } else { 487bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin for (i = 0; i < size; ++i) { 488bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin c = ustr[i]; 489a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for NUL-terminated string. */ 490a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (len < 0) { 491a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (c == '\0') 492a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin break; 493a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Quote at most size - 1 bytes. */ 494a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (i == size - 1) 495a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin continue; 496a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin } 497bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin switch (c) { 498bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\"': case '\\': 499bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 500bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = c; 501bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 502bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\f': 503bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 504bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'f'; 505bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 506bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\n': 507bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 508bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'n'; 509bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 510bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\r': 511bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 512bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'r'; 513bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 514bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\t': 515bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 516bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 't'; 517bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 518bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\v': 519bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 520bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'v'; 521bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 522bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin default: 523bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (isprint(c)) 524bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = c; 525bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin else if (i + 1 < size 526bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin && isdigit(ustr[i + 1])) { 527bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin sprintf(s, "\\%03o", c); 528bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin s += 4; 529bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } else { 530bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin sprintf(s, "\\%o", c); 531bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin s += strlen(s); 532bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 533bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 534bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 53576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 53676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 53776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 538bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\"'; 539bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s = '\0'; 5406d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath 5416d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath /* Return nonzero if the string was unterminated. */ 5426d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath return i == size; 54376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 54476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 545a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/* 546a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Print path string specified by address `addr' and length `n'. 547a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If path length exceeds `n', append `...' to the output. 548a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 54976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 550bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintpathn(struct tcb *tcp, long addr, int n) 55176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 552a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!addr) { 553371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath tprintf("NULL"); 554bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin return; 555bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 556bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 557a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Cap path length to the path buffer size, 558a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin and NUL-terminate the buffer. */ 559a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (n > sizeof path - 1) 560a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin n = sizeof path - 1; 561bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin path[n] = '\0'; 562a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin 563a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Fetch one byte more to find out whether path length > n. */ 564bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (umovestr(tcp, addr, n + 1, path) < 0) 56576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 56676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 567bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin static char outstr[4*(sizeof path - 1) + sizeof "\"...\""]; 568bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin int trunc = (path[n] != '\0'); 569bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 570bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (trunc) 571bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin path[n] = '\0'; 572a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin (void) string_quote(path, outstr, -1, n + 1); 573a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (trunc) 574bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin strcat(outstr, "..."); 575bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin tprintf("%s", outstr); 57676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 57776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 57876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 57976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 580bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintpath(struct tcb *tcp, long addr) 581bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin{ 582bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin printpathn(tcp, addr, sizeof path - 1); 583bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin} 584bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 585a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/* 586a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Print string specified by address `addr' and length `len'. 587a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If `len' < 0, treat the string as a NUL-terminated string. 588a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If string length exceeds `max_strlen', append `...' to the output. 589a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 590bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinvoid 591bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintstr(struct tcb *tcp, long addr, int len) 59276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 593bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin static char *str = NULL; 59476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char *outstr; 5956d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath int size; 59676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 59776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 59876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 59976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 60076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 601a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Allocate static buffers if they are not allocated yet. */ 602a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!str) 603a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin str = malloc(max_strlen + 1); 604a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!outstr) 605a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin outstr = malloc(4 * max_strlen + sizeof "\"...\""); 606a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!str || !outstr) { 607a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin fprintf(stderr, "out of memory\n"); 608a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin tprintf("%#lx", addr); 609a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin return; 61076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 611bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 61276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0) { 613a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* 614a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Treat as a NUL-terminated string: fetch one byte more 615a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * because string_quote() quotes one byte less. 616a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 617bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin size = max_strlen + 1; 618a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin str[max_strlen] = '\0'; 619bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (umovestr(tcp, addr, size, str) < 0) { 62076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 62176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 62276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 62376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 62476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 625a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin size = MIN(len, max_strlen); 626bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (umoven(tcp, addr, size, str) < 0) { 62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 62876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 62976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 63076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 63176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 632a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (string_quote(str, outstr, len, size) && 633a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin (len < 0 || len > max_strlen)) 634bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin strcat(outstr, "..."); 63576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 63676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", outstr); 63776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 63876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 6391d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H 6401d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesvoid 6411d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesdumpiov(tcp, len, addr) 6421d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesstruct tcb * tcp; 6431d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesint len; 6441d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hugheslong addr; 6451d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes{ 6464ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 6474ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin union { 6484ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin struct { u_int32_t base; u_int32_t len; } *iov32; 6494ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin struct { u_int64_t base; u_int64_t len; } *iov64; 6504ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin } iovu; 6514ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov iovu.iov64 6524ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define sizeof_iov \ 6534ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin (personality_wordsize[current_personality] == 4 \ 6544ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64)) 6554ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_base(i) \ 6564ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin (personality_wordsize[current_personality] == 4 \ 6574ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin ? (u_int64_t) iovu.iov32[i].base : iovu.iov64[i].base) 6584ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_len(i) \ 6594ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin (personality_wordsize[current_personality] == 4 \ 6604ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin ? (u_int64_t) iovu.iov32[i].len : iovu.iov64[i].len) 6614ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#else 6621d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes struct iovec *iov; 6634ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define sizeof_iov sizeof(*iov) 6644ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_base(i) iov[i].iov_base 6654ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_len(i) iov[i].iov_len 6664ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#endif 6671d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes int i; 668aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath unsigned long size; 6691d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 6704ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin size = sizeof_iov * (unsigned long) len; 6714ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin if (size / sizeof_iov != len 6724ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin || (iov = malloc(size)) == NULL) { 673aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath fprintf(stderr, "out of memory\n"); 6741d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes return; 6751d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 676aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath if (umoven(tcp, addr, size, (char *) iov) >= 0) { 6771d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes for (i = 0; i < len; i++) { 678adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko /* include the buffer number to make it easy to 679adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko * match up the trace with the source */ 680adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf(" * %lu bytes in buffer %d\n", 681adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko (unsigned long)iov_iov_len(i), i); 682adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko dumpstr(tcp, (long) iov_iov_base(i), 683adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko iov_iov_len(i)); 684adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko } 6851d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 6861d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes free((char *) iov); 6874ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef sizeof_iov 6884ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov_iov_base 6894ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov_iov_len 6904ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov 6911d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes} 6921d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 6931d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 69476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 69576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandumpstr(tcp, addr, len) 69676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 69776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 69876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 69976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 70076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int strsize = -1; 70176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static unsigned char *str; 70276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char outstr[80]; 70376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s; 70476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 70576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 70676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strsize < len) { 70776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 70876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(str); 70976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((str = malloc(len)) == NULL) { 71046100d07257824da2ae1147da0324b5788c95501Roland McGrath fprintf(stderr, "out of memory\n"); 71176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 71276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 71376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strsize = len; 71476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 71576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 71676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, addr, len, (char *) str) < 0) 71776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 71876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 71976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < len; i += 16) { 72076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s = outstr; 72176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " | %05x ", i); 72276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 9; 72376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 72476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 72576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 72676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 72776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " %02x", str[i + j]); 72876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 3; 72976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 73076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 73176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; *s++ = ' '; 73276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 73376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 73476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; 73576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 73676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 73776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 73876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 73976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isprint(str[i + j])) 74076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = str[i + j]; 74176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 74276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '.'; 74376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 74576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s |\n", outstr); 74876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 75176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PAGMASK (~(PAGSIZ - 1)) 75276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 75376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * move `len' bytes of data from process `pid' 75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * at address `addr' to our space at `laddr' 75576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 75676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 757ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoumoven(struct tcb *tcp, long addr, int len, char *laddr) 75876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 760eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath int pid = tcp->pid; 76176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 7625daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 76376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 76476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 76576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 76676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 76776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 77076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 77176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 772eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 773eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 774eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 775eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 776eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 777eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 778eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 779eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* But if not started, we had a bogus address. */ 780eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 781eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("ptrace: umoven"); 782eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 783eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 7845daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 78576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 78676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 78776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 78876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 789eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 790eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 791eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 792eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 793eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 794eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 795eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 796eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 797eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("ptrace: umoven"); 798eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 799eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 8005daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 80176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 80276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 80376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 80476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 80576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 80676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 80776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 80876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 80976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 81076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 81176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, PAGSIZ); 81276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 813eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_READDATA, pid, 814eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath (char *) addr, len, laddr) < 0) { 815eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno != ESRCH) { 816eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("umoven: ptrace(PTRACE_READDATA, ...)"); 817eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath abort(); 818eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 81976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 82076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 82176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len -= n; 82276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += n; 82376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman laddr += n; 82476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 82576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 82676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 827bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 828ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 829aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd_as; 8309ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 831aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd; 83276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 833aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes lseek(fd, addr, SEEK_SET); 834aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (read(fd, laddr, len) == -1) 83576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 836bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 83776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 83876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 83976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 84076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 84176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 84276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * like `umove' but make the additional effort of looking 84376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * for a terminating zero byte. 84476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 84576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 846ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoumovestr(struct tcb *tcp, long addr, int len, char *laddr) 84776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 848bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 849aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#ifdef HAVE_MP_PROCFS 850aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd_as; 851aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#else 852aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd; 853aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#endif 854aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes /* Some systems (e.g. FreeBSD) can be upset if we read off the 855aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes end of valid memory, avoid this by trying to read up 856aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes to page boundaries. But we don't know what a page is (and 857aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes getpagesize(2) (if it exists) doesn't necessarily return 858aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes hardware page size). Assume all pages >= 1024 (a-historical 859aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes I know) */ 860aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 861aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int page = 1024; /* How to find this? */ 862aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int move = page - (addr & (page - 1)); 863aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int left = len; 864aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 865aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes lseek(fd, addr, SEEK_SET); 866aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 867aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes while (left) { 868aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (move > left) move = left; 8699cecf7f8d6115a247be7186013857270b2d588d5John Hughes if ((move = read(fd, laddr, move)) <= 0) 870aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return left != len ? 0 : -1; 871aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (memchr (laddr, 0, move)) break; 872aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes left -= move; 873aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes laddr += move; 874aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes addr += move; 875aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes move = page; 876aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes } 877bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 8785daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 879eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath int pid = tcp->pid; 88076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, n, m; 88176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 88276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 88376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 88476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 88576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 88676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 88776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 88876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 88976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 890eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 891eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 892eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 893eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 894eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 895eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 896eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 897eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 898eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("umovestr"); 899eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 900eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 9015daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 90276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len)); 90376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (n & (sizeof(long) - 1)) 90476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[n++] == '\0') 90576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 90676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 90776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 90876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 909eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 910eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 911eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 912eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 913eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 914eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 915eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 916eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 917eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("umovestr"); 918eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 919eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 9205daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 92176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 92276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < sizeof(long); i++) 92376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[i] == '\0') 92476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 92576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 92676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 92776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 928bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 929aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return 0; 93076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 93176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 93276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 9333bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if !defined (SPARC) && !defined(SPARC64) 9343bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define PTRACE_WRITETEXT 101 9353bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define PTRACE_WRITEDATA 102 9363bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* !SPARC && !SPARC64 */ 93776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 93876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 93976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 94076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 94176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 942eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathuload(cmd, pid, addr, len, laddr) 943eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint cmd; 944eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint pid; 945eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathlong addr; 946eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint len; 947eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathchar *laddr; 94876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 94976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int peek, poke; 95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 95176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 95276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 95376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 95476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 95576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 95676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cmd == PTRACE_WRITETEXT) { 95776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKTEXT; 95876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKETEXT; 95976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 96076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 96176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKDATA; 96276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKEDATA; 96376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 96476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 96576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 96676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 96776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); 968eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 969eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(peek, pid, (char *) addr, 0); 970eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 971eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("uload: POKE"); 97276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 973eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 974eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len)); 975eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(poke, pid, (char *)addr, u.val) < 0) { 976eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("uload: POKE"); 97776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 97876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 979eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath addr += sizeof(long), laddr += m, len -= m; 98076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 98176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 98276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < sizeof(long)) 983eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(peek, pid, (char *) addr, 0); 984eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath memcpy(u.x, laddr, m = MIN(sizeof(long), len)); 985eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(poke, pid, (char *) addr, u.val) < 0) { 986eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("uload: POKE"); 98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 989eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath addr += sizeof(long), laddr += m, len -= m; 99076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 99376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 994eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint 995eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathtload(pid, addr, len, laddr) 996eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint pid; 997eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint addr, len; 998eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathchar *laddr; 999eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath{ 1000eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return uload(PTRACE_WRITETEXT, pid, addr, len, laddr); 1001eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath} 1002eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 1003eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint 1004eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathdload(pid, addr, len, laddr) 1005eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint pid; 1006eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint addr; 1007eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint len; 1008eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathchar *laddr; 100976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 1010eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return uload(PTRACE_WRITEDATA, pid, addr, len, laddr); 101176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 101276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 101376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 101476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1015bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 101676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 101776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 1018eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathupeek(tcp, off, res) 1019eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathstruct tcb *tcp; 1020eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathlong off; 1021eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathlong *res; 102276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 102376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 102476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10253bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SUNOS4_KERNEL_ARCH_KLUDGE 102676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman { 102776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int is_sun4m = -1; 102876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct utsname name; 102976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 103076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Round up the usual suspects. */ 103176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m == -1) { 103276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (uname(&name) < 0) { 103376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("upeek: uname?"); 103476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 103576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 103676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman is_sun4m = strcmp(name.machine, "sun4m") == 0; 103776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) { 1038d9f816f60457930af27349fac3d23b3b78338036Roland McGrath const struct xlat *x; 103976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 104076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (x = struct_user_offsets; x->str; x++) 104176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman x->val += 1024; 104276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 104376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 104476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) 104576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman off += 1024; 104676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 10473bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 1048eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1049732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko val = do_ptrace(PTRACE_PEEKUSER, tcp, (char *) off, 0); 1050eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (val == -1 && errno) { 1051eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno != ESRCH) { 1052eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath char buf[60]; 1053eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)", tcp->pid, off); 1054eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror(buf); 1055eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 105676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1057eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 105876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *res = val; 105976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 106076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 106176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1062bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 106376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 106476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 1065ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenkoprintcall(struct tcb *tcp) 106676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 10677a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath#define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \ 10687a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath sizeof(long) == 8 ? "[????????????????] " : \ 10697a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath NULL /* crash */) 107076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 107176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 10723bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef I386 107376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long eip; 107476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1075932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*EIP, &eip) < 0) { 10767a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 107776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 107876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 107976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", eip); 1080eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath 10813bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(S390) || defined(S390X) 1082adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko long psw; 1083eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if(upeek(tcp,PT_PSWADDR,&psw) < 0) { 1084adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko PRINTBADPC; 1085adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko return; 1086adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko } 10873bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef S390 1088adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf("[%08lx] ", psw); 10893bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif S390X 1090adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf("[%16lx] ", psw); 10913bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1092eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath 10933bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(X86_64) 10940e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig long rip; 10950e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig 1096932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 8*RIP, &rip) < 0) { 10977a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 10980e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return; 10990e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig } 11000e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig tprintf("[%16lx] ", rip); 11013bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(IA64) 11028b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman long ip; 11038b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 1104932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_B0, &ip) < 0) { 11057a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 11068b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return; 11078b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 11088b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tprintf("[%08lx] ", ip); 11093bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(POWERPC) 111076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 111176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1112932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) { 111376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 111476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 111576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 111676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 11173bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(M68K) 111876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 111976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1120932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*PT_PC, &pc) < 0) { 112176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 112276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 112376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 112476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 11253bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ALPHA) 112676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 112776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1128932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, REG_PC, &pc) < 0) { 11297a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath tprintf ("[????????????????] "); 113076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 113176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 113276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 11333bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SPARC) || defined(SPARC64) 11348566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger struct pt_regs regs; 1135eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) { 11367a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 113776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 113876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 11398566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# if defined(SPARC64) 11408566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger tprintf("[%08lx] ", regs.tpc); 11418566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# else 11428566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger tprintf("[%08lx] ", regs.pc); 11438566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# endif 11443bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(HPPA) 1145c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman long pc; 1146c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman 1147eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if(upeek(tcp,PT_IAOQ0,&pc) < 0) { 1148c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tprintf ("[????????] "); 1149c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return; 1150c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman } 1151c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tprintf("[%08lx] ", pc); 11523bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(MIPS) 115375c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman long pc; 115475c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman 1155932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, REG_EPC, &pc) < 0) { 115675c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman tprintf ("[????????] "); 115775c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman return; 115875c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman } 115975c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman tprintf("[%08lx] ", pc); 11603bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH) 1161adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko long pc; 1162ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman 1163adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko if (upeek(tcp, 4*REG_PC, &pc) < 0) { 1164adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf ("[????????] "); 1165adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko return; 1166adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko } 1167adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf("[%08lx] ", pc); 11683bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH64) 1169e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath long pc; 1170e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath 1171932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, REG_PC, &pc) < 0) { 11727a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath tprintf ("[????????????????] "); 1173e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath return; 1174e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath } 1175e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath tprintf("[%08lx] ", pc); 11763bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ARM) 1177ef388689610fa17df1d3001face8057b411a2e26Roland McGrath long pc; 1178e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath 1179932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*15, &pc) < 0) { 11807a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 1181ef388689610fa17df1d3001face8057b411a2e26Roland McGrath return; 1182ef388689610fa17df1d3001face8057b411a2e26Roland McGrath } 1183ef388689610fa17df1d3001face8057b411a2e26Roland McGrath tprintf("[%08lx] ", pc); 11845ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# elif defined(AVR32) 11855ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko long pc; 11865ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko 11875ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko if (upeek(tcp, REG_PC, &pc) < 0) { 11885ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko tprintf("[????????] "); 11895ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return; 11905ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko } 11915ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko tprintf("[%08lx] ", pc); 11923bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(BFIN) 119387ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin long pc; 119487ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin 1195932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_PC, &pc) < 0) { 119687ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin PRINTBADPC; 119787ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin return; 119887ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin } 119987ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin tprintf("[%08lx] ", pc); 1200ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#elif defined(CRISV10) 1201ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko long pc; 1202ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko 1203eeb9ce3895f1ca0920d50696ef8b48124cef9da6Edgar E. Iglesias if (upeek(tcp, 4*PT_IRP, &pc) < 0) { 1204ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko PRINTBADPC; 1205ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko return; 1206ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko } 1207ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko tprintf("[%08lx] ", pc); 1208ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#elif defined(CRISV32) 1209ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko long pc; 1210ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko 1211eeb9ce3895f1ca0920d50696ef8b48124cef9da6Edgar E. Iglesias if (upeek(tcp, 4*PT_ERP, &pc) < 0) { 1212ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko PRINTBADPC; 1213ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko return; 1214ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko } 1215ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko tprintf("[%08lx] ", pc); 12163bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* architecture */ 121776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 121876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 121976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 122076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct regs regs; 122176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1222eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 1223eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("printcall: ptrace(PTRACE_GETREGS, ...)"); 12247a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 122576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 122676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 122776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08x] ", regs.r_o7); 122876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 122976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 123076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 123176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* XXX */ 12327a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 123376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 123476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1235bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1236bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct reg regs; 1237bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 1238bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tprintf("[%08x] ", regs.r_eip); 1239bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 124076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 124176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12423bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko 12433bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko/* 12443bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * These #if's are huge, please indent them correctly. 12453bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * It's easy to get confused otherwise. 12463bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko */ 1247bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 124876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1249e5e60858063f214fcd7860f50f8bcb46f951f9abDmitry V. Levin#ifdef LINUX 1250d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 12513bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# include "syscall.h" 12523291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath 12533bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# include <sys/syscall.h> 12543bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef CLONE_PTRACE 12553bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define CLONE_PTRACE 0x00002000 12563bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 12573bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef CLONE_VFORK 12583bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define CLONE_VFORK 0x00004000 12593bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 12603bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef CLONE_VM 12613bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define CLONE_VM 0x00000100 12623bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 12633bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef CLONE_STOPPED 12643bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define CLONE_STOPPED 0x02000000 12653bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1266d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 12673bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef IA64 1268d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 126908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath/* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32 127008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath subsystem has them for x86... */ 12713bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define SYS_fork 2 12723bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define SYS_vfork 190 127308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 1274d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef unsigned long *arg_setup_state; 1275d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1276d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1277d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGratharg_setup(struct tcb *tcp, arg_setup_state *state) 1278d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 12791f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil unsigned long cfm, sof, sol; 12801f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil long bsp; 1281d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 12821f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil if (ia32) { 12831f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil /* Satisfy a false GCC warning. */ 12841f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil *state = NULL; 128508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return 0; 12861f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil } 128708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 1288932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_AR_BSP, &bsp) < 0) 1289d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1290932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_CFM, (long *) &cfm) < 0) 1291d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1292d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1293d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sof = (cfm >> 0) & 0x7f; 1294d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sol = (cfm >> 7) & 0x7f; 12951f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol); 1296d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 12971f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil *state = (unsigned long *) bsp; 1298d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1299d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1300d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13013bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_finish_change(tcp, state) 0 1302d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13033bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SYS_fork 1304d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1305d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathget_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp) 1306d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 130708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int ret; 130808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 130908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) 1310932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko ret = upeek (tcp, PT_R11, valp); 131108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath else 131208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ret = umoven (tcp, 131308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath (unsigned long) ia64_rse_skip_regs(*state, 0), 131408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath sizeof(long), (void *) valp); 131508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return ret; 1316d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1317d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1318d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1319d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathget_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp) 1320d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 132108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int ret; 132208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 132308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) 1324932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko ret = upeek (tcp, PT_R9, valp); 132508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath else 132608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ret = umoven (tcp, 132708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath (unsigned long) ia64_rse_skip_regs(*state, 1), 132808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath sizeof(long), (void *) valp); 132908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return ret; 1330d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 13313bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1332d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1333d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1334d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg0 (struct tcb *tcp, arg_setup_state *state, long val) 1335d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 133608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int req = PTRACE_POKEDATA; 133708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath void *ap; 133808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 133908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) { 134008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = (void *) (intptr_t) PT_R11; /* r11 == EBX */ 134108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath req = PTRACE_POKEUSER; 134208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath } else 134308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = ia64_rse_skip_regs(*state, 0); 1344eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1345eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(req, tcp->pid, ap, val); 1346eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return errno ? -1 : 0; 1347d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1348d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1349d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1350d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg1 (struct tcb *tcp, arg_setup_state *state, long val) 1351d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 135208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int req = PTRACE_POKEDATA; 135308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath void *ap; 135408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 135508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) { 135608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = (void *) (intptr_t) PT_R9; /* r9 == ECX */ 135708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath req = PTRACE_POKEUSER; 135808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath } else 135908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = ia64_rse_skip_regs(*state, 1); 1360eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1361eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(req, tcp->pid, ap, val); 1362eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return errno ? -1 : 0; 1363d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1364d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1365b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath/* ia64 does not return the input arguments from functions (and syscalls) 1366b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath according to ia64 RSE (Register Stack Engine) behavior. */ 1367b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath 13683bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) ((void) (state), 0) 13693bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg1(tcp, state, val) ((void) (state), 0) 1370b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath 13713bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (SPARC) || defined (SPARC64) 1372d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13738566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysingertypedef struct pt_regs arg_setup_state; 1374d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13753bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_setup(tcp, state) \ 1376eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0)) 13773bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_finish_change(tcp, state) \ 1378eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0)) 1379d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13808566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# define get_arg0(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O0], 0) 13818566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# define get_arg1(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O1], 0) 13828566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# define set_arg0(tcp, state, val) ((state)->u_regs[U_REG_O0] = (val), 0) 13838566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# define set_arg1(tcp, state, val) ((state)->u_regs[U_REG_O1] = (val), 0) 13843bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) 0 1385d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13863bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else /* other architectures */ 1387d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13883bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined S390 || defined S390X 13897b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath/* Note: this is only true for the `clone' system call, which handles 13907b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath arguments specially. We could as well say that its first two arguments 13917b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath are swapped relative to other architectures, but that would just be 13927b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath another #ifdef in the calls. */ 13933bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset PT_GPR3 13943bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset PT_ORIGGPR2 13953bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) ((void) (state), 0) 13963bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg1(tcp, state, val) ((void) (state), 0) 13973bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_index 1 13983bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_index 0 13993bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (ALPHA) || defined (MIPS) 14003bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset REG_A0 14013bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (REG_A0+1) 14025ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# elif defined (AVR32) 14035ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# define arg0_offset (REG_R12) 14045ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# define arg1_offset (REG_R11) 14053bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (POWERPC) 14063bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset (sizeof(unsigned long)*PT_R3) 14073bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (sizeof(unsigned long)*PT_R4) 14083bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) ((void) (state), 0) 14093bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (HPPA) 14103bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset PT_GR26 14113bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (PT_GR26-4) 14123bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (X86_64) 14133bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset ((long)(8*(current_personality ? RBX : RDI))) 14143bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset ((long)(8*(current_personality ? RCX : RSI))) 14153bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (SH) 14163bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset (4*(REG_REG0+4)) 14173bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (4*(REG_REG0+5)) 14183bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (SH64) 14193bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko /* ABI defines arg0 & 1 in r2 & r3 */ 14203bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset (REG_OFFSET+16) 14213bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (REG_OFFSET+24) 14223bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) 0 1423ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# elif defined CRISV10 || defined CRISV32 1424ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define arg0_offset (4*PT_R11) 1425ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define arg1_offset (4*PT_ORIG_R10) 1426ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define restore_arg0(tcp, state, val) 0 1427ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define restore_arg1(tcp, state, val) 0 1428ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define arg0_index 1 1429ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define arg1_index 0 14303bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else 14313bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset 0 14323bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset 4 14333bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined ARM 14343bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) 0 14353bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 14363bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1437d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1438d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef int arg_setup_state; 1439d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14403bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_setup(tcp, state) (0) 14413bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_finish_change(tcp, state) 0 14423bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define get_arg0(tcp, cookie, valp) \ 14433bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko (upeek ((tcp), arg0_offset, (valp))) 14443bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define get_arg1(tcp, cookie, valp) \ 14453bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko (upeek ((tcp), arg1_offset, (valp))) 1446d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1447d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1448eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathset_arg0 (struct tcb *tcp, void *cookie, long val) 1449d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1450eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val); 1451d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1452d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1453d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1454eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathset_arg1 (struct tcb *tcp, void *cookie, long val) 1455d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1456eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val); 1457d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1458d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14593bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* architectures */ 1460d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14613bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef restore_arg0 14623bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val)) 14633bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 14643bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef restore_arg1 14653bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val)) 14663bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1467d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14683bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef arg0_index 14693bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_index 0 14703bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_index 1 14713bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 147290d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath 1473d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint 1474418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkosetbpt(struct tcb *tcp) 1475d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 14763291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone }; 1477d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath arg_setup_state state; 1478d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1479d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (tcp->flags & TCB_BPTSET) { 1480d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1481d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1482d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath } 1483d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14843291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath /* 14853291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath * It's a silly kludge to initialize this with a search at runtime. 14863291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath * But it's better than maintaining another magic thing in the 14873291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath * godforsaken tables. 14883291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath */ 14893291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath if (clone_scno[current_personality] == 0) { 14903291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath int i; 14913291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath for (i = 0; i < nsyscalls; ++i) 14923291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath if (sysent[i].sys_func == sys_clone) { 14933291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath clone_scno[current_personality] = i; 14943291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath break; 14953291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath } 14963291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath } 14973291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath 149876989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath switch (known_scno(tcp)) { 14993bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SYS_vfork 15009383c6c539af09303efe0a16dea55363b095f66eRoland McGrath case SYS_vfork: 15013bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 15023bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SYS_fork 1503d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_fork: 15043bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 15053bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined SYS_fork || defined SYS_vfork 1506d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (arg_setup (tcp, &state) < 0 1507d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || get_arg0 (tcp, &state, &tcp->inst[0]) < 0 1508d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || get_arg1 (tcp, &state, &tcp->inst[1]) < 0 15093291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath || change_syscall(tcp, clone_scno[current_personality]) < 0 1510d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0 1511d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || set_arg1 (tcp, &state, 0) < 0 1512d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || arg_finish_change (tcp, &state) < 0) 1513d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1514c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD; 1515c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->u_arg[arg1_index] = 0; 1516d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags |= TCB_BPTSET; 1517d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 15183bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1519d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1520d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_clone: 15213bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SYS_clone2 1522d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_clone2: 15233bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 15248fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil /* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)' 15258fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil contrary to x86 SYS_vfork above. Even on x86 we turn the 15268fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil vfork semantics into plain fork - each application must not 15278fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil depend on the vfork specifics according to POSIX. We would 15288fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil hang waiting for the parent resume otherwise. We need to 15298fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil clear also CLONE_VM but only in the CLONE_VFORK case as 15308fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil otherwise we would break pthread_create. */ 15318fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil 1532d6ff0d520d4bd8dda1523ec57e8ba2bc0ab3cf69Roland McGrath if ((arg_setup (tcp, &state) < 0 1533d6ff0d520d4bd8dda1523ec57e8ba2bc0ab3cf69Roland McGrath || set_arg0 (tcp, &state, 1534d6ff0d520d4bd8dda1523ec57e8ba2bc0ab3cf69Roland McGrath (tcp->u_arg[arg0_index] | CLONE_PTRACE) 15358fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil & ~(tcp->u_arg[arg0_index] & CLONE_VFORK 15368fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil ? CLONE_VFORK | CLONE_VM : 0)) < 0 1537d6ff0d520d4bd8dda1523ec57e8ba2bc0ab3cf69Roland McGrath || arg_finish_change (tcp, &state) < 0)) 15385ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return -1; 1539d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags |= TCB_BPTSET; 1540c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->inst[0] = tcp->u_arg[arg0_index]; 1541c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->inst[1] = tcp->u_arg[arg1_index]; 1542d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1543d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1544d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath default: 1545d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n", 1546d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->scno, tcp->pid); 1547d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath break; 1548d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath } 1549d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1550d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1551d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1552d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1553d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint 1554d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathclearbpt(tcp) 1555d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstruct tcb *tcp; 1556d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1557d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath arg_setup_state state; 1558d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (arg_setup (tcp, &state) < 0 1559e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath || restore_arg0 (tcp, &state, tcp->inst[0]) < 0 1560e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath || restore_arg1 (tcp, &state, tcp->inst[1]) < 0 1561d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || arg_finish_change (tcp, &state)) 156246ed50d56909843420b0a0cb1360a500ce421d52Andreas Schwab if (errno != ESRCH) return -1; 1563d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags &= ~TCB_BPTSET; 1564d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1565d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1566d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 15673bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else /* !defined LINUX */ 1568d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 156976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 157076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermansetbpt(tcp) 157176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 157276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 15733bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SUNOS4 15743bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SPARC /* This code is slightly sparc specific */ 157576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1576e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 15773bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define BPT 0x91d02001 /* ta 1 */ 15783bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP 0x10800000 /* ba 0 */ 15793bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOPA 0x30800000 /* ba,a 0 */ 15803bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define NOP 0x01000000 15813bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if LOOPA 158276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[1] = {LOOPA}; 15833bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else 158476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[2] = {LOOP, NOP}; 15853bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 158676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 158776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 158876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 158976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 159076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1591eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 1592eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 159376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 159476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 159576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->baddr = regs.r_o7 + 8; 1596eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr, 1597eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sizeof tcp->inst, (char *)tcp->inst) < 0) { 1598eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_READTEXT, ...)"); 159976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 160076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 160176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 160276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 160376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * XXX - BRUTAL MODE ON 160476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We cannot set a real BPT in the child, since it will not be 160576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * traced at the moment it will reach the trap and would probably 160676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * die with a core dump. 160776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Thus, we are force our way in by taking out two instructions 160876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * and insert an eternal loop in stead, in expectance of the SIGSTOP 160976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * generated by out PTRACE_ATTACH. 161076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Of cause, if we evaporate ourselves in the middle of all this... 161176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 1612eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 161376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof loopdeloop, (char *) loopdeloop) < 0) { 1614eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)"); 161576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 161676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 161776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 161876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16193bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SPARC */ 16203bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SUNOS4 */ 162176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 162276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 162376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 162476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 162576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 162676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanclearbpt(tcp) 162776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 162876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 16293bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SUNOS4 16303bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SPARC 163176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16323bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if !LOOPA 1633e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 16343bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 163576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 163676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 163776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 163876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 163976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1640eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 164176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof tcp->inst, (char *) tcp->inst) < 0) { 1642eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)"); 164376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 164476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 164576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 164676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16473bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if !LOOPA 164876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 164976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Since we don't have a single instruction breakpoint, we may have 16503bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * to adjust the program counter after removing our `breakpoint'. 165176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 1652eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 1653eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clearbpt: ptrace(PTRACE_GETREGS, ...)"); 165476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 165576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1656eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if ((regs.r_pc < tcp->baddr) || 1657eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath (regs.r_pc > tcp->baddr + 4)) { 165876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet */ 165976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 166076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 166176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "NOTE: PC not at bpt (pc %#x baddr %#x)\n", 16623bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko regs.r_pc, tcp->baddr); 166376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 166476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 166576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (regs.r_pc != tcp->baddr) 166676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 166776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n", 166876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc, tcp->baddr); 166976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 167076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc = tcp->baddr; 1671eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) { 1672eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clearbpt: ptrace(PTRACE_SETREGS, ...)"); 167376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 167476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 16753bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* LOOPA */ 16763bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SPARC */ 16773bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SUNOS4 */ 167876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 167976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 168076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 168176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16823bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* !defined LINUX */ 1683d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1684bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 168576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16863bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko 168776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 168876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 168976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 1690932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenkogetex(tcp, hdr) 1691932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenkostruct tcb *tcp; 169276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct exec *hdr; 169376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 169476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 169576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 169676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; n < sizeof *hdr; n += 4) { 169776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long res; 1698932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, uoff(u_exdata) + n, &res) < 0) 169976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 170076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(((char *) hdr) + n, &res, 4); 170176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 170276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) { 170376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n", 170476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_magic, hdr->a_toolversion, hdr->a_machtype); 170576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n", 170676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry); 170776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 170876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 170976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 171076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 171176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 171276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfixvfork(tcp) 171376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 171476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 171576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 171676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 171776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Change `vfork' in a freshly exec'ed dynamically linked 171876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * executable's (internal) symbol table to plain old `fork' 171976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 172076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 172176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct exec hdr; 172276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic dyn; 172376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic_2 ld; 172476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *strtab, *cp; 172576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1726932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (getex(tcp, &hdr) < 0) 172776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 172876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!hdr.a_dynamic) 172976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 173076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 173176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) { 173276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read DYNAMIC\n"); 173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 173476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 173576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) { 173676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read link_dynamic_2\n"); 173776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 173876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 173976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) { 174046100d07257824da2ae1147da0324b5788c95501Roland McGrath fprintf(stderr, "out of memory\n"); 174176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 174276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1743eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 174476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 174576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 174676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 174776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 174876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strcmp(cp, "_vfork") == 0) { 174976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 175076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "fixvfork: FOUND _vfork\n"); 175176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strcpy(cp, "_fork"); 175276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 175376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 175476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cp += strlen(cp)+1; 175576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 175676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cp < strtab + ld.ld_symb_size) 175776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 175876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Write entire symbol table back to avoid 175976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * memory alignment bugs in ptrace 176076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 1761eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 176276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 176376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 176476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 176576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 176676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 176776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 176876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerr: 176976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 177076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 177176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 177276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 177376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 1774