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