util.c revision b15c4e47ff5b2b0dd71fa10472eafb1d5abf4c5f
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) \ 13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 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; 19676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 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; 23076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec * n + a->tv_usec / 1000000; 23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar * 23576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanxlookup(xlat, val) 236d9f816f60457930af27349fac3d23b3b78338036Roland McGrathconst struct xlat *xlat; 23776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint val; 23876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 23976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (; xlat->str != NULL; xlat++) 24076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val == val) 24176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return xlat->str; 24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 24376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 24476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 24576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 24676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Print entry in struct xlat table, if there. 24776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 24876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 24976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintxval(xlat, val, dflt) 250d9f816f60457930af27349fac3d23b3b78338036Roland McGrathconst struct xlat *xlat; 25176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint val; 252b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrathconst char *dflt; 25376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 25476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *str = xlookup(xlat, val); 25576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 25676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 25776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", str); 25876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 25976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#x /* %s */", val, dflt); 26076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 26176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 26276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 26376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interpret `xlat' as an array of flags 26476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * print the entries whose bits are on in `flags' 26576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * return # of flags printed. 26676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 26776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 26876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanaddflags(xlat, flags) 269d9f816f60457930af27349fac3d23b3b78338036Roland McGrathconst struct xlat *xlat; 27076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags; 27176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 27276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 27376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 27476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 27576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 27676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%s", xlat->str); 27776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 27876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 27976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 28076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 28176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags) { 28276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%#x", flags); 28376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 28476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 28576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 28676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 28776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 28876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 289b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrathprintflags(xlat, flags, dflt) 290d9f816f60457930af27349fac3d23b3b78338036Roland McGrathconst struct xlat *xlat; 29176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags; 292b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrathconst char *dflt; 29376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 29476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 29576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *sep; 29676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 29776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags == 0 && xlat->val == 0) { 29876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", xlat->str); 29976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 30076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 30176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 30276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = ""; 30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 30476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s%s", sep, xlat->str); 30676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 30776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = "|"; 30876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 30976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 31076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 311b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath 312b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (n) { 313b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (flags) { 314b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("%s%#x", sep, flags); 315b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath n++; 316b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } 317b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } else { 318b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (flags) { 319b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("%#x", flags); 320b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (dflt) 321b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf(" /* %s */", dflt); 322b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } else { 323b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (dflt) 324b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("0"); 325b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } 32676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 327b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath 32876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 32976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 33076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 33176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 33276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintnum(tcp, addr, fmt) 33376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *fmt; 33676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 337eb285359906700f46b22cf4f9911695034313736Roland McGrath long num; 33876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 33976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 34076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 34176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 34276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 34376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, addr, &num) < 0) { 34476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 34576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 34676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 34776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("["); 34876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf(fmt, num); 34976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("]"); 35076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 35176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 3526bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathvoid 3539814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathprintnum_int(tcp, addr, fmt) 3549814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathstruct tcb *tcp; 3559814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathlong addr; 3569814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathchar *fmt; 3579814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath{ 3589814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath int num; 3599814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath 3609814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath if (!addr) { 3619814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("NULL"); 3629814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath return; 3639814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath } 3649814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath if (umove(tcp, addr, &num) < 0) { 3659814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("%#lx", addr); 3669814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath return; 3679814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath } 3689814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("["); 3699814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf(fmt, num); 3709814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("]"); 3719814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath} 3729814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath 3739814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathvoid 3746bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathprintuid(text, uid) 3756bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathconst char *text; 3766bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathunsigned long uid; 3776bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath{ 3786bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath tprintf("%s", text); 3796bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath tprintf((uid == -1) ? "%ld" : "%lu", uid); 3806bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath} 3816bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath 38276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic char path[MAXPATHLEN + 1]; 38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 384a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrathstatic void 38576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstring_quote(str) 386a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrathconst char *str; 38776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 38876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char buf[2 * MAXPATHLEN + 1]; 38976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s; 39076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 39176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!strpbrk(str, "\"\'\\")) { 39276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("\"%s\"", str); 39376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 39476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 39576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (s = buf; *str; str++) { 39676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (*str) { 39776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\"': case '\'': case '\\': 39876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = *str; break; 39976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 40076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = *str; break; 40176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 40276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 40376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s = '\0'; 40476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("\"%s\"", buf); 40576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 40676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 40776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 40876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpath(tcp, addr) 40976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 41076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 41176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 412371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath if (addr == 0) 413371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath tprintf("NULL"); 414371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath else if (umovestr(tcp, addr, MAXPATHLEN, path) < 0) 41576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 41676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 41776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman string_quote(path); 41876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 41976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 42076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 42176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 42276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpathn(tcp, addr, n) 42376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 42476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 42576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 42676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 427b15c4e47ff5b2b0dd71fa10472eafb1d5abf4c5fRoland McGrath if (n >= sizeof path) 428b15c4e47ff5b2b0dd71fa10472eafb1d5abf4c5fRoland McGrath n = sizeof path - 1; 429b15c4e47ff5b2b0dd71fa10472eafb1d5abf4c5fRoland McGrath 430371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath if (addr == 0) 431371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath tprintf("NULL"); 432371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath else if (umovestr(tcp, addr, n, path) < 0) 43376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 43476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 43576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman path[n] = '\0'; 43676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman string_quote(path); 43776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 43876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 43976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 44076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 44176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintstr(tcp, addr, len) 44276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 44376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 44476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 44576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 44676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static unsigned char *str = NULL; 44776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char *outstr; 44876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, n, c, usehex; 44976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s, *outend; 45076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 45176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 45276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 45376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 45476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 45576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!str) { 45676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((str = malloc(max_strlen)) == NULL 45776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (outstr = malloc(2*max_strlen)) == NULL) { 45846100d07257824da2ae1147da0324b5788c95501Roland McGrath fprintf(stderr, "out of memory\n"); 45976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 46076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 46176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 46276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 4632e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman outend = outstr + max_strlen * 2 - 10; 46476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0) { 46576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = max_strlen; 46676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umovestr(tcp, addr, n, (char *) str) < 0) { 46776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 46876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 46976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 47076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 47176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 47276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, max_strlen); 47376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, addr, n, (char *) str) < 0) { 47476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 47576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 47676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 47776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 47876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 47976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usehex = 0; 48076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xflag > 1) 48176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usehex = 1; 48276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (xflag) { 48376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 48476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman c = str[i]; 48576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0 && c == '\0') 48676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 48776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!isprint(c) && !isspace(c)) { 48876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usehex = 1; 48976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 49076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 49176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 49276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 49376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 49476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s = outstr; 49576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\"'; 49676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 49776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (usehex) { 49876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 49976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman c = str[i]; 50076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0 && c == '\0') 50176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 50276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, "\\x%02x", c); 50376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 4; 50476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (s > outend) 50576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 50676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 50776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 50876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 50976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 51076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman c = str[i]; 51176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0 && c == '\0') 51276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 51376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (c) { 51476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\"': case '\'': case '\\': 51576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = c; break; 51676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\f': 51776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'f'; break; 51876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\n': 51976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'n'; break; 52076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\r': 52176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'r'; break; 52276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\t': 52376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 't'; break; 52476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\v': 52576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'v'; break; 52676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 52776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isprint(c)) 52876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = c; 52976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (i < n - 1 && isdigit(str[i + 1])) { 53076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, "\\%03o", c); 53176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 4; 53276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 53376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 53476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, "\\%o", c); 53576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += strlen(s); 53676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 53776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 53876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 53976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (s > outend) 54076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 54176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 54276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 54376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 54476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\"'; 54576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i < len || (len < 0 && (i == n || s > outend))) { 54676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '.'; *s++ = '.'; *s++ = '.'; 54776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 54876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s = '\0'; 54976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", outstr); 55076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 55176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 5521d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H 5531d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesvoid 5541d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesdumpiov(tcp, len, addr) 5551d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesstruct tcb * tcp; 5561d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesint len; 5571d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hugheslong addr; 5581d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes{ 5591d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes struct iovec *iov; 5601d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes int i; 561aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath unsigned long size; 5621d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 563aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath size = sizeof(*iov) * (unsigned long) len; 564aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath if (size / sizeof(*iov) != len 565aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath || (iov = (struct iovec *) malloc(size)) == NULL) { 566aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath fprintf(stderr, "out of memory\n"); 5671d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes return; 5681d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 569aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath if (umoven(tcp, addr, size, (char *) iov) >= 0) { 5701d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes for (i = 0; i < len; i++) { 5711d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes /* include the buffer number to make it easy to 5721d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes * match up the trace with the source */ 5731d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes tprintf(" * %lu bytes in buffer %d\n", 5741d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes (unsigned long)iov[i].iov_len, i); 5751d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes dumpstr(tcp, (long) iov[i].iov_base, 5761d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes iov[i].iov_len); 5771d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 5781d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 5791d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes free((char *) iov); 5801e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath 5811d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes} 5821d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 5831d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 58476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 58576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandumpstr(tcp, addr, len) 58676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 58776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 58876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 58976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 59076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int strsize = -1; 59176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static unsigned char *str; 59276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char outstr[80]; 59376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s; 59476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 59576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 59676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strsize < len) { 59776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 59876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(str); 59976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((str = malloc(len)) == NULL) { 60046100d07257824da2ae1147da0324b5788c95501Roland McGrath fprintf(stderr, "out of memory\n"); 60176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 60276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 60376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strsize = len; 60476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 60576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 60676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, addr, len, (char *) str) < 0) 60776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 60876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 60976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < len; i += 16) { 61076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s = outstr; 61176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " | %05x ", i); 61276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 9; 61376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 61476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 61576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 61676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 61776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " %02x", str[i + j]); 61876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 3; 61976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 62076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 62176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; *s++ = ' '; 62276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 62376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 62476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; 62576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 62676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 62876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 62976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isprint(str[i + j])) 63076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = str[i + j]; 63176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 63276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '.'; 63376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 63476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 63576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 63676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 63776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s |\n", outstr); 63876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 63976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 64076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 64176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PAGMASK (~(PAGSIZ - 1)) 64276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 64376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * move `len' bytes of data from process `pid' 64476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * at address `addr' to our space at `laddr' 64576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 64676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 64776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumoven(tcp, addr, len, laddr) 64876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 64976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 65076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 65176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 65276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 65376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 65476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 65576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 65676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 6575daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 65876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 65976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 66076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 66176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 66276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 66376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 66476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 66576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 66676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 66776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 66876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 66976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 6705daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 67176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 67276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 67376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 6745daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman /* But if not started, we had a bogus address. */ 67576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("ptrace: umoven"); 67676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 67776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 6785daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 67976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 68076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 68176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 68276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 68376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 68476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 68576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 6865daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 68776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 68876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 68976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 6904db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath if (addr != 0) 6914db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath perror("ptrace: umoven"); 69276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 69376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 6945daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 69576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 69676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 69776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 69876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 69976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 70076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 70176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 70276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 70376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 70476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 70576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 70676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 70776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 70876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 70976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 71076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 71176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 71276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 71376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 71476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 71576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 71676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umoven"); 71776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 71876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 71976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 72076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 72176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 72276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 72376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 72476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 72576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 72676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umoven"); 72776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 72876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 72976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 73076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 73176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 73276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !oldway */ 73376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 73476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 73576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 73676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, PAGSIZ); 73776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 73876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_READDATA, pid, 73976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (char *) addr, len, laddr) < 0) { 74076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umoven: ptrace(PTRACE_READDATA, ...)"); 74176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman abort(); 74276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 74376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len -= n; 74576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += n; 74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman laddr += n; 74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 74876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !oldway */ 74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 751bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 752ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 753aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd_as; 7549ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 755aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd; 75676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 757aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes lseek(fd, addr, SEEK_SET); 758aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (read(fd, laddr, len) == -1) 75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 760bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 76176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 76276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 76376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 76476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 76576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 76676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * like `umove' but make the additional effort of looking 76776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * for a terminating zero byte. 76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 77076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumovestr(tcp, addr, len, laddr) 77176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 77276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 77376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 77476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 77576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 776bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 777aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#ifdef HAVE_MP_PROCFS 778aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd_as; 779aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#else 780aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd; 781aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#endif 782aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes /* Some systems (e.g. FreeBSD) can be upset if we read off the 783aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes end of valid memory, avoid this by trying to read up 784aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes to page boundaries. But we don't know what a page is (and 785aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes getpagesize(2) (if it exists) doesn't necessarily return 786aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes hardware page size). Assume all pages >= 1024 (a-historical 787aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes I know) */ 788aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 789aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int page = 1024; /* How to find this? */ 790aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int move = page - (addr & (page - 1)); 791aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int left = len; 792aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 793aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes lseek(fd, addr, SEEK_SET); 794aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 795aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes while (left) { 796aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (move > left) move = left; 7979cecf7f8d6115a247be7186013857270b2d588d5John Hughes if ((move = read(fd, laddr, move)) <= 0) 798aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return left != len ? 0 : -1; 799aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (memchr (laddr, 0, move)) break; 800aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes left -= move; 801aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes laddr += move; 802aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes addr += move; 803aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes move = page; 804aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes } 805bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 8065daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 80776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 80876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, n, m; 80976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 81076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 81176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 81276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 81376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 81476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 81576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 81676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 81776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 81876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 81976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 82076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 8215daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 82276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 82376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 82476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 82576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umovestr"); 82676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 82776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 8285daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 82976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len)); 83076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (n & (sizeof(long) - 1)) 83176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[n++] == '\0') 83276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 83376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 83476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 83576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 83676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 83776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 83876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 8395daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 84076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 84176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 84276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 84376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umovestr"); 84476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 84576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 8465daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 84776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 84876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < sizeof(long); i++) 84976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[i] == '\0') 85076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 85176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 85276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 85376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 854bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 855aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return 0; 85676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 85776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 85876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 8596d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if !defined (SPARC) && !defined(SPARC64) 86076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITETEXT 101 86176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITEDATA 102 8626d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#endif /* !SPARC && !SPARC64 */ 86376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 86476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 86576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 86676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 86776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 86876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanuload(cmd, pid, addr, len, laddr) 86976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint cmd; 87076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 87176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 87276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 87376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 87476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 87576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 87676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 87776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 87876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 87976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, PAGSIZ); 88076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 88176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) { 88276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: ptrace(PTRACE_WRITE, ...)"); 88376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 88476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 88576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len -= n; 88676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += n; 88776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman laddr += n; 88876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 88976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 89076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int peek, poke; 89176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 89276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 89376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 89476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 89576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 89676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 89776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cmd == PTRACE_WRITETEXT) { 89876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKTEXT; 89976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKETEXT; 90076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 90176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 90276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKDATA; 90376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKEDATA; 90476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 90576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 90676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 90776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 90876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); 90976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 91076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(peek, pid, (char *) addr, 0); 91176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 91276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: POKE"); 91376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 91476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 91576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len)); 91676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(poke, pid, (char *)addr, u.val) < 0) { 91776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: POKE"); 91876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 91976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 92076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 92176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 92276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 92376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < sizeof(long)) 92476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(peek, pid, (char *) addr, 0); 92576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(u.x, laddr, m = MIN(sizeof(long), len)); 92676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(poke, pid, (char *) addr, u.val) < 0) { 92776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: POKE"); 92876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 92976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 93076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 93176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 93276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 93376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 93476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 93576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 93676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 93776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantload(pid, addr, len, laddr) 93876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 93976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr, len; 94076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 94176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 94276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return uload(PTRACE_WRITETEXT, pid, addr, len, laddr); 94376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 94476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 94576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 94676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandload(pid, addr, len, laddr) 94776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 94876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr; 94976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 95176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 95276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return uload(PTRACE_WRITEDATA, pid, addr, len, laddr); 95376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 95476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 95576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 95676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 957bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 95876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 95976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 96076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanupeek(pid, off, res) 96176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 96276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong off; 96376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong *res; 96476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 96576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 96676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 96776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE 96876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman { 96976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int is_sun4m = -1; 97076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct utsname name; 97176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 97276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Round up the usual suspects. */ 97376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m == -1) { 97476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (uname(&name) < 0) { 97576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("upeek: uname?"); 97676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 97776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 97876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman is_sun4m = strcmp(name.machine, "sun4m") == 0; 97976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) { 980d9f816f60457930af27349fac3d23b3b78338036Roland McGrath extern const struct xlat struct_user_offsets[]; 981d9f816f60457930af27349fac3d23b3b78338036Roland McGrath const struct xlat *x; 98276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 98376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (x = struct_user_offsets; x->str; x++) 98476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman x->val += 1024; 98576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 98676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) 98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman off += 1024; 98976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 99076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman val = ptrace(PTRACE_PEEKUSER, pid, (char *) off, 0); 99376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (val == -1 && errno) { 9941e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath char buf[60]; 9950e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)",pid,off); 9961e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath perror(buf); 99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 99876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 99976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *res = val; 100076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 100176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 100276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1003bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 100476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1005a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrath#if 0 100676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong 100776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetpc(tcp) 100876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 100976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 101076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 101176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 101276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 1013f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#if defined(I386) 101476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &pc) < 0) 101576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 10160e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined(X86_64) 10170e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (upeek(tcp->pid, 8*RIP, &pc) < 0) 10180e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return -1; 10198b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#elif defined(IA64) 10208b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(tcp->pid, PT_B0, &pc) < 0) 10218b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 1022f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ARM) 102376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*15, &pc) < 0) 102476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1025f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(POWERPC) 1026eb285359906700f46b22cf4f9911695034313736Roland McGrath if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) 102776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 102884fa923c15aa537b666d26694549091e9b9a5ddbRoland McGrath#elif defined(M68K) 102976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) 103076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1031f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ALPHA) 103276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, REG_PC, &pc) < 0) 103376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1034f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS) 1035f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman if (upeek(tcp->pid, REG_EPC, &pc) < 0) 1036f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman return -1; 10376d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#elif defined(SPARC) || defined(SPARC64) 10389ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 103976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) 104076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 10419ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman pc = regs.r_pc; 104210a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#elif defined(S390) || defined(S390X) 10434dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman if(upeek(tcp->pid,PT_PSWADDR,&pc) < 0) 104410a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig return -1; 1045c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1046c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) 1047c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return -1; 1048ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1049ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (upeek(tcp->pid, 4*REG_PC ,&pc) < 0) 1050ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman return -1; 1051f5a477788ed49d3c15e2080c03d30d4beaeefee3Roland McGrath#elif defined(SH64) 1052e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath if (upeek(tcp->pid, REG_PC ,&pc) < 0) 1053e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath return -1; 10547a0b649aeace5c1e1efe4a1d7b1ae6e3a87e0d44Wichert Akkerman#endif 105576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pc; 105676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 105776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 105876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 105976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 106076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Return current program counter for `pid' 106176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Assumes PC is never 0xffffffff 106276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 106376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct regs regs; 106476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 106576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 106676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("getpc: ptrace(PTRACE_GETREGS, ...)"); 106776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 106876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 106976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return regs.r_pc; 107076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 107176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 107276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 107376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* XXX */ 107476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 107576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */ 107676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1077bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1078bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct reg regs; 1079bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 1080bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return regs.r_eip; 1081bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 108276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 1083a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrath#endif 108476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 108576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 108676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintcall(tcp) 108776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 108876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 10897a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath#define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \ 10907a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath sizeof(long) == 8 ? "[????????????????] " : \ 10917a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath NULL /* crash */) 109276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 109376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 109476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386 109576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long eip; 109676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 109776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &eip) < 0) { 10987a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 109976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 110076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 110176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", eip); 1102eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath 1103eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath#elif defined(S390) || defined(S390X) 1104eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath long psw; 1105eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath if(upeek(tcp->pid,PT_PSWADDR,&psw) < 0) { 11067a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 1107eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath return; 1108eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath } 1109eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath#ifdef S390 1110eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath tprintf("[%08lx] ", psw); 1111eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath#elif S390X 1112eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath tprintf("[%16lx] ", psw); 1113eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath#endif 1114eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath 11150e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined(X86_64) 11160e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig long rip; 11170e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig 11180e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (upeek(tcp->pid, 8*RIP, &rip) < 0) { 11197a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 11200e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return; 11210e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig } 11220e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig tprintf("[%16lx] ", rip); 1123ef388689610fa17df1d3001face8057b411a2e26Roland McGrath#elif defined(IA64) 11248b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman long ip; 11258b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 11268b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(tcp->pid, PT_B0, &ip) < 0) { 11277a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 11288b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return; 11298b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 11308b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tprintf("[%08lx] ", ip); 1131faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(POWERPC) 113276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 113376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1134eb285359906700f46b22cf4f9911695034313736Roland McGrath if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) { 113576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 113676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 113776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 113876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 113984fa923c15aa537b666d26694549091e9b9a5ddbRoland McGrath#elif defined(M68K) 114076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 114176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 114276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) { 114376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 114476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 114576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 114676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 1147faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA) 114876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 114976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 115076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, REG_PC, &pc) < 0) { 11517a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath tprintf ("[????????????????] "); 115276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 115376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 115476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 11556d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#elif defined(SPARC) || defined(SPARC64) 11569ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 115776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) { 11587a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 115976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 116076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 11619ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tprintf("[%08lx] ", regs.r_pc); 1162c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1163c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman long pc; 1164c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman 1165c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) { 1166c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tprintf ("[????????] "); 1167c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return; 1168c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman } 1169c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tprintf("[%08lx] ", pc); 117075c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman#elif defined(MIPS) 117175c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman long pc; 117275c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman 117375c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman if (upeek(tcp->pid, REG_EPC, &pc) < 0) { 117475c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman tprintf ("[????????] "); 117575c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman return; 117675c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman } 117775c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman tprintf("[%08lx] ", pc); 1178ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1179ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman long pc; 1180ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman 1181ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (upeek(tcp->pid, 4*REG_PC, &pc) < 0) { 1182ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman tprintf ("[????????] "); 1183ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman return; 1184ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman } 1185ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman tprintf("[%08lx] ", pc); 1186f5a477788ed49d3c15e2080c03d30d4beaeefee3Roland McGrath#elif defined(SH64) 1187e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath long pc; 1188e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath 1189e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath if (upeek(tcp->pid, REG_PC, &pc) < 0) { 11907a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath tprintf ("[????????????????] "); 1191e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath return; 1192e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath } 1193e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath tprintf("[%08lx] ", pc); 1194ef388689610fa17df1d3001face8057b411a2e26Roland McGrath#elif defined(ARM) 1195ef388689610fa17df1d3001face8057b411a2e26Roland McGrath long pc; 1196e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath 1197ef388689610fa17df1d3001face8057b411a2e26Roland McGrath if (upeek(tcp->pid, 4*15, &pc) < 0) { 11987a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 1199ef388689610fa17df1d3001face8057b411a2e26Roland McGrath return; 1200ef388689610fa17df1d3001face8057b411a2e26Roland McGrath } 1201ef388689610fa17df1d3001face8057b411a2e26Roland McGrath tprintf("[%08lx] ", pc); 1202faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* !architecture */ 120376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 120476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 120576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 120676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct regs regs; 120776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 120876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 120976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("printcall: ptrace(PTRACE_GETREGS, ...)"); 12107a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 121176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 121276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 121376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08x] ", regs.r_o7); 121476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 121576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 121676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 121776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* XXX */ 12187a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 121976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 122076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1221bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1222bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct reg regs; 1223bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 1224bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tprintf("[%08x] ", regs.r_eip); 1225bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 122676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 122776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1228bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 122976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1230d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#if defined LINUX 1231d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1232d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#include <sys/syscall.h> 1233d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifndef CLONE_PTRACE 1234d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define CLONE_PTRACE 0x00002000 1235d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 123676989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath#ifndef CLONE_STOPPED 123776989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath# define CLONE_STOPPED 0x02000000 123876989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath#endif 1239d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1240d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef IA64 1241d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 124208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath/* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32 124308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath subsystem has them for x86... */ 124408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath#define SYS_fork 2 124508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath#define SYS_vfork 190 124608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 1247d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef unsigned long *arg_setup_state; 1248d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1249d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1250d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGratharg_setup(struct tcb *tcp, arg_setup_state *state) 1251d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1252d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath unsigned long *bsp, cfm, sof, sol; 1253d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 125408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) 125508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return 0; 125608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 1257d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) < 0) 1258d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1259d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (upeek(tcp->pid, PT_CFM, (long *) &cfm) < 0) 1260d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1261d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1262d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sof = (cfm >> 0) & 0x7f; 1263d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sol = (cfm >> 7) & 0x7f; 1264d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath bsp = ia64_rse_skip_regs(bsp, -sof + sol); 1265d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1266d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath *state = bsp; 1267d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1268d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1269d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1270d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_finish_change(tcp, state) 0 1271d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1272d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef SYS_fork 1273d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1274d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathget_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp) 1275d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 127608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int ret; 127708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 127808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) 127908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ret = upeek (tcp->pid, PT_R11, valp); 128008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath else 128108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ret = umoven (tcp, 128208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath (unsigned long) ia64_rse_skip_regs(*state, 0), 128308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath sizeof(long), (void *) valp); 128408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return ret; 1285d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1286d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1287d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1288d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathget_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp) 1289d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 129008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int ret; 129108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 129208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) 129308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ret = upeek (tcp->pid, PT_R9, valp); 129408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath else 129508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ret = umoven (tcp, 129608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath (unsigned long) ia64_rse_skip_regs(*state, 1), 129708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath sizeof(long), (void *) valp); 129808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return ret; 1299d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1300d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 1301d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1302d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1303d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg0 (struct tcb *tcp, arg_setup_state *state, long val) 1304d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 130508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int req = PTRACE_POKEDATA; 130608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath void *ap; 130708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 130808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) { 130908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = (void *) (intptr_t) PT_R11; /* r11 == EBX */ 131008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath req = PTRACE_POKEUSER; 131108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath } else 131208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = ia64_rse_skip_regs(*state, 0); 1313d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath errno = 0; 131408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ptrace(req, tcp->pid, ap, val); 1315d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return errno ? -1 : 0; 1316d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1317d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1318d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1319d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg1 (struct tcb *tcp, arg_setup_state *state, long val) 1320d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 132108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int req = PTRACE_POKEDATA; 132208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath void *ap; 132308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 132408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) { 132508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = (void *) (intptr_t) PT_R9; /* r9 == ECX */ 132608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath req = PTRACE_POKEUSER; 132708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath } else 132808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = ia64_rse_skip_regs(*state, 1); 1329d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath errno = 0; 133008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ptrace(req, tcp->pid, ap, val); 1331d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return errno ? -1 : 0; 1332d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1333d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13346d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#elif defined (SPARC) || defined (SPARC64) 1335d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1336d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef struct regs arg_setup_state; 1337d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1338d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_setup(tcp, state) \ 1339d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0)) 1340d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_finish_change(tcp, state) \ 1341d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0)) 1342d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1343d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0) 1344d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0) 1345d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define set_arg0(tcp, state, val) ((state)->r_o0 = (val), 0) 1346d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define set_arg1(tcp, state, val) ((state)->r_o1 = (val), 0) 1347e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg0(tcp, state, val) 0 1348d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1349d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#else 1350d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1351d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# if defined S390 || defined S390X 13527b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath/* Note: this is only true for the `clone' system call, which handles 13537b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath arguments specially. We could as well say that its first two arguments 13547b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath are swapped relative to other architectures, but that would just be 13557b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath another #ifdef in the calls. */ 13567b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath# define arg0_offset PT_GPR3 13577b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath# define arg1_offset PT_ORIGGPR2 13587b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath# define restore_arg0(tcp, state, val) ((void) (state), 0) 13597b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath# define restore_arg1(tcp, state, val) ((void) (state), 0) 1360c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath# define arg0_index 1 1361c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath# define arg1_index 0 1362d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# elif defined (ALPHA) || defined (MIPS) 1363d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg0_offset REG_A0 1364d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg1_offset (REG_A0+1) 1365d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# elif defined (POWERPC) 1366eb285359906700f46b22cf4f9911695034313736Roland McGrath# define arg0_offset (sizeof(unsigned long)*PT_R3) 1367eb285359906700f46b22cf4f9911695034313736Roland McGrath# define arg1_offset (sizeof(unsigned long)*PT_R4) 13687b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath# define restore_arg0(tcp, state, val) ((void) (state), 0) 1369d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# elif defined (HPPA) 1370d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg0_offset PT_GR26 1371d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg1_offset (PT_GR26-4) 13727f33cc3eb5ead7a79cae8c586e40d2f8b573eec1Roland McGrath# elif defined (X86_64) 13737f33cc3eb5ead7a79cae8c586e40d2f8b573eec1Roland McGrath# define arg0_offset ((long)(8*(current_personality ? RBX : RDI))) 13747f33cc3eb5ead7a79cae8c586e40d2f8b573eec1Roland McGrath# define arg1_offset ((long)(8*(current_personality ? RCX : RSI))) 1375ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath# elif defined (SH) 1376ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath# define arg0_offset (4*(REG_REG0+4)) 1377ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath# define arg1_offset (4*(REG_REG0+5)) 1378f5a477788ed49d3c15e2080c03d30d4beaeefee3Roland McGrath# elif defined (SH64) 1379e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath /* ABI defines arg0 & 1 in r2 & r3 */ 1380e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath# define arg0_offset (REG_OFFSET+16) 1381e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath# define arg1_offset (REG_OFFSET+24) 1382e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath# define restore_arg0(tcp, state, val) 0 1383d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# else 1384d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg0_offset 0 1385d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg1_offset 4 1386ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath# if defined ARM 1387e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg0(tcp, state, val) 0 1388e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# endif 1389d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# endif 1390d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1391d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef int arg_setup_state; 1392d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1393d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_setup(tcp, state) (0) 1394d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_finish_change(tcp, state) 0 1395d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg0(tcp, cookie, valp) \ 1396d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath (upeek ((tcp)->pid, arg0_offset, (valp))) 1397d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg1(tcp, cookie, valp) \ 1398d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath (upeek ((tcp)->pid, arg1_offset, (valp))) 1399d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1400d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1401d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg0 (struct tcb *tcp, void *cookie, long val) 1402d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1403ca85b97c9cea63db45e59a345218b902936b693dRoland McGrath return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val); 1404d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1405d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1406d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1407d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg1 (struct tcb *tcp, void *cookie, long val) 1408d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1409d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val); 1410d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1411d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1412d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 1413d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1414e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#ifndef restore_arg0 1415e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val)) 1416e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#endif 1417e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#ifndef restore_arg1 1418e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val)) 1419e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#endif 1420d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 142190d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath#ifndef arg0_index 142290d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath# define arg0_index 0 142390d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath# define arg1_index 1 142490d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath#endif 142590d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath 1426d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint 1427d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathsetbpt(tcp) 1428d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstruct tcb *tcp; 1429d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1430d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath extern int change_syscall(struct tcb *, int); 1431d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath arg_setup_state state; 1432d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1433d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (tcp->flags & TCB_BPTSET) { 1434d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1435d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1436d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath } 1437d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 143876989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath switch (known_scno(tcp)) { 14399383c6c539af09303efe0a16dea55363b095f66eRoland McGrath#ifdef SYS_vfork 14409383c6c539af09303efe0a16dea55363b095f66eRoland McGrath case SYS_vfork: 14419383c6c539af09303efe0a16dea55363b095f66eRoland McGrath#endif 1442d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef SYS_fork 1443d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_fork: 14449b0982b5d3b84c845192ad8b7ad822f81cf4743aRoland McGrath#endif 14459b0982b5d3b84c845192ad8b7ad822f81cf4743aRoland McGrath#if defined SYS_fork || defined SYS_vfork 1446d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (arg_setup (tcp, &state) < 0 1447d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || get_arg0 (tcp, &state, &tcp->inst[0]) < 0 1448d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || get_arg1 (tcp, &state, &tcp->inst[1]) < 0 1449d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || change_syscall(tcp, SYS_clone) < 0 1450d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0 1451d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || set_arg1 (tcp, &state, 0) < 0 1452d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || arg_finish_change (tcp, &state) < 0) 1453d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1454c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD; 1455c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->u_arg[arg1_index] = 0; 1456d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags |= TCB_BPTSET; 1457d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1458d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 1459d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1460d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_clone: 1461d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef SYS_clone2 1462d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_clone2: 1463d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 146402cee8d5cbcb0aaaf64d4f4d0916e3d4dbd8ee01Roland McGrath if ((tcp->u_arg[arg0_index] & CLONE_PTRACE) == 0 1465d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath && (arg_setup (tcp, &state) < 0 1466c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath || set_arg0 (tcp, &state, 1467c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->u_arg[arg0_index] | CLONE_PTRACE) < 0 1468d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || arg_finish_change (tcp, &state) < 0)) 1469d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1470d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags |= TCB_BPTSET; 1471c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->inst[0] = tcp->u_arg[arg0_index]; 1472c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->inst[1] = tcp->u_arg[arg1_index]; 1473d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1474d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1475d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath default: 1476d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n", 1477d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->scno, tcp->pid); 1478d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath break; 1479d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath } 1480d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1481d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1482d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1483d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1484d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint 1485d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathclearbpt(tcp) 1486d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstruct tcb *tcp; 1487d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1488d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath arg_setup_state state; 1489d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (arg_setup (tcp, &state) < 0 1490e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath || restore_arg0 (tcp, &state, tcp->inst[0]) < 0 1491e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath || restore_arg1 (tcp, &state, tcp->inst[1]) < 0 1492d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || arg_finish_change (tcp, &state)) 1493d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1494d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags &= ~TCB_BPTSET; 1495d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1496d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1497d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1498d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#else 1499d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 150076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 150176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermansetbpt(tcp) 150276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 150376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 150476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 150576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 15066d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if defined (SPARC) || defined (SPARC64) 150776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* We simply use the SunOS breakpoint code. */ 150876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15099ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 15106d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath unsigned long inst; 151176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA 0x30800000 /* ba,a 0 */ 151276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 151376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 151476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 151576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 151676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 151776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 151876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 151976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 152076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 15219ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tcp->baddr = regs.r_o7 + 8; 152276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 152376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0); 152476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if(errno) { 152576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 152676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 152776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 152876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 152976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 153076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * XXX - BRUTAL MODE ON 153176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We cannot set a real BPT in the child, since it will not be 153276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * traced at the moment it will reach the trap and would probably 153376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * die with a core dump. 153476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Thus, we are force our way in by taking out two instructions 153576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * and insert an eternal loop instead, in expectance of the SIGSTOP 153676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * generated by out PTRACE_ATTACH. 153776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Of cause, if we evaporate ourselves in the middle of all this... 153876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 153976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 15406d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath inst = LOOPA; 15416d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if defined (SPARC64) 15426d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath inst <<= 32; 15436d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath inst |= (tcp->inst[0] & 0xffffffffUL); 15446d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#endif 15456d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, inst); 154676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if(errno) { 154776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 154876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 154976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 155076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 155176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15526d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#else /* !SPARC && !SPARC64 */ 15538b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#ifdef IA64 15547b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (ia32) { 15557b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman# define LOOP 0x0000feeb 15567b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 15577b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "PANIC: bpt already set in pid %u\n", 15587b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->pid); 15597b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 15607b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 15617b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (upeek(tcp->pid, PT_CR_IIP, &tcp->baddr) < 0) 15627b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 15637b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (debug) 15647b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "[%d] setting bpt at %lx\n", 15657b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->pid, tcp->baddr); 15667b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, 15677b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman (char *) tcp->baddr, 0); 15687b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (errno) { 15697b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 15707b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 15717b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 15727b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 15737b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (errno) { 15747b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 15757b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 15767b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 15777b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->flags |= TCB_BPTSET; 15787b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } else { 15797b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman /* 15807b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * Our strategy here is to replace the bundle that 15817b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * contained the clone() syscall with a bundle of the 15827b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * form: 15837b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * 15847b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * { 1: br 1b; br 1b; br 1b } 15857b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * 15867b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * This ensures that the newly forked child will loop 15877b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * endlessly until we've got a chance to attach to it. 15887b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman */ 15898b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman# define LOOP0 0x0000100000000017 15908b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman# define LOOP1 0x4000000000200000 15918b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman unsigned long addr, ipsr; 15928b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid_t pid; 15938b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 15948b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid = tcp->pid; 15958b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(pid, PT_CR_IPSR, &ipsr) < 0) 15968b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 15978b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(pid, PT_CR_IIP, &addr) < 0) 15988b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 15997b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman /* store "ri" in low two bits */ 16007b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->baddr = addr | ((ipsr >> 41) & 0x3); 16018b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 16028b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman errno = 0; 16037b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0, 16047b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 0); 16057b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8, 16067b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 0); 16078b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (errno) { 16088b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 16098b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 16108b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 16118b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 16128b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman errno = 0; 16138b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0); 16148b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1); 16158b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (errno) { 16168b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 16178b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 16188b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 16198b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tcp->flags |= TCB_BPTSET; 16208b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 16218b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#else /* !IA64 */ 162276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16230e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#if defined (I386) || defined(X86_64) 162476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP 0x0000feeb 162576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K) 162676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP 0x60fe0000 162776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA) 16284dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0xc3ffffff 162976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC) 16301e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath#define LOOP 0x48000000 163176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined(ARM) 16329a8a37f2b28d1c0d3f57951fd5aeeb96ff7d2f16Wichert Akkerman#define LOOP 0xEAFFFFFE 1633f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS) 16344dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0x1000ffff 16354dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390) 16364dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0xa7f40000 /* BRC 15,0 */ 163710a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#elif defined(S390X) 163810a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#define LOOP 0xa7f4000000000000UL /* BRC 15,0 */ 1639c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1640c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#define LOOP 0xe81f1ff7 /* b,l,n <loc>,r0 */ 1641ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1642ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#ifdef __LITTLE_ENDIAN__ 1643ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#define LOOP 0x0000affe 1644ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#else 1645ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#define LOOP 0xfeaf0000 1646ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#endif 164776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 164876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture 164976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 165076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 165176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 165276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid); 165376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 165476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 165576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined (I386) 165676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &tcp->baddr) < 0) 165776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 16580e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined (X86_64) 16590e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (upeek(tcp->pid, 8*RIP, &tcp->baddr) < 0) 16600e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return -1; 166176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K) 166276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &tcp->baddr) < 0) 166376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 166476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA) 166576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 166676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ARM) 166776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1668f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined (MIPS) 1669f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman return -1; /* FIXME: I do not know what i do - Flo */ 167076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC) 1671eb285359906700f46b22cf4f9911695034313736Roland McGrath if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &tcp->baddr) < 0) 167276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 167310a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#elif defined(S390) || defined(S390X) 16744dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman if (upeek(tcp->pid,PT_PSWADDR, &tcp->baddr) < 0) 16754dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman return -1; 1676c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1677c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (upeek(tcp->pid, PT_IAOQ0, &tcp->baddr) < 0) 1678c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return -1; 1679c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tcp->baddr &= ~0x03; 1680ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1681ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (upeek(tcp->pid, 4*REG_PC, &tcp->baddr) < 0) 1682ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman return -1; 168376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 168476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture 168576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 168676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 168776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr); 168876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0); 168976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 169076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 169176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 169276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 169376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 169476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 169576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 169676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 169776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 169876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 169976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17008b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#endif /* !IA64 */ 17016d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#endif /* SPARC || SPARC64 */ 170276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 170376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 170476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 170576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC /* This code is slightly sparc specific */ 170676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1707e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 170876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define BPT 0x91d02001 /* ta 1 */ 170976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP 0x10800000 /* ba 0 */ 171076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA 0x30800000 /* ba,a 0 */ 171176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define NOP 0x01000000 171276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if LOOPA 171376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[1] = {LOOPA}; 171476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 171576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[2] = {LOOP, NOP}; 171676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 171776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 171876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 171976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 172076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 172176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 172276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 172376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 172476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 172576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 172676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->baddr = regs.r_o7 + 8; 172776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr, 172876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof tcp->inst, (char *)tcp->inst) < 0) { 172976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_READTEXT, ...)"); 173076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 173176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 173276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 173476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * XXX - BRUTAL MODE ON 173576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We cannot set a real BPT in the child, since it will not be 173676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * traced at the moment it will reach the trap and would probably 173776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * die with a core dump. 173876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Thus, we are force our way in by taking out two instructions 173976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * and insert an eternal loop in stead, in expectance of the SIGSTOP 174076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * generated by out PTRACE_ATTACH. 174176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Of cause, if we evaporate ourselves in the middle of all this... 174276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 174376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 174476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof loopdeloop, (char *) loopdeloop) < 0) { 174576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)"); 174676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 174776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 174876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 174976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 175076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */ 175176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 175276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 175376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 175476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 175576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 175676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 175776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanclearbpt(tcp) 175876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 175976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 176076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 176176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 17620e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#if defined(I386) || defined(X86_64) 176376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long eip; 1764faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(POWERPC) 176576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 1766faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68K) 176776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 1768faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA) 176976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 1770c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1771c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman long iaoq; 1772ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1773ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman long pc; 1774faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* architecture */ 177576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17766d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if defined (SPARC) || defined (SPARC64) 177776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Again, we borrow the SunOS breakpoint code. */ 177876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 177976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 178076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 178176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 178276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 178376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 178476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if(errno) { 178576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 178676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 178776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 178876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 1789faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(IA64) 17907b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (ia32) { 17917b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman unsigned long addr; 17927b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 17937b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (debug) 17947b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 17957b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 17967b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 17977b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 17987b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 17997b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman errno = 0; 18007b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 18017b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (errno) { 18027b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 18037b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 18047b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 18057b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 18067b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 18077b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (upeek(tcp->pid, PT_CR_IIP, &addr) < 0) 18087b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 18097b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (addr != tcp->baddr) { 18107b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman /* The breakpoint has not been reached yet. */ 18117b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (debug) 18127b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, 18137b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 18147b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman addr, tcp->baddr); 18157b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return 0; 18167b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 18177b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } else { 18188b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman unsigned long addr, ipsr; 18198b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid_t pid; 18208b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 18218b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid = tcp->pid; 18228b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 18238b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(pid, PT_CR_IPSR, &ipsr) < 0) 18248b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 18258b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(pid, PT_CR_IIP, &addr) < 0) 18268b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 18278b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 18288b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman /* restore original bundle: */ 18298b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman errno = 0; 18308b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]); 18318b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]); 18328b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (errno) { 18338b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)"); 18348b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 18358b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 18368b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 18378b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman /* restore original "ri" in ipsr: */ 18388b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41); 18398b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman errno = 0; 18408b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr); 18418b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (errno) { 18428b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)"); 18438b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 18448b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 18458b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 18468b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 18478b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 18488b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (addr != (tcp->baddr & ~0x3)) { 18498b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman /* the breakpoint has not been reached yet. */ 18508b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (debug) 18518b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 18528b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman addr, tcp->baddr); 18538b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return 0; 18548b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 18558b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 18566d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#else /* !IA64 && !SPARC && !SPARC64 */ 185776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 185876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 185976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 186076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 186176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 186276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 186376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 186476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 186576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 186676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 186776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 186876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 186976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 187076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 187176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 187276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386 187376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &eip) < 0) 187476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 187576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (eip != tcp->baddr) { 187676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 187776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 187876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 187976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 188076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman eip, tcp->baddr); 188176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 188276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 18830e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined(X86_64) 18840e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (upeek(tcp->pid, 8*RIP, &eip) < 0) 18850e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return -1; 18860e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (eip != tcp->baddr) { 18870e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig /* The breakpoint has not been reached yet. */ 18880e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (debug) 18890e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig fprintf(stderr, 18900e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 18910e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig eip, tcp->baddr); 18920e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return 0; 18930e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig } 1894c792698a99b640e7d256e8692c992bd967f0c5b2Wichert Akkerman#elif defined(POWERPC) 1895eb285359906700f46b22cf4f9911695034313736Roland McGrath if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) 189676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 189776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 189876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 189976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 190076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 190176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 190276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 190376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1904faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68K) 190576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) 190676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 190776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 190876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 190976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 191076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 191176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 191276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 191376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1914faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA) 191576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, REG_PC, &pc) < 0) 191676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 191776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 191876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 191976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 192076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 192176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 192276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 192376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1924c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1925c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (upeek(tcp->pid, PT_IAOQ0, &iaoq) < 0) 1926c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return -1; 1927c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman iaoq &= ~0x03; 1928c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) { 1929c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman /* The breakpoint has not been reached yet. */ 1930c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (debug) 1931c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n", 1932c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman iaoq, tcp->baddr); 1933c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return 0; 1934c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman } 1935c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman iaoq = tcp->baddr | 3; 1936c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman /* We should be pointing at a 'ldi -1000,r1' in glibc, so it is 1937c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit 1938c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman * has no significant effect. 1939c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman */ 1940c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq); 1941c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq); 1942ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1943ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (upeek(tcp->pid, 4*REG_PC, &pc) < 0) 1944ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman return -1; 1945ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (pc != tcp->baddr) { 1946ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman /* The breakpoint has not been reached yet. */ 1947ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (debug) 1948ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 1949ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman pc, tcp->baddr); 1950ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman return 0; 1951ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman } 1952ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman 1953faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* arch */ 19546d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#endif /* !SPARC && !SPARC64 && !IA64 */ 195576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 195676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 195776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 195876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC 195976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 196076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA 1961e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 196276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 196376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 196476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 196576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 196676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 196776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 196876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 196976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof tcp->inst, (char *) tcp->inst) < 0) { 197076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)"); 197176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 197276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 197376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 197476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 197576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA 197676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 197776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Since we don't have a single instruction breakpoint, we may have 197876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * to adjust the program counter after removing the our `breakpoint'. 197976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 198076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 198176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbpt: ptrace(PTRACE_GETREGS, ...)"); 198276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 198376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 198476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((regs.r_pc < tcp->baddr) || 198576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (regs.r_pc > tcp->baddr + 4)) { 198676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet */ 198776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 198876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 198976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "NOTE: PC not at bpt (pc %#x baddr %#x)\n", 199076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc, tcp->parent->baddr); 199176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 199276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 199376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (regs.r_pc != tcp->baddr) 199476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 199576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n", 199676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc, tcp->baddr); 199776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 199876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc = tcp->baddr; 199976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) { 200076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbpt: ptrace(PTRACE_SETREGS, ...)"); 200176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 200276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 200376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LOOPA */ 200476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */ 200576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 200676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 200776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 200876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 200976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2010d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 2011d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 2012bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 201376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 201476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 201576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 201676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 201776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetex(pid, hdr) 201876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 201976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct exec *hdr; 202076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 202176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 202276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 202376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; n < sizeof *hdr; n += 4) { 202476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long res; 202576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(pid, uoff(u_exdata) + n, &res) < 0) 202676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 202776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(((char *) hdr) + n, &res, 4); 202876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 202976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) { 203076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n", 203176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_magic, hdr->a_toolversion, hdr->a_machtype); 203276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n", 203376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry); 203476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 203576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 203676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 203776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 203876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 203976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfixvfork(tcp) 204076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 204176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 204276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 204376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 204476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Change `vfork' in a freshly exec'ed dynamically linked 204576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * executable's (internal) symbol table to plain old `fork' 204676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 204776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 204876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct exec hdr; 204976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic dyn; 205076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic_2 ld; 205176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *strtab, *cp; 205276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 205376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getex(pid, &hdr) < 0) 205476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 205576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!hdr.a_dynamic) 205676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 205776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 205876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) { 205976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read DYNAMIC\n"); 206076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 206176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 206276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) { 206376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read link_dynamic_2\n"); 206476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 206576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 206676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) { 206746100d07257824da2ae1147da0324b5788c95501Roland McGrath fprintf(stderr, "out of memory\n"); 206876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 206976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 207076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 207176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 207276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 207376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 207476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 207576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 207676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[symbol: %s]\n", cp); 207776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cp += strlen(cp)+1; 207876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 207976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 208076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 208176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 208276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strcmp(cp, "_vfork") == 0) { 208376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 208476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "fixvfork: FOUND _vfork\n"); 208576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strcpy(cp, "_fork"); 208676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 208776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 208876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cp += strlen(cp)+1; 208976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 209076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cp < strtab + ld.ld_symb_size) 209176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 209276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Write entire symbol table back to avoid 209376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * memory alignment bugs in ptrace 209476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 209576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 209676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 209776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 209876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 209976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 210076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 210176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 210276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerr: 210376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 210476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 210576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 210676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 210776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 2108