util.c revision b63256e69bf3f1a74aadb0e14556490bc8f4ef95
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. */ 249b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab if (llarg % 2) llarg++; 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. */ 258d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab if (llarg % 2) llarg++; 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 */ 28276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 2831201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoaddflags(const struct xlat *xlat, int flags) 28476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 28576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 28676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 28776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 28876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 28976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%s", xlat->str); 29076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 29176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 29276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 29376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 29476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags) { 29576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%#x", flags); 29676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 29776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 29876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 29976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 30076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 301a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath/* 302a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Interpret `xlat' as an array of flags/ 303a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Print to static string the entries whose bits are on in `flags' 304a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Return static string. 305a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath */ 306a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrathconst char * 307a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrathsprintflags(const char *prefix, const struct xlat *xlat, int flags) 308a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath{ 309a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath static char outstr[1024]; 310a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath int found = 0; 311a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 312a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath strcpy(outstr, prefix); 313a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 314a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath for (; xlat->str; xlat++) { 315a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if ((flags & xlat->val) == xlat->val) { 316a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if (found) 317a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath strcat(outstr, "|"); 318a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath strcat(outstr, xlat->str); 319a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath flags &= ~xlat->val; 320a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath found = 1; 321a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath } 322a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath } 323a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if (flags) { 324a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if (found) 325a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath strcat(outstr, "|"); 326a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath sprintf(outstr + strlen(outstr), "%#x", flags); 327a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath } 328a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 329a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath return outstr; 330a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath} 331a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 33276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 33330145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levinprintflags(const struct xlat *xlat, int flags, const char *dflt) 33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 33630145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levin const char *sep; 33776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 33876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags == 0 && xlat->val == 0) { 33976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", xlat->str); 34076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 34176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 34276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 34376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = ""; 34476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 34576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 34676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s%s", sep, xlat->str); 34776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 34876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = "|"; 34976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 35076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 35176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 352b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath 353b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (n) { 354b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (flags) { 355b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("%s%#x", sep, flags); 356b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath n++; 357b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } 358b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } else { 359b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (flags) { 360b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("%#x", flags); 361b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (dflt) 362b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf(" /* %s */", dflt); 363b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } else { 364b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (dflt) 365b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("0"); 366b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } 36776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 368b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath 36976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 37076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 37176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 37276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 37330145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levinprintnum(struct tcb *tcp, long addr, const char *fmt) 37476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 375eb285359906700f46b22cf4f9911695034313736Roland McGrath long num; 37676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 37776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 37876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 37976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 38076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 38176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, addr, &num) < 0) { 38276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 38476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 38576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("["); 38676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf(fmt, num); 38776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("]"); 38876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 38976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 3906bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathvoid 39130145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levinprintnum_int(struct tcb *tcp, long addr, const char *fmt) 3929814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath{ 3939814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath int num; 3949814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath 3959814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath if (!addr) { 3969814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("NULL"); 3979814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath return; 3989814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath } 3999814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath if (umove(tcp, addr, &num) < 0) { 4009814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("%#lx", addr); 4019814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath return; 4029814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath } 4039814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("["); 4049814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf(fmt, num); 4059814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("]"); 4069814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath} 4079814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath 4089814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathvoid 4093138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levinprintfd(struct tcb *tcp, int fd) 4103138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levin{ 4118a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards const char *p; 4128a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards 4138a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards if (show_fd_path && (p = getfdpath(tcp, fd))) 4148a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards tprintf("%d<%s>", fd, p); 4158a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards else 4168a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards tprintf("%d", fd); 4173138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levin} 4183138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levin 4193138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levinvoid 4201201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoprintuid(const char *text, unsigned long uid) 4216bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath{ 4226bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath tprintf("%s", text); 4236bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath tprintf((uid == -1) ? "%ld" : "%lu", uid); 4246bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath} 4256bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath 42676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic char path[MAXPATHLEN + 1]; 42776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 428a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/* 429a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Quote string `instr' of length `size' 430a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Write up to (3 + `size' * 4) bytes to `outstr' buffer. 431a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If `len' < 0, treat `instr' as a NUL-terminated string 432a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * and quote at most (`size' - 1) bytes. 433a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 4346d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrathstatic int 435bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinstring_quote(const char *instr, char *outstr, int len, int size) 43676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 437bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin const unsigned char *ustr = (const unsigned char *) instr; 438bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin char *s = outstr; 439bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin int usehex = 0, c, i; 44076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 441bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (xflag > 1) 442bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin usehex = 1; 443bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin else if (xflag) { 444a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for presence of symbol which require 445a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin to hex-quote the whole string. */ 446bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin for (i = 0; i < size; ++i) { 447bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin c = ustr[i]; 448a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for NUL-terminated string. */ 449a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (len < 0) { 450a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (c == '\0') 451a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin break; 452a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Quote at most size - 1 bytes. */ 453a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (i == size - 1) 454a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin continue; 455a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin } 456bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (!isprint(c) && !isspace(c)) { 457bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin usehex = 1; 458bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 459bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 460bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 46176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 462bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 463bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\"'; 464bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 465bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (usehex) { 466a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Hex-quote the whole string. */ 467bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin for (i = 0; i < size; ++i) { 468bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin c = ustr[i]; 469a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for NUL-terminated string. */ 470a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (len < 0) { 471a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (c == '\0') 472a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin break; 473a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Quote at most size - 1 bytes. */ 474a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (i == size - 1) 475a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin continue; 476a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin } 477bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin sprintf(s, "\\x%02x", c); 478bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin s += 4; 479bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 480bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } else { 481bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin for (i = 0; i < size; ++i) { 482bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin c = ustr[i]; 483a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for NUL-terminated string. */ 484a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (len < 0) { 485a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (c == '\0') 486a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin break; 487a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Quote at most size - 1 bytes. */ 488a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (i == size - 1) 489a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin continue; 490a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin } 491bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin switch (c) { 492bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\"': case '\\': 493bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 494bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = c; 495bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 496bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\f': 497bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 498bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'f'; 499bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 500bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\n': 501bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 502bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'n'; 503bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 504bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\r': 505bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 506bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'r'; 507bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 508bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\t': 509bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 510bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 't'; 511bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 512bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\v': 513bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 514bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'v'; 515bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 516bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin default: 517bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (isprint(c)) 518bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = c; 519bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin else if (i + 1 < size 520bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin && isdigit(ustr[i + 1])) { 521bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin sprintf(s, "\\%03o", c); 522bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin s += 4; 523bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } else { 524bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin sprintf(s, "\\%o", c); 525bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin s += strlen(s); 526bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 527bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 528bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 52976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 53076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 53176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 532bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\"'; 533bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s = '\0'; 5346d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath 5356d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath /* Return nonzero if the string was unterminated. */ 5366d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath return i == size; 53776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 53876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 539a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/* 540a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Print path string specified by address `addr' and length `n'. 541a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If path length exceeds `n', append `...' to the output. 542a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 54376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 544bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintpathn(struct tcb *tcp, long addr, int n) 54576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 546a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!addr) { 547371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath tprintf("NULL"); 548bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin return; 549bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 550bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 551a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Cap path length to the path buffer size, 552a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin and NUL-terminate the buffer. */ 553a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (n > sizeof path - 1) 554a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin n = sizeof path - 1; 555bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin path[n] = '\0'; 556a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin 557a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Fetch one byte more to find out whether path length > n. */ 558bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (umovestr(tcp, addr, n + 1, path) < 0) 55976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 56076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 561bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin static char outstr[4*(sizeof path - 1) + sizeof "\"...\""]; 562bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin int trunc = (path[n] != '\0'); 563bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 564bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (trunc) 565bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin path[n] = '\0'; 566a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin (void) string_quote(path, outstr, -1, n + 1); 567a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (trunc) 568bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin strcat(outstr, "..."); 569bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin tprintf("%s", outstr); 57076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 57176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 57276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 57376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 574bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintpath(struct tcb *tcp, long addr) 575bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin{ 576bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin printpathn(tcp, addr, sizeof path - 1); 577bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin} 578bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 579a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/* 580a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Print string specified by address `addr' and length `len'. 581a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If `len' < 0, treat the string as a NUL-terminated string. 582a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If string length exceeds `max_strlen', append `...' to the output. 583a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 584bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinvoid 585bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintstr(struct tcb *tcp, long addr, int len) 58676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 587bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin static char *str = NULL; 58876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char *outstr; 5896d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath int size; 59076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 59176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 59276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 59376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 59476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 595a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Allocate static buffers if they are not allocated yet. */ 596a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!str) 597a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin str = malloc(max_strlen + 1); 598a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!outstr) 599a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin outstr = malloc(4 * max_strlen + sizeof "\"...\""); 600a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!str || !outstr) { 601a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin fprintf(stderr, "out of memory\n"); 602a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin tprintf("%#lx", addr); 603a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin return; 60476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 605bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 60676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0) { 607a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* 608a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Treat as a NUL-terminated string: fetch one byte more 609a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * because string_quote() quotes one byte less. 610a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 611bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin size = max_strlen + 1; 612a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin str[max_strlen] = '\0'; 613bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (umovestr(tcp, addr, size, str) < 0) { 61476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 61576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 61676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 61776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 61876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 619a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin size = MIN(len, max_strlen); 620bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (umoven(tcp, addr, size, str) < 0) { 62176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 62276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 62376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 62476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 62576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 626a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (string_quote(str, outstr, len, size) && 627a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin (len < 0 || len > max_strlen)) 628bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin strcat(outstr, "..."); 62976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 63076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", outstr); 63176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 63276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 6331d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H 6341d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesvoid 6351201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkodumpiov(struct tcb *tcp, int len, long addr) 6361d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes{ 6374ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 6384ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin union { 6394ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin struct { u_int32_t base; u_int32_t len; } *iov32; 6404ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin struct { u_int64_t base; u_int64_t len; } *iov64; 6414ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin } iovu; 6424ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov iovu.iov64 6434ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define sizeof_iov \ 6444ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin (personality_wordsize[current_personality] == 4 \ 6454ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64)) 6464ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_base(i) \ 6474ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin (personality_wordsize[current_personality] == 4 \ 6484ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin ? (u_int64_t) iovu.iov32[i].base : iovu.iov64[i].base) 6494ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_len(i) \ 6504ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin (personality_wordsize[current_personality] == 4 \ 6514ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin ? (u_int64_t) iovu.iov32[i].len : iovu.iov64[i].len) 6524ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#else 6531d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes struct iovec *iov; 6544ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define sizeof_iov sizeof(*iov) 6554ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_base(i) iov[i].iov_base 6564ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_len(i) iov[i].iov_len 6574ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#endif 6581d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes int i; 659aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath unsigned long size; 6601d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 6614ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin size = sizeof_iov * (unsigned long) len; 6624ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin if (size / sizeof_iov != len 6634ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin || (iov = malloc(size)) == NULL) { 664aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath fprintf(stderr, "out of memory\n"); 6651d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes return; 6661d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 667aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath if (umoven(tcp, addr, size, (char *) iov) >= 0) { 6681d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes for (i = 0; i < len; i++) { 669adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko /* include the buffer number to make it easy to 670adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko * match up the trace with the source */ 671adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf(" * %lu bytes in buffer %d\n", 672adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko (unsigned long)iov_iov_len(i), i); 673adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko dumpstr(tcp, (long) iov_iov_base(i), 674adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko iov_iov_len(i)); 675adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko } 6761d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 6771d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes free((char *) iov); 6784ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef sizeof_iov 6794ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov_iov_base 6804ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov_iov_len 6814ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov 6821d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes} 6831d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 6841d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 68576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 6861201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkodumpstr(struct tcb *tcp, long addr, int len) 68776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 68876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int strsize = -1; 68976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static unsigned char *str; 69076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char outstr[80]; 69176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s; 69276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 69376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 69476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strsize < len) { 69576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 69676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(str); 69776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((str = malloc(len)) == NULL) { 69846100d07257824da2ae1147da0324b5788c95501Roland McGrath fprintf(stderr, "out of memory\n"); 69976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 70076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 70176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strsize = len; 70276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 70376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 70476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, addr, len, (char *) str) < 0) 70576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 70676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 70776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < len; i += 16) { 70876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s = outstr; 70976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " | %05x ", i); 71076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 9; 71176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 71276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 71376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 71476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 71576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " %02x", str[i + j]); 71676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 3; 71776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 71876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 71976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; *s++ = ' '; 72076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 72176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 72276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; 72376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 72476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 72576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 72676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 72776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isprint(str[i + j])) 72876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = str[i + j]; 72976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 73076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '.'; 73176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 73276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 73376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 73476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 73576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s |\n", outstr); 73676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 73776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 73876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 73976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PAGMASK (~(PAGSIZ - 1)) 74076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 74176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * move `len' bytes of data from process `pid' 74276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * at address `addr' to our space at `laddr' 74376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 745ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoumoven(struct tcb *tcp, long addr, int len, char *laddr) 74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 748eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath int pid = tcp->pid; 74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 7505daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 75176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 75276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 75376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 75576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 75676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 75776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 75876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 760eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 761eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 762eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 763eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 764eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 765eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 766eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 767eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* But if not started, we had a bogus address. */ 768eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 769eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("ptrace: umoven"); 770eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 771eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 7725daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 77376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 77476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 77576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 77676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 777eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 778eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 779eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 780eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 781eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 782eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 783eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 784eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 785eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("ptrace: umoven"); 786eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 787eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 7885daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 78976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 79076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 79176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 79276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 79376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 79476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 79576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 79676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 79776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 79876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 79976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, PAGSIZ); 80076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 801eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_READDATA, pid, 802eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath (char *) addr, len, laddr) < 0) { 803eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno != ESRCH) { 804eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("umoven: ptrace(PTRACE_READDATA, ...)"); 805eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath abort(); 806eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 80776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 80876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 80976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len -= n; 81076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += n; 81176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman laddr += n; 81276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 81376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 81476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 815bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 816ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 817aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd_as; 8189ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 819aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd; 82076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 821aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes lseek(fd, addr, SEEK_SET); 822aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (read(fd, laddr, len) == -1) 82376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 824bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 82576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 82676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 82776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 82876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 82976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 83076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * like `umove' but make the additional effort of looking 83176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * for a terminating zero byte. 83276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 83376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 834ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoumovestr(struct tcb *tcp, long addr, int len, char *laddr) 83576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 836bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 837aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#ifdef HAVE_MP_PROCFS 838aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd_as; 839aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#else 840aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd; 841aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#endif 842aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes /* Some systems (e.g. FreeBSD) can be upset if we read off the 843aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes end of valid memory, avoid this by trying to read up 844aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes to page boundaries. But we don't know what a page is (and 845aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes getpagesize(2) (if it exists) doesn't necessarily return 846aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes hardware page size). Assume all pages >= 1024 (a-historical 847aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes I know) */ 848aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 849b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko int page = 1024; /* How to find this? */ 850aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int move = page - (addr & (page - 1)); 851aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int left = len; 852aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 853aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes lseek(fd, addr, SEEK_SET); 854aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 855aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes while (left) { 856aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (move > left) move = left; 8579cecf7f8d6115a247be7186013857270b2d588d5John Hughes if ((move = read(fd, laddr, move)) <= 0) 858aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return left != len ? 0 : -1; 859b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (memchr(laddr, 0, move)) break; 860aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes left -= move; 861aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes laddr += move; 862aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes addr += move; 863aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes move = page; 864aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes } 865bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 8665daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 867eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath int pid = tcp->pid; 86876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, n, m; 86976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 87076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 87176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 87276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 87376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 87476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 87576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 87676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 87776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 878eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 879eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 880eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 881eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 882eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 883eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 884eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 885eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 886eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("umovestr"); 887eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 888eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 8895daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 890b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n, len)); 89176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (n & (sizeof(long) - 1)) 89276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[n++] == '\0') 89376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 89476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 89576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 89676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 897eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 898eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 899eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 900eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 901eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 902eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 903eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 904eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 905eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("umovestr"); 906eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 907eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 9085daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 90976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 91076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < sizeof(long); i++) 91176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[i] == '\0') 91276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 91376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 91476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 91576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 916bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 917aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return 0; 91876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 91976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 92076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 9213bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if !defined (SPARC) && !defined(SPARC64) 9223bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define PTRACE_WRITETEXT 101 9233bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define PTRACE_WRITEDATA 102 9243bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* !SPARC && !SPARC64 */ 92576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 92676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 92776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 92876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 92976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 9301201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkouload(int cmd, int pid, long addr, int len, char *laddr) 93176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 93276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int peek, poke; 93376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 93476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 93576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 93676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 93776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 93876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 93976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cmd == PTRACE_WRITETEXT) { 94076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKTEXT; 94176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKETEXT; 94276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 94376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 94476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKDATA; 94576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKEDATA; 94676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 94776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 94876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 94976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); 951eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 952eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(peek, pid, (char *) addr, 0); 953eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 954eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("uload: POKE"); 95576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 956eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 957eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len)); 958eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(poke, pid, (char *)addr, u.val) < 0) { 959eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("uload: POKE"); 96076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 96176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 962eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath addr += sizeof(long), laddr += m, len -= m; 96376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 96476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 96576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < sizeof(long)) 966eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(peek, pid, (char *) addr, 0); 967eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath memcpy(u.x, laddr, m = MIN(sizeof(long), len)); 968eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(poke, pid, (char *) addr, u.val) < 0) { 969eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("uload: POKE"); 97076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 97176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 972eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath addr += sizeof(long), laddr += m, len -= m; 97376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 97476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 97576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 97676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 977eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint 9781201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotload(int pid, int addr, int len, char *laddr) 979eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath{ 980eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return uload(PTRACE_WRITETEXT, pid, addr, len, laddr); 981eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath} 982eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 983eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint 9841201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkodload(int pid, int addr, int len, char *laddr) 98576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 986eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return uload(PTRACE_WRITEDATA, pid, addr, len, laddr); 98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 98976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 99076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 991bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 99376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 9941201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoupeek(struct tcb *tcp, long off, long *res) 99576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 9983bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SUNOS4_KERNEL_ARCH_KLUDGE 99976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman { 100076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int is_sun4m = -1; 100176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct utsname name; 100276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 100376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Round up the usual suspects. */ 100476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m == -1) { 100576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (uname(&name) < 0) { 100676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("upeek: uname?"); 100776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 100876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 100976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman is_sun4m = strcmp(name.machine, "sun4m") == 0; 101076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) { 1011d9f816f60457930af27349fac3d23b3b78338036Roland McGrath const struct xlat *x; 101276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 101376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (x = struct_user_offsets; x->str; x++) 101476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman x->val += 1024; 101576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 101676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 101776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) 101876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman off += 1024; 101976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 10203bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 1021eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1022732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko val = do_ptrace(PTRACE_PEEKUSER, tcp, (char *) off, 0); 1023eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (val == -1 && errno) { 1024eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno != ESRCH) { 1025eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath char buf[60]; 1026b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko sprintf(buf, "upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)", tcp->pid, off); 1027eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror(buf); 1028eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 102976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1030eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 103176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *res = val; 103276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 103376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 103476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1035bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 103676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 103776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 1038ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenkoprintcall(struct tcb *tcp) 103976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 10407a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath#define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \ 10417a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath sizeof(long) == 8 ? "[????????????????] " : \ 10427a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath NULL /* crash */) 104376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 104476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 10453bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef I386 104676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long eip; 104776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1048932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*EIP, &eip) < 0) { 10497a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 105076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 105176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 105276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", eip); 1053eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath 10543bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(S390) || defined(S390X) 1055adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko long psw; 1056b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (upeek(tcp, PT_PSWADDR, &psw) < 0) { 1057adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko PRINTBADPC; 1058adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko return; 1059adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko } 10603bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef S390 1061adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf("[%08lx] ", psw); 10623bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif S390X 1063adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf("[%16lx] ", psw); 10643bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1065eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath 10663bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(X86_64) 10670e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig long rip; 10680e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig 1069932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 8*RIP, &rip) < 0) { 10707a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 10710e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return; 10720e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig } 10730e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig tprintf("[%16lx] ", rip); 10743bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(IA64) 10758b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman long ip; 10768b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 1077932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_B0, &ip) < 0) { 10787a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 10798b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return; 10808b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 10818b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tprintf("[%08lx] ", ip); 10823bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(POWERPC) 108376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 108476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1085932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) { 1086d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab PRINTBADPC; 108776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 108876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1089d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab# ifdef POWERPC64 1090d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab tprintf("[%016lx] ", pc); 1091d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab# else 109276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 1093d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab# endif 10943bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(M68K) 109576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 109676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1097932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*PT_PC, &pc) < 0) { 1098b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko tprintf("[????????] "); 109976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 110076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 110176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 11023bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ALPHA) 110376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 110476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1105932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, REG_PC, &pc) < 0) { 1106b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko tprintf("[????????????????] "); 110776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 110876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 110976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 11103bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SPARC) || defined(SPARC64) 11118566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger struct pt_regs regs; 1112b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 11137a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 111476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 111576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 11168566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# if defined(SPARC64) 11178566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger tprintf("[%08lx] ", regs.tpc); 11188566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# else 11198566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger tprintf("[%08lx] ", regs.pc); 11208566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# endif 11213bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(HPPA) 1122c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman long pc; 1123c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman 1124b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (upeek(tcp, PT_IAOQ0, &pc) < 0) { 1125b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko tprintf("[????????] "); 1126c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return; 1127c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman } 1128c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tprintf("[%08lx] ", pc); 11293bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(MIPS) 113075c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman long pc; 113175c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman 1132932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, REG_EPC, &pc) < 0) { 1133b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko tprintf("[????????] "); 113475c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman return; 113575c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman } 113675c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman tprintf("[%08lx] ", pc); 11373bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH) 1138adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko long pc; 1139ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman 1140adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko if (upeek(tcp, 4*REG_PC, &pc) < 0) { 1141b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko tprintf("[????????] "); 1142adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko return; 1143adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko } 1144adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf("[%08lx] ", pc); 11453bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH64) 1146e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath long pc; 1147e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath 1148932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, REG_PC, &pc) < 0) { 1149b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko tprintf("[????????????????] "); 1150e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath return; 1151e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath } 1152e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath tprintf("[%08lx] ", pc); 11533bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ARM) 1154ef388689610fa17df1d3001face8057b411a2e26Roland McGrath long pc; 1155e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath 1156932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*15, &pc) < 0) { 11577a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 1158ef388689610fa17df1d3001face8057b411a2e26Roland McGrath return; 1159ef388689610fa17df1d3001face8057b411a2e26Roland McGrath } 1160ef388689610fa17df1d3001face8057b411a2e26Roland McGrath tprintf("[%08lx] ", pc); 11615ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# elif defined(AVR32) 11625ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko long pc; 11635ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko 11645ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko if (upeek(tcp, REG_PC, &pc) < 0) { 11655ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko tprintf("[????????] "); 11665ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return; 11675ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko } 11685ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko tprintf("[%08lx] ", pc); 11693bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(BFIN) 117087ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin long pc; 117187ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin 1172932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_PC, &pc) < 0) { 117387ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin PRINTBADPC; 117487ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin return; 117587ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin } 117687ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin tprintf("[%08lx] ", pc); 1177ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#elif defined(CRISV10) 1178ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko long pc; 1179ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko 1180eeb9ce3895f1ca0920d50696ef8b48124cef9da6Edgar E. Iglesias if (upeek(tcp, 4*PT_IRP, &pc) < 0) { 1181ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko PRINTBADPC; 1182ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko return; 1183ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko } 1184ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko tprintf("[%08lx] ", pc); 1185ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#elif defined(CRISV32) 1186ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko long pc; 1187ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko 1188eeb9ce3895f1ca0920d50696ef8b48124cef9da6Edgar E. Iglesias if (upeek(tcp, 4*PT_ERP, &pc) < 0) { 1189ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko PRINTBADPC; 1190ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko return; 1191ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko } 1192ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko tprintf("[%08lx] ", pc); 11933bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* architecture */ 119476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 119576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 119676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 119776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct regs regs; 119876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1199eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 1200eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("printcall: ptrace(PTRACE_GETREGS, ...)"); 12017a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 120276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 120376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 120476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08x] ", regs.r_o7); 120576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 120676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 120776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 120876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* XXX */ 12097a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 121076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 121176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1212bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1213bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct reg regs; 1214bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 1215bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tprintf("[%08x] ", regs.r_eip); 1216bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 121776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 121876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12193bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko 12203bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko/* 12213bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * These #if's are huge, please indent them correctly. 12223bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * It's easy to get confused otherwise. 12233bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko */ 1224bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 122576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1226e5e60858063f214fcd7860f50f8bcb46f951f9abDmitry V. Levin#ifdef LINUX 1227d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 12283bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# include "syscall.h" 12293291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath 12303bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# include <sys/syscall.h> 12313bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef CLONE_PTRACE 12323bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define CLONE_PTRACE 0x00002000 12333bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 12343bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef CLONE_VFORK 12353bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define CLONE_VFORK 0x00004000 12363bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 12373bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef CLONE_VM 12383bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define CLONE_VM 0x00000100 12393bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 12403bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef CLONE_STOPPED 12413bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define CLONE_STOPPED 0x02000000 12423bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1243d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 12443bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef IA64 1245d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 124608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath/* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32 124708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath subsystem has them for x86... */ 12483bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define SYS_fork 2 12493bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define SYS_vfork 190 125008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 1251d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef unsigned long *arg_setup_state; 1252d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1253d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1254d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGratharg_setup(struct tcb *tcp, arg_setup_state *state) 1255d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 12561f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil unsigned long cfm, sof, sol; 12571f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil long bsp; 1258d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 12591f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil if (ia32) { 12601f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil /* Satisfy a false GCC warning. */ 12611f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil *state = NULL; 126208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return 0; 12631f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil } 126408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 1265932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_AR_BSP, &bsp) < 0) 1266d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1267932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_CFM, (long *) &cfm) < 0) 1268d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1269d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1270d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sof = (cfm >> 0) & 0x7f; 1271d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sol = (cfm >> 7) & 0x7f; 12721f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol); 1273d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 12741f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil *state = (unsigned long *) bsp; 1275d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1276d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1277d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 12783bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_finish_change(tcp, state) 0 1279d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 12803bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SYS_fork 1281d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 12821201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoget_arg0(struct tcb *tcp, arg_setup_state *state, long *valp) 1283d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 128408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int ret; 128508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 128608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) 1287b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ret = upeek(tcp, PT_R11, valp); 128808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath else 1289b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ret = umoven(tcp, 129008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath (unsigned long) ia64_rse_skip_regs(*state, 0), 129108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath sizeof(long), (void *) valp); 129208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return ret; 1293d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1294d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1295d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 12961201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoget_arg1(struct tcb *tcp, arg_setup_state *state, long *valp) 1297d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 129808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int ret; 129908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 130008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) 1301b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ret = upeek(tcp, PT_R9, valp); 130208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath else 1303b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ret = umoven(tcp, 130408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath (unsigned long) ia64_rse_skip_regs(*state, 1), 130508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath sizeof(long), (void *) valp); 130608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return ret; 1307d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 13083bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1309d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1310d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 13111201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoset_arg0(struct tcb *tcp, arg_setup_state *state, long val) 1312d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 131308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int req = PTRACE_POKEDATA; 131408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath void *ap; 131508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 131608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) { 131708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = (void *) (intptr_t) PT_R11; /* r11 == EBX */ 131808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath req = PTRACE_POKEUSER; 131908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath } else 132008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = ia64_rse_skip_regs(*state, 0); 1321eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1322eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(req, tcp->pid, ap, val); 1323eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return errno ? -1 : 0; 1324d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1325d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1326d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 13271201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoset_arg1(struct tcb *tcp, arg_setup_state *state, long val) 1328d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 132908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int req = PTRACE_POKEDATA; 133008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath void *ap; 133108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 133208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) { 133308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = (void *) (intptr_t) PT_R9; /* r9 == ECX */ 133408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath req = PTRACE_POKEUSER; 133508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath } else 133608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = ia64_rse_skip_regs(*state, 1); 1337eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1338eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(req, tcp->pid, ap, val); 1339eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return errno ? -1 : 0; 1340d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1341d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1342b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath/* ia64 does not return the input arguments from functions (and syscalls) 1343b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath according to ia64 RSE (Register Stack Engine) behavior. */ 1344b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath 13453bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) ((void) (state), 0) 13463bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg1(tcp, state, val) ((void) (state), 0) 1347b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath 13483bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (SPARC) || defined (SPARC64) 1349d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13508566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysingertypedef struct pt_regs arg_setup_state; 1351d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13523bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_setup(tcp, state) \ 1353b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko (ptrace(PTRACE_GETREGS, tcp->pid, (char *) (state), 0)) 13543bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_finish_change(tcp, state) \ 1355b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko (ptrace(PTRACE_SETREGS, tcp->pid, (char *) (state), 0)) 1356d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13578566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# define get_arg0(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O0], 0) 13588566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# define get_arg1(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O1], 0) 13598566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# define set_arg0(tcp, state, val) ((state)->u_regs[U_REG_O0] = (val), 0) 13608566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysinger# define set_arg1(tcp, state, val) ((state)->u_regs[U_REG_O1] = (val), 0) 13613bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) 0 1362d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13633bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else /* other architectures */ 1364d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13653bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined S390 || defined S390X 13667b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath/* Note: this is only true for the `clone' system call, which handles 13677b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath arguments specially. We could as well say that its first two arguments 13687b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath are swapped relative to other architectures, but that would just be 13697b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath another #ifdef in the calls. */ 13703bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset PT_GPR3 13713bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset PT_ORIGGPR2 13723bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) ((void) (state), 0) 13733bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg1(tcp, state, val) ((void) (state), 0) 13743bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_index 1 13753bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_index 0 13763bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (ALPHA) || defined (MIPS) 13773bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset REG_A0 13783bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (REG_A0+1) 13795ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# elif defined (AVR32) 13805ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# define arg0_offset (REG_R12) 13815ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# define arg1_offset (REG_R11) 13823bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (POWERPC) 13833bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset (sizeof(unsigned long)*PT_R3) 13843bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (sizeof(unsigned long)*PT_R4) 13853bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) ((void) (state), 0) 13863bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (HPPA) 13873bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset PT_GR26 13883bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (PT_GR26-4) 13893bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (X86_64) 13903bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset ((long)(8*(current_personality ? RBX : RDI))) 13913bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset ((long)(8*(current_personality ? RCX : RSI))) 13923bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (SH) 13933bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset (4*(REG_REG0+4)) 13943bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (4*(REG_REG0+5)) 13953bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (SH64) 13963bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko /* ABI defines arg0 & 1 in r2 & r3 */ 13973bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset (REG_OFFSET+16) 13983bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (REG_OFFSET+24) 13993bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) 0 1400ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# elif defined CRISV10 || defined CRISV32 1401ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define arg0_offset (4*PT_R11) 1402ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define arg1_offset (4*PT_ORIG_R10) 1403ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define restore_arg0(tcp, state, val) 0 1404ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define restore_arg1(tcp, state, val) 0 1405ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define arg0_index 1 1406ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define arg1_index 0 14073bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else 14083bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset 0 14093bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset 4 14103bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined ARM 14113bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) 0 14123bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 14133bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1414d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1415d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef int arg_setup_state; 1416d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14173bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_setup(tcp, state) (0) 14183bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_finish_change(tcp, state) 0 14193bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define get_arg0(tcp, cookie, valp) \ 1420b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko (upeek((tcp), arg0_offset, (valp))) 14213bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define get_arg1(tcp, cookie, valp) \ 1422b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko (upeek((tcp), arg1_offset, (valp))) 1423d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1424d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 14251201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoset_arg0(struct tcb *tcp, void *cookie, long val) 1426d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1427b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko return ptrace(PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val); 1428d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1429d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1430d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 14311201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoset_arg1(struct tcb *tcp, void *cookie, long val) 1432d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1433b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko return ptrace(PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val); 1434d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1435d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14363bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* architectures */ 1437d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14383bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef restore_arg0 14393bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val)) 14403bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 14413bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef restore_arg1 14423bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val)) 14433bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1444d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14453bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef arg0_index 14463bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_index 0 14473bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_index 1 14483bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 144990d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath 1450d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint 1451418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkosetbpt(struct tcb *tcp) 1452d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 14533291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone }; 1454d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath arg_setup_state state; 1455d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1456d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (tcp->flags & TCB_BPTSET) { 1457d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1458d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1459d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath } 1460d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14613291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath /* 14623291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath * It's a silly kludge to initialize this with a search at runtime. 14633291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath * But it's better than maintaining another magic thing in the 14643291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath * godforsaken tables. 14653291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath */ 14663291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath if (clone_scno[current_personality] == 0) { 14673291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath int i; 14683291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath for (i = 0; i < nsyscalls; ++i) 14693291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath if (sysent[i].sys_func == sys_clone) { 14703291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath clone_scno[current_personality] = i; 14713291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath break; 14723291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath } 14733291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath } 14743291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath 147576989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath switch (known_scno(tcp)) { 14763bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SYS_vfork 14779383c6c539af09303efe0a16dea55363b095f66eRoland McGrath case SYS_vfork: 14783bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 14793bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SYS_fork 1480d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_fork: 14813bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 14823bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined SYS_fork || defined SYS_vfork 1483b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (arg_setup(tcp, &state) < 0 1484b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || get_arg0(tcp, &state, &tcp->inst[0]) < 0 1485b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || get_arg1(tcp, &state, &tcp->inst[1]) < 0 14863291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath || change_syscall(tcp, clone_scno[current_personality]) < 0 1487b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || set_arg0(tcp, &state, CLONE_PTRACE|SIGCHLD) < 0 1488b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || set_arg1(tcp, &state, 0) < 0 1489b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || arg_finish_change(tcp, &state) < 0) 1490d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1491c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD; 1492c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->u_arg[arg1_index] = 0; 1493d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags |= TCB_BPTSET; 1494d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 14953bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1496d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1497d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_clone: 14983bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SYS_clone2 1499d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_clone2: 15003bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 15018fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil /* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)' 15028fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil contrary to x86 SYS_vfork above. Even on x86 we turn the 15038fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil vfork semantics into plain fork - each application must not 15048fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil depend on the vfork specifics according to POSIX. We would 15058fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil hang waiting for the parent resume otherwise. We need to 15068fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil clear also CLONE_VM but only in the CLONE_VFORK case as 15078fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil otherwise we would break pthread_create. */ 15088fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil 1509b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if ((arg_setup(tcp, &state) < 0 1510b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || set_arg0(tcp, &state, 1511d6ff0d520d4bd8dda1523ec57e8ba2bc0ab3cf69Roland McGrath (tcp->u_arg[arg0_index] | CLONE_PTRACE) 15128fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil & ~(tcp->u_arg[arg0_index] & CLONE_VFORK 15138fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil ? CLONE_VFORK | CLONE_VM : 0)) < 0 1514b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || arg_finish_change(tcp, &state) < 0)) 15155ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return -1; 1516d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags |= TCB_BPTSET; 1517c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->inst[0] = tcp->u_arg[arg0_index]; 1518c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->inst[1] = tcp->u_arg[arg1_index]; 1519d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1520d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1521d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath default: 1522d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n", 1523d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->scno, tcp->pid); 1524d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath break; 1525d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath } 1526d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1527d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1528d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1529d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1530d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint 15311201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoclearbpt(struct tcb *tcp) 1532d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1533d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath arg_setup_state state; 1534b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (arg_setup(tcp, &state) < 0 1535b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || restore_arg0(tcp, &state, tcp->inst[0]) < 0 1536b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || restore_arg1(tcp, &state, tcp->inst[1]) < 0 1537b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || arg_finish_change(tcp, &state)) 153846ed50d56909843420b0a0cb1360a500ce421d52Andreas Schwab if (errno != ESRCH) return -1; 1539d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags &= ~TCB_BPTSET; 1540d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1541d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1542d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 15433bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else /* !defined LINUX */ 1544d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 154576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 15461201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkosetbpt(struct tcb *tcp) 154776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 15483bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SUNOS4 15493bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SPARC /* This code is slightly sparc specific */ 155076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1551e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 15523bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define BPT 0x91d02001 /* ta 1 */ 15533bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP 0x10800000 /* ba 0 */ 15543bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOPA 0x30800000 /* ba,a 0 */ 15553bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define NOP 0x01000000 15563bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if LOOPA 155776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[1] = {LOOPA}; 15583bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else 155976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[2] = {LOOP, NOP}; 15603bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 156176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 156276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 156376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 156476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 156576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1566eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 1567eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 156876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 156976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 157076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->baddr = regs.r_o7 + 8; 1571eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr, 1572eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sizeof tcp->inst, (char *)tcp->inst) < 0) { 1573eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_READTEXT, ...)"); 157476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 157576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 157676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 157776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 157876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * XXX - BRUTAL MODE ON 157976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We cannot set a real BPT in the child, since it will not be 158076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * traced at the moment it will reach the trap and would probably 158176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * die with a core dump. 158276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Thus, we are force our way in by taking out two instructions 158376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * and insert an eternal loop in stead, in expectance of the SIGSTOP 158476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * generated by out PTRACE_ATTACH. 158576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Of cause, if we evaporate ourselves in the middle of all this... 158676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 1587eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 158876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof loopdeloop, (char *) loopdeloop) < 0) { 1589eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)"); 159076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 159176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 159276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 159376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15943bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SPARC */ 15953bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SUNOS4 */ 159676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 159776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 159876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 159976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 160076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 16011201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoclearbpt(struct tcb *tcp) 160276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 16033bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SUNOS4 16043bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SPARC 160576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16063bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if !LOOPA 1607e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 16083bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 160976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 161076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 161176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 161276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 161376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1614eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 161576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof tcp->inst, (char *) tcp->inst) < 0) { 1616eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)"); 161776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 161876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 161976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 162076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16213bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if !LOOPA 162276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 162376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Since we don't have a single instruction breakpoint, we may have 16243bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * to adjust the program counter after removing our `breakpoint'. 162576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 1626eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 1627eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clearbpt: ptrace(PTRACE_GETREGS, ...)"); 162876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 162976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1630eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if ((regs.r_pc < tcp->baddr) || 1631eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath (regs.r_pc > tcp->baddr + 4)) { 163276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet */ 163376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 163476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 163576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "NOTE: PC not at bpt (pc %#x baddr %#x)\n", 16363bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko regs.r_pc, tcp->baddr); 163776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 163876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 163976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (regs.r_pc != tcp->baddr) 164076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 164176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n", 164276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc, tcp->baddr); 164376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 164476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc = tcp->baddr; 1645eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) { 1646eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clearbpt: ptrace(PTRACE_SETREGS, ...)"); 164776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 164876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 16493bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* LOOPA */ 16503bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SPARC */ 16513bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SUNOS4 */ 165276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 165376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 165476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 165576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16563bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* !defined LINUX */ 1657d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1658bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 165976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16603bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko 166176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 166276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 166376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 16641201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkogetex(struct tcb *tcp, struct exec *hdr) 166576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 166676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 166776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 166876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; n < sizeof *hdr; n += 4) { 166976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long res; 1670932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, uoff(u_exdata) + n, &res) < 0) 167176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 167276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(((char *) hdr) + n, &res, 4); 167376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 167476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) { 167576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n", 167676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_magic, hdr->a_toolversion, hdr->a_machtype); 167776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n", 167876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry); 167976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 168076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 168176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 168276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 168376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 16841201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkofixvfork(struct tcb *tcp) 168576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 168676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 168776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 168876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Change `vfork' in a freshly exec'ed dynamically linked 168976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * executable's (internal) symbol table to plain old `fork' 169076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 169176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 169276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct exec hdr; 169376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic dyn; 169476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic_2 ld; 169576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *strtab, *cp; 169676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1697932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (getex(tcp, &hdr) < 0) 169876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 169976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!hdr.a_dynamic) 170076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 170176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 170276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) { 170376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read DYNAMIC\n"); 170476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 170576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 170676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) { 170776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read link_dynamic_2\n"); 170876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 170976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 171076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) { 171146100d07257824da2ae1147da0324b5788c95501Roland McGrath fprintf(stderr, "out of memory\n"); 171276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 171376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1714eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 171576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 171676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 171776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 171876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 171976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strcmp(cp, "_vfork") == 0) { 172076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 172176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "fixvfork: FOUND _vfork\n"); 172276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strcpy(cp, "_fork"); 172376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 172476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 172576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cp += strlen(cp)+1; 172676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 172776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cp < strtab + ld.ld_symb_size) 172876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 172976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Write entire symbol table back to avoid 173076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * memory alignment bugs in ptrace 173176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 1732eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 173476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 173576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 173676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 173776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 173876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 173976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerr: 174076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 174176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 174276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 174376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 174476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 1745