util.c revision bf357fcb76baeb64a45fc2b6b355c913c63e6015
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 3476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "defs.h" 3576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/user.h> 3676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/param.h> 3776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <fcntl.h> 381d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H 392d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# include <sys/uio.h> 401d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 4136915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman 428470374cba7df0e70653d95c4f336a4082c68d82Denys Vlasenko#if defined(IA64) 43d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# include <asm/ptrace_offsets.h> 44d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# include <asm/rse.h> 458b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#endif 468b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 4736915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#ifdef HAVE_SYS_REG_H 488470374cba7df0e70653d95c4f336a4082c68d82Denys Vlasenko# include <sys/reg.h> 4936915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman# define PTRACE_PEEKUSR PTRACE_PEEKUSER 50faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(HAVE_LINUX_PTRACE_H) 518470374cba7df0e70653d95c4f336a4082c68d82Denys Vlasenko# undef PTRACE_SYSCALL 52ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# ifdef HAVE_STRUCT_IA64_FPREG 53ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# define ia64_fpreg XXX_ia64_fpreg 54ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# endif 55ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# ifdef HAVE_STRUCT_PT_ALL_USER_REGS 56ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# define pt_all_user_regs XXX_pt_all_user_regs 57ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# endif 588470374cba7df0e70653d95c4f336a4082c68d82Denys Vlasenko# include <linux/ptrace.h> 59ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# undef ia64_fpreg 60ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# undef pt_all_user_regs 612e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#endif 622e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman 6376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* macros */ 6476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MAX 652d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define MAX(a,b) (((a) > (b)) ? (a) : (b)) 6676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 6776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MIN 682d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define MIN(a,b) (((a) < (b)) ? (a) : (b)) 6976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 7076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 7176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 72ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levinstring_to_uint(const char *str) 73ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin{ 74ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin char *error; 75ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin long value; 76ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin 77ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin if (!*str) 78ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin return -1; 79ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin errno = 0; 80ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin value = strtol(str, &error, 10); 81ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin if (errno || *error || value < 0 || (long)(int)value != value) 82ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin return -1; 83ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin return (int)value; 84ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin} 85ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin 86ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levinint 871201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_nz(struct timeval *a) 8876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 8976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return a->tv_sec || a->tv_usec; 9076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 9176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 9276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 931201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_cmp(struct timeval *a, struct timeval *b) 9476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 9576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (a->tv_sec < b->tv_sec 9676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec)) 9776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 9876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (a->tv_sec > b->tv_sec 9976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec)) 10076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 10176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 10276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 10376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandouble 1051201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_float(struct timeval *tv) 10676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 10776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tv->tv_sec + tv->tv_usec/1000000.0; 10876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 10976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 1111201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_add(struct timeval *tv, struct timeval *a, struct timeval *b) 11276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 11376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec + b->tv_sec; 11476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec + b->tv_usec; 11558372f52ac5f824be687c01bfc1db1ffb963f91eRoland McGrath if (tv->tv_usec >= 1000000) { 11676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec++; 11776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec -= 1000000; 11876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 11976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 1221201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_sub(struct timeval *tv, struct timeval *a, struct timeval *b) 12376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 12476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec - b->tv_sec; 12576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec - b->tv_usec; 12676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (((long) tv->tv_usec) < 0) { 12776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec--; 12876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec += 1000000; 12976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 13176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 1331201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_div(struct timeval *tv, struct timeval *a, int n) 13476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n; 13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000; 13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 13876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 13976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 14076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 1411201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotv_mul(struct timeval *tv, struct timeval *a, int n) 14276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 14376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec * n; 144fefdd97156bb2f86c5b6596dc7e28d954516b3edDmitry V. Levin tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000; 14576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 148ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinconst char * 149ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinxlookup(const struct xlat *xlat, int val) 15076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 15176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (; xlat->str != NULL; xlat++) 15276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val == val) 15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return xlat->str; 15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1570a295bc97fd2ba9e6dc02f382dc87bc8705dc4d0Denys Vlasenko#if !defined HAVE_STPCPY 1585284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenkochar * 1595284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenkostpcpy(char *dst, const char *src) 1605284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko{ 1615284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko while ((*dst = *src++) != '\0') 1625284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko dst++; 1635284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko return dst; 1645284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko} 1650a295bc97fd2ba9e6dc02f382dc87bc8705dc4d0Denys Vlasenko#endif 1665284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko 16776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Print entry in struct xlat table, if there. 16976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 171ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinprintxval(const struct xlat *xlat, int val, const char *dflt) 17276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 173ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levin const char *str = xlookup(xlat, val); 17476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 1765940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko tprints(str); 17776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 17876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#x /* %s */", val, dflt); 17976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 18076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 181b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab#if HAVE_LONG_LONG 182b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab/* 183b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab * Print 64bit argument at position llarg and return the index of the next 184b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab * argument. 185b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab */ 186b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwabint 187b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwabprintllval(struct tcb *tcp, const char *format, int llarg) 188b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab{ 189aa925db23634fe6a2c1d4b47accb3649daf1b781Denys Vlasenko# if defined(X86_64) || defined(POWERPC64) 190b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab if (current_personality == 0) { 191b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab tprintf(format, tcp->u_arg[llarg]); 192b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab llarg++; 193b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab } else { 194d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab# ifdef POWERPC64 195d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab /* Align 64bit argument to 64bit boundary. */ 1964b08df42ff069dcf44b8ed206ae33a2904c366baDenys Vlasenko llarg = (llarg + 1) & 0x1e; 197d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab# endif 198b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab tprintf(format, LONG_LONG(tcp->u_arg[llarg], tcp->u_arg[llarg + 1])); 199b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab llarg += 2; 200b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab } 201d69fa497f4729373618fb7b506a2362422487ab1Andreas Schwab# elif defined IA64 || defined ALPHA 202b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab tprintf(format, tcp->u_arg[llarg]); 203b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab llarg++; 20435be58119e3727a694d8c9f9b83f372401fcc4c0H.J. Lu# elif defined LINUX_MIPSN32 || defined X32 205b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab tprintf(format, tcp->ext_arg[llarg]); 206b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab llarg++; 207b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# else 208b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab tprintf(format, LONG_LONG(tcp->u_arg[llarg], tcp->u_arg[llarg + 1])); 209b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab llarg += 2; 210b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab# endif 211b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab return llarg; 212b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab} 213b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab#endif 214b5600fc3df0453ba11f254a9b49add3ffbec9733Andreas Schwab 21576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 21676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interpret `xlat' as an array of flags 21776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * print the entries whose bits are on in `flags' 21876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * return # of flags printed. 21976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 2204924dbd6d750665cf383b20ab4fd67e48219ab91Denys Vlasenkovoid 2211201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoaddflags(const struct xlat *xlat, int flags) 22276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 2234924dbd6d750665cf383b20ab4fd67e48219ab91Denys Vlasenko for (; xlat->str; xlat++) { 22476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 22576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%s", xlat->str); 22676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 22776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 22876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 22976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags) { 23076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%#x", flags); 23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 234a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath/* 2354924dbd6d750665cf383b20ab4fd67e48219ab91Denys Vlasenko * Interpret `xlat' as an array of flags. 236a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Print to static string the entries whose bits are on in `flags' 237a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Return static string. 238a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath */ 239a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrathconst char * 240a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrathsprintflags(const char *prefix, const struct xlat *xlat, int flags) 241a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath{ 242a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath static char outstr[1024]; 2435284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko char *outptr; 244a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath int found = 0; 245a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 2465284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko outptr = stpcpy(outstr, prefix); 247a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 248a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath for (; xlat->str; xlat++) { 249a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if ((flags & xlat->val) == xlat->val) { 250a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if (found) 2515284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko *outptr++ = '|'; 2525284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko outptr = stpcpy(outptr, xlat->str); 253a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath found = 1; 2544f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko flags &= ~xlat->val; 2554f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko if (!flags) 2564f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko break; 257a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath } 258a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath } 259a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if (flags) { 260a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if (found) 2615284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko *outptr++ = '|'; 2625284557bfad96f12dd5798539008e1644f1dc094Denys Vlasenko outptr += sprintf(outptr, "%#x", flags); 263a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath } 264a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 265a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath return outstr; 266a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath} 267a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 26876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 26930145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levinprintflags(const struct xlat *xlat, int flags, const char *dflt) 27076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 27176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 27230145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levin const char *sep; 27376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 27476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags == 0 && xlat->val == 0) { 2755940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko tprints(xlat->str); 27676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 27776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 27876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 27976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = ""; 28076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 28176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 28276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s%s", sep, xlat->str); 28376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 28476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = "|"; 28576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 28676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 28776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 288b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath 289b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (n) { 290b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (flags) { 291b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("%s%#x", sep, flags); 292b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath n++; 293b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } 294b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } else { 295b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (flags) { 296b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("%#x", flags); 297b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (dflt) 298b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf(" /* %s */", dflt); 299b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } else { 300b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (dflt) 30160fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints("0"); 302b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } 30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 304b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath 30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 30676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 30776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 30876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 30930145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levinprintnum(struct tcb *tcp, long addr, const char *fmt) 31076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 311eb285359906700f46b22cf4f9911695034313736Roland McGrath long num; 31276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 31376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 31460fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints("NULL"); 31576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 31676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 31776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, addr, &num) < 0) { 31876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 31976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 32076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 32160fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints("["); 32276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf(fmt, num); 32360fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints("]"); 32476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 32576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 3266bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathvoid 32730145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levinprintnum_int(struct tcb *tcp, long addr, const char *fmt) 3289814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath{ 3299814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath int num; 3309814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath 3319814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath if (!addr) { 33260fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints("NULL"); 3339814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath return; 3349814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath } 3359814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath if (umove(tcp, addr, &num) < 0) { 3369814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("%#lx", addr); 3379814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath return; 3389814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath } 33960fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints("["); 3409814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf(fmt, num); 34160fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints("]"); 3429814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath} 3439814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath 3449814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathvoid 3453138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levinprintfd(struct tcb *tcp, int fd) 3463138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levin{ 3478a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards const char *p; 3488a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards 3498a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards if (show_fd_path && (p = getfdpath(tcp, fd))) 3508a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards tprintf("%d<%s>", fd, p); 3518a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards else 3528a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards tprintf("%d", fd); 3533138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levin} 3543138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levin 3553138213bc9a827a372ad9f8009ebcc5d8797ce2dDmitry V. Levinvoid 3561201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoprintuid(const char *text, unsigned long uid) 3576bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath{ 3585940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko tprintf((uid == -1) ? "%s%ld" : "%s%lu", text, uid); 3596bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath} 3606bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath 361a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/* 362a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Quote string `instr' of length `size' 363a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Write up to (3 + `size' * 4) bytes to `outstr' buffer. 364b5d43b81a8abdf17bc3aa585a66215ebe3ba3671Denys Vlasenko * If `len' is -1, treat `instr' as a NUL-terminated string 365a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * and quote at most (`size' - 1) bytes. 3666cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * 367b5d43b81a8abdf17bc3aa585a66215ebe3ba3671Denys Vlasenko * Returns 0 if len == -1 and NUL was seen, 1 otherwise. 3686cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * Note that if len >= 0, always returns 1. 369a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 370ebee04cfb009bdc46599774b4647f6615b6ce3a2Mike Frysingerint 371b5d43b81a8abdf17bc3aa585a66215ebe3ba3671Denys Vlasenkostring_quote(const char *instr, char *outstr, long len, int size) 37276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 373bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin const unsigned char *ustr = (const unsigned char *) instr; 374bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin char *s = outstr; 3758778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko int usehex, c, i, eol; 37676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 3778778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko eol = 0x100; /* this can never match a char */ 378b5d43b81a8abdf17bc3aa585a66215ebe3ba3671Denys Vlasenko if (len == -1) { 3798778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko size--; 3808778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko eol = '\0'; 3818778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko } 3828778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko 3838778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko usehex = 0; 384bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (xflag > 1) 385bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin usehex = 1; 386bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin else if (xflag) { 387a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for presence of symbol which require 388a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin to hex-quote the whole string. */ 389bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin for (i = 0; i < size; ++i) { 390bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin c = ustr[i]; 391a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for NUL-terminated string. */ 3928778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko if (c == eol) 3938778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko break; 394bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (!isprint(c) && !isspace(c)) { 395bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin usehex = 1; 396bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 397bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 398bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 39976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 400bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 401bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\"'; 402bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 403bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (usehex) { 404a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Hex-quote the whole string. */ 405bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin for (i = 0; i < size; ++i) { 406bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin c = ustr[i]; 407a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for NUL-terminated string. */ 4088778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko if (c == eol) 4098778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko goto asciz_ended; 4108778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko *s++ = '\\'; 4118778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko *s++ = 'x'; 4128778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko *s++ = "0123456789abcdef"[c >> 4]; 4138778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko *s++ = "0123456789abcdef"[c & 0xf]; 414bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 415bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } else { 416bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin for (i = 0; i < size; ++i) { 417bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin c = ustr[i]; 418a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for NUL-terminated string. */ 4198778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko if (c == eol) 4208778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko goto asciz_ended; 421bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin switch (c) { 422bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\"': case '\\': 423bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 424bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = c; 425bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 426bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\f': 427bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 428bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'f'; 429bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 430bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\n': 431bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 432bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'n'; 433bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 434bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\r': 435bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 436bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'r'; 437bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 438bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\t': 439bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 440bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 't'; 441bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 442bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\v': 443bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 444bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'v'; 445bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 446bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin default: 447bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (isprint(c)) 448bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = c; 4498778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko else { 4508778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko /* Print \octal */ 4518778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko *s++ = '\\'; 4528778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko if (i + 1 < size 4538778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko && ustr[i + 1] >= '0' 4548778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko && ustr[i + 1] <= '9' 4558778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko ) { 4568778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko /* Print \ooo */ 4578778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko *s++ = '0' + (c >> 6); 4588778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko *s++ = '0' + ((c >> 3) & 0x7); 4598778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko } else { 4608778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko /* Print \[[o]o]o */ 4618778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko if ((c >> 3) != 0) { 4628778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko if ((c >> 6) != 0) 4638778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko *s++ = '0' + (c >> 6); 4648778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko *s++ = '0' + ((c >> 3) & 0x7); 4658778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko } 4668778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko } 4678778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko *s++ = '0' + (c & 0x7); 468bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 469bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 470bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 47176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 47276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 47376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 474bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\"'; 475bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s = '\0'; 4766d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath 4778778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko /* Return zero if we printed entire ASCIZ string (didn't truncate it) */ 478b5d43b81a8abdf17bc3aa585a66215ebe3ba3671Denys Vlasenko if (len == -1 && ustr[i] == '\0') { 4798778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko /* We didn't see NUL yet (otherwise we'd jump to 'asciz_ended') 4808778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko * but next char is NUL. 4818778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko */ 4828778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko return 0; 4838778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko } 4848778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko 4858778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko return 1; 4868778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko 4878778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko asciz_ended: 4888778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko *s++ = '\"'; 4898778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko *s = '\0'; 4908778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko /* Return zero: we printed entire ASCIZ string (didn't truncate it) */ 4918778bffdd25dca050b3aa2a7a7e05bc8a63a6665Denys Vlasenko return 0; 49276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 49376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 494a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/* 495a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Print path string specified by address `addr' and length `n'. 496a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If path length exceeds `n', append `...' to the output. 497a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 49876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 499bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintpathn(struct tcb *tcp, long addr, int n) 50076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 501b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko char path[MAXPATHLEN + 1]; 5026cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko int nul_seen; 503b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko 504a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!addr) { 50560fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints("NULL"); 506bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin return; 507bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 508bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 5096cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko /* Cap path length to the path buffer size */ 510a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (n > sizeof path - 1) 511a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin n = sizeof path - 1; 512a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin 513a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Fetch one byte more to find out whether path length > n. */ 5146cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko nul_seen = umovestr(tcp, addr, n + 1, path); 5156cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko if (nul_seen < 0) 51676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 51776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 518b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko char *outstr; 519bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 5206cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko path[n] = '\0'; 521b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko n++; 5226cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko outstr = alloca(4 * n); /* 4*(n-1) + 3 for quotes and NUL */ 523b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko string_quote(path, outstr, -1, n); 524b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko tprints(outstr); 5256cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko if (!nul_seen) 526b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko tprints("..."); 52776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 52876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 52976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 53076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 531bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintpath(struct tcb *tcp, long addr) 532bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin{ 533b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko /* Size must correspond to char path[] size in printpathn */ 534b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko printpathn(tcp, addr, MAXPATHLEN); 535bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin} 536bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 537a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/* 538a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Print string specified by address `addr' and length `len'. 539a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If `len' < 0, treat the string as a NUL-terminated string. 540a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If string length exceeds `max_strlen', append `...' to the output. 541a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 542bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinvoid 543b5d43b81a8abdf17bc3aa585a66215ebe3ba3671Denys Vlasenkoprintstr(struct tcb *tcp, long addr, long len) 54476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 545bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin static char *str = NULL; 54676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char *outstr; 5476d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath int size; 548b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko int ellipsis; 54976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 55076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 55160fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints("NULL"); 55276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 55376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 554a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Allocate static buffers if they are not allocated yet. */ 5551d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!str) { 556378f9c5ad0043632475cd17cbe5fe4cf38971b2bDmitry V. Levin unsigned int outstr_size = 4 * max_strlen + /*for quotes and NUL:*/ 3; 557378f9c5ad0043632475cd17cbe5fe4cf38971b2bDmitry V. Levin 558378f9c5ad0043632475cd17cbe5fe4cf38971b2bDmitry V. Levin if (outstr_size / 4 != max_strlen) 559378f9c5ad0043632475cd17cbe5fe4cf38971b2bDmitry V. Levin die_out_of_memory(); 560a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin str = malloc(max_strlen + 1); 5611d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!str) 5621d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 563378f9c5ad0043632475cd17cbe5fe4cf38971b2bDmitry V. Levin outstr = malloc(outstr_size); 5641d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!outstr) 5651d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 56676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 567bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 568b5d43b81a8abdf17bc3aa585a66215ebe3ba3671Denys Vlasenko if (len == -1) { 569a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* 570a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Treat as a NUL-terminated string: fetch one byte more 571a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * because string_quote() quotes one byte less. 572a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 573bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin size = max_strlen + 1; 574bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (umovestr(tcp, addr, size, str) < 0) { 57576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 57676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 57776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 57876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 57976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 580b5d43b81a8abdf17bc3aa585a66215ebe3ba3671Denys Vlasenko size = max_strlen; 581b5d43b81a8abdf17bc3aa585a66215ebe3ba3671Denys Vlasenko if (size > (unsigned long)len) 582b5d43b81a8abdf17bc3aa585a66215ebe3ba3671Denys Vlasenko size = (unsigned long)len; 583bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (umoven(tcp, addr, size, str) < 0) { 58476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 58576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 58676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 58776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 58876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 5896cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko /* If string_quote didn't see NUL and (it was supposed to be ASCIZ str 5906cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * or we were requested to print more than -s NUM chars)... 5916cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko */ 592b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko ellipsis = (string_quote(str, outstr, len, size) && 593b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko (len < 0 || len > max_strlen)); 59476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 595b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko tprints(outstr); 596b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko if (ellipsis) 597b3c52cf02ae536634898cd12afa5f3fcad17fbf2Denys Vlasenko tprints("..."); 59876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 59976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 6001d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H 6011d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesvoid 6021201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkodumpiov(struct tcb *tcp, int len, long addr) 6031d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes{ 6048470374cba7df0e70653d95c4f336a4082c68d82Denys Vlasenko#if SUPPORTED_PERSONALITIES > 1 6054ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin union { 6064ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin struct { u_int32_t base; u_int32_t len; } *iov32; 6074ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin struct { u_int64_t base; u_int64_t len; } *iov64; 6084ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin } iovu; 6094ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov iovu.iov64 6104ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define sizeof_iov \ 6119fd4f96d2a2527ac7ca90c156bfc11ce10118684Denys Vlasenko (current_wordsize == 4 ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64)) 6124ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_base(i) \ 6139fd4f96d2a2527ac7ca90c156bfc11ce10118684Denys Vlasenko (current_wordsize == 4 ? (uint64_t) iovu.iov32[i].base : iovu.iov64[i].base) 6144ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_len(i) \ 6159fd4f96d2a2527ac7ca90c156bfc11ce10118684Denys Vlasenko (current_wordsize == 4 ? (uint64_t) iovu.iov32[i].len : iovu.iov64[i].len) 6164ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#else 6171d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes struct iovec *iov; 6184ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define sizeof_iov sizeof(*iov) 6194ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_base(i) iov[i].iov_base 6204ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_len(i) iov[i].iov_len 6214ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#endif 6221d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes int i; 62379a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko unsigned size; 6241d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 62579a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko size = sizeof_iov * len; 62679a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko /* Assuming no sane program has millions of iovs */ 62779a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko if ((unsigned)len > 1024*1024 /* insane or negative size? */ 6284ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin || (iov = malloc(size)) == NULL) { 62979a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko fprintf(stderr, "Out of memory\n"); 63079a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko return; 6311d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 632aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath if (umoven(tcp, addr, size, (char *) iov) >= 0) { 6331d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes for (i = 0; i < len; i++) { 634adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko /* include the buffer number to make it easy to 635adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko * match up the trace with the source */ 636adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf(" * %lu bytes in buffer %d\n", 637adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko (unsigned long)iov_iov_len(i), i); 638adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko dumpstr(tcp, (long) iov_iov_base(i), 639adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko iov_iov_len(i)); 640adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko } 6411d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 64279a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko free(iov); 6434ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef sizeof_iov 6444ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov_iov_base 6454ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov_iov_len 6464ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov 6471d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes} 6481d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 6491d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 65076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 6511201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkodumpstr(struct tcb *tcp, long addr, int len) 65276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 65376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int strsize = -1; 65476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static unsigned char *str; 65576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s; 65676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 65776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 65876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strsize < len) { 6595d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko free(str); 6605d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko str = malloc(len); 66179a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko if (!str) { 66279a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko strsize = -1; 66379a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko fprintf(stderr, "Out of memory\n"); 66479a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko return; 66579a79ea851250a30005d6323b20a9e30d9f336c1Denys Vlasenko } 66676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strsize = len; 66776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 66876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 66976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, addr, len, (char *) str) < 0) 67076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 67176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 67276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < len; i += 16) { 6731d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko char outstr[80]; 6741d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko 67576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s = outstr; 67676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " | %05x ", i); 67776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 9; 67876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 67976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 68076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 68176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 68276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " %02x", str[i + j]); 68376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 3; 68476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 68576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 68676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; *s++ = ' '; 68776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 68876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 68976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; 69076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 69176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 69276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 69376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 69476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isprint(str[i + j])) 69576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = str[i + j]; 69676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 69776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '.'; 69876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 69976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 70076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 70176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 70276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s |\n", outstr); 70376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 70476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 70576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 706612659e41e2f41490ea5ae2926f5e002bb398334Mike Frysinger#ifdef HAVE_PROCESS_VM_READV 707612659e41e2f41490ea5ae2926f5e002bb398334Mike Frysinger/* C library supports this, but the kernel might not. */ 708612659e41e2f41490ea5ae2926f5e002bb398334Mike Frysingerstatic bool process_vm_readv_not_supported = 0; 709612659e41e2f41490ea5ae2926f5e002bb398334Mike Frysinger#else 710612659e41e2f41490ea5ae2926f5e002bb398334Mike Frysinger 7113af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko/* Need to do this since process_vm_readv() is not yet available in libc. 7123af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko * When libc is be updated, only "static bool process_vm_readv_not_supported" 7133af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko * line should remain. 7143af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko */ 7153af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko#if !defined(__NR_process_vm_readv) 7163af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko# if defined(I386) 7173af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko# define __NR_process_vm_readv 347 7183af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko# elif defined(X86_64) 7193af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko# define __NR_process_vm_readv 310 7203af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko# elif defined(POWERPC) 7213af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko# define __NR_process_vm_readv 351 7223af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko# endif 7233af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko#endif 7243af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko 7253af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko#if defined(__NR_process_vm_readv) 7263af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenkostatic bool process_vm_readv_not_supported = 0; 72724ee60b836ad33bb4ac694ca99d6c94a8cc5ff92Mike Frysinger/* Have to avoid duplicating with the C library headers. */ 72824ee60b836ad33bb4ac694ca99d6c94a8cc5ff92Mike Frysingerstatic ssize_t strace_process_vm_readv(pid_t pid, 7293af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko const struct iovec *lvec, 7303af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko unsigned long liovcnt, 7313af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko const struct iovec *rvec, 7323af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko unsigned long riovcnt, 7333af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko unsigned long flags) 7343af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko{ 7353af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko return syscall(__NR_process_vm_readv, (long)pid, lvec, liovcnt, rvec, riovcnt, flags); 7363af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko} 73724ee60b836ad33bb4ac694ca99d6c94a8cc5ff92Mike Frysinger#define process_vm_readv strace_process_vm_readv 7383af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko#else 7393af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenkostatic bool process_vm_readv_not_supported = 1; 7403af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko# define process_vm_readv(...) (errno = ENOSYS, -1) 7413af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko#endif 742612659e41e2f41490ea5ae2926f5e002bb398334Mike Frysinger 743612659e41e2f41490ea5ae2926f5e002bb398334Mike Frysinger#endif /* end of hack */ 7443af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko 74576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PAGMASK (~(PAGSIZ - 1)) 74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * move `len' bytes of data from process `pid' 74876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * at address `addr' to our space at `laddr' 74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 751ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoumoven(struct tcb *tcp, long addr, int len, char *laddr) 75276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 753eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath int pid = tcp->pid; 75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 755a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko int started; 75676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 75776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 75876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 76076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 761d2a660f534d98169f60d50706cbb2ec15fa13cf8Denys Vlasenko#if SUPPORTED_PERSONALITIES > 1 7629fd4f96d2a2527ac7ca90c156bfc11ce10118684Denys Vlasenko if (current_wordsize < sizeof(addr)) 7639fd4f96d2a2527ac7ca90c156bfc11ce10118684Denys Vlasenko addr &= (1ul << 8 * current_wordsize) - 1; 764d2a660f534d98169f60d50706cbb2ec15fa13cf8Denys Vlasenko#endif 765d2a660f534d98169f60d50706cbb2ec15fa13cf8Denys Vlasenko 7663af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko if (!process_vm_readv_not_supported) { 7673af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko struct iovec local[1], remote[1]; 7683af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko int r; 7693af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko 7703af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko local[0].iov_base = laddr; 7713af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko remote[0].iov_base = (void*)addr; 7723af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko local[0].iov_len = remote[0].iov_len = len; 7733af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko r = process_vm_readv(pid, 7743af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko local, 1, 7753af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko remote, 1, 7763af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko /*flags:*/ 0 7773af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko ); 7783af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko if (r < 0) { 7793af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko if (errno == ENOSYS) 7803af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko process_vm_readv_not_supported = 1; 7819a71bcdab254e4cd93b8f1e93c659644eb70ea9bDmitry V. Levin else if (errno != EINVAL && errno != ESRCH) 7829a71bcdab254e4cd93b8f1e93c659644eb70ea9bDmitry V. Levin /* EINVAL or ESRCH could be seen if process is gone, 7839a71bcdab254e4cd93b8f1e93c659644eb70ea9bDmitry V. Levin * all the rest is strange and should be reported. */ 7849a71bcdab254e4cd93b8f1e93c659644eb70ea9bDmitry V. Levin perror_msg("%s", "process_vm_readv"); 7853af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko goto vm_readv_didnt_work; 7863af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko } 7873af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko return r; 7883af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko } 7893af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko vm_readv_didnt_work: 7903af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko 791a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko started = 0; 79276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 79376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 79476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 79576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 796eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 797eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 798eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 799eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* But if not started, we had a bogus address. */ 800eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 8014c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%lx", pid, addr); 802eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 803eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 8045daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 805a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko m = MIN(sizeof(long) - n, len); 806a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko memcpy(laddr, &u.x[n], m); 80776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 80876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 80976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 810eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 811eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 812eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 813eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 814eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 815eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 816eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 817eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 8184c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%lx", pid, addr); 819eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 820eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 8215daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 822a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko m = MIN(sizeof(long), len); 823a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko memcpy(laddr, u.x, m); 82476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 82576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 82676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 82776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 82876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 82976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 83076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 8316cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * Like `umove' but make the additional effort of looking 83276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * for a terminating zero byte. 8336cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * 8346cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * Returns < 0 on error, > 0 if NUL was seen, 8356cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * (TODO if useful: return count of bytes including NUL), 8366cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * else 0 if len bytes were read but no NUL byte seen. 8376cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * 8386cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * Note: there is no guarantee we won't overwrite some bytes 8396cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * in laddr[] _after_ terminating NUL (but, of course, 8406cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko * we never write past laddr[len-1]). 84176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 84276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 843ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoumovestr(struct tcb *tcp, long addr, int len, char *laddr) 84476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 845a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko int started; 846eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath int pid = tcp->pid; 84776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, n, m; 84876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 84976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 85076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 85176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 85276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 853856c7ed97bce524ade99bb1fc41e746973d45accDmitry V. Levin#if SUPPORTED_PERSONALITIES > 1 8549fd4f96d2a2527ac7ca90c156bfc11ce10118684Denys Vlasenko if (current_wordsize < sizeof(addr)) 8559fd4f96d2a2527ac7ca90c156bfc11ce10118684Denys Vlasenko addr &= (1ul << 8 * current_wordsize) - 1; 856856c7ed97bce524ade99bb1fc41e746973d45accDmitry V. Levin#endif 857856c7ed97bce524ade99bb1fc41e746973d45accDmitry V. Levin 8583af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko if (!process_vm_readv_not_supported) { 8593af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko struct iovec local[1], remote[1]; 8603af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko 8613af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko local[0].iov_base = laddr; 8623af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko remote[0].iov_base = (void*)addr; 8633af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko 8643af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko while (len > 0) { 8653af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko int end_in_page; 8663af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko int r; 8673af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko int chunk_len; 8683af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko 8693af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko /* Don't read kilobytes: most strings are short */ 8703af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko chunk_len = len; 8713af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko if (chunk_len > 256) 8723af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko chunk_len = 256; 8733af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko /* Don't cross pages. I guess otherwise we can get EFAULT 8743af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko * and fail to notice that terminating NUL lies 8753af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko * in the existing (first) page. 8763af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko * (I hope there aren't arches with pages < 4K) 8773af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko */ 8783af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko end_in_page = ((addr + chunk_len) & 4095); 8793af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko r = chunk_len - end_in_page; 8803af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko if (r > 0) /* if chunk_len > end_in_page */ 8813af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko chunk_len = r; /* chunk_len -= end_in_page */ 8823af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko 8833af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko local[0].iov_len = remote[0].iov_len = chunk_len; 8843af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko r = process_vm_readv(pid, 8853af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko local, 1, 8863af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko remote, 1, 8873af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko /*flags:*/ 0 8883af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko ); 8893af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko if (r < 0) { 8903af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko if (errno == ENOSYS) 8913af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko process_vm_readv_not_supported = 1; 8929a71bcdab254e4cd93b8f1e93c659644eb70ea9bDmitry V. Levin else if (errno != EINVAL && errno != ESRCH) 8939a71bcdab254e4cd93b8f1e93c659644eb70ea9bDmitry V. Levin /* EINVAL or ESRCH could be seen 8949a71bcdab254e4cd93b8f1e93c659644eb70ea9bDmitry V. Levin * if process is gone, all the rest 8959a71bcdab254e4cd93b8f1e93c659644eb70ea9bDmitry V. Levin * is strange and should be reported. */ 8969a71bcdab254e4cd93b8f1e93c659644eb70ea9bDmitry V. Levin perror_msg("%s", "process_vm_readv"); 8973af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko goto vm_readv_didnt_work; 8983af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko } 8993af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko if (memchr(local[0].iov_base, '\0', r)) 9003af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko return 1; 9013af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko local[0].iov_base += r; 9023af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko remote[0].iov_base += r; 9033af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko len -= r; 9043af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko } 9053af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko return 0; 9063af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko } 9073af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko vm_readv_didnt_work: 9083af224c5cd8a64a6af3f875549ff821e2b5cb211Denys Vlasenko 909a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko started = 0; 91076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 91176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 91276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 91376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 914eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 915eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 916eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 917eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 9184c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%lx", pid, addr); 919eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 920eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 9215daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 922a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko m = MIN(sizeof(long) - n, len); 923a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko memcpy(laddr, &u.x[n], m); 92476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (n & (sizeof(long) - 1)) 92576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[n++] == '\0') 9266cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko return 1; 92776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 92876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 92976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 930eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 931eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 932eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 933eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 934eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 935eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 936eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 937eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 9384c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%lx", pid, addr); 939eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 940eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 9415daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 942a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko m = MIN(sizeof(long), len); 943a47e6b9fbb98e2363af28cf9cfa436964faa4fc6Denys Vlasenko memcpy(laddr, u.x, m); 94476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < sizeof(long); i++) 94576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[i] == '\0') 9466cecba53225ae30f1a28ce6954fb0cda847f3688Denys Vlasenko return 1; 94776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 94876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 949aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return 0; 95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 95176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 95276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 9531201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoupeek(struct tcb *tcp, long off, long *res) 95476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 95576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 95676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 957eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 958114aefd6183b8c073453f8def73270c42255f974Denys Vlasenko val = ptrace(PTRACE_PEEKUSER, tcp->pid, (char *) off, 0); 959eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (val == -1 && errno) { 960eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno != ESRCH) { 9614c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko perror_msg("upeek: PTRACE_PEEKUSER pid:%d @0x%lx)", tcp->pid, off); 962eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 96376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 964eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 96576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *res = val; 96676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 96776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 96876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 969d27809c978f3c8c3271f7d726dc92dd0eefa8a0fDenys Vlasenko/* Note! On new kernels (about 2.5.46+), we use PTRACE_O_TRACECLONE 970d27809c978f3c8c3271f7d726dc92dd0eefa8a0fDenys Vlasenko * and PTRACE_O_TRACE[V]FORK for tracing children. 971d27809c978f3c8c3271f7d726dc92dd0eefa8a0fDenys Vlasenko * If you are adding a new arch which is only supported by newer kernels, 972d27809c978f3c8c3271f7d726dc92dd0eefa8a0fDenys Vlasenko * you most likely don't need to add any code below 973d27809c978f3c8c3271f7d726dc92dd0eefa8a0fDenys Vlasenko * beside a dummy "return 0" block in change_syscall(). 974d27809c978f3c8c3271f7d726dc92dd0eefa8a0fDenys Vlasenko */ 975d27809c978f3c8c3271f7d726dc92dd0eefa8a0fDenys Vlasenko 9763bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko/* 9773bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * These #if's are huge, please indent them correctly. 9783bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * It's easy to get confused otherwise. 9793bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko */ 98076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 9812d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#include "syscall.h" 9823291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath 9832d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#ifndef CLONE_PTRACE 9842d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define CLONE_PTRACE 0x00002000 9852d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif 9862d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#ifndef CLONE_VFORK 9872d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define CLONE_VFORK 0x00004000 9882d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif 9892d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#ifndef CLONE_VM 9902d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define CLONE_VM 0x00000100 9912d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif 992d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 9932d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#ifdef IA64 994d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 995d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef unsigned long *arg_setup_state; 996d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 997d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 998d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGratharg_setup(struct tcb *tcp, arg_setup_state *state) 999d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 10001f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil unsigned long cfm, sof, sol; 10011f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil long bsp; 1002d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 10031f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil if (ia32) { 10041f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil /* Satisfy a false GCC warning. */ 10051f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil *state = NULL; 100608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return 0; 10071f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil } 100808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 1009932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_AR_BSP, &bsp) < 0) 1010d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1011932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_CFM, (long *) &cfm) < 0) 1012d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1013d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1014d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sof = (cfm >> 0) & 0x7f; 1015d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sol = (cfm >> 7) & 0x7f; 10161f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol); 1017d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 10181f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil *state = (unsigned long *) bsp; 1019d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1020d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1021d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 10222d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg_finish_change(tcp, state) 0 1023d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1024d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 10251201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoget_arg0(struct tcb *tcp, arg_setup_state *state, long *valp) 1026d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 102708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int ret; 102808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 102908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) 1030b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ret = upeek(tcp, PT_R11, valp); 103108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath else 1032b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ret = umoven(tcp, 103308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath (unsigned long) ia64_rse_skip_regs(*state, 0), 103408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath sizeof(long), (void *) valp); 103508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return ret; 1036d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1037d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1038d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 10391201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoget_arg1(struct tcb *tcp, arg_setup_state *state, long *valp) 1040d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 104108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int ret; 104208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 104308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) 1044b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ret = upeek(tcp, PT_R9, valp); 104508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath else 1046b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ret = umoven(tcp, 104708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath (unsigned long) ia64_rse_skip_regs(*state, 1), 104808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath sizeof(long), (void *) valp); 104908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return ret; 1050d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1051d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1052d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 10531201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoset_arg0(struct tcb *tcp, arg_setup_state *state, long val) 1054d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 105508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int req = PTRACE_POKEDATA; 105608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath void *ap; 105708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 105808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) { 105908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = (void *) (intptr_t) PT_R11; /* r11 == EBX */ 106008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath req = PTRACE_POKEUSER; 106108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath } else 106208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = ia64_rse_skip_regs(*state, 0); 1063eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1064eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(req, tcp->pid, ap, val); 1065eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return errno ? -1 : 0; 1066d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1067d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1068d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 10691201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoset_arg1(struct tcb *tcp, arg_setup_state *state, long val) 1070d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 107108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int req = PTRACE_POKEDATA; 107208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath void *ap; 107308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 107408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) { 107508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = (void *) (intptr_t) PT_R9; /* r9 == ECX */ 107608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath req = PTRACE_POKEUSER; 107708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath } else 107808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = ia64_rse_skip_regs(*state, 1); 1079eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1080eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(req, tcp->pid, ap, val); 1081eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return errno ? -1 : 0; 1082d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1083d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1084b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath/* ia64 does not return the input arguments from functions (and syscalls) 1085b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath according to ia64 RSE (Register Stack Engine) behavior. */ 1086b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath 10872d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg0(tcp, state, val) ((void) (state), 0) 10882d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg1(tcp, state, val) ((void) (state), 0) 1089b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath 10902d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#elif defined(SPARC) || defined(SPARC64) 1091d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1092ce7d953ebecc10f71e191b6d18cfeb2399429d5fDenys Vlasenko# if defined(SPARC64) 1093ce7d953ebecc10f71e191b6d18cfeb2399429d5fDenys Vlasenko# undef PTRACE_GETREGS 1094ce7d953ebecc10f71e191b6d18cfeb2399429d5fDenys Vlasenko# define PTRACE_GETREGS PTRACE_GETREGS64 1095ce7d953ebecc10f71e191b6d18cfeb2399429d5fDenys Vlasenko# undef PTRACE_SETREGS 1096ce7d953ebecc10f71e191b6d18cfeb2399429d5fDenys Vlasenko# define PTRACE_SETREGS PTRACE_SETREGS64 1097ce7d953ebecc10f71e191b6d18cfeb2399429d5fDenys Vlasenko# endif 1098ce7d953ebecc10f71e191b6d18cfeb2399429d5fDenys Vlasenko 10998566c500253f3bef38ace7d6031f76fe5d21f7e0Mike Frysingertypedef struct pt_regs arg_setup_state; 1100d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 11012d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg_setup(tcp, state) \ 11022d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko (ptrace(PTRACE_GETREGS, (tcp)->pid, (char *) (state), 0)) 11032d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg_finish_change(tcp, state) \ 11042d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko (ptrace(PTRACE_SETREGS, (tcp)->pid, (char *) (state), 0)) 1105d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 11062d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define get_arg0(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O0], 0) 11072d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define get_arg1(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O1], 0) 11082d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define set_arg0(tcp, state, val) ((state)->u_regs[U_REG_O0] = (val), 0) 11092d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define set_arg1(tcp, state, val) ((state)->u_regs[U_REG_O1] = (val), 0) 11102d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg0(tcp, state, val) 0 1111d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 11122d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#else /* other architectures */ 1113d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 11142d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# if defined S390 || defined S390X 11157b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath/* Note: this is only true for the `clone' system call, which handles 11167b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath arguments specially. We could as well say that its first two arguments 11177b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath are swapped relative to other architectures, but that would just be 11187b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath another #ifdef in the calls. */ 11192d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg0_offset PT_GPR3 11202d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg1_offset PT_ORIGGPR2 11212d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg0(tcp, state, val) ((void) (state), 0) 11222d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg1(tcp, state, val) ((void) (state), 0) 11232d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg0_index 1 11242d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg1_index 0 11252d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# elif defined(ALPHA) || defined(MIPS) 11262d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg0_offset REG_A0 11272d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg1_offset (REG_A0+1) 11282d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# elif defined(POWERPC) 11292d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg0_offset (sizeof(unsigned long)*PT_R3) 11302d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg1_offset (sizeof(unsigned long)*PT_R4) 11312d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg0(tcp, state, val) ((void) (state), 0) 11322d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# elif defined(HPPA) 11332d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg0_offset PT_GR26 11342d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg1_offset (PT_GR26-4) 113535be58119e3727a694d8c9f9b83f372401fcc4c0H.J. Lu# elif defined(X86_64) || defined(X32) 11362d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg0_offset ((long)(8*(current_personality ? RBX : RDI))) 11372d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg1_offset ((long)(8*(current_personality ? RCX : RSI))) 11382d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# elif defined(SH) 11392d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg0_offset (4*(REG_REG0+4)) 11402d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg1_offset (4*(REG_REG0+5)) 11412d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# elif defined(SH64) 11422d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko /* ABI defines arg0 & 1 in r2 & r3 */ 11432d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg0_offset (REG_OFFSET+16) 11442d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg1_offset (REG_OFFSET+24) 11452d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg0(tcp, state, val) 0 11462d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# elif defined CRISV10 || defined CRISV32 11472d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg0_offset (4*PT_R11) 11482d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg1_offset (4*PT_ORIG_R10) 11492d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg0(tcp, state, val) 0 11502d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg1(tcp, state, val) 0 11512d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg0_index 1 11522d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg1_index 0 11532d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# else 11542d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg0_offset 0 11552d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg1_offset 4 11562d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# if defined ARM 11572d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg0(tcp, state, val) 0 11582d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# endif 11592d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# endif 1160d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1161d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef int arg_setup_state; 1162d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 11632d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg_setup(tcp, state) (0) 11642d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg_finish_change(tcp, state) 0 11652d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define get_arg0(tcp, cookie, valp) (upeek((tcp), arg0_offset, (valp))) 11662d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define get_arg1(tcp, cookie, valp) (upeek((tcp), arg1_offset, (valp))) 1167d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1168d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 11691201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoset_arg0(struct tcb *tcp, void *cookie, long val) 1170d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1171b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko return ptrace(PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val); 1172d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1173d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1174d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 11751201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoset_arg1(struct tcb *tcp, void *cookie, long val) 1176d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1177b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko return ptrace(PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val); 1178d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1179d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 11802d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif /* architectures */ 1181d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 11822d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#ifndef restore_arg0 11832d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val)) 11842d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif 11852d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#ifndef restore_arg1 11862d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val)) 11872d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif 1188d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 11892d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#ifndef arg0_index 11902d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg0_index 0 11912d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko# define arg1_index 1 11922d1e90f9588281bb5520783006c06bc23f997bf8Denys Vlasenko#endif 119390d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath 119405eb905c4433c60d538e134619a3117522072a2fJames Hoganstatic int 119505eb905c4433c60d538e134619a3117522072a2fJames Hoganchange_syscall(struct tcb *tcp, arg_setup_state *state, int new) 119605eb905c4433c60d538e134619a3117522072a2fJames Hogan{ 119705eb905c4433c60d538e134619a3117522072a2fJames Hogan#if defined(I386) 119805eb905c4433c60d538e134619a3117522072a2fJames Hogan if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0) 119905eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 120005eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 1201bf357fcb76baeb64a45fc2b6b355c913c63e6015Denys Vlasenko#elif defined(X86_64) 120205eb905c4433c60d538e134619a3117522072a2fJames Hogan if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0) 120305eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 120405eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 1205bf357fcb76baeb64a45fc2b6b355c913c63e6015Denys Vlasenko#elif defined(X32) 1206bf357fcb76baeb64a45fc2b6b355c913c63e6015Denys Vlasenko /* setbpt/clearbpt never used: */ 1207bf357fcb76baeb64a45fc2b6b355c913c63e6015Denys Vlasenko /* X32 is only supported since about linux-3.0.30 */ 1208bf357fcb76baeb64a45fc2b6b355c913c63e6015Denys Vlasenko return 0; 120905eb905c4433c60d538e134619a3117522072a2fJames Hogan#elif defined(POWERPC) 121005eb905c4433c60d538e134619a3117522072a2fJames Hogan if (ptrace(PTRACE_POKEUSER, tcp->pid, 121105eb905c4433c60d538e134619a3117522072a2fJames Hogan (char*)(sizeof(unsigned long)*PT_R0), new) < 0) 121205eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 121305eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 121405eb905c4433c60d538e134619a3117522072a2fJames Hogan#elif defined(S390) || defined(S390X) 121505eb905c4433c60d538e134619a3117522072a2fJames Hogan /* s390 linux after 2.4.7 has a hook in entry.S to allow this */ 121605eb905c4433c60d538e134619a3117522072a2fJames Hogan if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new) < 0) 121705eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 121805eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 121905eb905c4433c60d538e134619a3117522072a2fJames Hogan#elif defined(M68K) 122005eb905c4433c60d538e134619a3117522072a2fJames Hogan if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new) < 0) 122105eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 122205eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 122305eb905c4433c60d538e134619a3117522072a2fJames Hogan#elif defined(SPARC) || defined(SPARC64) 122405eb905c4433c60d538e134619a3117522072a2fJames Hogan state->u_regs[U_REG_G1] = new; 122505eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 122605eb905c4433c60d538e134619a3117522072a2fJames Hogan#elif defined(MIPS) 122705eb905c4433c60d538e134619a3117522072a2fJames Hogan if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new) < 0) 122805eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 122905eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 123005eb905c4433c60d538e134619a3117522072a2fJames Hogan#elif defined(ALPHA) 123105eb905c4433c60d538e134619a3117522072a2fJames Hogan if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new) < 0) 123205eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 123305eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 123405eb905c4433c60d538e134619a3117522072a2fJames Hogan#elif defined(AVR32) 1235d27809c978f3c8c3271f7d726dc92dd0eefa8a0fDenys Vlasenko /* setbpt/clearbpt never used: */ 1236d27809c978f3c8c3271f7d726dc92dd0eefa8a0fDenys Vlasenko /* AVR32 is only supported since about linux-2.6.19 */ 123705eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 123805eb905c4433c60d538e134619a3117522072a2fJames Hogan#elif defined(BFIN) 1239d27809c978f3c8c3271f7d726dc92dd0eefa8a0fDenys Vlasenko /* setbpt/clearbpt never used: */ 1240d27809c978f3c8c3271f7d726dc92dd0eefa8a0fDenys Vlasenko /* Blackfin is only supported since about linux-2.6.23 */ 124105eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 124205eb905c4433c60d538e134619a3117522072a2fJames Hogan#elif defined(IA64) 124305eb905c4433c60d538e134619a3117522072a2fJames Hogan if (ia32) { 124405eb905c4433c60d538e134619a3117522072a2fJames Hogan switch (new) { 124505eb905c4433c60d538e134619a3117522072a2fJames Hogan case 2: 124605eb905c4433c60d538e134619a3117522072a2fJames Hogan break; /* x86 SYS_fork */ 124705eb905c4433c60d538e134619a3117522072a2fJames Hogan case SYS_clone: 124805eb905c4433c60d538e134619a3117522072a2fJames Hogan new = 120; 124905eb905c4433c60d538e134619a3117522072a2fJames Hogan break; 125005eb905c4433c60d538e134619a3117522072a2fJames Hogan default: 125105eb905c4433c60d538e134619a3117522072a2fJames Hogan fprintf(stderr, "%s: unexpected syscall %d\n", 125205eb905c4433c60d538e134619a3117522072a2fJames Hogan __FUNCTION__, new); 125305eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 125405eb905c4433c60d538e134619a3117522072a2fJames Hogan } 125505eb905c4433c60d538e134619a3117522072a2fJames Hogan if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new) < 0) 125605eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 125705eb905c4433c60d538e134619a3117522072a2fJames Hogan } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new) < 0) 125805eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 125905eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 126005eb905c4433c60d538e134619a3117522072a2fJames Hogan#elif defined(HPPA) 126105eb905c4433c60d538e134619a3117522072a2fJames Hogan if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new) < 0) 126205eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 126305eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 126405eb905c4433c60d538e134619a3117522072a2fJames Hogan#elif defined(SH) 126505eb905c4433c60d538e134619a3117522072a2fJames Hogan if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new) < 0) 126605eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 126705eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 126805eb905c4433c60d538e134619a3117522072a2fJames Hogan#elif defined(SH64) 126905eb905c4433c60d538e134619a3117522072a2fJames Hogan /* Top half of reg encodes the no. of args n as 0x1n. 127005eb905c4433c60d538e134619a3117522072a2fJames Hogan Assume 0 args as kernel never actually checks... */ 127105eb905c4433c60d538e134619a3117522072a2fJames Hogan if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), 127205eb905c4433c60d538e134619a3117522072a2fJames Hogan 0x100000 | new) < 0) 127305eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 127405eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 127505eb905c4433c60d538e134619a3117522072a2fJames Hogan#elif defined(CRISV10) || defined(CRISV32) 127605eb905c4433c60d538e134619a3117522072a2fJames Hogan if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_R9), new) < 0) 127705eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 127805eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 127905eb905c4433c60d538e134619a3117522072a2fJames Hogan#elif defined(ARM) 128005eb905c4433c60d538e134619a3117522072a2fJames Hogan /* Some kernels support this, some (pre-2.6.16 or so) don't. */ 128105eb905c4433c60d538e134619a3117522072a2fJames Hogan# ifndef PTRACE_SET_SYSCALL 128205eb905c4433c60d538e134619a3117522072a2fJames Hogan# define PTRACE_SET_SYSCALL 23 128305eb905c4433c60d538e134619a3117522072a2fJames Hogan# endif 128405eb905c4433c60d538e134619a3117522072a2fJames Hogan if (ptrace(PTRACE_SET_SYSCALL, tcp->pid, 0, new & 0xffff) != 0) 128505eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 128605eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 1287bf357fcb76baeb64a45fc2b6b355c913c63e6015Denys Vlasenko#elif defined(AARCH64) 1288bf357fcb76baeb64a45fc2b6b355c913c63e6015Denys Vlasenko /* setbpt/clearbpt never used: */ 1289bf357fcb76baeb64a45fc2b6b355c913c63e6015Denys Vlasenko /* AARCH64 is only supported since about linux-3.0.31 */ 1290bf357fcb76baeb64a45fc2b6b355c913c63e6015Denys Vlasenko return 0; 129105eb905c4433c60d538e134619a3117522072a2fJames Hogan#elif defined(TILE) 1292d27809c978f3c8c3271f7d726dc92dd0eefa8a0fDenys Vlasenko /* setbpt/clearbpt never used: */ 1293d27809c978f3c8c3271f7d726dc92dd0eefa8a0fDenys Vlasenko /* Tilera CPUs are only supported since about linux-2.6.34 */ 129405eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 129505eb905c4433c60d538e134619a3117522072a2fJames Hogan#elif defined(MICROBLAZE) 129605eb905c4433c60d538e134619a3117522072a2fJames Hogan if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR(0)), new) < 0) 129705eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 129805eb905c4433c60d538e134619a3117522072a2fJames Hogan return 0; 129905eb905c4433c60d538e134619a3117522072a2fJames Hogan#else 130005eb905c4433c60d538e134619a3117522072a2fJames Hogan#warning Do not know how to handle change_syscall for this architecture 130105eb905c4433c60d538e134619a3117522072a2fJames Hogan#endif /* architecture */ 130205eb905c4433c60d538e134619a3117522072a2fJames Hogan return -1; 130305eb905c4433c60d538e134619a3117522072a2fJames Hogan} 130405eb905c4433c60d538e134619a3117522072a2fJames Hogan 1305d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint 1306418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkosetbpt(struct tcb *tcp) 1307d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 13083291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone }; 1309d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath arg_setup_state state; 1310d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1311d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (tcp->flags & TCB_BPTSET) { 1312d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1313d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1314d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath } 1315d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13163291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath /* 13173291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath * It's a silly kludge to initialize this with a search at runtime. 13183291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath * But it's better than maintaining another magic thing in the 13193291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath * godforsaken tables. 13203291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath */ 13213291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath if (clone_scno[current_personality] == 0) { 13223291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath int i; 13233291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath for (i = 0; i < nsyscalls; ++i) 13243291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath if (sysent[i].sys_func == sys_clone) { 13253291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath clone_scno[current_personality] = i; 13263291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath break; 13273291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath } 13283291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath } 13293291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath 13300c661513e5a4594cfae98042018ed549b1e26b8dDmitry V. Levin if (sysent[tcp->scno].sys_func == sys_fork || 13310c661513e5a4594cfae98042018ed549b1e26b8dDmitry V. Levin sysent[tcp->scno].sys_func == sys_vfork) { 1332b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (arg_setup(tcp, &state) < 0 1333b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || get_arg0(tcp, &state, &tcp->inst[0]) < 0 1334b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || get_arg1(tcp, &state, &tcp->inst[1]) < 0 133505eb905c4433c60d538e134619a3117522072a2fJames Hogan || change_syscall(tcp, &state, 133605eb905c4433c60d538e134619a3117522072a2fJames Hogan clone_scno[current_personality]) < 0 1337b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || set_arg0(tcp, &state, CLONE_PTRACE|SIGCHLD) < 0 1338b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || set_arg1(tcp, &state, 0) < 0 1339b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || arg_finish_change(tcp, &state) < 0) 1340d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1341c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD; 1342c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->u_arg[arg1_index] = 0; 1343d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags |= TCB_BPTSET; 1344d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 13450c661513e5a4594cfae98042018ed549b1e26b8dDmitry V. Levin } 1346d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13470c661513e5a4594cfae98042018ed549b1e26b8dDmitry V. Levin if (sysent[tcp->scno].sys_func == sys_clone) { 13488fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil /* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)' 13490c661513e5a4594cfae98042018ed549b1e26b8dDmitry V. Levin contrary to x86 vfork above. Even on x86 we turn the 13508fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil vfork semantics into plain fork - each application must not 13518fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil depend on the vfork specifics according to POSIX. We would 13528fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil hang waiting for the parent resume otherwise. We need to 13538fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil clear also CLONE_VM but only in the CLONE_VFORK case as 13548fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil otherwise we would break pthread_create. */ 13558fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil 1356c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko long new_arg0 = (tcp->u_arg[arg0_index] | CLONE_PTRACE); 1357c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko if (new_arg0 & CLONE_VFORK) 1358c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko new_arg0 &= ~(unsigned long)(CLONE_VFORK | CLONE_VM); 1359c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko if (arg_setup(tcp, &state) < 0 1360c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko || set_arg0(tcp, &state, new_arg0) < 0 1361c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko || arg_finish_change(tcp, &state) < 0) 13625ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return -1; 1363c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->inst[0] = tcp->u_arg[arg0_index]; 1364c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->inst[1] = tcp->u_arg[arg1_index]; 136555980f5b72000406e3fd843b098b5c1328a21e45Denys Vlasenko tcp->flags |= TCB_BPTSET; 1366d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1367d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath } 1368d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13690c661513e5a4594cfae98042018ed549b1e26b8dDmitry V. Levin fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n", 13700c661513e5a4594cfae98042018ed549b1e26b8dDmitry V. Levin tcp->scno, tcp->pid); 1371d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1372d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1373d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1374d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint 13751201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoclearbpt(struct tcb *tcp) 1376d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1377d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath arg_setup_state state; 1378b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (arg_setup(tcp, &state) < 0 137905eb905c4433c60d538e134619a3117522072a2fJames Hogan || change_syscall(tcp, &state, tcp->scno) < 0 1380b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || restore_arg0(tcp, &state, tcp->inst[0]) < 0 1381b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || restore_arg1(tcp, &state, tcp->inst[1]) < 0 1382b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko || arg_finish_change(tcp, &state)) 1383c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko if (errno != ESRCH) 1384c133bf0eb240de31856f82972cf7f6f1e512780bDenys Vlasenko return -1; 1385d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags &= ~TCB_BPTSET; 1386d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1387d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1388