util.c revision 09a13c2da736aa9a74e7de761062c82832f7cf04
176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> 376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> 476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> 54dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> 64dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 74dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman * Linux for s390 port by D.J. Barrow 84dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com> 976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * All rights reserved. 1076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 1176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Redistribution and use in source and binary forms, with or without 1276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * modification, are permitted provided that the following conditions 1376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * are met: 1476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 1. Redistributions of source code must retain the above copyright 1576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * notice, this list of conditions and the following disclaimer. 1676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 2. Redistributions in binary form must reproduce the above copyright 1776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * notice, this list of conditions and the following disclaimer in the 1876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * documentation and/or other materials provided with the distribution. 1976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 3. The name of the author may not be used to endorse or promote products 2076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * derived from this software without specific prior written permission. 2176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 2276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 3376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * $Id$ 3476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 3576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 3676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "defs.h" 3776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 38d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#include <signal.h> 39d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#include <sys/syscall.h> 4076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/user.h> 4176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/param.h> 4276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <fcntl.h> 431d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H 441d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#include <sys/uio.h> 451d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 4676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 4776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <machine/reg.h> 4876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <a.out.h> 4976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <link.h> 5076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 5136915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman 5243a7482edbc7142b91e95d7aedeb9d121fc4880fWichert Akkerman#if defined(linux) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1)) 5376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <linux/ptrace.h> 541e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath#endif 5536915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman 568b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#if defined(LINUX) && defined(IA64) 57d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# include <asm/ptrace_offsets.h> 58d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# include <asm/rse.h> 598b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#endif 608b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 6136915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#ifdef HAVE_SYS_REG_H 6236915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#include <sys/reg.h> 6336915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman# define PTRACE_PEEKUSR PTRACE_PEEKUSER 64faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(HAVE_LINUX_PTRACE_H) 65faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#undef PTRACE_SYSCALL 66ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# ifdef HAVE_STRUCT_IA64_FPREG 67ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# define ia64_fpreg XXX_ia64_fpreg 68ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# endif 69ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# ifdef HAVE_STRUCT_PT_ALL_USER_REGS 70ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# define pt_all_user_regs XXX_pt_all_user_regs 71ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# endif 72faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#include <linux/ptrace.h> 73ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# undef ia64_fpreg 74ce9f0740d3b6e9910f25712771961bdb4bb4eaa2Roland McGrath# undef pt_all_user_regs 752e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#endif 762e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman 7776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE 7876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/utsname.h> 7976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 8076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 816d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if defined(LINUXSPARC) 829ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 834db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# define fpq kernel_fpq 844db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# define fq kernel_fq 854db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# define fpu kernel_fpu 864db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# include <asm/reg.h> 874db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# undef fpq 884db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# undef fq 894db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# undef fpu 909ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 916d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if defined (SPARC64) 926d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# define r_pc r_tpc 936d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# undef PTRACE_GETREGS 946d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# define PTRACE_GETREGS PTRACE_GETREGS64 956d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# undef PTRACE_SETREGS 966d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath# define PTRACE_SETREGS PTRACE_SETREGS64 976d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#endif /* SPARC64 */ 986d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath 999ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#if !defined(__GLIBC__) 10076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <linux/unistd.h> 10276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define _hack_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\ 10476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman type5,arg5,syscall) \ 10576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantype name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ 10676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ \ 10776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long __res; \ 10876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman\ 10976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman__asm__ volatile ("or %%g0, %1, %%o0\n\t" \ 11076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %2, %%o1\n\t" \ 11176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %3, %%o2\n\t" \ 11276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %4, %%o3\n\t" \ 11376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %5, %%o4\n\t" \ 11476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %6, %%g1\n\t" \ 1156d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if defined (SPARC64) 1166d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath "t 0x6d\n\t" \ 1176d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#else 11876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "t 0x10\n\t" \ 1196d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#endif 12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "bcc 1f\n\t" \ 12176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %%o0, %0\n\t" \ 12276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "sub %%g0, %%o0, %0\n\t" \ 12376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "1:\n\t" \ 12476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman : "=r" (__res) \ 12576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman : "0" ((long)(arg1)),"1" ((long)(arg2)), \ 12676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "2" ((long)(arg3)),"3" ((long)(arg4)),"4" ((long)(arg5)), \ 12776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "i" (__NR_##syscall) \ 12876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman : "g1", "o0", "o1", "o2", "o3", "o4"); \ 12976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanif (__res>=0) \ 130adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko return (type) __res; \ 13176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerrno = -__res; \ 13276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanreturn -1; \ 13376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 13476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,int,__addr2,ptrace) 13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define _ptrace 13876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 14076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1419ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 1429ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 14376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* macros */ 14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MAX 14576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MAX(a,b) (((a) > (b)) ? (a) : (b)) 14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MIN 14876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MIN(a,b) (((a) < (b)) ? (a) : (b)) 14976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 15076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 151a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrath#if 0 15276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_tv(tv, a, b) 15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv; 15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint a; 15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint b; 15776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 15876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a; 15976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = b; 16076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 161a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrath#endif 16276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 16476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_nz(a) 16576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a; 16676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 16776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return a->tv_sec || a->tv_usec; 16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 16976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 17176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_cmp(a, b) 17276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a, *b; 17376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 17476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (a->tv_sec < b->tv_sec 17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec)) 17676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 17776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (a->tv_sec > b->tv_sec 17876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec)) 17976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 18076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 18176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 18276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 18376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandouble 18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_float(tv) 18576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv; 18676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 18776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tv->tv_sec + tv->tv_usec/1000000.0; 18876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 18976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 19076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 19176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_add(tv, a, b) 19276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b; 19376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 19476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec + b->tv_sec; 19576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec + b->tv_usec; 19658372f52ac5f824be687c01bfc1db1ffb963f91eRoland McGrath if (tv->tv_usec >= 1000000) { 19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec++; 19876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec -= 1000000; 19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 20076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 20176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 20276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 20376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_sub(tv, a, b) 20476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b; 20576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 20676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec - b->tv_sec; 20776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec - b->tv_usec; 20876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (((long) tv->tv_usec) < 0) { 20976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec--; 21076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec += 1000000; 21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 21576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_div(tv, a, n) 21676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a; 21776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 21876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 21976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n; 22076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000; 22176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 22276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 22376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 22476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 22576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_mul(tv, a, n) 22676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a; 22776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 22876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 22976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec * n; 230fefdd97156bb2f86c5b6596dc7e28d954516b3edDmitry V. Levin tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000; 23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 234ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinconst char * 235ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinxlookup(const struct xlat *xlat, int val) 23676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 23776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (; xlat->str != NULL; xlat++) 23876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val == val) 23976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return xlat->str; 24076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 24176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 24376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 244eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Generic ptrace wrapper which tracks ESRCH errors 245eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * by setting tcp->ptrace_errno to ESRCH. 246732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * 247732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * We assume that ESRCH indicates likely process death (SIGKILL?), 248732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * modulo bugs where process somehow ended up not stopped. 249732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Unfortunately kernel uses ESRCH for that case too. Oh well. 250eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * 251eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Currently used by upeek() only. 252eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * TODO: use this in all other ptrace() calls while decoding. 253732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko */ 254732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenkolong 255eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathdo_ptrace(int request, struct tcb *tcp, void *addr, void *data) 256732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko{ 257732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko long l; 258732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko 259732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko errno = 0; 26009a13c2da736aa9a74e7de761062c82832f7cf04Mike Frysinger l = ptrace(request, tcp->pid, addr, (long) data); 261eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Non-ESRCH errors might be our invalid reg/mem accesses, 262eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * we do not record them. */ 263eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno == ESRCH) 264eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tcp->ptrace_errno = ESRCH; 265732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko return l; 266732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko} 267732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko 268732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko/* 269732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Used when we want to unblock stopped traced process. 270732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL. 271732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Returns 0 on success or if error was ESRCH 272732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * (presumably process was killed while we talk to it). 273732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko * Otherwise prints error message and returns -1. 274732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko */ 275732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenkoint 276eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathptrace_restart(int op, struct tcb *tcp, int sig) 277732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko{ 278732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko int err; 279eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath const char *msg; 280732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko 281732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko errno = 0; 28209a13c2da736aa9a74e7de761062c82832f7cf04Mike Frysinger ptrace(op, tcp->pid, (void *) 1, (long) sig); 283732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko err = errno; 284732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko if (!err || err == ESRCH) 285732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko return 0; 286732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko 287732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko tcp->ptrace_errno = err; 288eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath msg = "SYSCALL"; 289eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (op == PTRACE_CONT) 290eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath msg = "CONT"; 291eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (op == PTRACE_DETACH) 292eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath msg = "DETACH"; 293eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath fprintf(stderr, "strace: ptrace(PTRACE_%s,1,%d): %s\n", 294eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath msg, sig, strerror(err)); 295732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko return -1; 296732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko} 297732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko 298732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko/* 29976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Print entry in struct xlat table, if there. 30076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 30176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 302ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinprintxval(const struct xlat *xlat, int val, const char *dflt) 30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 304ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levin const char *str = xlookup(xlat, val); 30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 30676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 30776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", str); 30876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 30976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#x /* %s */", val, dflt); 31076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 31176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 31276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 31376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interpret `xlat' as an array of flags 31476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * print the entries whose bits are on in `flags' 31576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * return # of flags printed. 31676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 31776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 31876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanaddflags(xlat, flags) 319d9f816f60457930af27349fac3d23b3b78338036Roland McGrathconst struct xlat *xlat; 32076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags; 32176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 32276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 32376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 32476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 32576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 32676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%s", xlat->str); 32776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 32876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 32976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 33076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 33176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags) { 33276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%#x", flags); 33376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 33676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 33776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 338a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath/* 339a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Interpret `xlat' as an array of flags/ 340a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Print to static string the entries whose bits are on in `flags' 341a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath * Return static string. 342a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath */ 343a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrathconst char * 344a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrathsprintflags(const char *prefix, const struct xlat *xlat, int flags) 345a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath{ 346a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath static char outstr[1024]; 347a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath int found = 0; 348a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 349a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath strcpy(outstr, prefix); 350a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 351a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath for (; xlat->str; xlat++) { 352a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if ((flags & xlat->val) == xlat->val) { 353a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if (found) 354a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath strcat(outstr, "|"); 355a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath strcat(outstr, xlat->str); 356a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath flags &= ~xlat->val; 357a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath found = 1; 358a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath } 359a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath } 360a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if (flags) { 361a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath if (found) 362a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath strcat(outstr, "|"); 363a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath sprintf(outstr + strlen(outstr), "%#x", flags); 364a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath } 365a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 366a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath return outstr; 367a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath} 368a6c0d8c90a1cc3117f70281968d9efe6de755d83Roland McGrath 36976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 370b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrathprintflags(xlat, flags, dflt) 371d9f816f60457930af27349fac3d23b3b78338036Roland McGrathconst struct xlat *xlat; 37276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags; 373b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrathconst char *dflt; 37476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 37576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 37676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *sep; 37776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 37876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags == 0 && xlat->val == 0) { 37976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", xlat->str); 38076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 38176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 38276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = ""; 38476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 38576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 38676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s%s", sep, xlat->str); 38776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 38876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = "|"; 38976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 39076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 39176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 392b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath 393b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (n) { 394b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (flags) { 395b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("%s%#x", sep, flags); 396b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath n++; 397b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } 398b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } else { 399b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (flags) { 400b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("%#x", flags); 401b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (dflt) 402b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf(" /* %s */", dflt); 403b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } else { 404b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (dflt) 405b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("0"); 406b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } 40776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 408b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath 40976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 41076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 41176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 41276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 41376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintnum(tcp, addr, fmt) 41476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 41576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 41676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *fmt; 41776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 418eb285359906700f46b22cf4f9911695034313736Roland McGrath long num; 41976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 42076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 42176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 42276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 42376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 42476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, addr, &num) < 0) { 42576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 42676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 42776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 42876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("["); 42976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf(fmt, num); 43076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("]"); 43176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 43276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 4336bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathvoid 4349814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathprintnum_int(tcp, addr, fmt) 4359814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathstruct tcb *tcp; 4369814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathlong addr; 4379814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathchar *fmt; 4389814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath{ 4399814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath int num; 4409814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath 4419814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath if (!addr) { 4429814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("NULL"); 4439814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath return; 4449814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath } 4459814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath if (umove(tcp, addr, &num) < 0) { 4469814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("%#lx", addr); 4479814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath return; 4489814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath } 4499814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("["); 4509814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf(fmt, num); 4519814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("]"); 4529814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath} 4539814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath 4549814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathvoid 4556bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathprintuid(text, uid) 4566bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathconst char *text; 4576bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathunsigned long uid; 4586bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath{ 4596bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath tprintf("%s", text); 4606bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath tprintf((uid == -1) ? "%ld" : "%lu", uid); 4616bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath} 4626bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath 46376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic char path[MAXPATHLEN + 1]; 46476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 465a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/* 466a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Quote string `instr' of length `size' 467a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Write up to (3 + `size' * 4) bytes to `outstr' buffer. 468a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If `len' < 0, treat `instr' as a NUL-terminated string 469a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * and quote at most (`size' - 1) bytes. 470a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 4716d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrathstatic int 472bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinstring_quote(const char *instr, char *outstr, int len, int size) 47376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 474bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin const unsigned char *ustr = (const unsigned char *) instr; 475bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin char *s = outstr; 476bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin int usehex = 0, c, i; 47776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 478bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (xflag > 1) 479bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin usehex = 1; 480bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin else if (xflag) { 481a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for presence of symbol which require 482a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin to hex-quote the whole string. */ 483bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin for (i = 0; i < size; ++i) { 484bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin c = ustr[i]; 485a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for NUL-terminated string. */ 486a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (len < 0) { 487a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (c == '\0') 488a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin break; 489a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Quote at most size - 1 bytes. */ 490a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (i == size - 1) 491a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin continue; 492a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin } 493bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (!isprint(c) && !isspace(c)) { 494bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin usehex = 1; 495bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 496bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 497bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 49876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 499bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 500bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\"'; 501bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 502bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (usehex) { 503a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Hex-quote the whole string. */ 504bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin for (i = 0; i < size; ++i) { 505bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin c = ustr[i]; 506a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for NUL-terminated string. */ 507a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (len < 0) { 508a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (c == '\0') 509a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin break; 510a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Quote at most size - 1 bytes. */ 511a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (i == size - 1) 512a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin continue; 513a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin } 514bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin sprintf(s, "\\x%02x", c); 515bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin s += 4; 516bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 517bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } else { 518bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin for (i = 0; i < size; ++i) { 519bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin c = ustr[i]; 520a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Check for NUL-terminated string. */ 521a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (len < 0) { 522a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (c == '\0') 523a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin break; 524a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Quote at most size - 1 bytes. */ 525a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (i == size - 1) 526a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin continue; 527a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin } 528bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin switch (c) { 529bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\"': case '\\': 530bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 531bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = c; 532bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 533bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\f': 534bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 535bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'f'; 536bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 537bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\n': 538bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 539bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'n'; 540bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 541bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\r': 542bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 543bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'r'; 544bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 545bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\t': 546bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 547bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 't'; 548bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 549bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin case '\v': 550bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\\'; 551bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = 'v'; 552bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 553bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin default: 554bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (isprint(c)) 555bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = c; 556bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin else if (i + 1 < size 557bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin && isdigit(ustr[i + 1])) { 558bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin sprintf(s, "\\%03o", c); 559bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin s += 4; 560bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } else { 561bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin sprintf(s, "\\%o", c); 562bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin s += strlen(s); 563bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 564bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin break; 565bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 56676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 56776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 56876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 569bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s++ = '\"'; 570bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin *s = '\0'; 5716d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath 5726d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath /* Return nonzero if the string was unterminated. */ 5736d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath return i == size; 57476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 57576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 576a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/* 577a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Print path string specified by address `addr' and length `n'. 578a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If path length exceeds `n', append `...' to the output. 579a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 58076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 581bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintpathn(struct tcb *tcp, long addr, int n) 58276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 583a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!addr) { 584371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath tprintf("NULL"); 585bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin return; 586bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin } 587bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 588a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Cap path length to the path buffer size, 589a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin and NUL-terminate the buffer. */ 590a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (n > sizeof path - 1) 591a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin n = sizeof path - 1; 592bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin path[n] = '\0'; 593a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin 594a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Fetch one byte more to find out whether path length > n. */ 595bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (umovestr(tcp, addr, n + 1, path) < 0) 59676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 59776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 598bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin static char outstr[4*(sizeof path - 1) + sizeof "\"...\""]; 599bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin int trunc = (path[n] != '\0'); 600bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 601bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (trunc) 602bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin path[n] = '\0'; 603a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin (void) string_quote(path, outstr, -1, n + 1); 604a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (trunc) 605bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin strcat(outstr, "..."); 606bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin tprintf("%s", outstr); 60776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 60876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 60976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 61076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 611bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintpath(struct tcb *tcp, long addr) 612bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin{ 613bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin printpathn(tcp, addr, sizeof path - 1); 614bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin} 615bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 616a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin/* 617a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Print string specified by address `addr' and length `len'. 618a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If `len' < 0, treat the string as a NUL-terminated string. 619a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * If string length exceeds `max_strlen', append `...' to the output. 620a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 621bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinvoid 622bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levinprintstr(struct tcb *tcp, long addr, int len) 62376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 624bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin static char *str = NULL; 62576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char *outstr; 6266d9703205e06c77c6c8d38eac6796cfc9a4ea92cRoland McGrath int size; 62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 62876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 62976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 63076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 63176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 632a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* Allocate static buffers if they are not allocated yet. */ 633a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!str) 634a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin str = malloc(max_strlen + 1); 635a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!outstr) 636a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin outstr = malloc(4 * max_strlen + sizeof "\"...\""); 637a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (!str || !outstr) { 638a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin fprintf(stderr, "out of memory\n"); 639a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin tprintf("%#lx", addr); 640a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin return; 64176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 642bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin 64376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0) { 644a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin /* 645a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * Treat as a NUL-terminated string: fetch one byte more 646a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin * because string_quote() quotes one byte less. 647a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin */ 648bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin size = max_strlen + 1; 649a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin str[max_strlen] = '\0'; 650bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (umovestr(tcp, addr, size, str) < 0) { 65176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 65276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 65376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 65476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 65576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 656a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin size = MIN(len, max_strlen); 657bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin if (umoven(tcp, addr, size, str) < 0) { 65876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 65976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 66076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 66176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 66276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 663a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin if (string_quote(str, outstr, len, size) && 664a501f1426eeeeeb6fc31317c1ab7cc491026f495Dmitry V. Levin (len < 0 || len > max_strlen)) 665bea0203d2d4c8be1818c7d93a630306d79edf716Dmitry V. Levin strcat(outstr, "..."); 66676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 66776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", outstr); 66876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 66976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 6701d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H 6711d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesvoid 6721d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesdumpiov(tcp, len, addr) 6731d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesstruct tcb * tcp; 6741d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesint len; 6751d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hugheslong addr; 6761d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes{ 6774ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 6784ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin union { 6794ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin struct { u_int32_t base; u_int32_t len; } *iov32; 6804ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin struct { u_int64_t base; u_int64_t len; } *iov64; 6814ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin } iovu; 6824ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov iovu.iov64 6834ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define sizeof_iov \ 6844ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin (personality_wordsize[current_personality] == 4 \ 6854ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64)) 6864ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_base(i) \ 6874ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin (personality_wordsize[current_personality] == 4 \ 6884ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin ? (u_int64_t) iovu.iov32[i].base : iovu.iov64[i].base) 6894ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_len(i) \ 6904ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin (personality_wordsize[current_personality] == 4 \ 6914ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin ? (u_int64_t) iovu.iov32[i].len : iovu.iov64[i].len) 6924ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#else 6931d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes struct iovec *iov; 6944ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define sizeof_iov sizeof(*iov) 6954ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_base(i) iov[i].iov_base 6964ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_len(i) iov[i].iov_len 6974ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#endif 6981d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes int i; 699aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath unsigned long size; 7001d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 7014ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin size = sizeof_iov * (unsigned long) len; 7024ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin if (size / sizeof_iov != len 7034ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin || (iov = malloc(size)) == NULL) { 704aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath fprintf(stderr, "out of memory\n"); 7051d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes return; 7061d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 707aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath if (umoven(tcp, addr, size, (char *) iov) >= 0) { 7081d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes for (i = 0; i < len; i++) { 709adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko /* include the buffer number to make it easy to 710adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko * match up the trace with the source */ 711adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf(" * %lu bytes in buffer %d\n", 712adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko (unsigned long)iov_iov_len(i), i); 713adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko dumpstr(tcp, (long) iov_iov_base(i), 714adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko iov_iov_len(i)); 715adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko } 7161d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 7171d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes free((char *) iov); 7184ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef sizeof_iov 7194ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov_iov_base 7204ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov_iov_len 7214ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov 7221d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes} 7231d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 7241d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 72576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 72676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandumpstr(tcp, addr, len) 72776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 72876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 72976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 73076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 73176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int strsize = -1; 73276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static unsigned char *str; 73376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char outstr[80]; 73476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s; 73576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 73676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 73776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strsize < len) { 73876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 73976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(str); 74076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((str = malloc(len)) == NULL) { 74146100d07257824da2ae1147da0324b5788c95501Roland McGrath fprintf(stderr, "out of memory\n"); 74276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 74376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strsize = len; 74576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, addr, len, (char *) str) < 0) 74876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < len; i += 16) { 75176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s = outstr; 75276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " | %05x ", i); 75376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 9; 75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 75576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 75676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 75776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 75876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " %02x", str[i + j]); 75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 3; 76076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 76176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 76276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; *s++ = ' '; 76376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 76476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 76576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; 76676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 76776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 77076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isprint(str[i + j])) 77176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = str[i + j]; 77276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 77376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '.'; 77476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 77576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 77676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 77776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 77876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s |\n", outstr); 77976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 78076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 78176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 78276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PAGMASK (~(PAGSIZ - 1)) 78376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 78476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * move `len' bytes of data from process `pid' 78576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * at address `addr' to our space at `laddr' 78676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 78776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 788ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoumoven(struct tcb *tcp, long addr, int len, char *laddr) 78976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 79076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 791eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath int pid = tcp->pid; 79276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 7935daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 79476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 79576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 79676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 79776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 79876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 79976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 80076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 80176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 80276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 803eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 804eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 805eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 806eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 807eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 808eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 809eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 810eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* But if not started, we had a bogus address. */ 811eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 812eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("ptrace: umoven"); 813eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 814eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 8155daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 81676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 81776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 81876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 81976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 820eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 821eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 822eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 823eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 824eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 825eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 826eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 827eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 828eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("ptrace: umoven"); 829eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 830eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 8315daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 83276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 83376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 83476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 83576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 83676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 83776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 83876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 83976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 84076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 84176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 84276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 84376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 84476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 84576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 84676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 84776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 84876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 84976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 850eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 851eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 852eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 853eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno != ESRCH) 854eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("umoven"); 85576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 856eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 85776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 85876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 85976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 86076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 861eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 862eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 863eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 864eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno != ESRCH) 865eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("umoven"); 86676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 867eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 86876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 86976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 87076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 87176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !oldway */ 87276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 87376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 87476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 87576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, PAGSIZ); 87676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 877eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_READDATA, pid, 878eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath (char *) addr, len, laddr) < 0) { 879eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno != ESRCH) { 880eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("umoven: ptrace(PTRACE_READDATA, ...)"); 881eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath abort(); 882eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 88376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 88476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 88576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len -= n; 88676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += n; 88776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman laddr += n; 88876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 88976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !oldway */ 89076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 89176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 892bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 893ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 894aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd_as; 8959ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 896aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd; 89776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 898aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes lseek(fd, addr, SEEK_SET); 899aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (read(fd, laddr, len) == -1) 90076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 901bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 90276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 90376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 90476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 90576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 90676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 90776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * like `umove' but make the additional effort of looking 90876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * for a terminating zero byte. 90976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 91076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 911ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoumovestr(struct tcb *tcp, long addr, int len, char *laddr) 91276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 913bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 914aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#ifdef HAVE_MP_PROCFS 915aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd_as; 916aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#else 917aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd; 918aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#endif 919aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes /* Some systems (e.g. FreeBSD) can be upset if we read off the 920aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes end of valid memory, avoid this by trying to read up 921aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes to page boundaries. But we don't know what a page is (and 922aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes getpagesize(2) (if it exists) doesn't necessarily return 923aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes hardware page size). Assume all pages >= 1024 (a-historical 924aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes I know) */ 925aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 926aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int page = 1024; /* How to find this? */ 927aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int move = page - (addr & (page - 1)); 928aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int left = len; 929aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 930aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes lseek(fd, addr, SEEK_SET); 931aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 932aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes while (left) { 933aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (move > left) move = left; 9349cecf7f8d6115a247be7186013857270b2d588d5John Hughes if ((move = read(fd, laddr, move)) <= 0) 935aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return left != len ? 0 : -1; 936aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (memchr (laddr, 0, move)) break; 937aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes left -= move; 938aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes laddr += move; 939aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes addr += move; 940aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes move = page; 941aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes } 942bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 9435daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 944eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath int pid = tcp->pid; 94576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, n, m; 94676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 94776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 94876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 94976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 95176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 95276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 95376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 95476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 955eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 956eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 957eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 958eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 959eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 960eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 961eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 962eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 963eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("umovestr"); 964eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 965eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 9665daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 96776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len)); 96876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (n & (sizeof(long) - 1)) 96976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[n++] == '\0') 97076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 97176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 97276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 97376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 974eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 975eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 976eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 977eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (started && (errno==EPERM || errno==EIO)) { 978eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Ran into 'end of memory' - stupid "printpath" */ 979eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 980eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 981eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (addr != 0 && errno != EIO && errno != ESRCH) 982eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("umovestr"); 983eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 984eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 9855daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 98676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < sizeof(long); i++) 98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[i] == '\0') 98976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 99076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 993bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 994aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return 0; 99576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 9983bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if !defined (SPARC) && !defined(SPARC64) 9993bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define PTRACE_WRITETEXT 101 10003bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define PTRACE_WRITEDATA 102 10013bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* !SPARC && !SPARC64 */ 100276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 100376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 100476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 100576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 100676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 1007eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathuload(cmd, pid, addr, len, laddr) 1008eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint cmd; 1009eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint pid; 1010eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathlong addr; 1011eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint len; 1012eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathchar *laddr; 101376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 10143bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if 0 101576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 101676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 101776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 101876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, PAGSIZ); 101976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 1020eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) { 1021eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("uload: ptrace(PTRACE_WRITE, ...)"); 102276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 102376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 102476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len -= n; 102576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += n; 102676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman laddr += n; 102776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 10283bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else 102976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int peek, poke; 103076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 103176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 103276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 103376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 103476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 103576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 103676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cmd == PTRACE_WRITETEXT) { 103776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKTEXT; 103876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKETEXT; 103976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 104076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 104176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKDATA; 104276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKEDATA; 104376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 104476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 104576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 104676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 104776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); 1048eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1049eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(peek, pid, (char *) addr, 0); 1050eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 1051eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("uload: POKE"); 105276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1053eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 1054eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len)); 1055eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(poke, pid, (char *)addr, u.val) < 0) { 1056eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("uload: POKE"); 105776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 105876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1059eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath addr += sizeof(long), laddr += m, len -= m; 106076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 106176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 106276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < sizeof(long)) 1063eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath u.val = ptrace(peek, pid, (char *) addr, 0); 1064eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath memcpy(u.x, laddr, m = MIN(sizeof(long), len)); 1065eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(poke, pid, (char *) addr, u.val) < 0) { 1066eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("uload: POKE"); 106776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 106876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1069eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath addr += sizeof(long), laddr += m, len -= m; 107076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 10713bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 107276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 107376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 107476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1075eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint 1076eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathtload(pid, addr, len, laddr) 1077eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint pid; 1078eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint addr, len; 1079eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathchar *laddr; 1080eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath{ 1081eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return uload(PTRACE_WRITETEXT, pid, addr, len, laddr); 1082eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath} 1083eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 1084eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint 1085eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathdload(pid, addr, len, laddr) 1086eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint pid; 1087eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint addr; 1088eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathint len; 1089eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathchar *laddr; 109076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 1091eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return uload(PTRACE_WRITEDATA, pid, addr, len, laddr); 109276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 109376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 109476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 109576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1096bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 109776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 109876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 1099eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathupeek(tcp, off, res) 1100eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathstruct tcb *tcp; 1101eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathlong off; 1102eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathlong *res; 110376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 110476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 110576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11063bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SUNOS4_KERNEL_ARCH_KLUDGE 110776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman { 110876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int is_sun4m = -1; 110976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct utsname name; 111076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 111176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Round up the usual suspects. */ 111276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m == -1) { 111376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (uname(&name) < 0) { 111476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("upeek: uname?"); 111576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 111676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 111776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman is_sun4m = strcmp(name.machine, "sun4m") == 0; 111876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) { 1119d9f816f60457930af27349fac3d23b3b78338036Roland McGrath const struct xlat *x; 112076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 112176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (x = struct_user_offsets; x->str; x++) 112276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman x->val += 1024; 112376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 112476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 112576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) 112676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman off += 1024; 112776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 11283bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 1129eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1130732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko val = do_ptrace(PTRACE_PEEKUSER, tcp, (char *) off, 0); 1131eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (val == -1 && errno) { 1132eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno != ESRCH) { 1133eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath char buf[60]; 1134eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)", tcp->pid, off); 1135eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror(buf); 1136eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 113776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1138eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 113976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *res = val; 114076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 114176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 114276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1143bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 114476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1145a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrath#if 0 114676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong 11475ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenkogetpc(struct tcb *tcp) 114876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 114976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 115076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 115176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 11523bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined(I386) 1153932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*EIP, &pc) < 0) 115476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 11553bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(X86_64) 1156932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 8*RIP, &pc) < 0) 11570e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return -1; 11583bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(IA64) 1159932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_B0, &pc) < 0) 11608b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 11613bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ARM) 1162932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*15, &pc) < 0) 116376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 11645ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# elif defined(AVR32) 11655ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko if (upeek(tcp, REG_PC, &pc) < 0) 11665ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return -1; 11673bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(BFIN) 1168932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, REG_PC, &pc) < 0) 116987ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin return -1; 11703bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(POWERPC) 1171932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) 117276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 11733bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(M68K) 1174932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*PT_PC, &pc) < 0) 117576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 11763bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ALPHA) 1177932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, REG_PC, &pc) < 0) 117876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 11793bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(MIPS) 11803bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko if (upeek(tcp, REG_EPC, &pc) < 0) 11813bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko return -1; 11823bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SPARC) || defined(SPARC64) 11839ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 1184eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) 118576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 11869ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman pc = regs.r_pc; 11873bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(S390) || defined(S390X) 1188eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if(upeek(tcp,PT_PSWADDR,&pc) < 0) 118910a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig return -1; 11903bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(HPPA) 1191eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if(upeek(tcp,PT_IAOQ0,&pc) < 0) 1192c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return -1; 11933bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH) 1194eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (upeek(tcp, 4*REG_PC ,&pc) < 0) 1195adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko return -1; 11963bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH64) 1197adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko if (upeek(tcp, REG_PC ,&pc) < 0) 1198adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko return -1; 11993bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 120076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pc; 120176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 120276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 120376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 120476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 120576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Return current program counter for `pid' 120676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Assumes PC is never 0xffffffff 120776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 120876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct regs regs; 120976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1210eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 1211eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("getpc: ptrace(PTRACE_GETREGS, ...)"); 121276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1213eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 121476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return regs.r_pc; 121576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 121676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 121776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 121876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* XXX */ 121976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 122076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */ 122176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1222bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1223bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct reg regs; 1224bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 1225bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return regs.r_eip; 1226bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 122776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 12283bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko#endif /* 0 */ 122976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 123076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 1231ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenkoprintcall(struct tcb *tcp) 123276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 12337a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath#define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \ 12347a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath sizeof(long) == 8 ? "[????????????????] " : \ 12357a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath NULL /* crash */) 123676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 123776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 12383bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef I386 123976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long eip; 124076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1241932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*EIP, &eip) < 0) { 12427a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 124376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 124476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 124576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", eip); 1246eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath 12473bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(S390) || defined(S390X) 1248adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko long psw; 1249eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if(upeek(tcp,PT_PSWADDR,&psw) < 0) { 1250adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko PRINTBADPC; 1251adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko return; 1252adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko } 12533bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef S390 1254adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf("[%08lx] ", psw); 12553bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif S390X 1256adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf("[%16lx] ", psw); 12573bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1258eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath 12593bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(X86_64) 12600e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig long rip; 12610e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig 1262932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 8*RIP, &rip) < 0) { 12637a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 12640e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return; 12650e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig } 12660e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig tprintf("[%16lx] ", rip); 12673bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(IA64) 12688b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman long ip; 12698b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 1270932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_B0, &ip) < 0) { 12717a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 12728b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return; 12738b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 12748b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tprintf("[%08lx] ", ip); 12753bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(POWERPC) 127676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 127776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1278932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) { 127976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 128076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 128176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 128276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 12833bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(M68K) 128476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 128576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1286932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*PT_PC, &pc) < 0) { 128776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 128876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 128976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 129076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 12913bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ALPHA) 129276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 129376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1294932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, REG_PC, &pc) < 0) { 12957a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath tprintf ("[????????????????] "); 129676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 129776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 129876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 12993bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SPARC) || defined(SPARC64) 13009ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 1301eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) { 13027a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 130376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 130476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 13059ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tprintf("[%08lx] ", regs.r_pc); 13063bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(HPPA) 1307c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman long pc; 1308c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman 1309eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if(upeek(tcp,PT_IAOQ0,&pc) < 0) { 1310c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tprintf ("[????????] "); 1311c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return; 1312c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman } 1313c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tprintf("[%08lx] ", pc); 13143bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(MIPS) 131575c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman long pc; 131675c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman 1317932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, REG_EPC, &pc) < 0) { 131875c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman tprintf ("[????????] "); 131975c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman return; 132075c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman } 132175c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman tprintf("[%08lx] ", pc); 13223bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH) 1323adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko long pc; 1324ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman 1325adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko if (upeek(tcp, 4*REG_PC, &pc) < 0) { 1326adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf ("[????????] "); 1327adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko return; 1328adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko } 1329adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko tprintf("[%08lx] ", pc); 13303bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH64) 1331e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath long pc; 1332e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath 1333932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, REG_PC, &pc) < 0) { 13347a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath tprintf ("[????????????????] "); 1335e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath return; 1336e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath } 1337e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath tprintf("[%08lx] ", pc); 13383bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ARM) 1339ef388689610fa17df1d3001face8057b411a2e26Roland McGrath long pc; 1340e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath 1341932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*15, &pc) < 0) { 13427a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 1343ef388689610fa17df1d3001face8057b411a2e26Roland McGrath return; 1344ef388689610fa17df1d3001face8057b411a2e26Roland McGrath } 1345ef388689610fa17df1d3001face8057b411a2e26Roland McGrath tprintf("[%08lx] ", pc); 13465ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# elif defined(AVR32) 13475ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko long pc; 13485ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko 13495ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko if (upeek(tcp, REG_PC, &pc) < 0) { 13505ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko tprintf("[????????] "); 13515ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return; 13525ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko } 13535ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko tprintf("[%08lx] ", pc); 13543bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(BFIN) 135587ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin long pc; 135687ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin 1357932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_PC, &pc) < 0) { 135887ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin PRINTBADPC; 135987ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin return; 136087ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin } 136187ea1f4fe68c6110a96a76f8601b3e204200082dDmitry V. Levin tprintf("[%08lx] ", pc); 1362ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#elif defined(CRISV10) 1363ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko long pc; 1364ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko 1365eeb9ce3895f1ca0920d50696ef8b48124cef9da6Edgar E. Iglesias if (upeek(tcp, 4*PT_IRP, &pc) < 0) { 1366ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko PRINTBADPC; 1367ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko return; 1368ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko } 1369ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko tprintf("[%08lx] ", pc); 1370ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko#elif defined(CRISV32) 1371ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko long pc; 1372ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko 1373eeb9ce3895f1ca0920d50696ef8b48124cef9da6Edgar E. Iglesias if (upeek(tcp, 4*PT_ERP, &pc) < 0) { 1374ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko PRINTBADPC; 1375ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko return; 1376ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko } 1377ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko tprintf("[%08lx] ", pc); 13783bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* architecture */ 137976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 138076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 138176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 138276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct regs regs; 138376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1384eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 1385eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("printcall: ptrace(PTRACE_GETREGS, ...)"); 13867a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 138776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 138876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 138976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08x] ", regs.r_o7); 139076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 139176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 139276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 139376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* XXX */ 13947a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 139576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 139676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1397bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1398bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct reg regs; 1399bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 1400bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tprintf("[%08x] ", regs.r_eip); 1401bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 140276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 140376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 14043bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko 14053bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko/* 14063bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * These #if's are huge, please indent them correctly. 14073bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * It's easy to get confused otherwise. 14083bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko */ 1409bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 141076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 14113bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined LINUX 1412d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14133bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# include "syscall.h" 14143291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath 14153bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# include <sys/syscall.h> 14163bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef CLONE_PTRACE 14173bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define CLONE_PTRACE 0x00002000 14183bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 14193bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef CLONE_VFORK 14203bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define CLONE_VFORK 0x00004000 14213bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 14223bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef CLONE_VM 14233bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define CLONE_VM 0x00000100 14243bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 14253bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef CLONE_STOPPED 14263bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define CLONE_STOPPED 0x02000000 14273bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1428d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14293bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef IA64 1430d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 143108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath/* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32 143208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath subsystem has them for x86... */ 14333bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define SYS_fork 2 14343bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define SYS_vfork 190 143508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 1436d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef unsigned long *arg_setup_state; 1437d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1438d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1439d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGratharg_setup(struct tcb *tcp, arg_setup_state *state) 1440d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 14411f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil unsigned long cfm, sof, sol; 14421f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil long bsp; 1443d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14441f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil if (ia32) { 14451f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil /* Satisfy a false GCC warning. */ 14461f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil *state = NULL; 144708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return 0; 14481f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil } 144908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 1450932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_AR_BSP, &bsp) < 0) 1451d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1452932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_CFM, (long *) &cfm) < 0) 1453d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1454d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1455d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sof = (cfm >> 0) & 0x7f; 1456d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sol = (cfm >> 7) & 0x7f; 14571f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol); 1458d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14591f942710a57860eeabfa03e62b8ac151022d1be3Jan Kratochvil *state = (unsigned long *) bsp; 1460d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1461d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1462d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14633bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_finish_change(tcp, state) 0 1464d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 14653bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SYS_fork 1466d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1467d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathget_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp) 1468d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 146908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int ret; 147008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 147108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) 1472932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko ret = upeek (tcp, PT_R11, valp); 147308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath else 147408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ret = umoven (tcp, 147508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath (unsigned long) ia64_rse_skip_regs(*state, 0), 147608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath sizeof(long), (void *) valp); 147708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return ret; 1478d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1479d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1480d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1481d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathget_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp) 1482d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 148308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int ret; 148408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 148508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) 1486932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko ret = upeek (tcp, PT_R9, valp); 148708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath else 148808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ret = umoven (tcp, 148908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath (unsigned long) ia64_rse_skip_regs(*state, 1), 149008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath sizeof(long), (void *) valp); 149108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return ret; 1492d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 14933bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1494d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1495d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1496d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg0 (struct tcb *tcp, arg_setup_state *state, long val) 1497d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 149808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int req = PTRACE_POKEDATA; 149908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath void *ap; 150008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 150108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) { 150208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = (void *) (intptr_t) PT_R11; /* r11 == EBX */ 150308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath req = PTRACE_POKEUSER; 150408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath } else 150508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = ia64_rse_skip_regs(*state, 0); 1506eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1507eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(req, tcp->pid, ap, val); 1508eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return errno ? -1 : 0; 1509d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1510d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1511d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1512d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg1 (struct tcb *tcp, arg_setup_state *state, long val) 1513d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 151408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int req = PTRACE_POKEDATA; 151508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath void *ap; 151608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 151708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) { 151808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = (void *) (intptr_t) PT_R9; /* r9 == ECX */ 151908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath req = PTRACE_POKEUSER; 152008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath } else 152108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = ia64_rse_skip_regs(*state, 1); 1522eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1523eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(req, tcp->pid, ap, val); 1524eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return errno ? -1 : 0; 1525d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1526d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1527b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath/* ia64 does not return the input arguments from functions (and syscalls) 1528b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath according to ia64 RSE (Register Stack Engine) behavior. */ 1529b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath 15303bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) ((void) (state), 0) 15313bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg1(tcp, state, val) ((void) (state), 0) 1532b659f87e7d5b10f2c06626368efb8a0637f91da5Roland McGrath 15333bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (SPARC) || defined (SPARC64) 1534d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1535d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef struct regs arg_setup_state; 1536d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 15373bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_setup(tcp, state) \ 1538eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0)) 15393bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_finish_change(tcp, state) \ 1540eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0)) 1541d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 15423bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0) 15433bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0) 15443bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define set_arg0(tcp, state, val) ((state)->r_o0 = (val), 0) 15453bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define set_arg1(tcp, state, val) ((state)->r_o1 = (val), 0) 15463bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) 0 1547d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 15483bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else /* other architectures */ 1549d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 15503bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined S390 || defined S390X 15517b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath/* Note: this is only true for the `clone' system call, which handles 15527b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath arguments specially. We could as well say that its first two arguments 15537b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath are swapped relative to other architectures, but that would just be 15547b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath another #ifdef in the calls. */ 15553bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset PT_GPR3 15563bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset PT_ORIGGPR2 15573bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) ((void) (state), 0) 15583bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg1(tcp, state, val) ((void) (state), 0) 15593bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_index 1 15603bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_index 0 15613bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (ALPHA) || defined (MIPS) 15623bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset REG_A0 15633bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (REG_A0+1) 15645ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# elif defined (AVR32) 15655ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# define arg0_offset (REG_R12) 15665ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko# define arg1_offset (REG_R11) 15673bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (POWERPC) 15683bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset (sizeof(unsigned long)*PT_R3) 15693bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (sizeof(unsigned long)*PT_R4) 15703bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) ((void) (state), 0) 15713bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (HPPA) 15723bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset PT_GR26 15733bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (PT_GR26-4) 15743bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (X86_64) 15753bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset ((long)(8*(current_personality ? RBX : RDI))) 15763bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset ((long)(8*(current_personality ? RCX : RSI))) 15773bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (SH) 15783bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset (4*(REG_REG0+4)) 15793bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (4*(REG_REG0+5)) 15803bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (SH64) 15813bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko /* ABI defines arg0 & 1 in r2 & r3 */ 15823bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset (REG_OFFSET+16) 15833bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset (REG_OFFSET+24) 15843bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) 0 1585ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# elif defined CRISV10 || defined CRISV32 1586ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define arg0_offset (4*PT_R11) 1587ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define arg1_offset (4*PT_ORIG_R10) 1588ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define restore_arg0(tcp, state, val) 0 1589ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define restore_arg1(tcp, state, val) 0 1590ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define arg0_index 1 1591ea0e6e80260d2b1b7ad40282012b0e47869bcddfDenys Vlasenko# define arg1_index 0 15923bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else 15933bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_offset 0 15943bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_offset 4 15953bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined ARM 15963bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) 0 15973bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 15983bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1599d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1600d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef int arg_setup_state; 1601d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 16023bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_setup(tcp, state) (0) 16033bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg_finish_change(tcp, state) 0 16043bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define get_arg0(tcp, cookie, valp) \ 16053bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko (upeek ((tcp), arg0_offset, (valp))) 16063bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define get_arg1(tcp, cookie, valp) \ 16073bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko (upeek ((tcp), arg1_offset, (valp))) 1608d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1609d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1610eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathset_arg0 (struct tcb *tcp, void *cookie, long val) 1611d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1612eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val); 1613d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1614d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1615d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1616eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathset_arg1 (struct tcb *tcp, void *cookie, long val) 1617d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1618eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val); 1619d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1620d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 16213bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* architectures */ 1622d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 16233bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef restore_arg0 16243bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val)) 16253bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 16263bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef restore_arg1 16273bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val)) 16283bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1629d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 16303bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifndef arg0_index 16313bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg0_index 0 16323bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define arg1_index 1 16333bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 163490d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath 1635d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint 1636418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkosetbpt(struct tcb *tcp) 1637d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 16383291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone }; 1639d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath arg_setup_state state; 1640d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1641d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (tcp->flags & TCB_BPTSET) { 1642d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1643d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1644d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath } 1645d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 16463291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath /* 16473291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath * It's a silly kludge to initialize this with a search at runtime. 16483291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath * But it's better than maintaining another magic thing in the 16493291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath * godforsaken tables. 16503291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath */ 16513291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath if (clone_scno[current_personality] == 0) { 16523291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath int i; 16533291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath for (i = 0; i < nsyscalls; ++i) 16543291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath if (sysent[i].sys_func == sys_clone) { 16553291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath clone_scno[current_personality] = i; 16563291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath break; 16573291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath } 16583291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath } 16593291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath 166076989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath switch (known_scno(tcp)) { 16613bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SYS_vfork 16629383c6c539af09303efe0a16dea55363b095f66eRoland McGrath case SYS_vfork: 16633bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 16643bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SYS_fork 1665d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_fork: 16663bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 16673bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined SYS_fork || defined SYS_vfork 1668d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (arg_setup (tcp, &state) < 0 1669d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || get_arg0 (tcp, &state, &tcp->inst[0]) < 0 1670d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || get_arg1 (tcp, &state, &tcp->inst[1]) < 0 16713291ef2013cf9510f8ca493ab1c81862fd3a5e15Roland McGrath || change_syscall(tcp, clone_scno[current_personality]) < 0 1672d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0 1673d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || set_arg1 (tcp, &state, 0) < 0 1674d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || arg_finish_change (tcp, &state) < 0) 1675d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1676c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD; 1677c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->u_arg[arg1_index] = 0; 1678d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags |= TCB_BPTSET; 1679d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 16803bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1681d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1682d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_clone: 16833bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SYS_clone2 1684d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_clone2: 16853bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 16868fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil /* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)' 16878fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil contrary to x86 SYS_vfork above. Even on x86 we turn the 16888fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil vfork semantics into plain fork - each application must not 16898fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil depend on the vfork specifics according to POSIX. We would 16908fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil hang waiting for the parent resume otherwise. We need to 16918fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil clear also CLONE_VM but only in the CLONE_VFORK case as 16928fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil otherwise we would break pthread_create. */ 16938fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil 1694d6ff0d520d4bd8dda1523ec57e8ba2bc0ab3cf69Roland McGrath if ((arg_setup (tcp, &state) < 0 1695d6ff0d520d4bd8dda1523ec57e8ba2bc0ab3cf69Roland McGrath || set_arg0 (tcp, &state, 1696d6ff0d520d4bd8dda1523ec57e8ba2bc0ab3cf69Roland McGrath (tcp->u_arg[arg0_index] | CLONE_PTRACE) 16978fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil & ~(tcp->u_arg[arg0_index] & CLONE_VFORK 16988fc9575e0b45aae0af00e73da2d7b7bca5ebbf13Jan Kratochvil ? CLONE_VFORK | CLONE_VM : 0)) < 0 1699d6ff0d520d4bd8dda1523ec57e8ba2bc0ab3cf69Roland McGrath || arg_finish_change (tcp, &state) < 0)) 17005ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return -1; 1701d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags |= TCB_BPTSET; 1702c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->inst[0] = tcp->u_arg[arg0_index]; 1703c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->inst[1] = tcp->u_arg[arg1_index]; 1704d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1705d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1706d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath default: 1707d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n", 1708d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->scno, tcp->pid); 1709d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath break; 1710d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath } 1711d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1712d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1713d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1714d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1715d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint 1716d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathclearbpt(tcp) 1717d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstruct tcb *tcp; 1718d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1719d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath arg_setup_state state; 1720d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (arg_setup (tcp, &state) < 0 1721e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath || restore_arg0 (tcp, &state, tcp->inst[0]) < 0 1722e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath || restore_arg1 (tcp, &state, tcp->inst[1]) < 0 1723d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || arg_finish_change (tcp, &state)) 1724d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1725d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags &= ~TCB_BPTSET; 1726d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1727d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1728d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 17293bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else /* !defined LINUX */ 1730d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 173176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 173276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermansetbpt(tcp) 173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 173476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 17353bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef LINUX 17363bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko DEAD CODE HERE? WE ARE IN 'else !defined LINUX' 17373bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined (SPARC) || defined (SPARC64) 173876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* We simply use the SunOS breakpoint code. */ 173976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17409ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 17416d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath unsigned long inst; 17423bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOPA 0x30800000 /* ba,a 0 */ 174376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 174476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 174576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 174676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 174776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1748eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 1749eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 175076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 175176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 17529ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tcp->baddr = regs.r_o7 + 8; 1753eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1754eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0); 1755eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if(errno) { 1756eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 175776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1758eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 175976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 176076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 176176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * XXX - BRUTAL MODE ON 176276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We cannot set a real BPT in the child, since it will not be 176376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * traced at the moment it will reach the trap and would probably 176476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * die with a core dump. 176576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Thus, we are force our way in by taking out two instructions 176676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * and insert an eternal loop instead, in expectance of the SIGSTOP 17673bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * generated by our PTRACE_ATTACH. 176876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Of cause, if we evaporate ourselves in the middle of all this... 176976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 177076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 17716d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath inst = LOOPA; 17723bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined (SPARC64) 17736d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath inst <<= 32; 17746d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath inst |= (tcp->inst[0] & 0xffffffffUL); 17753bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 1776eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, inst); 1777eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if(errno) { 1778eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 177976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1780eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 178176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 178276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17833bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else /* !SPARC && !SPARC64 */ 17843bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef IA64 17857b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (ia32) { 17867b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman# define LOOP 0x0000feeb 17877b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 17887b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "PANIC: bpt already set in pid %u\n", 17897b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->pid); 17907b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 17917b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 1792932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_CR_IIP, &tcp->baddr) < 0) 17937b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 17947b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (debug) 17957b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "[%d] setting bpt at %lx\n", 17967b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->pid, tcp->baddr); 1797eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, 1798eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath (char *) tcp->baddr, 0); 1799eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 1800eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 18017b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 1802eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 1803eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 1804eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 1805eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 18067b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 1807eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 18087b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->flags |= TCB_BPTSET; 18097b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } else { 18107b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman /* 18117b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * Our strategy here is to replace the bundle that 18127b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * contained the clone() syscall with a bundle of the 18137b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * form: 18147b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * 18157b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * { 1: br 1b; br 1b; br 1b } 18167b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * 18177b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * This ensures that the newly forked child will loop 18187b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * endlessly until we've got a chance to attach to it. 18197b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman */ 18203bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP0 0x0000100000000017 18213bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP1 0x4000000000200000 18228b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman unsigned long addr, ipsr; 18238b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid_t pid; 18248b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 18258b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid = tcp->pid; 1826932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_CR_IPSR, &ipsr) < 0) 18278b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 1828932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_CR_IIP, &addr) < 0) 18298b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 18307b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman /* store "ri" in low two bits */ 18317b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->baddr = addr | ((ipsr >> 41) & 0x3); 18328b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 1833eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1834eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0, 1835eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 0); 1836eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8, 1837eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 0); 1838eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 1839eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 18408b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 1841eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 18428b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 1843eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 1844eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0); 1845eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1); 1846eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 1847eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 18488b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 18498b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 18508b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tcp->flags |= TCB_BPTSET; 18518b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 18523bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else /* !IA64 */ 18533bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko 18543bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined (I386) || defined(X86_64) 18553bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP 0x0000feeb 18563bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (M68K) 18573bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP 0x60fe0000 18583bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (ALPHA) 18593bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP 0xc3ffffff 18603bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (POWERPC) 18613bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP 0x48000000 18623bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ARM) 18633bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP 0xEAFFFFFE 18643bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(MIPS) 18653bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP 0x1000ffff 18663bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(S390) 18673bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP 0xa7f40000 /* BRC 15,0 */ 18683bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(S390X) 18693bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP 0xa7f4000000000000UL /* BRC 15,0 */ 18703bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(HPPA) 18713bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP 0xe81f1ff7 /* b,l,n <loc>,r0 */ 18723bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH) 18733bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef __LITTLE_ENDIAN__ 18743bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP 0x0000affe 18753bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else 18763bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP 0xfeaf0000 18773bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 18783bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else 18793bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# error unknown architecture 18803bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 188176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 188276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 188376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid); 188476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 188576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 18863bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined (I386) 1887932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*EIP, &tcp->baddr) < 0) 188876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 18893bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (X86_64) 1890932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 8*RIP, &tcp->baddr) < 0) 18910e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return -1; 18923bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (M68K) 1893932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*PT_PC, &tcp->baddr) < 0) 18945ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return -1; 18953bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (ALPHA) 189676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 18973bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (ARM) 189876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 18993bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (MIPS) 1900f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman return -1; /* FIXME: I do not know what i do - Flo */ 19013bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined (POWERPC) 1902932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &tcp->baddr) < 0) 190376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 19043bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(S390) || defined(S390X) 1905932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp,PT_PSWADDR, &tcp->baddr) < 0) 19064dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman return -1; 19073bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(HPPA) 1908932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_IAOQ0, &tcp->baddr) < 0) 1909c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return -1; 1910c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tcp->baddr &= ~0x03; 19113bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH) 1912adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko if (upeek(tcp, 4*REG_PC, &tcp->baddr) < 0) 1913adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko return -1; 19143bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else 19153bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# error unknown architecture 19163bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 191776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 191876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr); 1919eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0); 1920eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 1921eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 192276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1923eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 1924eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 1925eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 1926eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 192776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 192876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 192976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 193076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 19313bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* !IA64 */ 19323bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* !SPARC && !SPARC64 */ 19333bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* LINUX */ 193476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 19353bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SUNOS4 19363bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SPARC /* This code is slightly sparc specific */ 193776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1938e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 19393bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define BPT 0x91d02001 /* ta 1 */ 19403bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOP 0x10800000 /* ba 0 */ 19413bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define LOOPA 0x30800000 /* ba,a 0 */ 19423bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# define NOP 0x01000000 19433bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if LOOPA 194476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[1] = {LOOPA}; 19453bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else 194676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[2] = {LOOP, NOP}; 19473bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 194876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 194976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 195076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 195176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 195276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1953eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 1954eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 195576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 195676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 195776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->baddr = regs.r_o7 + 8; 1958eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr, 1959eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sizeof tcp->inst, (char *)tcp->inst) < 0) { 1960eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_READTEXT, ...)"); 196176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 196276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 196376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 196476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 196576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * XXX - BRUTAL MODE ON 196676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We cannot set a real BPT in the child, since it will not be 196776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * traced at the moment it will reach the trap and would probably 196876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * die with a core dump. 196976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Thus, we are force our way in by taking out two instructions 197076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * and insert an eternal loop in stead, in expectance of the SIGSTOP 197176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * generated by out PTRACE_ATTACH. 197276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Of cause, if we evaporate ourselves in the middle of all this... 197376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 1974eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 197576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof loopdeloop, (char *) loopdeloop) < 0) { 1976eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)"); 197776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 197876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 197976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 198076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 19813bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SPARC */ 19823bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SUNOS4 */ 198376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 198476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 198576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 198676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 198776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 198876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanclearbpt(tcp) 198976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 199076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 199176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 19923bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef LINUX 19933bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko DEAD CODE HERE? WE ARE IN 'else !defined LINUX' 19943bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined(I386) || defined(X86_64) 199576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long eip; 19963bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(POWERPC) 199776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 19983bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(M68K) 199976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 20003bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ALPHA) 200176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 20023bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(HPPA) 2003c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman long iaoq; 20043bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH) 2005adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko long pc; 20063bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* architecture */ 200776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 20083bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if defined (SPARC) || defined (SPARC64) 200976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Again, we borrow the SunOS breakpoint code. */ 201076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 201176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 201276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 201376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2014eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 2015eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 2016eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if(errno) { 2017eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 201876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 201976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 202076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 20213bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(IA64) 20227b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (ia32) { 20237b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman unsigned long addr; 20247b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 20257b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (debug) 20267b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 20277b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 20287b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 20297b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 20307b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 2031eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 2032eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 2033eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 2034eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 20357b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 20367b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 20377b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 20387b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 2039932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_CR_IIP, &addr) < 0) 20407b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 20417b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (addr != tcp->baddr) { 20427b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman /* The breakpoint has not been reached yet. */ 20437b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (debug) 20447b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, 20457b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 20467b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman addr, tcp->baddr); 20477b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return 0; 20487b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 20497b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } else { 20508b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman unsigned long addr, ipsr; 20518b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid_t pid; 20528b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 20538b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid = tcp->pid; 20548b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 2055932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_CR_IPSR, &ipsr) < 0) 20568b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 2057932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_CR_IIP, &addr) < 0) 20588b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 20598b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 20608b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman /* restore original bundle: */ 2061eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 2062eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]); 2063eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]); 2064eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 2065eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)"); 20668b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 20678b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 20688b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 20698b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman /* restore original "ri" in ipsr: */ 20708b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41); 2071eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 2072eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr); 2073eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 2074eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)"); 20758b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 20768b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 20778b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 20788b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 20798b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 20808b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (addr != (tcp->baddr & ~0x3)) { 20818b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman /* the breakpoint has not been reached yet. */ 20828b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (debug) 20838b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 20848b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman addr, tcp->baddr); 20858b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return 0; 20868b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 20878b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 20883bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# else /* !IA64 && !SPARC && !SPARC64 */ 208976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 209076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 209176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 209276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 209376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 209476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 209576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2096eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = 0; 2097eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 2098eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (errno) { 2099eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 210076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 210176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 210276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 210376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 21043bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef I386 2105932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*EIP, &eip) < 0) 210676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 210776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (eip != tcp->baddr) { 210876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 210976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 211076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 211176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 211276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman eip, tcp->baddr); 211376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 211476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 21153bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(X86_64) 2116932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 8*RIP, &eip) < 0) 21170e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return -1; 21180e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (eip != tcp->baddr) { 21190e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig /* The breakpoint has not been reached yet. */ 21200e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (debug) 21210e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig fprintf(stderr, 21220e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 21230e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig eip, tcp->baddr); 21240e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return 0; 21250e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig } 21263bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(POWERPC) 2127932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) 212876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 212976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 213076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 213176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 213276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 213376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 213476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 213576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 21363bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(M68K) 2137932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, 4*PT_PC, &pc) < 0) 213876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 213976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 214076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 214176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 214276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 214376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 214476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 214576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 21463bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(ALPHA) 2147932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, REG_PC, &pc) < 0) 214876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 214976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 215076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 215176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 215276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 215376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 215476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 215576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 21563bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(HPPA) 2157932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, PT_IAOQ0, &iaoq) < 0) 2158c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return -1; 2159c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman iaoq &= ~0x03; 2160c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) { 2161c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman /* The breakpoint has not been reached yet. */ 2162c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (debug) 2163c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n", 2164c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman iaoq, tcp->baddr); 2165c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return 0; 2166c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman } 2167c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman iaoq = tcp->baddr | 3; 2168c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman /* We should be pointing at a 'ldi -1000,r1' in glibc, so it is 2169c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit 2170c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman * has no significant effect. 2171c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman */ 2172eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq); 2173eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq); 21743bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# elif defined(SH) 2175adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko if (upeek(tcp, 4*REG_PC, &pc) < 0) 2176adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko return -1; 2177adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko if (pc != tcp->baddr) { 2178adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko /* The breakpoint has not been reached yet. */ 2179adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko if (debug) 2180adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2181adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko pc, tcp->baddr); 2182adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko return 0; 2183adedb510197209e7077310f9e9f67e3d51fb8617Denys Vlasenko } 2184ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman 21853bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* arch */ 21863bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* !SPARC && !SPARC64 && !IA64 */ 21873bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* LINUX */ 218876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 21893bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SUNOS4 21903bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# ifdef SPARC 219176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 21923bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if !LOOPA 2193e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 21943bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 219576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 219676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 219776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 219876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 219976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2200eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 220176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof tcp->inst, (char *) tcp->inst) < 0) { 2202eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)"); 220376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 220476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 220576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 220676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 22073bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if !LOOPA 220876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 220976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Since we don't have a single instruction breakpoint, we may have 22103bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko * to adjust the program counter after removing our `breakpoint'. 221176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 2212eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 2213eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clearbpt: ptrace(PTRACE_GETREGS, ...)"); 221476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 221576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2216eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if ((regs.r_pc < tcp->baddr) || 2217eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath (regs.r_pc > tcp->baddr + 4)) { 221876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet */ 221976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 222076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 222176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "NOTE: PC not at bpt (pc %#x baddr %#x)\n", 22223bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko regs.r_pc, tcp->baddr); 222376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 222476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 222576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (regs.r_pc != tcp->baddr) 222676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 222776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n", 222876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc, tcp->baddr); 222976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 223076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc = tcp->baddr; 2231eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) { 2232eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("clearbpt: ptrace(PTRACE_SETREGS, ...)"); 223376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 223476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 22353bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* LOOPA */ 22363bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SPARC */ 22373bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* SUNOS4 */ 223876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 223976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 224076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 224176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 22423bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif /* !defined LINUX */ 2243d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 2244bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 224576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 22463bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko 224776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 224876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 224976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 2250932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenkogetex(tcp, hdr) 2251932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenkostruct tcb *tcp; 225276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct exec *hdr; 225376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 225476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 225576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 225676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; n < sizeof *hdr; n += 4) { 225776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long res; 2258932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (upeek(tcp, uoff(u_exdata) + n, &res) < 0) 225976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 226076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(((char *) hdr) + n, &res, 4); 226176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 226276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) { 226376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n", 226476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_magic, hdr->a_toolversion, hdr->a_machtype); 226576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n", 226676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry); 226776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 226876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 226976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 227076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 227176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 227276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfixvfork(tcp) 227376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 227476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 227576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 227676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 227776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Change `vfork' in a freshly exec'ed dynamically linked 227876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * executable's (internal) symbol table to plain old `fork' 227976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 228076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 228176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct exec hdr; 228276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic dyn; 228376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic_2 ld; 228476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *strtab, *cp; 228576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2286932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko if (getex(tcp, &hdr) < 0) 228776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 228876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!hdr.a_dynamic) 228976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 229076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 229176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) { 229276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read DYNAMIC\n"); 229376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 229476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 229576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) { 229676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read link_dynamic_2\n"); 229776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 229876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 229976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) { 230046100d07257824da2ae1147da0324b5788c95501Roland McGrath fprintf(stderr, "out of memory\n"); 230176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 230276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2303eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 230476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 230576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 230676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 23073bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# if 0 230876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 230976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[symbol: %s]\n", cp); 231076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cp += strlen(cp)+1; 231176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 231276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 23133bb7cd6660032e97f76e8f62efd3540dbba97656Denys Vlasenko# endif 231476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 231576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strcmp(cp, "_vfork") == 0) { 231676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 231776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "fixvfork: FOUND _vfork\n"); 231876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strcpy(cp, "_fork"); 231976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 232076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 232176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cp += strlen(cp)+1; 232276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 232376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cp < strtab + ld.ld_symb_size) 232476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 232576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Write entire symbol table back to avoid 232676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * memory alignment bugs in ptrace 232776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 2328eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 232976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 233076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 233176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 233276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 233376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 233476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 233576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerr: 233676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 233776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 233876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 233976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 234076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 2341