util.c revision a503dcf82047ecf3d8c535406898f3059e424131
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; 19658372f52ac5f824be687c01bfc1db1ffb963f91eRoland McGrath if (tv->tv_usec >= 1000000) { 19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec++; 19876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec -= 1000000; 19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 20076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 20176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 20276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 20376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_sub(tv, a, b) 20476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b; 20576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 20676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec - b->tv_sec; 20776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec - b->tv_usec; 20876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (((long) tv->tv_usec) < 0) { 20976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec--; 21076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec += 1000000; 21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 21576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_div(tv, a, n) 21676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a; 21776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 21876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 21976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n; 22076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000; 22176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 22276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 22376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 22476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 22576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_mul(tv, a, n) 22676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a; 22776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 22876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 22976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec * n; 230fefdd97156bb2f86c5b6596dc7e28d954516b3edDmitry V. Levin tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000; 23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 234ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinconst char * 235ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinxlookup(const struct xlat *xlat, int val) 23676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 23776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (; xlat->str != NULL; xlat++) 23876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val == val) 23976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return xlat->str; 24076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 24176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 24376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 24476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Print entry in struct xlat table, if there. 24576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 24676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 247ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levinprintxval(const struct xlat *xlat, int val, const char *dflt) 24876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 249ab9008bc085848e6c898cd38b7415baa161c5890Dmitry V. Levin const char *str = xlookup(xlat, val); 25076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 25176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 25276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", str); 25376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 25476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#x /* %s */", val, dflt); 25576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 25676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 25776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 25876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interpret `xlat' as an array of flags 25976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * print the entries whose bits are on in `flags' 26076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * return # of flags printed. 26176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 26276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 26376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanaddflags(xlat, flags) 264d9f816f60457930af27349fac3d23b3b78338036Roland McGrathconst struct xlat *xlat; 26576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags; 26676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 26776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 26876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 26976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 27076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 27176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%s", xlat->str); 27276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 27376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 27476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 27576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 27676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags) { 27776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%#x", flags); 27876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 27976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 28076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 28176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 28276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 28376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 284b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrathprintflags(xlat, flags, dflt) 285d9f816f60457930af27349fac3d23b3b78338036Roland McGrathconst struct xlat *xlat; 28676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags; 287b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrathconst char *dflt; 28876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 28976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 29076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *sep; 29176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 29276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags == 0 && xlat->val == 0) { 29376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", xlat->str); 29476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 29576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 29676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 29776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = ""; 29876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 29976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 30076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s%s", sep, xlat->str); 30176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 30276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = "|"; 30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 30476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 306b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath 307b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (n) { 308b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (flags) { 309b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("%s%#x", sep, flags); 310b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath n++; 311b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } 312b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } else { 313b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (flags) { 314b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("%#x", flags); 315b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (dflt) 316b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf(" /* %s */", dflt); 317b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } else { 318b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath if (dflt) 319b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath tprintf("0"); 320b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath } 32176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 322b2dee13345a62c80a677f3342cd525d611fbc632Roland McGrath 32376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 32476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 32576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 32676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 32776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintnum(tcp, addr, fmt) 32876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 32976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 33076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *fmt; 33176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 332eb285359906700f46b22cf4f9911695034313736Roland McGrath long num; 33376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 33676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 33776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 33876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, addr, &num) < 0) { 33976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 34076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 34176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 34276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("["); 34376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf(fmt, num); 34476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("]"); 34576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 34676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 3476bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathvoid 3489814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathprintnum_int(tcp, addr, fmt) 3499814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathstruct tcb *tcp; 3509814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathlong addr; 3519814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathchar *fmt; 3529814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath{ 3539814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath int num; 3549814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath 3559814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath if (!addr) { 3569814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("NULL"); 3579814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath return; 3589814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath } 3599814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath if (umove(tcp, addr, &num) < 0) { 3609814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("%#lx", addr); 3619814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath return; 3629814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath } 3639814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("["); 3649814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf(fmt, num); 3659814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath tprintf("]"); 3669814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath} 3679814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrath 3689814a94bd10aea81b8bcb29e2ba167b09d70cedbRoland McGrathvoid 3696bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathprintuid(text, uid) 3706bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathconst char *text; 3716bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrathunsigned long uid; 3726bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath{ 3736bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath tprintf("%s", text); 3746bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath tprintf((uid == -1) ? "%ld" : "%lu", uid); 3756bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath} 3766bc1220fe3f10e16919f182ad394c35619fe2e7fRoland McGrath 37776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic char path[MAXPATHLEN + 1]; 37876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 379a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrathstatic void 38076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstring_quote(str) 381a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrathconst char *str; 38276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char buf[2 * MAXPATHLEN + 1]; 38476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s; 38576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 38676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!strpbrk(str, "\"\'\\")) { 38776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("\"%s\"", str); 38876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 38976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 39076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (s = buf; *str; str++) { 39176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (*str) { 39276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\"': case '\'': case '\\': 39376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = *str; break; 39476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 39576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = *str; break; 39676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 39776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 39876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s = '\0'; 39976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("\"%s\"", buf); 40076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 40176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 40276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 40376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpath(tcp, addr) 40476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 40576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 40676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 407371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath if (addr == 0) 408371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath tprintf("NULL"); 409371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath else if (umovestr(tcp, addr, MAXPATHLEN, path) < 0) 41076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 41176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 41276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman string_quote(path); 41376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 41476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 41576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 41676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 41776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpathn(tcp, addr, n) 41876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 41976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 42076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 42176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 422b15c4e47ff5b2b0dd71fa10472eafb1d5abf4c5fRoland McGrath if (n >= sizeof path) 423b15c4e47ff5b2b0dd71fa10472eafb1d5abf4c5fRoland McGrath n = sizeof path - 1; 424b15c4e47ff5b2b0dd71fa10472eafb1d5abf4c5fRoland McGrath 425371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath if (addr == 0) 426371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath tprintf("NULL"); 427371ed8fceca7e2812a5edbaab2db2cce966dc0e8Roland McGrath else if (umovestr(tcp, addr, n, path) < 0) 42876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 42976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 43076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman path[n] = '\0'; 43176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman string_quote(path); 43276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 43376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 43476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 43576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 43676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintstr(tcp, addr, len) 43776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 43876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 43976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 44076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 44176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static unsigned char *str = NULL; 44276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char *outstr; 44376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, n, c, usehex; 44476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s, *outend; 445a503dcf82047ecf3d8c535406898f3059e424131Roland McGrath int trunc; 44676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 44776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 44876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 44976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 45076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 45176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!str) { 452a503dcf82047ecf3d8c535406898f3059e424131Roland McGrath if ((str = malloc(max_strlen + 1)) == NULL 453779c466c0fdb4a0e4039d5ed407d1e6f61c23437Roland McGrath || (outstr = malloc(4*max_strlen 454779c466c0fdb4a0e4039d5ed407d1e6f61c23437Roland McGrath + sizeof "\"\"...")) == NULL) { 45546100d07257824da2ae1147da0324b5788c95501Roland McGrath fprintf(stderr, "out of memory\n"); 45676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 45776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 45876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 45976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 460779c466c0fdb4a0e4039d5ed407d1e6f61c23437Roland McGrath outend = outstr + max_strlen * 4; 46176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0) { 462a503dcf82047ecf3d8c535406898f3059e424131Roland McGrath n = max_strlen + 1; 46376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umovestr(tcp, addr, n, (char *) str) < 0) { 46476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 46576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 46676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 46776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 46876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 469a503dcf82047ecf3d8c535406898f3059e424131Roland McGrath n = MIN(len, max_strlen + 1); 47076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, addr, n, (char *) str) < 0) { 47176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 47276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 47376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 47476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 47576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 476a503dcf82047ecf3d8c535406898f3059e424131Roland McGrath trunc = n > max_strlen && str[--n] != 0; 477a503dcf82047ecf3d8c535406898f3059e424131Roland McGrath 47876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usehex = 0; 47976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xflag > 1) 48076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usehex = 1; 48176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (xflag) { 48276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 48376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman c = str[i]; 48476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0 && c == '\0') 48576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 48676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!isprint(c) && !isspace(c)) { 48776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usehex = 1; 48876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 48976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 49076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 49176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 49276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 49376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s = outstr; 49476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\"'; 49576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 49676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (usehex) { 49776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 49876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman c = str[i]; 49976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0 && c == '\0') 50076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 50176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, "\\x%02x", c); 50276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 4; 50376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (s > outend) 50476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 50576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 50676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 50776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 50876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 50976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman c = str[i]; 51076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0 && c == '\0') 51176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 51276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (c) { 51376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\"': case '\'': case '\\': 51476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = c; break; 51576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\f': 51676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'f'; break; 51776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\n': 51876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'n'; break; 51976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\r': 52076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'r'; break; 52176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\t': 52276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 't'; break; 52376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\v': 52476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'v'; break; 52576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 52676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isprint(c)) 52776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = c; 52876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (i < n - 1 && isdigit(str[i + 1])) { 52976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, "\\%03o", c); 53076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 4; 53176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 53276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 53376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, "\\%o", c); 53476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += strlen(s); 53576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 53676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 53776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 53876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (s > outend) 53976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 54076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 54176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 54276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 54376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\"'; 544a503dcf82047ecf3d8c535406898f3059e424131Roland McGrath if (i < len || (len < 0 && (trunc || s > outend))) { 54576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '.'; *s++ = '.'; *s++ = '.'; 54676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 54776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s = '\0'; 54876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", outstr); 54976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 55076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 5511d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H 5521d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesvoid 5531d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesdumpiov(tcp, len, addr) 5541d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesstruct tcb * tcp; 5551d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesint len; 5561d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hugheslong addr; 5571d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes{ 5584ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 5594ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin union { 5604ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin struct { u_int32_t base; u_int32_t len; } *iov32; 5614ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin struct { u_int64_t base; u_int64_t len; } *iov64; 5624ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin } iovu; 5634ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov iovu.iov64 5644ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define sizeof_iov \ 5654ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin (personality_wordsize[current_personality] == 4 \ 5664ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64)) 5674ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_base(i) \ 5684ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin (personality_wordsize[current_personality] == 4 \ 5694ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin ? (u_int64_t) iovu.iov32[i].base : iovu.iov64[i].base) 5704ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_len(i) \ 5714ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin (personality_wordsize[current_personality] == 4 \ 5724ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin ? (u_int64_t) iovu.iov32[i].len : iovu.iov64[i].len) 5734ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#else 5741d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes struct iovec *iov; 5754ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define sizeof_iov sizeof(*iov) 5764ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_base(i) iov[i].iov_base 5774ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#define iov_iov_len(i) iov[i].iov_len 5784ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#endif 5791d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes int i; 580aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath unsigned long size; 5811d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 5824ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin size = sizeof_iov * (unsigned long) len; 5834ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin if (size / sizeof_iov != len 5844ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin || (iov = malloc(size)) == NULL) { 585aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath fprintf(stderr, "out of memory\n"); 5861d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes return; 5871d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 588aa524c88c49814863cb7f19e5c8a8eeca6ce22feRoland McGrath if (umoven(tcp, addr, size, (char *) iov) >= 0) { 5891d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes for (i = 0; i < len; i++) { 5901d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes /* include the buffer number to make it easy to 5911d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes * match up the trace with the source */ 5921d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes tprintf(" * %lu bytes in buffer %d\n", 5934ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin (unsigned long)iov_iov_len(i), i); 5944ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin dumpstr(tcp, (long) iov_iov_base(i), 5954ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin iov_iov_len(i)); 5961d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 5971d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 5981d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes free((char *) iov); 5994ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef sizeof_iov 6004ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov_iov_base 6014ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov_iov_len 6024ebb4e3d312bb8215f4eea9130cce6bb8bdb972fDmitry V. Levin#undef iov 6031d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes} 6041d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 6051d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 60676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 60776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandumpstr(tcp, addr, len) 60876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 60976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 61076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 61176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 61276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int strsize = -1; 61376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static unsigned char *str; 61476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char outstr[80]; 61576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s; 61676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 61776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 61876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strsize < len) { 61976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 62076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(str); 62176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((str = malloc(len)) == NULL) { 62246100d07257824da2ae1147da0324b5788c95501Roland McGrath fprintf(stderr, "out of memory\n"); 62376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 62476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 62576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strsize = len; 62676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 62876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, addr, len, (char *) str) < 0) 62976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 63076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 63176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < len; i += 16) { 63276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s = outstr; 63376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " | %05x ", i); 63476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 9; 63576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 63676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 63776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 63876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 63976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " %02x", str[i + j]); 64076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 3; 64176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 64276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 64376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; *s++ = ' '; 64476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 64576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 64676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; 64776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 64876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 64976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 65076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 65176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isprint(str[i + j])) 65276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = str[i + j]; 65376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 65476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '.'; 65576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 65676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 65776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 65876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 65976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s |\n", outstr); 66076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 66176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 66276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 66376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PAGMASK (~(PAGSIZ - 1)) 66476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 66576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * move `len' bytes of data from process `pid' 66676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * at address `addr' to our space at `laddr' 66776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 66876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 66976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumoven(tcp, addr, len, laddr) 67076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 67176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 67276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 67376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 67476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 67576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 67676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 67776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 67876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 6795daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 68076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 68176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 68276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 68376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 68476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 68576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 68676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 68776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 68876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 68976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 69076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 69176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 6925daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 69376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 69476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 69576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 6965daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman /* But if not started, we had a bogus address. */ 69776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("ptrace: umoven"); 69876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 69976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 7005daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 70176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 70276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 70376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 70476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 70576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 70676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 70776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 7085daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 70976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 71076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 71176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 7124db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath if (addr != 0) 7134db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath perror("ptrace: umoven"); 71476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 71576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 7165daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 71776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 71876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 71976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 72076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 72176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 72276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 72376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 72476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 72576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 72676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 72776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 72876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 72976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 73076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 73176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 73276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 73376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 73476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 73576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 73676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 73776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 73876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umoven"); 73976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 74076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 74176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 74276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 74376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 74576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 74876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umoven"); 74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 75176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 75276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 75376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !oldway */ 75576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 75676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 75776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 75876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, PAGSIZ); 75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 76076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_READDATA, pid, 76176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (char *) addr, len, laddr) < 0) { 76276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umoven: ptrace(PTRACE_READDATA, ...)"); 76376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman abort(); 76476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 76576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 76676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len -= n; 76776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += n; 76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman laddr += n; 76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 77076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !oldway */ 77176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 77276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 773bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 774ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 775aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd_as; 7769ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 777aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd; 77876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 779aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes lseek(fd, addr, SEEK_SET); 780aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (read(fd, laddr, len) == -1) 78176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 782bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 78376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 78476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 78576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 78676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 78776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 78876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * like `umove' but make the additional effort of looking 78976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * for a terminating zero byte. 79076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 79176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 79276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumovestr(tcp, addr, len, laddr) 79376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 79476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 79576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 79676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 79776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 798bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 799aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#ifdef HAVE_MP_PROCFS 800aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd_as; 801aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#else 802aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd; 803aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#endif 804aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes /* Some systems (e.g. FreeBSD) can be upset if we read off the 805aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes end of valid memory, avoid this by trying to read up 806aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes to page boundaries. But we don't know what a page is (and 807aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes getpagesize(2) (if it exists) doesn't necessarily return 808aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes hardware page size). Assume all pages >= 1024 (a-historical 809aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes I know) */ 810aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 811aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int page = 1024; /* How to find this? */ 812aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int move = page - (addr & (page - 1)); 813aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int left = len; 814aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 815aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes lseek(fd, addr, SEEK_SET); 816aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 817aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes while (left) { 818aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (move > left) move = left; 8199cecf7f8d6115a247be7186013857270b2d588d5John Hughes if ((move = read(fd, laddr, move)) <= 0) 820aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return left != len ? 0 : -1; 821aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (memchr (laddr, 0, move)) break; 822aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes left -= move; 823aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes laddr += move; 824aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes addr += move; 825aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes move = page; 826aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes } 827bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 8285daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 82976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 83076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, n, m; 83176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 83276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 83376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 83476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 83576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 83676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 83776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 83876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 83976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 84076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 84176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 84276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 8435daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 84476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 84576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 84676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 84776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umovestr"); 84876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 84976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 8505daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 85176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len)); 85276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (n & (sizeof(long) - 1)) 85376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[n++] == '\0') 85476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 85576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 85676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 85776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 85876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 85976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 86076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 8615daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 86276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 86376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 86476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 86576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umovestr"); 86676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 86776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 8685daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 86976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 87076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < sizeof(long); i++) 87176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[i] == '\0') 87276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 87376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 87476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 87576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 876bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 877aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return 0; 87876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 87976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 88076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 8816d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if !defined (SPARC) && !defined(SPARC64) 88276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITETEXT 101 88376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITEDATA 102 8846d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#endif /* !SPARC && !SPARC64 */ 88576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 88676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 88776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 88876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 88976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 89076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanuload(cmd, pid, addr, len, laddr) 89176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint cmd; 89276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 89376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 89476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 89576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 89676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 89776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 89876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 89976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 90076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 90176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, PAGSIZ); 90276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 90376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) { 90476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: ptrace(PTRACE_WRITE, ...)"); 90576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 90676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 90776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len -= n; 90876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += n; 90976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman laddr += n; 91076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 91176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 91276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int peek, poke; 91376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 91476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 91576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 91676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 91776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 91876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 91976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cmd == PTRACE_WRITETEXT) { 92076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKTEXT; 92176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKETEXT; 92276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 92376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 92476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKDATA; 92576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKEDATA; 92676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 92776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 92876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 92976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 93076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); 93176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 93276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(peek, pid, (char *) addr, 0); 93376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 93476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: POKE"); 93576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 93676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 93776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len)); 93876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(poke, pid, (char *)addr, u.val) < 0) { 93976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: POKE"); 94076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 94176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 94276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 94376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 94476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 94576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < sizeof(long)) 94676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(peek, pid, (char *) addr, 0); 94776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(u.x, laddr, m = MIN(sizeof(long), len)); 94876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(poke, pid, (char *) addr, u.val) < 0) { 94976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: POKE"); 95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 95176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 95276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 95376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 95476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 95576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 95676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 95776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 95876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 95976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantload(pid, addr, len, laddr) 96076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 96176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr, len; 96276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 96376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 96476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return uload(PTRACE_WRITETEXT, pid, addr, len, laddr); 96576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 96676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 96776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 96876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandload(pid, addr, len, laddr) 96976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 97076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr; 97176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 97276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 97376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 97476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return uload(PTRACE_WRITEDATA, pid, addr, len, laddr); 97576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 97676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 97776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 97876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 979bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 98076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 98176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 98276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanupeek(pid, off, res) 98376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 98476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong off; 98576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong *res; 98676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 98976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE 99076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman { 99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int is_sun4m = -1; 99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct utsname name; 99376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 99476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Round up the usual suspects. */ 99576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m == -1) { 99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (uname(&name) < 0) { 99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("upeek: uname?"); 99876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 99976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 100076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman is_sun4m = strcmp(name.machine, "sun4m") == 0; 100176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) { 1002d9f816f60457930af27349fac3d23b3b78338036Roland McGrath extern const struct xlat struct_user_offsets[]; 1003d9f816f60457930af27349fac3d23b3b78338036Roland McGrath const struct xlat *x; 100476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 100576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (x = struct_user_offsets; x->str; x++) 100676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman x->val += 1024; 100776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 100876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 100976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) 101076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman off += 1024; 101176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 101276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 101376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 101476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman val = ptrace(PTRACE_PEEKUSER, pid, (char *) off, 0); 101576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (val == -1 && errno) { 10161e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath char buf[60]; 10170e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)",pid,off); 10181e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath perror(buf); 101976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 102076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 102176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *res = val; 102276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 102376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 102476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1025bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 102676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1027a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrath#if 0 102876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong 102976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetpc(tcp) 103076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 103176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 103276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 103376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 103476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 1035f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#if defined(I386) 103676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &pc) < 0) 103776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 10380e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined(X86_64) 10390e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (upeek(tcp->pid, 8*RIP, &pc) < 0) 10400e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return -1; 10418b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#elif defined(IA64) 10428b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(tcp->pid, PT_B0, &pc) < 0) 10438b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 1044f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ARM) 104576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*15, &pc) < 0) 104676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1047f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(POWERPC) 1048eb285359906700f46b22cf4f9911695034313736Roland McGrath if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) 104976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 105084fa923c15aa537b666d26694549091e9b9a5ddbRoland McGrath#elif defined(M68K) 105176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) 105276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1053f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ALPHA) 105476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, REG_PC, &pc) < 0) 105576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1056f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS) 1057f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman if (upeek(tcp->pid, REG_EPC, &pc) < 0) 1058f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman return -1; 10596d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#elif defined(SPARC) || defined(SPARC64) 10609ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 106176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) 106276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 10639ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman pc = regs.r_pc; 106410a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#elif defined(S390) || defined(S390X) 10654dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman if(upeek(tcp->pid,PT_PSWADDR,&pc) < 0) 106610a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig return -1; 1067c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1068c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) 1069c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return -1; 1070ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1071ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (upeek(tcp->pid, 4*REG_PC ,&pc) < 0) 1072ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman return -1; 1073f5a477788ed49d3c15e2080c03d30d4beaeefee3Roland McGrath#elif defined(SH64) 1074e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath if (upeek(tcp->pid, REG_PC ,&pc) < 0) 1075e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath return -1; 10767a0b649aeace5c1e1efe4a1d7b1ae6e3a87e0d44Wichert Akkerman#endif 107776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pc; 107876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 107976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 108076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 108176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 108276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Return current program counter for `pid' 108376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Assumes PC is never 0xffffffff 108476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 108576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct regs regs; 108676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 108776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 108876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("getpc: ptrace(PTRACE_GETREGS, ...)"); 108976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 109076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 109176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return regs.r_pc; 109276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 109376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 109476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 109576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* XXX */ 109676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 109776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */ 109876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1099bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1100bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct reg regs; 1101bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 1102bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return regs.r_eip; 1103bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 110476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 1105a4d4853f679014799a6608cc8114e6ce7f37ae89Roland McGrath#endif 110676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 110776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 110876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintcall(tcp) 110976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 111076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 11117a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath#define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \ 11127a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath sizeof(long) == 8 ? "[????????????????] " : \ 11137a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath NULL /* crash */) 111476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 111576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 111676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386 111776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long eip; 111876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 111976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &eip) < 0) { 11207a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 112176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 112276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 112376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", eip); 1124eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath 1125eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath#elif defined(S390) || defined(S390X) 1126eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath long psw; 1127eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath if(upeek(tcp->pid,PT_PSWADDR,&psw) < 0) { 11287a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 1129eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath return; 1130eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath } 1131eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath#ifdef S390 1132eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath tprintf("[%08lx] ", psw); 1133eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath#elif S390X 1134eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath tprintf("[%16lx] ", psw); 1135eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath#endif 1136eac26fc53eaf2cd52c1c531d1d3817a66b8b2180Roland McGrath 11370e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined(X86_64) 11380e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig long rip; 11390e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig 11400e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (upeek(tcp->pid, 8*RIP, &rip) < 0) { 11417a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 11420e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return; 11430e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig } 11440e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig tprintf("[%16lx] ", rip); 1145ef388689610fa17df1d3001face8057b411a2e26Roland McGrath#elif defined(IA64) 11468b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman long ip; 11478b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 11488b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(tcp->pid, PT_B0, &ip) < 0) { 11497a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 11508b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return; 11518b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 11528b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tprintf("[%08lx] ", ip); 1153faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(POWERPC) 115476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 115576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1156eb285359906700f46b22cf4f9911695034313736Roland McGrath if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) { 115776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 115876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 115976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 116076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 116184fa923c15aa537b666d26694549091e9b9a5ddbRoland McGrath#elif defined(M68K) 116276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 116376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 116476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) { 116576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 116676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 116776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 116876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 1169faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA) 117076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 117176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 117276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, REG_PC, &pc) < 0) { 11737a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath tprintf ("[????????????????] "); 117476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 117576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 117676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 11776d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#elif defined(SPARC) || defined(SPARC64) 11789ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 117976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) { 11807a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 118176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 118276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 11839ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tprintf("[%08lx] ", regs.r_pc); 1184c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1185c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman long pc; 1186c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman 1187c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) { 1188c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tprintf ("[????????] "); 1189c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return; 1190c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman } 1191c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tprintf("[%08lx] ", pc); 119275c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman#elif defined(MIPS) 119375c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman long pc; 119475c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman 119575c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman if (upeek(tcp->pid, REG_EPC, &pc) < 0) { 119675c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman tprintf ("[????????] "); 119775c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman return; 119875c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman } 119975c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman tprintf("[%08lx] ", pc); 1200ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1201ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman long pc; 1202ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman 1203ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (upeek(tcp->pid, 4*REG_PC, &pc) < 0) { 1204ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman tprintf ("[????????] "); 1205ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman return; 1206ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman } 1207ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman tprintf("[%08lx] ", pc); 1208f5a477788ed49d3c15e2080c03d30d4beaeefee3Roland McGrath#elif defined(SH64) 1209e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath long pc; 1210e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath 1211e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath if (upeek(tcp->pid, REG_PC, &pc) < 0) { 12127a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath tprintf ("[????????????????] "); 1213e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath return; 1214e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath } 1215e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath tprintf("[%08lx] ", pc); 1216ef388689610fa17df1d3001face8057b411a2e26Roland McGrath#elif defined(ARM) 1217ef388689610fa17df1d3001face8057b411a2e26Roland McGrath long pc; 1218e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath 1219ef388689610fa17df1d3001face8057b411a2e26Roland McGrath if (upeek(tcp->pid, 4*15, &pc) < 0) { 12207a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 1221ef388689610fa17df1d3001face8057b411a2e26Roland McGrath return; 1222ef388689610fa17df1d3001face8057b411a2e26Roland McGrath } 1223ef388689610fa17df1d3001face8057b411a2e26Roland McGrath tprintf("[%08lx] ", pc); 1224faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* !architecture */ 122576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 122676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 122776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 122876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct regs regs; 122976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 123076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 123176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("printcall: ptrace(PTRACE_GETREGS, ...)"); 12327a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 123376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 123476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 123576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08x] ", regs.r_o7); 123676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 123776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 123876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 123976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* XXX */ 12407a91883b32776a7fc8255ddbcf2d1781be9e2c2eRoland McGrath PRINTBADPC; 124176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 124276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1243bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1244bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct reg regs; 1245bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 1246bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tprintf("[%08x] ", regs.r_eip); 1247bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 124876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 124976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1250bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 125176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1252d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#if defined LINUX 1253d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1254d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#include <sys/syscall.h> 1255d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifndef CLONE_PTRACE 1256d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define CLONE_PTRACE 0x00002000 1257d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 125876989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath#ifndef CLONE_STOPPED 125976989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath# define CLONE_STOPPED 0x02000000 126076989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath#endif 1261d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1262d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef IA64 1263d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 126408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath/* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32 126508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath subsystem has them for x86... */ 126608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath#define SYS_fork 2 126708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath#define SYS_vfork 190 126808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 1269d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef unsigned long *arg_setup_state; 1270d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1271d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1272d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGratharg_setup(struct tcb *tcp, arg_setup_state *state) 1273d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1274d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath unsigned long *bsp, cfm, sof, sol; 1275d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 127608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) 127708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return 0; 127808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 1279d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) < 0) 1280d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1281d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (upeek(tcp->pid, PT_CFM, (long *) &cfm) < 0) 1282d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1283d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1284d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sof = (cfm >> 0) & 0x7f; 1285d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sol = (cfm >> 7) & 0x7f; 1286d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath bsp = ia64_rse_skip_regs(bsp, -sof + sol); 1287d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1288d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath *state = bsp; 1289d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1290d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1291d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1292d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_finish_change(tcp, state) 0 1293d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1294d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef SYS_fork 1295d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1296d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathget_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp) 1297d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 129808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int ret; 129908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 130008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) 130108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ret = upeek (tcp->pid, PT_R11, valp); 130208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath else 130308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ret = umoven (tcp, 130408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath (unsigned long) ia64_rse_skip_regs(*state, 0), 130508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath sizeof(long), (void *) valp); 130608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return ret; 1307d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1308d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1309d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1310d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathget_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp) 1311d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 131208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int ret; 131308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 131408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) 131508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ret = upeek (tcp->pid, PT_R9, valp); 131608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath else 131708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ret = umoven (tcp, 131808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath (unsigned long) ia64_rse_skip_regs(*state, 1), 131908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath sizeof(long), (void *) valp); 132008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath return ret; 1321d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1322d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 1323d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1324d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1325d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg0 (struct tcb *tcp, arg_setup_state *state, long val) 1326d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 132708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int req = PTRACE_POKEDATA; 132808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath void *ap; 132908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 133008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) { 133108267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = (void *) (intptr_t) PT_R11; /* r11 == EBX */ 133208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath req = PTRACE_POKEUSER; 133308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath } else 133408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = ia64_rse_skip_regs(*state, 0); 1335d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath errno = 0; 133608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ptrace(req, tcp->pid, ap, val); 1337d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return errno ? -1 : 0; 1338d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1339d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1340d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1341d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg1 (struct tcb *tcp, arg_setup_state *state, long val) 1342d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 134308267b8d6703c23332e39b1296e10e327196acb3Roland McGrath int req = PTRACE_POKEDATA; 134408267b8d6703c23332e39b1296e10e327196acb3Roland McGrath void *ap; 134508267b8d6703c23332e39b1296e10e327196acb3Roland McGrath 134608267b8d6703c23332e39b1296e10e327196acb3Roland McGrath if (ia32) { 134708267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = (void *) (intptr_t) PT_R9; /* r9 == ECX */ 134808267b8d6703c23332e39b1296e10e327196acb3Roland McGrath req = PTRACE_POKEUSER; 134908267b8d6703c23332e39b1296e10e327196acb3Roland McGrath } else 135008267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ap = ia64_rse_skip_regs(*state, 1); 1351d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath errno = 0; 135208267b8d6703c23332e39b1296e10e327196acb3Roland McGrath ptrace(req, tcp->pid, ap, val); 1353d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return errno ? -1 : 0; 1354d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1355d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 13566d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#elif defined (SPARC) || defined (SPARC64) 1357d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1358d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef struct regs arg_setup_state; 1359d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1360d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_setup(tcp, state) \ 1361d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0)) 1362d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_finish_change(tcp, state) \ 1363d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0)) 1364d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1365d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0) 1366d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0) 1367d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define set_arg0(tcp, state, val) ((state)->r_o0 = (val), 0) 1368d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define set_arg1(tcp, state, val) ((state)->r_o1 = (val), 0) 1369e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg0(tcp, state, val) 0 1370d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1371d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#else 1372d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1373d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# if defined S390 || defined S390X 13747b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath/* Note: this is only true for the `clone' system call, which handles 13757b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath arguments specially. We could as well say that its first two arguments 13767b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath are swapped relative to other architectures, but that would just be 13777b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath another #ifdef in the calls. */ 13787b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath# define arg0_offset PT_GPR3 13797b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath# define arg1_offset PT_ORIGGPR2 13807b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath# define restore_arg0(tcp, state, val) ((void) (state), 0) 13817b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath# define restore_arg1(tcp, state, val) ((void) (state), 0) 1382c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath# define arg0_index 1 1383c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath# define arg1_index 0 1384d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# elif defined (ALPHA) || defined (MIPS) 1385d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg0_offset REG_A0 1386d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg1_offset (REG_A0+1) 1387d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# elif defined (POWERPC) 1388eb285359906700f46b22cf4f9911695034313736Roland McGrath# define arg0_offset (sizeof(unsigned long)*PT_R3) 1389eb285359906700f46b22cf4f9911695034313736Roland McGrath# define arg1_offset (sizeof(unsigned long)*PT_R4) 13907b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath# define restore_arg0(tcp, state, val) ((void) (state), 0) 1391d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# elif defined (HPPA) 1392d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg0_offset PT_GR26 1393d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg1_offset (PT_GR26-4) 13947f33cc3eb5ead7a79cae8c586e40d2f8b573eec1Roland McGrath# elif defined (X86_64) 13957f33cc3eb5ead7a79cae8c586e40d2f8b573eec1Roland McGrath# define arg0_offset ((long)(8*(current_personality ? RBX : RDI))) 13967f33cc3eb5ead7a79cae8c586e40d2f8b573eec1Roland McGrath# define arg1_offset ((long)(8*(current_personality ? RCX : RSI))) 1397ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath# elif defined (SH) 1398ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath# define arg0_offset (4*(REG_REG0+4)) 1399ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath# define arg1_offset (4*(REG_REG0+5)) 1400f5a477788ed49d3c15e2080c03d30d4beaeefee3Roland McGrath# elif defined (SH64) 1401e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath /* ABI defines arg0 & 1 in r2 & r3 */ 1402e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath# define arg0_offset (REG_OFFSET+16) 1403e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath# define arg1_offset (REG_OFFSET+24) 1404e1e584b8fa0d97caad461f82a5427cd37d6327f3Roland McGrath# define restore_arg0(tcp, state, val) 0 1405d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# else 1406d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg0_offset 0 1407d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg1_offset 4 1408ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath# if defined ARM 1409e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg0(tcp, state, val) 0 1410e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# endif 1411d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# endif 1412d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1413d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef int arg_setup_state; 1414d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1415d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_setup(tcp, state) (0) 1416d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_finish_change(tcp, state) 0 1417d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg0(tcp, cookie, valp) \ 1418d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath (upeek ((tcp)->pid, arg0_offset, (valp))) 1419d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg1(tcp, cookie, valp) \ 1420d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath (upeek ((tcp)->pid, arg1_offset, (valp))) 1421d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1422d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1423d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg0 (struct tcb *tcp, void *cookie, long val) 1424d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1425ca85b97c9cea63db45e59a345218b902936b693dRoland McGrath return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val); 1426d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1427d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1428d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1429d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg1 (struct tcb *tcp, void *cookie, long val) 1430d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1431d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val); 1432d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1433d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1434d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 1435d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1436e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#ifndef restore_arg0 1437e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val)) 1438e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#endif 1439e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#ifndef restore_arg1 1440e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val)) 1441e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#endif 1442d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 144390d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath#ifndef arg0_index 144490d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath# define arg0_index 0 144590d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath# define arg1_index 1 144690d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath#endif 144790d0afd72811fa149d66b9c6b59d0ebcbf9aba6bRoland McGrath 1448d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint 1449d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathsetbpt(tcp) 1450d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstruct tcb *tcp; 1451d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1452d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath extern int change_syscall(struct tcb *, int); 1453d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath arg_setup_state state; 1454d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1455d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (tcp->flags & TCB_BPTSET) { 1456d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1457d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1458d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath } 1459d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 146076989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath switch (known_scno(tcp)) { 14619383c6c539af09303efe0a16dea55363b095f66eRoland McGrath#ifdef SYS_vfork 14629383c6c539af09303efe0a16dea55363b095f66eRoland McGrath case SYS_vfork: 14639383c6c539af09303efe0a16dea55363b095f66eRoland McGrath#endif 1464d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef SYS_fork 1465d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_fork: 14669b0982b5d3b84c845192ad8b7ad822f81cf4743aRoland McGrath#endif 14679b0982b5d3b84c845192ad8b7ad822f81cf4743aRoland McGrath#if defined SYS_fork || defined SYS_vfork 1468d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (arg_setup (tcp, &state) < 0 1469d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || get_arg0 (tcp, &state, &tcp->inst[0]) < 0 1470d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || get_arg1 (tcp, &state, &tcp->inst[1]) < 0 1471d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || change_syscall(tcp, SYS_clone) < 0 1472d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0 1473d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || set_arg1 (tcp, &state, 0) < 0 1474d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || arg_finish_change (tcp, &state) < 0) 1475d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1476c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD; 1477c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->u_arg[arg1_index] = 0; 1478d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags |= TCB_BPTSET; 1479d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1480d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 1481d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1482d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_clone: 1483d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef SYS_clone2 1484d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_clone2: 1485d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 148602cee8d5cbcb0aaaf64d4f4d0916e3d4dbd8ee01Roland McGrath if ((tcp->u_arg[arg0_index] & CLONE_PTRACE) == 0 1487d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath && (arg_setup (tcp, &state) < 0 1488c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath || set_arg0 (tcp, &state, 1489c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->u_arg[arg0_index] | CLONE_PTRACE) < 0 1490d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || arg_finish_change (tcp, &state) < 0)) 1491d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1492d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags |= TCB_BPTSET; 1493c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->inst[0] = tcp->u_arg[arg0_index]; 1494c9dc3c1ea77e24e531bde164ba90cc226b1305f8Roland McGrath tcp->inst[1] = tcp->u_arg[arg1_index]; 1495d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1496d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1497d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath default: 1498d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n", 1499d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->scno, tcp->pid); 1500d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath break; 1501d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath } 1502d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1503d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1504d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1505d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1506d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint 1507d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathclearbpt(tcp) 1508d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstruct tcb *tcp; 1509d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1510d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath arg_setup_state state; 1511d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (arg_setup (tcp, &state) < 0 1512e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath || restore_arg0 (tcp, &state, tcp->inst[0]) < 0 1513e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath || restore_arg1 (tcp, &state, tcp->inst[1]) < 0 1514d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || arg_finish_change (tcp, &state)) 1515d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1516d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags &= ~TCB_BPTSET; 1517d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1518d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1519d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1520d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#else 1521d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 152276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 152376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermansetbpt(tcp) 152476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 152576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 152676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 152776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 15286d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if defined (SPARC) || defined (SPARC64) 152976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* We simply use the SunOS breakpoint code. */ 153076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15319ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 15326d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath unsigned long inst; 153376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA 0x30800000 /* ba,a 0 */ 153476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 153576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 153676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 153776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 153876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 153976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 154076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 154176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 154276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 15439ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tcp->baddr = regs.r_o7 + 8; 154476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 154576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0); 154676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if(errno) { 154776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 154876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 154976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 155076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 155176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 155276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * XXX - BRUTAL MODE ON 155376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We cannot set a real BPT in the child, since it will not be 155476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * traced at the moment it will reach the trap and would probably 155576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * die with a core dump. 155676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Thus, we are force our way in by taking out two instructions 155776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * and insert an eternal loop instead, in expectance of the SIGSTOP 155876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * generated by out PTRACE_ATTACH. 155976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Of cause, if we evaporate ourselves in the middle of all this... 156076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 156176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 15626d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath inst = LOOPA; 15636d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if defined (SPARC64) 15646d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath inst <<= 32; 15656d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath inst |= (tcp->inst[0] & 0xffffffffUL); 15666d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#endif 15676d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, inst); 156876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if(errno) { 156976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 157076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 157176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 157276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 157376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15746d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#else /* !SPARC && !SPARC64 */ 15758b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#ifdef IA64 15767b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (ia32) { 15777b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman# define LOOP 0x0000feeb 15787b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 15797b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "PANIC: bpt already set in pid %u\n", 15807b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->pid); 15817b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 15827b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 15837b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (upeek(tcp->pid, PT_CR_IIP, &tcp->baddr) < 0) 15847b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 15857b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (debug) 15867b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "[%d] setting bpt at %lx\n", 15877b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->pid, tcp->baddr); 15887b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, 15897b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman (char *) tcp->baddr, 0); 15907b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (errno) { 15917b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 15927b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 15937b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 15947b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 15957b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (errno) { 15967b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 15977b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 15987b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 15997b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->flags |= TCB_BPTSET; 16007b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } else { 16017b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman /* 16027b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * Our strategy here is to replace the bundle that 16037b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * contained the clone() syscall with a bundle of the 16047b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * form: 16057b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * 16067b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * { 1: br 1b; br 1b; br 1b } 16077b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * 16087b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * This ensures that the newly forked child will loop 16097b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * endlessly until we've got a chance to attach to it. 16107b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman */ 16118b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman# define LOOP0 0x0000100000000017 16128b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman# define LOOP1 0x4000000000200000 16138b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman unsigned long addr, ipsr; 16148b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid_t pid; 16158b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 16168b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid = tcp->pid; 16178b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(pid, PT_CR_IPSR, &ipsr) < 0) 16188b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 16198b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(pid, PT_CR_IIP, &addr) < 0) 16208b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 16217b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman /* store "ri" in low two bits */ 16227b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->baddr = addr | ((ipsr >> 41) & 0x3); 16238b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 16248b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman errno = 0; 16257b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0, 16267b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 0); 16277b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8, 16287b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 0); 16298b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (errno) { 16308b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 16318b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 16328b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 16338b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 16348b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman errno = 0; 16358b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0); 16368b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1); 16378b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (errno) { 16388b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 16398b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 16408b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 16418b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tcp->flags |= TCB_BPTSET; 16428b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 16438b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#else /* !IA64 */ 164476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16450e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#if defined (I386) || defined(X86_64) 164676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP 0x0000feeb 164776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K) 164876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP 0x60fe0000 164976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA) 16504dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0xc3ffffff 165176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC) 16521e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath#define LOOP 0x48000000 165376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined(ARM) 16549a8a37f2b28d1c0d3f57951fd5aeeb96ff7d2f16Wichert Akkerman#define LOOP 0xEAFFFFFE 1655f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS) 16564dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0x1000ffff 16574dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390) 16584dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0xa7f40000 /* BRC 15,0 */ 165910a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#elif defined(S390X) 166010a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#define LOOP 0xa7f4000000000000UL /* BRC 15,0 */ 1661c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1662c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#define LOOP 0xe81f1ff7 /* b,l,n <loc>,r0 */ 1663ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1664ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#ifdef __LITTLE_ENDIAN__ 1665ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#define LOOP 0x0000affe 1666ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#else 1667ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#define LOOP 0xfeaf0000 1668ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#endif 166976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 167076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture 167176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 167276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 167376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 167476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid); 167576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 167676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 167776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined (I386) 167876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &tcp->baddr) < 0) 167976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 16800e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined (X86_64) 16810e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (upeek(tcp->pid, 8*RIP, &tcp->baddr) < 0) 16820e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return -1; 168376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K) 168476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &tcp->baddr) < 0) 168576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 168676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA) 168776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 168876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ARM) 168976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1690f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined (MIPS) 1691f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman return -1; /* FIXME: I do not know what i do - Flo */ 169276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC) 1693eb285359906700f46b22cf4f9911695034313736Roland McGrath if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &tcp->baddr) < 0) 169476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 169510a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#elif defined(S390) || defined(S390X) 16964dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman if (upeek(tcp->pid,PT_PSWADDR, &tcp->baddr) < 0) 16974dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman return -1; 1698c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1699c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (upeek(tcp->pid, PT_IAOQ0, &tcp->baddr) < 0) 1700c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return -1; 1701c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tcp->baddr &= ~0x03; 1702ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1703ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (upeek(tcp->pid, 4*REG_PC, &tcp->baddr) < 0) 1704ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman return -1; 170576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 170676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture 170776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 170876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 170976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr); 171076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0); 171176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 171276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 171376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 171476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 171576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 171676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 171776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 171876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 171976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 172076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 172176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17228b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#endif /* !IA64 */ 17236d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#endif /* SPARC || SPARC64 */ 172476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 172576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 172676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 172776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC /* This code is slightly sparc specific */ 172876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1729e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 173076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define BPT 0x91d02001 /* ta 1 */ 173176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP 0x10800000 /* ba 0 */ 173276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA 0x30800000 /* ba,a 0 */ 173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define NOP 0x01000000 173476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if LOOPA 173576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[1] = {LOOPA}; 173676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 173776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[2] = {LOOP, NOP}; 173876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 173976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 174076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 174176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 174276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 174376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 174476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 174576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 174676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 174776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 174876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->baddr = regs.r_o7 + 8; 174976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr, 175076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof tcp->inst, (char *)tcp->inst) < 0) { 175176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_READTEXT, ...)"); 175276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 175376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 175476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 175576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 175676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * XXX - BRUTAL MODE ON 175776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We cannot set a real BPT in the child, since it will not be 175876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * traced at the moment it will reach the trap and would probably 175976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * die with a core dump. 176076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Thus, we are force our way in by taking out two instructions 176176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * and insert an eternal loop in stead, in expectance of the SIGSTOP 176276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * generated by out PTRACE_ATTACH. 176376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Of cause, if we evaporate ourselves in the middle of all this... 176476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 176576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 176676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof loopdeloop, (char *) loopdeloop) < 0) { 176776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)"); 176876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 176976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 177076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 177176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 177276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */ 177376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 177476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 177576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 177676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 177776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 177876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 177976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanclearbpt(tcp) 178076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 178176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 178276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 178376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 17840e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#if defined(I386) || defined(X86_64) 178576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long eip; 1786faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(POWERPC) 178776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 1788faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68K) 178976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 1790faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA) 179176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 1792c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1793c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman long iaoq; 1794ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1795ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman long pc; 1796faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* architecture */ 179776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17986d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#if defined (SPARC) || defined (SPARC64) 179976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Again, we borrow the SunOS breakpoint code. */ 180076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 180176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 180276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 180376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 180476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 180576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 180676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if(errno) { 180776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 180876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 180976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 181076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 1811faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(IA64) 18127b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (ia32) { 18137b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman unsigned long addr; 18147b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 18157b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (debug) 18167b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 18177b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 18187b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 18197b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 18207b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 18217b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman errno = 0; 18227b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 18237b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (errno) { 18247b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 18257b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 18267b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 18277b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 18287b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 18297b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (upeek(tcp->pid, PT_CR_IIP, &addr) < 0) 18307b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 18317b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (addr != tcp->baddr) { 18327b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman /* The breakpoint has not been reached yet. */ 18337b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (debug) 18347b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, 18357b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 18367b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman addr, tcp->baddr); 18377b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return 0; 18387b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 18397b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } else { 18408b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman unsigned long addr, ipsr; 18418b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid_t pid; 18428b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 18438b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid = tcp->pid; 18448b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 18458b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(pid, PT_CR_IPSR, &ipsr) < 0) 18468b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 18478b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(pid, PT_CR_IIP, &addr) < 0) 18488b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 18498b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 18508b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman /* restore original bundle: */ 18518b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman errno = 0; 18528b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]); 18538b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]); 18548b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (errno) { 18558b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)"); 18568b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 18578b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 18588b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 18598b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman /* restore original "ri" in ipsr: */ 18608b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41); 18618b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman errno = 0; 18628b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr); 18638b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (errno) { 18648b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)"); 18658b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 18668b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 18678b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 18688b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 18698b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 18708b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (addr != (tcp->baddr & ~0x3)) { 18718b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman /* the breakpoint has not been reached yet. */ 18728b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (debug) 18738b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 18748b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman addr, tcp->baddr); 18758b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return 0; 18768b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 18778b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 18786d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#else /* !IA64 && !SPARC && !SPARC64 */ 187976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 188076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 188176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 188276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 188376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 188476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 188576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 188676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 188776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 188876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 188976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 189076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 189176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 189276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 189376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 189476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386 189576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &eip) < 0) 189676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 189776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (eip != tcp->baddr) { 189876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 189976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 190076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 190176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 190276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman eip, tcp->baddr); 190376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 190476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 19050e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined(X86_64) 19060e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (upeek(tcp->pid, 8*RIP, &eip) < 0) 19070e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return -1; 19080e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (eip != tcp->baddr) { 19090e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig /* The breakpoint has not been reached yet. */ 19100e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (debug) 19110e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig fprintf(stderr, 19120e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 19130e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig eip, tcp->baddr); 19140e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return 0; 19150e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig } 1916c792698a99b640e7d256e8692c992bd967f0c5b2Wichert Akkerman#elif defined(POWERPC) 1917eb285359906700f46b22cf4f9911695034313736Roland McGrath if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) 191876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 191976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 192076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 192176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 192276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 192376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 192476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 192576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1926faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68K) 192776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) 192876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 192976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 193076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 193176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 193276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 193376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 193476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 193576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1936faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA) 193776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, REG_PC, &pc) < 0) 193876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 193976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 194076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 194176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 194276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 194376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 194476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 194576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1946c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1947c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (upeek(tcp->pid, PT_IAOQ0, &iaoq) < 0) 1948c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return -1; 1949c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman iaoq &= ~0x03; 1950c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) { 1951c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman /* The breakpoint has not been reached yet. */ 1952c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (debug) 1953c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n", 1954c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman iaoq, tcp->baddr); 1955c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return 0; 1956c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman } 1957c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman iaoq = tcp->baddr | 3; 1958c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman /* We should be pointing at a 'ldi -1000,r1' in glibc, so it is 1959c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit 1960c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman * has no significant effect. 1961c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman */ 1962c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq); 1963c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq); 1964ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1965ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (upeek(tcp->pid, 4*REG_PC, &pc) < 0) 1966ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman return -1; 1967ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (pc != tcp->baddr) { 1968ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman /* The breakpoint has not been reached yet. */ 1969ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (debug) 1970ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 1971ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman pc, tcp->baddr); 1972ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman return 0; 1973ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman } 1974ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman 1975faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* arch */ 19766d1a65c759c6c650e47ce5045a26380a4acbdffaRoland McGrath#endif /* !SPARC && !SPARC64 && !IA64 */ 197776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 197876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 197976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 198076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC 198176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 198276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA 1983e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 198476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 198576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 198676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 198776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 198876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 198976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 199076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 199176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof tcp->inst, (char *) tcp->inst) < 0) { 199276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)"); 199376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 199476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 199576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 199676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 199776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA 199876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 199976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Since we don't have a single instruction breakpoint, we may have 200076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * to adjust the program counter after removing the our `breakpoint'. 200176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 200276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 200376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbpt: ptrace(PTRACE_GETREGS, ...)"); 200476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 200576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 200676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((regs.r_pc < tcp->baddr) || 200776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (regs.r_pc > tcp->baddr + 4)) { 200876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet */ 200976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 201076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 201176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "NOTE: PC not at bpt (pc %#x baddr %#x)\n", 201276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc, tcp->parent->baddr); 201376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 201476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 201576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (regs.r_pc != tcp->baddr) 201676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 201776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n", 201876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc, tcp->baddr); 201976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 202076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc = tcp->baddr; 202176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) { 202276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbpt: ptrace(PTRACE_SETREGS, ...)"); 202376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 202476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 202576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LOOPA */ 202676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */ 202776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 202876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 202976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 203076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 203176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2032d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 2033d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 2034bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 203576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 203676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 203776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 203876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 203976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetex(pid, hdr) 204076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 204176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct exec *hdr; 204276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 204376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 204476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 204576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; n < sizeof *hdr; n += 4) { 204676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long res; 204776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(pid, uoff(u_exdata) + n, &res) < 0) 204876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 204976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(((char *) hdr) + n, &res, 4); 205076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 205176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) { 205276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n", 205376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_magic, hdr->a_toolversion, hdr->a_machtype); 205476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n", 205576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry); 205676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 205776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 205876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 205976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 206076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 206176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfixvfork(tcp) 206276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 206376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 206476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 206576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 206676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Change `vfork' in a freshly exec'ed dynamically linked 206776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * executable's (internal) symbol table to plain old `fork' 206876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 206976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 207076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct exec hdr; 207176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic dyn; 207276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic_2 ld; 207376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *strtab, *cp; 207476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 207576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getex(pid, &hdr) < 0) 207676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 207776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!hdr.a_dynamic) 207876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 207976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 208076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) { 208176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read DYNAMIC\n"); 208276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 208376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 208476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) { 208576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read link_dynamic_2\n"); 208676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 208776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 208876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) { 208946100d07257824da2ae1147da0324b5788c95501Roland McGrath fprintf(stderr, "out of memory\n"); 209076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 209176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 209276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 209376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 209476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 209576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 209676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 209776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 209876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[symbol: %s]\n", cp); 209976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cp += strlen(cp)+1; 210076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 210176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 210276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 210376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 210476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strcmp(cp, "_vfork") == 0) { 210576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 210676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "fixvfork: FOUND _vfork\n"); 210776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strcpy(cp, "_fork"); 210876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 210976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 211076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cp += strlen(cp)+1; 211176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 211276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cp < strtab + ld.ld_symb_size) 211376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 211476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Write entire symbol table back to avoid 211576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * memory alignment bugs in ptrace 211676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 211776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 211876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 211976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 212076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 212176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 212276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 212376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 212476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerr: 212576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 212676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 212776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 212876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 212976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 2130