util.c revision 4924dbd6d750665cf383b20ab4fd67e48219ab91
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 971201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_nz(struct timeval *a) 9876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 9976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return a->tv_sec || a->tv_usec; 10076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 10176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 1031201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_cmp(struct timeval *a, struct timeval *b) 10476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 10576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (a->tv_sec < b->tv_sec 10676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec)) 10776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 10876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (a->tv_sec > b->tv_sec 10976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec)) 11076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 11176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 11276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 11376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandouble 1151201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_float(struct timeval *tv) 11676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 11776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tv->tv_sec + tv->tv_usec/1000000.0; 11876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 11976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 1211201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_add(struct timeval *tv, struct timeval *a, struct timeval *b) 12276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 12376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec + b->tv_sec; 12476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec + b->tv_usec; 12558372f52ac5f824be687c01bfc1db1ffb963f91eRoland McGrath if (tv->tv_usec >= 1000000) { 12676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec++; 12776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec -= 1000000; 12876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 12976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 1321201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_sub(struct timeval *tv, struct timeval *a, struct timeval *b) 13376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 13476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec - b->tv_sec; 13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec - b->tv_usec; 13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (((long) tv->tv_usec) < 0) { 13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec--; 13876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec += 1000000; 13976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 14076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 14176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 14276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 1431201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_div(struct timeval *tv, struct timeval *a, int n) 14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 14576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n; 14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000; 14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 14876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 14976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 1511201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_mul(struct timeval *tv, struct timeval *a, int n) 15276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec * n; 154fefdd97156bb2f86c5b6596dc7e28d954516b3edDmitry V. Levin tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000; 15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 15776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 158ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinconst char * 159ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinxlookup(const struct xlat *xlat, int val) 16076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 16176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (; xlat->str != NULL; xlat++) 16276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val == val) 16376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return xlat->str; 16476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 16576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 16676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 168eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Generic ptrace wrapper which tracks ESRCH errors 169eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * by setting tcp->ptrace_errno to ESRCH. 170732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * 171732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * We assume that ESRCH indicates likely process death (SIGKILL?), 172732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * modulo bugs where process somehow ended up not stopped. 173732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Unfortunately kernel uses ESRCH for that case too. Oh well. 174eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * 175eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Currently used by upeek() only. 176eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * TODO: use this in all other ptrace() calls while decoding. 177732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko */ 178732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenkolong 179eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathdo_ptrace(int request, struct tcb *tcp, void *addr, void *data) 180732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko{ 181732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko long l; 182732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko 183732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko errno = 0; 18409a13c2da736aa9a74e7de761062c82832f7cf04Mike Frysinger l = ptrace(request, tcp->pid, addr, (long) data); 185eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Non-ESRCH errors might be our invalid reg/mem accesses, 186eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * we do not record them. */ 187eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno == ESRCH) 188eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tcp->ptrace_errno = ESRCH; 189732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko return l; 190732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko} 191732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko 192732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko/* 193732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Used when we want to unblock stopped traced process. 194732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL. 195732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Returns 0 on success or if error was ESRCH 196732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * (presumably process was killed while we talk to it). 197732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Otherwise prints error message and returns -1. 198732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko */ 199732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenkoint 200eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathptrace_restart(int op, struct tcb *tcp, int sig) 201732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko{ 202732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko int err; 203eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath const char *msg; 204732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko 205732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko errno = 0; 20609a13c2da736aa9a74e7de761062c82832f7cf04Mike Frysinger ptrace(op, tcp->pid, (void *) 1, (long) sig); 207732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko err = errno; 208732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko if (!err || err == ESRCH) 209732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko return 0; 210732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko 211732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko tcp->ptrace_errno = err; 212eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath msg = "SYSCALL"; 213eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (op == PTRACE_CONT) 214eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath msg = "CONT"; 215eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (op == PTRACE_DETACH) 216eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath msg = "DETACH"; 217eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath fprintf(stderr, "strace: ptrace(PTRACE_%s,1,%d): %s\n", 218eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath msg, sig, strerror(err)); 219732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko return -1; 220732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko} 221732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko 222732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko/* 22376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Print entry in struct xlat table, if there. 22476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 22576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 226ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinprintxval(const struct xlat *xlat, int val, const char *dflt) 22776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 228ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levin const char *str = xlookup(xlat, val); 22976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 23076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", str); 23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#x /* %s */", val, dflt); 23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 23576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 236b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab#if HAVE_LONG_LONG 237b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab/* 238b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab * Print 64bit argument at position llarg and return the index of the next 239b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab * argument. 240b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab */ 241b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwabint 242b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwabprintllval(struct tcb *tcp, const char *format, int llarg) 243b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab{ 244b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# if defined(FREEBSD) \ 245d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab || (defined(LINUX) && defined(POWERPC) && !defined(POWERPC64)) \ 2467a5b08fb26dcfb343e2c89567bf139af252a95fdDmitry V. Levin || defined(LINUX_MIPSO32) \ 2477a5b08fb26dcfb343e2c89567bf139af252a95fdDmitry V. Levin || defined(__ARM_EABI__) 248b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab /* Align 64bit argument to 64bit boundary. */ 2494b08df42ff069dcf44b8ed206ae33a2904c366baDenys Vlasenko llarg = (llarg + 1) & 0x1e; 250b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# endif 251d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab# if defined LINUX && (defined X86_64 || defined POWERPC64) 252b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab if (current_personality == 0) { 253b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab tprintf(format, tcp->u_arg[llarg]); 254b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab llarg++; 255b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab } else { 256d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab# ifdef POWERPC64 257d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab /* Align 64bit argument to 64bit boundary. */ 2584b08df42ff069dcf44b8ed206ae33a2904c366baDenys Vlasenko llarg = (llarg + 1) & 0x1e; 259d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab# endif 260b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab tprintf(format, LONG_LONG(tcp->u_arg[llarg], tcp->u_arg[llarg + 1])); 261b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab llarg += 2; 262b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab } 263d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab# elif defined IA64 || defined ALPHA 264b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab tprintf(format, tcp->u_arg[llarg]); 265b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab llarg++; 266b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# elif defined LINUX_MIPSN32 267b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab tprintf(format, tcp->ext_arg[llarg]); 268b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab llarg++; 269b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# else 270b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab tprintf(format, LONG_LONG(tcp->u_arg[llarg], tcp->u_arg[llarg + 1])); 271b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab llarg += 2; 272b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# endif 273b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab return llarg; 274b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab} 275b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab#endif 276b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab 27776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 27876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interpret `xlat' as an array of flags 27976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * print the entries whose bits are on in `flags' 28076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * return # of flags printed. 28176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 2824924dbd6d750665cf383b20ab4fd67e48219ab91Denys Vlasenkovoid 2831201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoaddflags(const struct xlat *xlat, int flags) 28476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 2854924dbd6d750665cf383b20ab4fd67e48219ab91Denys Vlasenko for (; xlat->str; xlat++) { 28676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 28776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%s", xlat->str); 28876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 28976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 29076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 29176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags) { 29276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%#x", flags); 29376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 29476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 29576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 296a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath/* 2974924dbd6d750665cf383b20ab4fd67e48219ab91Denys Vlasenko * Interpret `xlat' as an array of flags. 298a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Print to static string the entries whose bits are on in `flags' 299a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Return static string. 300a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath */ 301a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrathconst char * 302a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrathsprintflags(const char *prefix, const struct xlat *xlat, int flags) 303a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath{ 304a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath static char outstr[1024]; 305a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath int found = 0; 306a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 307a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath strcpy(outstr, prefix); 308a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 309a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath for (; xlat->str; xlat++) { 310a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if ((flags & xlat->val) == xlat->val) { 311a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if (found) 312a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath strcat(outstr, "|"); 313a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath strcat(outstr, xlat->str); 314a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath flags &= ~xlat->val; 315a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath found = 1; 316a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath } 317a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath } 318a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if (flags) { 319a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if (found) 320a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath strcat(outstr, "|"); 321a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath sprintf(outstr + strlen(outstr), "%#x", flags); 322a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath } 323a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 324a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath return outstr; 325a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath} 326a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 32776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 32830145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levinprintflags(const struct xlat *xlat, int flags, const char *dflt) 32976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 33076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 33130145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levin const char *sep; 33276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 33376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags == 0 && xlat->val == 0) { 33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", xlat->str); 33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 33676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 33776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 33876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = ""; 33976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 34076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 34176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s%s", sep, xlat->str); 34276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 34376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = "|"; 34476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 34576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 34676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 347b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath 348b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (n) { 349b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (flags) { 350b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("%s%#x", sep, flags); 351b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath n++; 352b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } 353b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } else { 354b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (flags) { 355b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("%#x", flags); 356b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (dflt) 357b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf(" /* %s */", dflt); 358b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } else { 359b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (dflt) 360b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("0"); 361b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } 36276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 363b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath 36476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 36576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 36676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 36776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 36830145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levinprintnum(struct tcb *tcp, long addr, const char *fmt) 36976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 370eb285359906700f46b22cf4f9911695034313736Roland McGrath long num; 37176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 37276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 37376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 37476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 37576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 37676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, addr, &num) < 0) { 37776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 37876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 37976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 38076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("["); 38176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf(fmt, num); 38276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("]"); 38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 38476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 3856bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathvoid 38630145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levinprintnum_int(struct tcb *tcp, long addr, const char *fmt) 3879814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath{ 3889814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath int num; 3899814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath 3909814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath if (!addr) { 3919814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("NULL"); 3929814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath return; 3939814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath } 3949814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath if (umove(tcp, addr, &num) < 0) { 3959814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("%#lx", addr); 3969814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath return; 3979814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath } 3989814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("["); 3999814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf(fmt, num); 4009814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("]"); 4019814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath} 4029814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath 4039814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathvoid 4043138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levinprintfd(struct tcb *tcp, int fd) 4053138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levin{ 4068a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards const char *p; 4078a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards 4088a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards if (show_fd_path && (p = getfdpath(tcp, fd))) 4098a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards tprintf("%d<%s>", fd, p); 4108a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards else 4118a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards tprintf("%d", fd); 4123138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levin} 4133138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levin 4143138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levinvoid 4151201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoprintuid(const char *text, unsigned long uid) 4166bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath{ 4176bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath tprintf("%s", text); 4186bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath tprintf((uid == -1) ? "%ld" : "%lu", uid); 4196bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath} 4206bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath 42176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic char path[MAXPATHLEN + 1]; 42276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 423a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/* 424a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Quote string `instr' of length `size' 425a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Write up to (3 + `size' * 4) bytes to `outstr' buffer. 426a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If `len' < 0, treat `instr' as a NUL-terminated string 427a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * and quote at most (`size' - 1) bytes. 428a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 4296d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrathstatic int 430bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinstring_quote(const char *instr, char *outstr, int len, int size) 43176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 432bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin const unsigned char *ustr = (const unsigned char *) instr; 433bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin char *s = outstr; 434bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin int usehex = 0, c, i; 43576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 436bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (xflag > 1) 437bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin usehex = 1; 438bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin else if (xflag) { 439a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for presence of symbol which require 440a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin to hex-quote the whole string. */ 441bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin for (i = 0; i < size; ++i) { 442bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin c = ustr[i]; 443a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for NUL-terminated string. */ 444a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (len < 0) { 445a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (c == '\0') 446a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin break; 447a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Quote at most size - 1 bytes. */ 448a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (i == size - 1) 449a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin continue; 450a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin } 451bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (!isprint(c) && !isspace(c)) { 452bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin usehex = 1; 453bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 454bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 455bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 45676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 457bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 458bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\"'; 459bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 460bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (usehex) { 461a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Hex-quote the whole string. */ 462bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin for (i = 0; i < size; ++i) { 463bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin c = ustr[i]; 464a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for NUL-terminated string. */ 465a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (len < 0) { 466a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (c == '\0') 467a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin break; 468a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Quote at most size - 1 bytes. */ 469a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (i == size - 1) 470a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin continue; 471a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin } 472bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin sprintf(s, "\\x%02x", c); 473bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin s += 4; 474bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 475bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } else { 476bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin for (i = 0; i < size; ++i) { 477bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin c = ustr[i]; 478a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for NUL-terminated string. */ 479a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (len < 0) { 480a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (c == '\0') 481a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin break; 482a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Quote at most size - 1 bytes. */ 483a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (i == size - 1) 484a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin continue; 485a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin } 486bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin switch (c) { 487bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\"': case '\\': 488bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 489bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = c; 490bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 491bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\f': 492bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 493bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'f'; 494bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 495bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\n': 496bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 497bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'n'; 498bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 499bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\r': 500bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 501bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'r'; 502bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 503bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\t': 504bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 505bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 't'; 506bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 507bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\v': 508bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 509bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'v'; 510bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 511bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin default: 512bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (isprint(c)) 513bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = c; 514bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin else if (i + 1 < size 515bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin && isdigit(ustr[i + 1])) { 516bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin sprintf(s, "\\%03o", c); 517bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin s += 4; 518bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } else { 519bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin sprintf(s, "\\%o", c); 520bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin s += strlen(s); 521bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 522bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 523bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 52476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 52576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 52676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 527bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\"'; 528bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s = '\0'; 5296d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath 5306d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath /* Return nonzero if the string was unterminated. */ 5316d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath return i == size; 53276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 53376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 534a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/* 535a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Print path string specified by address `addr' and length `n'. 536a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If path length exceeds `n', append `...' to the output. 537a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 53876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 539bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintpathn(struct tcb *tcp, long addr, int n) 54076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 541a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!addr) { 542371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath tprintf("NULL"); 543bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin return; 544bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 545bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 546a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Cap path length to the path buffer size, 547a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin and NUL-terminate the buffer. */ 548a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (n > sizeof path - 1) 549a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin n = sizeof path - 1; 550bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin path[n] = '\0'; 551a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin 552a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Fetch one byte more to find out whether path length > n. */ 553bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (umovestr(tcp, addr, n + 1, path) < 0) 55476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 55576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 556bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin static char outstr[4*(sizeof path - 1) + sizeof "\"...\""]; 557bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin int trunc = (path[n] != '\0'); 558bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 559bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (trunc) 560bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin path[n] = '\0'; 561a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin (void) string_quote(path, outstr, -1, n + 1); 562a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (trunc) 563bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin strcat(outstr, "..."); 564bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin tprintf("%s", outstr); 56576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 56676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 56776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 56876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 569bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintpath(struct tcb *tcp, long addr) 570bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin{ 571bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin printpathn(tcp, addr, sizeof path - 1); 572bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin} 573bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 574a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/* 575a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Print string specified by address `addr' and length `len'. 576a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If `len' < 0, treat the string as a NUL-terminated string. 577a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If string length exceeds `max_strlen', append `...' to the output. 578a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 579bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinvoid 580bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintstr(struct tcb *tcp, long addr, int len) 58176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 582bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin static char *str = NULL; 58376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char *outstr; 5846d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath int size; 58576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 58676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 58776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 58876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 58976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 590a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Allocate static buffers if they are not allocated yet. */ 591a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!str) 592a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin str = malloc(max_strlen + 1); 593a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!outstr) 594a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin outstr = malloc(4 * max_strlen + sizeof "\"...\""); 595a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!str || !outstr) { 596a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin fprintf(stderr, "out of memory\n"); 597a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin tprintf("%#lx", addr); 598a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin return; 59976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 600bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 60176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0) { 602a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* 603a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Treat as a NUL-terminated string: fetch one byte more 604a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * because string_quote() quotes one byte less. 605a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 606bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin size = max_strlen + 1; 607a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin str[max_strlen] = '\0'; 608bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (umovestr(tcp, addr, size, str) < 0) { 60976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 61076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 61176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 61276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 61376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 614a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin size = MIN(len, max_strlen); 615bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (umoven(tcp, addr, size, str) < 0) { 61676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 61776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 61876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 61976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 62076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 621a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (string_quote(str, outstr, len, size) && 622a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin (len < 0 || len > max_strlen)) 623bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin strcat(outstr, "..."); 62476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 62576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", outstr); 62676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 6281d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H 6291d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesvoid 6301201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkodumpiov(struct tcb *tcp, int len, long addr) 6311d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes{ 6324ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 6334ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin union { 6344ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin struct { u_int32_t base; u_int32_t len; } *iov32; 6354ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin struct { u_int64_t base; u_int64_t len; } *iov64; 6364ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin } iovu; 6374ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov iovu.iov64 6384ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define sizeof_iov \ 6394ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin (personality_wordsize[current_personality] == 4 \ 6404ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64)) 6414ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_base(i) \ 6424ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin (personality_wordsize[current_personality] == 4 \ 6434ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin ? (u_int64_t) iovu.iov32[i].base : iovu.iov64[i].base) 6444ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_len(i) \ 6454ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin (personality_wordsize[current_personality] == 4 \ 6464ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin ? (u_int64_t) iovu.iov32[i].len : iovu.iov64[i].len) 6474ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#else 6481d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes struct iovec *iov; 6494ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define sizeof_iov sizeof(*iov) 6504ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_base(i) iov[i].iov_base 6514ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_len(i) iov[i].iov_len 6524ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#endif 6531d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes int i; 654aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath unsigned long size; 6551d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 6564ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin size = sizeof_iov * (unsigned long) len; 6574ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin if (size / sizeof_iov != len 6584ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin || (iov = malloc(size)) == NULL) { 659aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath fprintf(stderr, "out of memory\n"); 6601d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes return; 6611d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 662aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath if (umoven(tcp, addr, size, (char *) iov) >= 0) { 6631d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes for (i = 0; i < len; i++) { 664adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko /* include the buffer number to make it easy to 665adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko * match up the trace with the source */ 666adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf(" * %lu bytes in buffer %d\n", 667adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko (unsigned long)iov_iov_len(i), i); 668adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko dumpstr(tcp, (long) iov_iov_base(i), 669adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko iov_iov_len(i)); 670adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko } 6711d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 6721d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes free((char *) iov); 6734ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef sizeof_iov 6744ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov_iov_base 6754ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov_iov_len 6764ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov 6771d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes} 6781d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 6791d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 68076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 6811201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkodumpstr(struct tcb *tcp, long addr, int len) 68276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 68376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int strsize = -1; 68476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static unsigned char *str; 68576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char outstr[80]; 68676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s; 68776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 68876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 68976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strsize < len) { 69076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 69176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(str); 69276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((str = malloc(len)) == NULL) { 69346100d07257824da2ae1147da0324b5788c95501Roland McGrath fprintf(stderr, "out of memory\n"); 69476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 69576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 69676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strsize = len; 69776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 69876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 69976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, addr, len, (char *) str) < 0) 70076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 70176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 70276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < len; i += 16) { 70376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s = outstr; 70476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " | %05x ", i); 70576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 9; 70676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 70776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 70876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 70976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 71076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " %02x", str[i + j]); 71176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 3; 71276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 71376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 71476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; *s++ = ' '; 71576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 71676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 71776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; 71876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 71976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 72076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 72176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 72276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isprint(str[i + j])) 72376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = str[i + j]; 72476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 72576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '.'; 72676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 72776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 72876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 72976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 73076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s |\n", outstr); 73176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 73276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 73376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 73476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PAGMASK (~(PAGSIZ - 1)) 73576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 73676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * move `len' bytes of data from process `pid' 73776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * at address `addr' to our space at `laddr' 73876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 73976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 740ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoumoven(struct tcb *tcp, long addr, int len, char *laddr) 74176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 74276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 743eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath int pid = tcp->pid; 74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 7455daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 74876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 75176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 75276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 75376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 755eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 756eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 757eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 758eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 759eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 760eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 761eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 762eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* But if not started, we had a bogus address. */ 763eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 764eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("ptrace: umoven"); 765eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 766eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 7675daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 77076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 77176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 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 if (addr != 0 && errno != EIO && errno != ESRCH) 780eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("ptrace: umoven"); 781eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 782eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 7835daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 78476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 78576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 78676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 78776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 78876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 78976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 79076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 79176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 79276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 79376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 79476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, PAGSIZ); 79576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 796eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_READDATA, pid, 797eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath (char *) addr, len, laddr) < 0) { 798eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno != ESRCH) { 799eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("umoven: ptrace(PTRACE_READDATA, ...)"); 800eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath abort(); 801eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 80276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 80376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 80476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len -= n; 80576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += n; 80676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman laddr += n; 80776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 80876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 80976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 810bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 811ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 812aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd_as; 8139ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 814aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd; 81576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 816aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes lseek(fd, addr, SEEK_SET); 817aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (read(fd, laddr, len) == -1) 81876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 819bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 82076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 82176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 82276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 82376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 82476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 82576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * like `umove' but make the additional effort of looking 82676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * for a terminating zero byte. 82776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 82876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 829ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoumovestr(struct tcb *tcp, long addr, int len, char *laddr) 83076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 831bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 832aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#ifdef HAVE_MP_PROCFS 833aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd_as; 834aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#else 835aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd; 836aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#endif 837aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes /* Some systems (e.g. FreeBSD) can be upset if we read off the 838aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes end of valid memory, avoid this by trying to read up 839aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes to page boundaries. But we don't know what a page is (and 840aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes getpagesize(2) (if it exists) doesn't necessarily return 841aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes hardware page size). Assume all pages >= 1024 (a-historical 842aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes I know) */ 843aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 844b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko int page = 1024; /* How to find this? */ 845aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int move = page - (addr & (page - 1)); 846aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int left = len; 847aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 848aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes lseek(fd, addr, SEEK_SET); 849aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 850aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes while (left) { 851aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (move > left) move = left; 8529cecf7f8d6115a247be7186013857270b2d588d5John Hughes if ((move = read(fd, laddr, move)) <= 0) 853aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return left != len ? 0 : -1; 854b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (memchr(laddr, 0, move)) break; 855aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes left -= move; 856aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes laddr += move; 857aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes addr += move; 858aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes move = page; 859aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes } 860bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 8615daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 862eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath int pid = tcp->pid; 86376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, n, m; 86476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 86576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 86676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 86776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 86876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 86976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 87076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 87176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 87276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 873eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 874eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 875eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 876eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 877eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 878eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 879eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 880eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 881eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("umovestr"); 882eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 883eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 8845daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 885b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n, len)); 88676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (n & (sizeof(long) - 1)) 88776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[n++] == '\0') 88876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 88976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 89076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 89176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 892eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 893eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 894eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 895eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 896eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 897eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 898eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 899eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 900eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("umovestr"); 901eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 902eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 9035daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 90476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 90576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < sizeof(long); i++) 90676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[i] == '\0') 90776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 90876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 90976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 91076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 911bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 912aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return 0; 91376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 91476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 91576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 9163bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if !defined (SPARC) && !defined(SPARC64) 9173bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define PTRACE_WRITETEXT 101 9183bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define PTRACE_WRITEDATA 102 9193bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* !SPARC && !SPARC64 */ 92076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 92176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 92276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 92376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 92476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 9251201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkouload(int cmd, int pid, long addr, int len, char *laddr) 92676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 92776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int peek, poke; 92876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 92976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 93076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 93176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 93276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 93376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 93476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cmd == PTRACE_WRITETEXT) { 93576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKTEXT; 93676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKETEXT; 93776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 93876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 93976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKDATA; 94076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKEDATA; 94176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 94276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 94376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 94476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 94576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); 946eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 947eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(peek, pid, (char *) addr, 0); 948eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 949eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("uload: POKE"); 95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 951eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 952eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len)); 953eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(poke, pid, (char *)addr, u.val) < 0) { 954eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("uload: POKE"); 95576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 95676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 957eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath addr += sizeof(long), laddr += m, len -= m; 95876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 95976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 96076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < sizeof(long)) 961eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(peek, pid, (char *) addr, 0); 962eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath memcpy(u.x, laddr, m = MIN(sizeof(long), len)); 963eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(poke, pid, (char *) addr, u.val) < 0) { 964eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("uload: POKE"); 96576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 96676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 967eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath addr += sizeof(long), laddr += m, len -= m; 96876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 96976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 97076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 97176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 972eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint 9731201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotload(int pid, int addr, int len, char *laddr) 974eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath{ 975eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return uload(PTRACE_WRITETEXT, pid, addr, len, laddr); 976eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath} 977eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 978eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint 9791201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkodload(int pid, int addr, int len, char *laddr) 98076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 981eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return uload(PTRACE_WRITEDATA, pid, addr, len, laddr); 98276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 98376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 98476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 98576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 986bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 9891201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoupeek(struct tcb *tcp, long off, long *res) 99076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 9933bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SUNOS4_KERNEL_ARCH_KLUDGE 99476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman { 99576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int is_sun4m = -1; 99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct utsname name; 99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 99876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Round up the usual suspects. */ 99976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m == -1) { 100076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (uname(&name) < 0) { 100176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("upeek: uname?"); 100276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 100376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 100476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman is_sun4m = strcmp(name.machine, "sun4m") == 0; 100576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) { 1006d9f816f60457930af27349fac3d23b3b78338036Roland McGrath const struct xlat *x; 100776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 100876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (x = struct_user_offsets; x->str; x++) 100976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman x->val += 1024; 101076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 101176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 101276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) 101376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman off += 1024; 101476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 10153bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 1016eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1017732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko val = do_ptrace(PTRACE_PEEKUSER, tcp, (char *) off, 0); 1018eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (val == -1 && errno) { 1019eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno != ESRCH) { 1020eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath char buf[60]; 1021b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko sprintf(buf, "upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)", tcp->pid, off); 1022eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror(buf); 1023eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 102476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1025eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 102676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *res = val; 102776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 102876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 102976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1030bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 103176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 103276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 1033ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenkoprintcall(struct tcb *tcp) 103476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 10357a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath#define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \ 10367a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath sizeof(long) == 8 ? "[????????????????] " : \ 10377a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath NULL /* crash */) 103876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 103976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 10403bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef I386 104176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long eip; 104276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1043932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*EIP, &eip) < 0) { 10447a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 104576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 104676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 104776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", eip); 1048eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath 10493bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(S390) || defined(S390X) 1050adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko long psw; 1051b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (upeek(tcp, PT_PSWADDR, &psw) < 0) { 1052adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko PRINTBADPC; 1053adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko return; 1054adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko } 10553bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef S390 1056adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf("[%08lx] ", psw); 10573bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif S390X 1058adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf("[%16lx] ", psw); 10593bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1060eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath 10613bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(X86_64) 10620e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig long rip; 10630e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig 1064932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 8*RIP, &rip) < 0) { 10657a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 10660e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return; 10670e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig } 10680e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig tprintf("[%16lx] ", rip); 10693bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(IA64) 10708b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman long ip; 10718b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 1072932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_B0, &ip) < 0) { 10737a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 10748b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return; 10758b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 10768b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tprintf("[%08lx] ", ip); 10773bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(POWERPC) 107876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 107976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1080932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) { 1081d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab PRINTBADPC; 108276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 108376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1084d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab# ifdef POWERPC64 1085d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab tprintf("[%016lx] ", pc); 1086d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab# else 108776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 1088d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab# endif 10893bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(M68K) 109076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 109176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1092932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*PT_PC, &pc) < 0) { 1093b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko tprintf("[????????] "); 109476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 109576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 109676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 10973bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ALPHA) 109876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 109976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1100932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, REG_PC, &pc) < 0) { 1101b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko tprintf("[????????????????] "); 110276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 110376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 110476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 11053bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SPARC) || defined(SPARC64) 11068566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger struct pt_regs regs; 1107b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 11087a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 110976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 111076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 11118566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# if defined(SPARC64) 11128566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger tprintf("[%08lx] ", regs.tpc); 11138566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# else 11148566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger tprintf("[%08lx] ", regs.pc); 11158566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# endif 11163bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(HPPA) 1117c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman long pc; 1118c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman 1119b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (upeek(tcp, PT_IAOQ0, &pc) < 0) { 1120b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko tprintf("[????????] "); 1121c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return; 1122c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman } 1123c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tprintf("[%08lx] ", pc); 11243bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(MIPS) 112575c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman long pc; 112675c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman 1127932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, REG_EPC, &pc) < 0) { 1128b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko tprintf("[????????] "); 112975c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman return; 113075c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman } 113175c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman tprintf("[%08lx] ", pc); 11323bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH) 1133adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko long pc; 1134ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman 1135adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko if (upeek(tcp, 4*REG_PC, &pc) < 0) { 1136b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko tprintf("[????????] "); 1137adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko return; 1138adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko } 1139adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf("[%08lx] ", pc); 11403bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH64) 1141e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath long pc; 1142e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath 1143932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, REG_PC, &pc) < 0) { 1144b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko tprintf("[????????????????] "); 1145e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath return; 1146e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath } 1147e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath tprintf("[%08lx] ", pc); 11483bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ARM) 1149ef388689610fa17df1d3001face8057b411a2e26Roland McGrath long pc; 1150e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath 1151932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*15, &pc) < 0) { 11527a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 1153ef388689610fa17df1d3001face8057b411a2e26Roland McGrath return; 1154ef388689610fa17df1d3001face8057b411a2e26Roland McGrath } 1155ef388689610fa17df1d3001face8057b411a2e26Roland McGrath tprintf("[%08lx] ", pc); 11565ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# elif defined(AVR32) 11575ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko long pc; 11585ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko 11595ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko if (upeek(tcp, REG_PC, &pc) < 0) { 11605ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko tprintf("[????????] "); 11615ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return; 11625ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko } 11635ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko tprintf("[%08lx] ", pc); 11643bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(BFIN) 116587ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin long pc; 116687ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin 1167932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_PC, &pc) < 0) { 116887ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin PRINTBADPC; 116987ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin return; 117087ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin } 117187ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin tprintf("[%08lx] ", pc); 1172ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#elif defined(CRISV10) 1173ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko long pc; 1174ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko 1175eeb9ce3895f1ca0920d50696ef8b48124cef9da6Edgar E. Iglesias if (upeek(tcp, 4*PT_IRP, &pc) < 0) { 1176ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko PRINTBADPC; 1177ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko return; 1178ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko } 1179ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko tprintf("[%08lx] ", pc); 1180ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#elif defined(CRISV32) 1181ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko long pc; 1182ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko 1183eeb9ce3895f1ca0920d50696ef8b48124cef9da6Edgar E. Iglesias if (upeek(tcp, 4*PT_ERP, &pc) < 0) { 1184ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko PRINTBADPC; 1185ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko return; 1186ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko } 1187ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko tprintf("[%08lx] ", pc); 11883bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* architecture */ 118976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 119076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 119176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 119276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct regs regs; 119376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1194eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 1195eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("printcall: ptrace(PTRACE_GETREGS, ...)"); 11967a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 119776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 119876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 119976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08x] ", regs.r_o7); 120076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 120176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 120276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 120376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* XXX */ 12047a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 120576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 120676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1207bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1208bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct reg regs; 1209bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 1210bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tprintf("[%08x] ", regs.r_eip); 1211bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 121276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 121376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12143bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko 12153bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko/* 12163bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * These #if's are huge, please indent them correctly. 12173bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * It's easy to get confused otherwise. 12183bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko */ 1219bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 122076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1221e7c9024acf94101ceb17006102629f14e0f25553Denys Vlasenko# ifdef LINUX 1222d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 12233bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# include "syscall.h" 12243291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath 12253bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# include <sys/syscall.h> 12263bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef CLONE_PTRACE 12273bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define CLONE_PTRACE 0x00002000 12283bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 12293bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef CLONE_VFORK 12303bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define CLONE_VFORK 0x00004000 12313bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 12323bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef CLONE_VM 12333bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define CLONE_VM 0x00000100 12343bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 12353bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef CLONE_STOPPED 12363bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define CLONE_STOPPED 0x02000000 12373bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1238d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 12393bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef IA64 1240d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 124108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath/* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32 124208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath subsystem has them for x86... */ 12433bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define SYS_fork 2 12443bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define SYS_vfork 190 124508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 1246d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef unsigned long *arg_setup_state; 1247d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1248d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1249d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGratharg_setup(struct tcb *tcp, arg_setup_state *state) 1250d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 12511f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil unsigned long cfm, sof, sol; 12521f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil long bsp; 1253d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 12541f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil if (ia32) { 12551f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil /* Satisfy a false GCC warning. */ 12561f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil *state = NULL; 125708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return 0; 12581f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil } 125908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 1260932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_AR_BSP, &bsp) < 0) 1261d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1262932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_CFM, (long *) &cfm) < 0) 1263d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1264d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1265d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sof = (cfm >> 0) & 0x7f; 1266d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sol = (cfm >> 7) & 0x7f; 12671f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol); 1268d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 12691f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil *state = (unsigned long *) bsp; 1270d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1271d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1272d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 12733bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_finish_change(tcp, state) 0 1274d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 12753bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SYS_fork 1276d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 12771201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoget_arg0(struct tcb *tcp, arg_setup_state *state, long *valp) 1278d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 127908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int ret; 128008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 128108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) 1282b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ret = upeek(tcp, PT_R11, valp); 128308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath else 1284b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ret = umoven(tcp, 128508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath (unsigned long) ia64_rse_skip_regs(*state, 0), 128608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath sizeof(long), (void *) valp); 128708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return ret; 1288d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1289d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1290d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 12911201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoget_arg1(struct tcb *tcp, arg_setup_state *state, long *valp) 1292d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 129308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int ret; 129408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 129508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) 1296b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ret = upeek(tcp, PT_R9, valp); 129708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath else 1298b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ret = umoven(tcp, 129908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath (unsigned long) ia64_rse_skip_regs(*state, 1), 130008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath sizeof(long), (void *) valp); 130108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return ret; 1302d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 13033bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1304d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1305d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 13061201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoset_arg0(struct tcb *tcp, arg_setup_state *state, long val) 1307d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 130808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int req = PTRACE_POKEDATA; 130908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath void *ap; 131008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 131108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) { 131208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = (void *) (intptr_t) PT_R11; /* r11 == EBX */ 131308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath req = PTRACE_POKEUSER; 131408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath } else 131508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = ia64_rse_skip_regs(*state, 0); 1316eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1317eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(req, tcp->pid, ap, val); 1318eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return errno ? -1 : 0; 1319d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1320d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1321d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 13221201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoset_arg1(struct tcb *tcp, arg_setup_state *state, long val) 1323d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 132408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int req = PTRACE_POKEDATA; 132508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath void *ap; 132608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 132708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) { 132808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = (void *) (intptr_t) PT_R9; /* r9 == ECX */ 132908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath req = PTRACE_POKEUSER; 133008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath } else 133108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = ia64_rse_skip_regs(*state, 1); 1332eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1333eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(req, tcp->pid, ap, val); 1334eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return errno ? -1 : 0; 1335d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1336d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1337b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath/* ia64 does not return the input arguments from functions (and syscalls) 1338b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath according to ia64 RSE (Register Stack Engine) behavior. */ 1339b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath 13403bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) ((void) (state), 0) 13413bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg1(tcp, state, val) ((void) (state), 0) 1342b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath 13433bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (SPARC) || defined (SPARC64) 1344d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13458566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysingertypedef struct pt_regs arg_setup_state; 1346d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13473bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_setup(tcp, state) \ 1348b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko (ptrace(PTRACE_GETREGS, tcp->pid, (char *) (state), 0)) 13493bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_finish_change(tcp, state) \ 1350b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko (ptrace(PTRACE_SETREGS, tcp->pid, (char *) (state), 0)) 1351d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13528566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# define get_arg0(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O0], 0) 13538566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# define get_arg1(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O1], 0) 13548566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# define set_arg0(tcp, state, val) ((state)->u_regs[U_REG_O0] = (val), 0) 13558566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# define set_arg1(tcp, state, val) ((state)->u_regs[U_REG_O1] = (val), 0) 13563bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) 0 1357d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13583bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else /* other architectures */ 1359d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13603bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined S390 || defined S390X 13617b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath/* Note: this is only true for the `clone' system call, which handles 13627b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath arguments specially. We could as well say that its first two arguments 13637b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath are swapped relative to other architectures, but that would just be 13647b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath another #ifdef in the calls. */ 13653bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset PT_GPR3 13663bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset PT_ORIGGPR2 13673bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) ((void) (state), 0) 13683bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg1(tcp, state, val) ((void) (state), 0) 13693bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_index 1 13703bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_index 0 13713bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (ALPHA) || defined (MIPS) 13723bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset REG_A0 13733bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (REG_A0+1) 13745ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# elif defined (AVR32) 13755ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# define arg0_offset (REG_R12) 13765ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# define arg1_offset (REG_R11) 13773bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (POWERPC) 13783bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset (sizeof(unsigned long)*PT_R3) 13793bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (sizeof(unsigned long)*PT_R4) 13803bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) ((void) (state), 0) 13813bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (HPPA) 13823bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset PT_GR26 13833bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (PT_GR26-4) 13843bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (X86_64) 13853bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset ((long)(8*(current_personality ? RBX : RDI))) 13863bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset ((long)(8*(current_personality ? RCX : RSI))) 13873bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (SH) 13883bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset (4*(REG_REG0+4)) 13893bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (4*(REG_REG0+5)) 13903bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (SH64) 13913bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko /* ABI defines arg0 & 1 in r2 & r3 */ 13923bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset (REG_OFFSET+16) 13933bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (REG_OFFSET+24) 13943bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) 0 1395ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# elif defined CRISV10 || defined CRISV32 1396ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define arg0_offset (4*PT_R11) 1397ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define arg1_offset (4*PT_ORIG_R10) 1398ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define restore_arg0(tcp, state, val) 0 1399ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define restore_arg1(tcp, state, val) 0 1400ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define arg0_index 1 1401ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define arg1_index 0 14023bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else 14033bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset 0 14043bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset 4 14053bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined ARM 14063bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) 0 14073bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 14083bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1409d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1410d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef int arg_setup_state; 1411d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14123bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_setup(tcp, state) (0) 14133bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_finish_change(tcp, state) 0 14143bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define get_arg0(tcp, cookie, valp) \ 1415b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko (upeek((tcp), arg0_offset, (valp))) 14163bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define get_arg1(tcp, cookie, valp) \ 1417b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko (upeek((tcp), arg1_offset, (valp))) 1418d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1419d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 14201201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoset_arg0(struct tcb *tcp, void *cookie, long val) 1421d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1422b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko return ptrace(PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val); 1423d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1424d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1425d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 14261201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoset_arg1(struct tcb *tcp, void *cookie, long val) 1427d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1428b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko return ptrace(PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val); 1429d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1430d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14313bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* architectures */ 1432d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14333bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef restore_arg0 14343bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val)) 14353bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 14363bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef restore_arg1 14373bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val)) 14383bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1439d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14403bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef arg0_index 14413bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_index 0 14423bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_index 1 14433bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 144490d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath 1445d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint 1446418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkosetbpt(struct tcb *tcp) 1447d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 14483291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone }; 1449d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath arg_setup_state state; 1450d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1451d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (tcp->flags & TCB_BPTSET) { 1452d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1453d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1454d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath } 1455d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14563291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath /* 14573291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath * It's a silly kludge to initialize this with a search at runtime. 14583291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath * But it's better than maintaining another magic thing in the 14593291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath * godforsaken tables. 14603291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath */ 14613291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath if (clone_scno[current_personality] == 0) { 14623291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath int i; 14633291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath for (i = 0; i < nsyscalls; ++i) 14643291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath if (sysent[i].sys_func == sys_clone) { 14653291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath clone_scno[current_personality] = i; 14663291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath break; 14673291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath } 14683291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath } 14693291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath 147076989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath switch (known_scno(tcp)) { 14713bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SYS_vfork 14729383c6c539af09303efe0a16dea55363b095f66eRoland McGrath case SYS_vfork: 14733bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 14743bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SYS_fork 1475d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_fork: 14763bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 14773bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined SYS_fork || defined SYS_vfork 1478b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (arg_setup(tcp, &state) < 0 1479b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || get_arg0(tcp, &state, &tcp->inst[0]) < 0 1480b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || get_arg1(tcp, &state, &tcp->inst[1]) < 0 14813291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath || change_syscall(tcp, clone_scno[current_personality]) < 0 1482b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || set_arg0(tcp, &state, CLONE_PTRACE|SIGCHLD) < 0 1483b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || set_arg1(tcp, &state, 0) < 0 1484b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || arg_finish_change(tcp, &state) < 0) 1485d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1486c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD; 1487c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->u_arg[arg1_index] = 0; 1488d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags |= TCB_BPTSET; 1489d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 14903bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1491d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1492c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko case SYS_clone: ; 14933bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SYS_clone2 1494c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko case SYS_clone2: ; 14953bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 14968fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil /* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)' 14978fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil contrary to x86 SYS_vfork above. Even on x86 we turn the 14988fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil vfork semantics into plain fork - each application must not 14998fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil depend on the vfork specifics according to POSIX. We would 15008fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil hang waiting for the parent resume otherwise. We need to 15018fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil clear also CLONE_VM but only in the CLONE_VFORK case as 15028fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil otherwise we would break pthread_create. */ 15038fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil 1504c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko long new_arg0 = (tcp->u_arg[arg0_index] | CLONE_PTRACE); 1505c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko if (new_arg0 & CLONE_VFORK) 1506c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko new_arg0 &= ~(unsigned long)(CLONE_VFORK | CLONE_VM); 1507c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko if (arg_setup(tcp, &state) < 0 1508c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko || set_arg0(tcp, &state, new_arg0) < 0 1509c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko || arg_finish_change(tcp, &state) < 0) 15105ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return -1; 1511d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags |= TCB_BPTSET; 1512c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->inst[0] = tcp->u_arg[arg0_index]; 1513c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->inst[1] = tcp->u_arg[arg1_index]; 1514d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1515d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1516d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath default: 1517d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n", 1518d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->scno, tcp->pid); 1519d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath break; 1520d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath } 1521d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1522d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1523d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1524d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1525d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint 15261201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoclearbpt(struct tcb *tcp) 1527d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1528d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath arg_setup_state state; 1529b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (arg_setup(tcp, &state) < 0 1530b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || restore_arg0(tcp, &state, tcp->inst[0]) < 0 1531b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || restore_arg1(tcp, &state, tcp->inst[1]) < 0 1532b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || arg_finish_change(tcp, &state)) 1533c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko if (errno != ESRCH) 1534c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko return -1; 1535d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags &= ~TCB_BPTSET; 1536d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1537d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1538d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 15393bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else /* !defined LINUX */ 1540d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 154176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 15421201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkosetbpt(struct tcb *tcp) 154376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 15443bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SUNOS4 15453bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SPARC /* This code is slightly sparc specific */ 154676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1547e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 15483bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define BPT 0x91d02001 /* ta 1 */ 15493bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP 0x10800000 /* ba 0 */ 15503bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOPA 0x30800000 /* ba,a 0 */ 15513bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define NOP 0x01000000 15523bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if LOOPA 155376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[1] = {LOOPA}; 15543bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else 155576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[2] = {LOOP, NOP}; 15563bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 155776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 155876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 155976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 156076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 156176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1562eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 1563eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 156476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 156576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 156676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->baddr = regs.r_o7 + 8; 1567eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr, 1568eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sizeof tcp->inst, (char *)tcp->inst) < 0) { 1569eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_READTEXT, ...)"); 157076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 157176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 157276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 157376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 157476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * XXX - BRUTAL MODE ON 157576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We cannot set a real BPT in the child, since it will not be 157676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * traced at the moment it will reach the trap and would probably 157776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * die with a core dump. 157876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Thus, we are force our way in by taking out two instructions 157976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * and insert an eternal loop in stead, in expectance of the SIGSTOP 158076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * generated by out PTRACE_ATTACH. 158176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Of cause, if we evaporate ourselves in the middle of all this... 158276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 1583eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 158476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof loopdeloop, (char *) loopdeloop) < 0) { 1585eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)"); 158676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 158776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 158876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 158976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15903bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SPARC */ 15913bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SUNOS4 */ 159276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 159376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 159476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 159576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 159676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 15971201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoclearbpt(struct tcb *tcp) 159876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 15993bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SUNOS4 16003bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SPARC 160176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16023bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if !LOOPA 1603e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 16043bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 160576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 160676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 160776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 160876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 160976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1610eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 161176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof tcp->inst, (char *) tcp->inst) < 0) { 1612eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)"); 161376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 161476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 161576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 161676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16173bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if !LOOPA 161876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 161976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Since we don't have a single instruction breakpoint, we may have 16203bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * to adjust the program counter after removing our `breakpoint'. 162176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 1622eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 1623eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clearbpt: ptrace(PTRACE_GETREGS, ...)"); 162476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 162576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1626eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if ((regs.r_pc < tcp->baddr) || 1627eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath (regs.r_pc > tcp->baddr + 4)) { 162876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet */ 162976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 163076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 163176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "NOTE: PC not at bpt (pc %#x baddr %#x)\n", 16323bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko regs.r_pc, tcp->baddr); 163376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 163476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 163576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (regs.r_pc != tcp->baddr) 163676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 163776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n", 163876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc, tcp->baddr); 163976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 164076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc = tcp->baddr; 1641eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) { 1642eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clearbpt: ptrace(PTRACE_SETREGS, ...)"); 164376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 164476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 16453bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* LOOPA */ 16463bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SPARC */ 16473bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SUNOS4 */ 164876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 164976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 165076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 165176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16523bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* !defined LINUX */ 1653d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1654bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 165576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16563bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko 165776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 165876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 165976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 16601201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkogetex(struct tcb *tcp, struct exec *hdr) 166176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 166276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 166376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 166476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; n < sizeof *hdr; n += 4) { 166576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long res; 1666932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, uoff(u_exdata) + n, &res) < 0) 166776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 166876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(((char *) hdr) + n, &res, 4); 166976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 167076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) { 167176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n", 167276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_magic, hdr->a_toolversion, hdr->a_machtype); 167376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n", 167476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry); 167576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 167676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 167776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 167876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 167976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 16801201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkofixvfork(struct tcb *tcp) 168176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 168276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 168376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 168476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Change `vfork' in a freshly exec'ed dynamically linked 168576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * executable's (internal) symbol table to plain old `fork' 168676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 168776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 168876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct exec hdr; 168976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic dyn; 169076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic_2 ld; 169176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *strtab, *cp; 169276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1693932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (getex(tcp, &hdr) < 0) 169476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 169576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!hdr.a_dynamic) 169676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 169776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 169876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) { 169976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read DYNAMIC\n"); 170076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 170176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 170276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) { 170376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read link_dynamic_2\n"); 170476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 170576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 170676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) { 170746100d07257824da2ae1147da0324b5788c95501Roland McGrath fprintf(stderr, "out of memory\n"); 170876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 170976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1710eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 171176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 171276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 171376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 171476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 171576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strcmp(cp, "_vfork") == 0) { 171676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 171776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "fixvfork: FOUND _vfork\n"); 171876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strcpy(cp, "_fork"); 171976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 172076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 172176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cp += strlen(cp)+1; 172276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 172376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cp < strtab + ld.ld_symb_size) 172476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 172576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Write entire symbol table back to avoid 172676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * memory alignment bugs in ptrace 172776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 1728eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 172976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 173076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 173176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 173276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 173476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 173576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerr: 173676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 173776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 173876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 173976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 174076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 1741