util.c revision ac971c27278e1d45bf12c1ba522c7507ba778144
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 66faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#include <linux/ptrace.h> 672e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#endif 682e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman 6976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE 7076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/utsname.h> 7176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 7276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 739ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#if defined(LINUX) && defined(SPARC) 749ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 754db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# define fpq kernel_fpq 764db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# define fq kernel_fq 774db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# define fpu kernel_fpu 784db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# include <asm/reg.h> 794db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# undef fpq 804db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# undef fq 814db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath# undef fpu 829ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 839ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#if !defined(__GLIBC__) 8476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 8576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <linux/unistd.h> 8676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 8776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define _hack_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\ 8876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman type5,arg5,syscall) \ 8976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantype name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ 9076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ \ 9176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long __res; \ 9276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman\ 9376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman__asm__ volatile ("or %%g0, %1, %%o0\n\t" \ 9476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %2, %%o1\n\t" \ 9576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %3, %%o2\n\t" \ 9676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %4, %%o3\n\t" \ 9776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %5, %%o4\n\t" \ 9876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %6, %%g1\n\t" \ 9976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "t 0x10\n\t" \ 10076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "bcc 1f\n\t" \ 10176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %%o0, %0\n\t" \ 10276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "sub %%g0, %%o0, %0\n\t" \ 10376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "1:\n\t" \ 10476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman : "=r" (__res) \ 10576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman : "0" ((long)(arg1)),"1" ((long)(arg2)), \ 10676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "2" ((long)(arg3)),"3" ((long)(arg4)),"4" ((long)(arg5)), \ 10776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "i" (__NR_##syscall) \ 10876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman : "g1", "o0", "o1", "o2", "o3", "o4"); \ 10976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanif (__res>=0) \ 11076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return (type) __res; \ 11176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerrno = -__res; \ 11276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanreturn -1; \ 11376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 11476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,int,__addr2,ptrace) 11676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define _ptrace 11876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1219ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 1229ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 12376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* macros */ 12476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MAX 12576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MAX(a,b) (((a) > (b)) ? (a) : (b)) 12676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 12776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MIN 12876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MIN(a,b) (((a) < (b)) ? (a) : (b)) 12976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 13276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_tv(tv, a, b) 13376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv; 13476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint a; 13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint b; 13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a; 13876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = b; 13976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 14076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 14176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 14276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_nz(a) 14376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a; 14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 14576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return a->tv_sec || a->tv_usec; 14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 14876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 14976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_cmp(a, b) 15076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a, *b; 15176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 15276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (a->tv_sec < b->tv_sec 15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec)) 15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (a->tv_sec > b->tv_sec 15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec)) 15776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 15876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 15976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 16076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandouble 16276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_float(tv) 16376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv; 16476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 16576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tv->tv_sec + tv->tv_usec/1000000.0; 16676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 16776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 16976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_add(tv, a, b) 17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b; 17176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 17276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec + b->tv_sec; 17376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec + b->tv_usec; 17476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tv->tv_usec > 1000000) { 17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec++; 17676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec -= 1000000; 17776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 17876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 17976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 18076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 18176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_sub(tv, a, b) 18276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b; 18376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec - b->tv_sec; 18576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec - b->tv_usec; 18676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (((long) tv->tv_usec) < 0) { 18776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec--; 18876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec += 1000000; 18976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 19076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 19176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 19276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 19376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_div(tv, a, n) 19476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a; 19576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 19676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n; 19876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000; 19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 20076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 20176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 20276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 20376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_mul(tv, a, n) 20476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a; 20576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 20676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 20776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec * n; 20876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec * n + a->tv_usec / 1000000; 20976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 21076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar * 21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanxlookup(xlat, val) 21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat; 21576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint val; 21676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 21776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (; xlat->str != NULL; xlat++) 21876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val == val) 21976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return xlat->str; 22076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 22176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 22276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 22376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 22476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Print entry in struct xlat table, if there. 22576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 22676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 22776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintxval(xlat, val, dflt) 22876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat; 22976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint val; 23076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *dflt; 23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *str = xlookup(xlat, val); 23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 23576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", str); 23676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 23776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#x /* %s */", val, dflt); 23876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 23976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 24076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 24176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interpret `xlat' as an array of flags 24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * print the entries whose bits are on in `flags' 24376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * return # of flags printed. 24476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 24576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 24676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanaddflags(xlat, flags) 24776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat; 24876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags; 24976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 25076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 25176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 25276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 25376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 25476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%s", xlat->str); 25576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 25676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 25776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 25876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 25976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags) { 26076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%#x", flags); 26176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 26276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 26376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 26476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 26576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 26676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 26776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintflags(xlat, flags) 26876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat; 26976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags; 27076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 27176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 27276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *sep; 27376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 27476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags == 0 && xlat->val == 0) { 27576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", xlat->str); 27676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 27776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 27876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 27976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = ""; 28076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 28176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 28276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s%s", sep, xlat->str); 28376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 28476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = "|"; 28576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 28676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 28776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 28876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags) { 28976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s%#x", sep, flags); 29076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 29176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 29276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 29376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 29476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 29576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 29676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintnum(tcp, addr, fmt) 29776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 29876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 29976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *fmt; 30076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 301eb285359906700f46b22cf4f9911695034313736Roland McGrath long num; 30276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 30476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 30676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 30776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, addr, &num) < 0) { 30876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 30976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 31076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 31176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("["); 31276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf(fmt, num); 31376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("]"); 31476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 31576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 31676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic char path[MAXPATHLEN + 1]; 31776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 31876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 31976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstring_quote(str) 32076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *str; 32176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 32276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char buf[2 * MAXPATHLEN + 1]; 32376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s; 32476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 32576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!strpbrk(str, "\"\'\\")) { 32676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("\"%s\"", str); 32776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 32876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 32976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (s = buf; *str; str++) { 33076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (*str) { 33176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\"': case '\'': case '\\': 33276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = *str; break; 33376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = *str; break; 33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 33676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 33776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s = '\0'; 33876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("\"%s\"", buf); 33976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 34076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 34176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 34276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpath(tcp, addr) 34376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 34476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 34576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 34676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umovestr(tcp, addr, MAXPATHLEN, path) < 0) 34776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 34876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 34976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman string_quote(path); 35076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 35176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 35276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 35376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 35476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpathn(tcp, addr, n) 35576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 35676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 35776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 35876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 35976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umovestr(tcp, addr, n, path) < 0) 36076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 36176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 36276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman path[n] = '\0'; 36376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman string_quote(path); 36476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 36576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 36676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 36776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 36876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintstr(tcp, addr, len) 36976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 37076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 37176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 37276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 37376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static unsigned char *str = NULL; 37476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char *outstr; 37576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, n, c, usehex; 37676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s, *outend; 37776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 37876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 37976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 38076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 38176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 38276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!str) { 38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((str = malloc(max_strlen)) == NULL 38476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (outstr = malloc(2*max_strlen)) == NULL) { 38576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "printstr: no memory\n"); 38676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 38776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 38876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 38976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 3902e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman outend = outstr + max_strlen * 2 - 10; 39176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0) { 39276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = max_strlen; 39376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umovestr(tcp, addr, n, (char *) str) < 0) { 39476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 39576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 39676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 39776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 39876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 39976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, max_strlen); 40076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, addr, n, (char *) str) < 0) { 40176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 40276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 40376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 40476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 40576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 40676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usehex = 0; 40776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xflag > 1) 40876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usehex = 1; 40976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (xflag) { 41076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 41176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman c = str[i]; 41276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0 && c == '\0') 41376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 41476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!isprint(c) && !isspace(c)) { 41576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usehex = 1; 41676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 41776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 41876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 41976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 42076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 42176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s = outstr; 42276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\"'; 42376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 42476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (usehex) { 42576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 42676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman c = str[i]; 42776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0 && c == '\0') 42876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 42976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, "\\x%02x", c); 43076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 4; 43176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (s > outend) 43276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 43376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 43476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 43576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 43676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 43776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman c = str[i]; 43876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0 && c == '\0') 43976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 44076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (c) { 44176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\"': case '\'': case '\\': 44276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = c; break; 44376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\f': 44476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'f'; break; 44576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\n': 44676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'n'; break; 44776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\r': 44876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'r'; break; 44976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\t': 45076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 't'; break; 45176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\v': 45276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'v'; break; 45376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 45476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isprint(c)) 45576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = c; 45676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (i < n - 1 && isdigit(str[i + 1])) { 45776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, "\\%03o", c); 45876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 4; 45976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 46076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 46176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, "\\%o", c); 46276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += strlen(s); 46376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 46476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 46576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 46676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (s > outend) 46776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 46876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 46976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 47076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 47176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\"'; 47276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i < len || (len < 0 && (i == n || s > outend))) { 47376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '.'; *s++ = '.'; *s++ = '.'; 47476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 47576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s = '\0'; 47676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", outstr); 47776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 47876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 4791d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H 4801d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesvoid 4811d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesdumpiov(tcp, len, addr) 4821d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesstruct tcb * tcp; 4831d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesint len; 4841d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hugheslong addr; 4851d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes{ 4861d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes struct iovec *iov; 4871d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes int i; 4881d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 4891e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath 4901d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes if ((iov = (struct iovec *) malloc(len * sizeof *iov)) == NULL) { 4911d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes fprintf(stderr, "dump: No memory"); 4921d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes return; 4931d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 4941d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes if (umoven(tcp, addr, 4951d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes len * sizeof *iov, (char *) iov) >= 0) { 4961e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath 4971d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes for (i = 0; i < len; i++) { 4981d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes /* include the buffer number to make it easy to 4991d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes * match up the trace with the source */ 5001d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes tprintf(" * %lu bytes in buffer %d\n", 5011d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes (unsigned long)iov[i].iov_len, i); 5021d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes dumpstr(tcp, (long) iov[i].iov_base, 5031d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes iov[i].iov_len); 5041d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 5051d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 5061d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes free((char *) iov); 5071e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath 5081d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes} 5091d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 5101d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 51176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 51276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandumpstr(tcp, addr, len) 51376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 51476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 51576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 51676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 51776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int strsize = -1; 51876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static unsigned char *str; 51976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char outstr[80]; 52076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s; 52176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 52276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 52376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strsize < len) { 52476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 52576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(str); 52676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((str = malloc(len)) == NULL) { 52776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "dump: no memory\n"); 52876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 52976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 53076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strsize = len; 53176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 53276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 53376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, addr, len, (char *) str) < 0) 53476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 53576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 53676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < len; i += 16) { 53776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s = outstr; 53876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " | %05x ", i); 53976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 9; 54076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 54176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 54276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 54376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 54476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " %02x", str[i + j]); 54576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 3; 54676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 54776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 54876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; *s++ = ' '; 54976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 55076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 55176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; 55276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 55376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 55476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 55576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 55676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isprint(str[i + j])) 55776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = str[i + j]; 55876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 55976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '.'; 56076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 56176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 56276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 56376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 56476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s |\n", outstr); 56576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 56676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 56776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 56876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PAGMASK (~(PAGSIZ - 1)) 56976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 57076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * move `len' bytes of data from process `pid' 57176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * at address `addr' to our space at `laddr' 57276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 57376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 57476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumoven(tcp, addr, len, laddr) 57576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 57676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 57776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 57876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 57976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 58076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 58176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 58276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 58376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 5845daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 58576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 58676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 58776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 58876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 58976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 59076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 59176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 59276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 59376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 59476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 59576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 59676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 5975daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 59876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 59976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 60076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 6015daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman /* But if not started, we had a bogus address. */ 60276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("ptrace: umoven"); 60376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 60476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 6055daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 60676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 60776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 60876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 60976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 61076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 61176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 61276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 6135daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 61476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 61576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 61676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 6174db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath if (addr != 0) 6184db2624c8f6ec2c6f204c945df349bf42a897d01Roland McGrath perror("ptrace: umoven"); 61976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 62076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 6215daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 62276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 62376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 62476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 62576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 62676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 62876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 62976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 63076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 63176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 63276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 63376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 63476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 63576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 63676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 63776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 63876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 63976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 64076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 64176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 64276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 64376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umoven"); 64476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 64576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 64676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 64776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 64876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 64976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 65076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 65176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 65276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 65376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umoven"); 65476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 65576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 65676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 65776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 65876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 65976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !oldway */ 66076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 66176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 66276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 66376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, PAGSIZ); 66476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 66576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_READDATA, pid, 66676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (char *) addr, len, laddr) < 0) { 66776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umoven: ptrace(PTRACE_READDATA, ...)"); 66876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman abort(); 66976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 67076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 67176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len -= n; 67276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += n; 67376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman laddr += n; 67476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 67576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !oldway */ 67676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 67776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 678bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 679ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 680aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd_as; 6819ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 682aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd; 68376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 684aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes lseek(fd, addr, SEEK_SET); 685aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (read(fd, laddr, len) == -1) 68676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 687bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 68876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 68976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 69076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 69176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 69276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 69376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * like `umove' but make the additional effort of looking 69476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * for a terminating zero byte. 69576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 69676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 69776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumovestr(tcp, addr, len, laddr) 69876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 69976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 70076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 70176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 70276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 703bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 704aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#ifdef HAVE_MP_PROCFS 705aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd_as; 706aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#else 707aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd; 708aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#endif 709aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes /* Some systems (e.g. FreeBSD) can be upset if we read off the 710aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes end of valid memory, avoid this by trying to read up 711aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes to page boundaries. But we don't know what a page is (and 712aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes getpagesize(2) (if it exists) doesn't necessarily return 713aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes hardware page size). Assume all pages >= 1024 (a-historical 714aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes I know) */ 715aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 716aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int page = 1024; /* How to find this? */ 717aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int move = page - (addr & (page - 1)); 718aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int left = len; 719aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 720aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes lseek(fd, addr, SEEK_SET); 721aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 722aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes while (left) { 723aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (move > left) move = left; 7249cecf7f8d6115a247be7186013857270b2d588d5John Hughes if ((move = read(fd, laddr, move)) <= 0) 725aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return left != len ? 0 : -1; 726aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (memchr (laddr, 0, move)) break; 727aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes left -= move; 728aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes laddr += move; 729aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes addr += move; 730aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes move = page; 731aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes } 732bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 7335daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 73476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 73576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, n, m; 73676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 73776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 73876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 73976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 74076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 74176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 74276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 74376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 74576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 7485daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 75176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 75276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umovestr"); 75376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 7555daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 75676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len)); 75776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (n & (sizeof(long) - 1)) 75876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[n++] == '\0') 75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 76076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 76176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 76276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 76376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 76476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 76576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 7665daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 76776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 77076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umovestr"); 77176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 77276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 7735daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 77476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 77576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < sizeof(long); i++) 77676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[i] == '\0') 77776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 77876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 77976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 78076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 781bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 782aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return 0; 78376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 78476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 78576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 78676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SPARC 78776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITETEXT 101 78876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITEDATA 102 78976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !SPARC */ 79076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 79176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 79276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 79376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 79476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 79576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanuload(cmd, pid, addr, len, laddr) 79676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint cmd; 79776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 79876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 79976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 80076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 80176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 80276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 80376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 80476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 80576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 80676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, PAGSIZ); 80776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 80876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) { 80976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: ptrace(PTRACE_WRITE, ...)"); 81076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 81176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 81276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len -= n; 81376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += n; 81476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman laddr += n; 81576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 81676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 81776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int peek, poke; 81876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 81976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 82076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 82176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 82276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 82376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 82476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cmd == PTRACE_WRITETEXT) { 82576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKTEXT; 82676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKETEXT; 82776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 82876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 82976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKDATA; 83076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKEDATA; 83176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 83276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 83376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 83476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 83576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); 83676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 83776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(peek, pid, (char *) addr, 0); 83876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 83976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: POKE"); 84076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 84176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 84276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len)); 84376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(poke, pid, (char *)addr, u.val) < 0) { 84476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: POKE"); 84576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 84676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 84776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 84876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 84976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 85076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < sizeof(long)) 85176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(peek, pid, (char *) addr, 0); 85276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(u.x, laddr, m = MIN(sizeof(long), len)); 85376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(poke, pid, (char *) addr, u.val) < 0) { 85476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: POKE"); 85576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 85676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 85776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 85876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 85976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 86076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 86176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 86276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 86376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 86476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantload(pid, addr, len, laddr) 86576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 86676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr, len; 86776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 86876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 86976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return uload(PTRACE_WRITETEXT, pid, addr, len, laddr); 87076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 87176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 87276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 87376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandload(pid, addr, len, laddr) 87476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 87576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr; 87676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 87776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 87876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 87976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return uload(PTRACE_WRITEDATA, pid, addr, len, laddr); 88076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 88176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 88276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 88376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 884bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 88576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 88676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 88776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanupeek(pid, off, res) 88876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 88976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong off; 89076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong *res; 89176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 89276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 89376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 89476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE 89576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman { 89676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int is_sun4m = -1; 89776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct utsname name; 89876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 89976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Round up the usual suspects. */ 90076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m == -1) { 90176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (uname(&name) < 0) { 90276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("upeek: uname?"); 90376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 90476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 90576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman is_sun4m = strcmp(name.machine, "sun4m") == 0; 90676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) { 90776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman extern struct xlat struct_user_offsets[]; 90876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct xlat *x; 90976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 91076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (x = struct_user_offsets; x->str; x++) 91176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman x->val += 1024; 91276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 91376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 91476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) 91576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman off += 1024; 91676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 91776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 91876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 91976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman val = ptrace(PTRACE_PEEKUSER, pid, (char *) off, 0); 92076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (val == -1 && errno) { 9211e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath char buf[60]; 9220e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)",pid,off); 9231e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath perror(buf); 92476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 92576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 92676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *res = val; 92776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 92876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 92976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 930bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 93176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 93276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong 93376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetpc(tcp) 93476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 93576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 93676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 93776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 93876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 939f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#if defined(I386) 94076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &pc) < 0) 94176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 9420e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined(X86_64) 9430e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (upeek(tcp->pid, 8*RIP, &pc) < 0) 9440e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return -1; 9458b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#elif defined(IA64) 9468b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(tcp->pid, PT_B0, &pc) < 0) 9478b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 948f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ARM) 94976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*15, &pc) < 0) 95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 951f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(POWERPC) 952eb285359906700f46b22cf4f9911695034313736Roland McGrath if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) 95376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 954f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(M68k) 95576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) 95676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 957f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ALPHA) 95876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, REG_PC, &pc) < 0) 95976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 960f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS) 961f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman if (upeek(tcp->pid, REG_EPC, &pc) < 0) 962f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman return -1; 963f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(SPARC) 9649ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 96576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) 96676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 9679ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman pc = regs.r_pc; 96810a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#elif defined(S390) || defined(S390X) 9694dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman if(upeek(tcp->pid,PT_PSWADDR,&pc) < 0) 97010a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig return -1; 971c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 972c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) 973c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return -1; 974ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 975ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (upeek(tcp->pid, 4*REG_PC ,&pc) < 0) 976ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman return -1; 9777a0b649aeace5c1e1efe4a1d7b1ae6e3a87e0d44Wichert Akkerman#endif 97876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pc; 97976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 98076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 98176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 98276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 98376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Return current program counter for `pid' 98476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Assumes PC is never 0xffffffff 98576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 98676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct regs regs; 98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 98976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("getpc: ptrace(PTRACE_GETREGS, ...)"); 99076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return regs.r_pc; 99376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 99476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 99576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* XXX */ 99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 99876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */ 99976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1000bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1001bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct reg regs; 1002bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 1003bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return regs.r_eip; 1004bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 100576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 100676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 100776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 100876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintcall(tcp) 100976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 101076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 101176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 101276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 101376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386 101476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long eip; 101576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 101676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &eip) < 0) { 101776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[????????] "); 101876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 101976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 102076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", eip); 10210e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined(X86_64) 10220e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig long rip; 10230e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig 10240e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (upeek(tcp->pid, 8*RIP, &rip) < 0) { 10250e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig tprintf("[????????] "); 10260e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return; 10270e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig } 10280e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig tprintf("[%16lx] ", rip); 1029faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(IA62) 10308b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman long ip; 10318b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 10328b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(tcp->pid, PT_B0, &ip) < 0) { 10338b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tprintf("[????????] "); 10348b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return; 10358b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 10368b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tprintf("[%08lx] ", ip); 1037faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(POWERPC) 103876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 103976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1040eb285359906700f46b22cf4f9911695034313736Roland McGrath if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) { 104176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 104276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 104376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 104476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 1045faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68k) 104676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 104776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 104876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) { 104976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 105076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 105176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 105276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 1053faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA) 105476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 105576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 105676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, REG_PC, &pc) < 0) { 105776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 105876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 105976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 106076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 1061faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(SPARC) 10629ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 106376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) { 106476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[????????] "); 106576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 106676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 10679ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tprintf("[%08lx] ", regs.r_pc); 1068c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1069c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman long pc; 1070c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman 1071c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) { 1072c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tprintf ("[????????] "); 1073c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return; 1074c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman } 1075c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tprintf("[%08lx] ", pc); 107675c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman#elif defined(MIPS) 107775c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman long pc; 107875c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman 107975c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman if (upeek(tcp->pid, REG_EPC, &pc) < 0) { 108075c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman tprintf ("[????????] "); 108175c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman return; 108275c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman } 108375c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman tprintf("[%08lx] ", pc); 1084ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1085ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman long pc; 1086ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman 1087ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (upeek(tcp->pid, 4*REG_PC, &pc) < 0) { 1088ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman tprintf ("[????????] "); 1089ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman return; 1090ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman } 1091ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman tprintf("[%08lx] ", pc); 1092faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* !architecture */ 109376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 109476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 109576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 109676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct regs regs; 109776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 109876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 109976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("printcall: ptrace(PTRACE_GETREGS, ...)"); 110076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[????????] "); 110176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 110276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 110376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08x] ", regs.r_o7); 110476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 110576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 110676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 110776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* XXX */ 110876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[????????] "); 110976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 111076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1111bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1112bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct reg regs; 1113bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 1114bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tprintf("[%08x] ", regs.r_eip); 1115bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 111676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 111776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1118bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 111976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1120d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#if defined LINUX 1121d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1122d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#include <sys/syscall.h> 1123d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifndef CLONE_PTRACE 1124d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define CLONE_PTRACE 0x00002000 1125d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 1126d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1127d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef IA64 1128d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1129d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef unsigned long *arg_setup_state; 1130d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1131d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1132d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGratharg_setup(struct tcb *tcp, arg_setup_state *state) 1133d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1134d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath unsigned long *bsp, cfm, sof, sol; 1135d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1136d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) < 0) 1137d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1138d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (upeek(tcp->pid, PT_CFM, (long *) &cfm) < 0) 1139d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1140d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1141d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sof = (cfm >> 0) & 0x7f; 1142d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sol = (cfm >> 7) & 0x7f; 1143d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath bsp = ia64_rse_skip_regs(bsp, -sof + sol); 1144d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1145d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath *state = bsp; 1146d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1147d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1148d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1149d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_finish_change(tcp, state) 0 1150d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1151d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef SYS_fork 1152d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1153d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathget_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp) 1154d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1155d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return umoven (tcp, (unsigned long) ia64_rse_skip_regs(*state, 0), 1156d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sizeof(long), (void *) valp); 1157d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1158d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1159d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1160d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathget_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp) 1161d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1162d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return umoven (tcp, (unsigned long) ia64_rse_skip_regs(*state, 1), 1163d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath sizeof(long), (void *) valp); 1164d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1165d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 1166d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1167d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1168d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg0 (struct tcb *tcp, arg_setup_state *state, long val) 1169d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1170d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath unsigned long *ap; 1171d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath ap = ia64_rse_skip_regs(*state, 0); 1172d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath errno = 0; 1173d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath ptrace(PTRACE_POKEDATA, tcp->pid, (void *) ap, val); 1174d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return errno ? -1 : 0; 1175d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1176d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1177d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1178d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg1 (struct tcb *tcp, arg_setup_state *state, long val) 1179d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1180d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath unsigned long *ap; 1181d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath ap = ia64_rse_skip_regs(*state, 1); 1182d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath errno = 0; 1183d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath ptrace(PTRACE_POKEDATA, tcp->pid, (void *) ap, val); 1184d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return errno ? -1 : 0; 1185d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1186d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1187d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#elif defined (SPARC) 1188d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1189d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef struct regs arg_setup_state; 1190d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1191d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_setup(tcp, state) \ 1192d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0)) 1193d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_finish_change(tcp, state) \ 1194d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0)) 1195d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1196d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0) 1197d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0) 1198d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define set_arg0(tcp, state, val) ((state)->r_o0 = (val), 0) 1199d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define set_arg1(tcp, state, val) ((state)->r_o1 = (val), 0) 1200e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg0(tcp, state, val) 0 1201d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1202d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#else 1203d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1204d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# if defined S390 || defined S390X 12057b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath/* Note: this is only true for the `clone' system call, which handles 12067b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath arguments specially. We could as well say that its first two arguments 12077b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath are swapped relative to other architectures, but that would just be 12087b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath another #ifdef in the calls. */ 12097b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath# define arg0_offset PT_GPR3 12107b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath# define arg1_offset PT_ORIGGPR2 12117b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath# define restore_arg0(tcp, state, val) ((void) (state), 0) 12127b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath# define restore_arg1(tcp, state, val) ((void) (state), 0) 1213d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# elif defined (ALPHA) || defined (MIPS) 1214d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg0_offset REG_A0 1215d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg1_offset (REG_A0+1) 1216d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# elif defined (POWERPC) 1217eb285359906700f46b22cf4f9911695034313736Roland McGrath# define arg0_offset (sizeof(unsigned long)*PT_R3) 1218eb285359906700f46b22cf4f9911695034313736Roland McGrath# define arg1_offset (sizeof(unsigned long)*PT_R4) 12197b3082206c5ea5ea41259c8b013138c6f6b6463aRoland McGrath# define restore_arg0(tcp, state, val) ((void) (state), 0) 1220d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# elif defined (HPPA) 1221d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg0_offset PT_GR26 1222d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg1_offset (PT_GR26-4) 12237f33cc3eb5ead7a79cae8c586e40d2f8b573eec1Roland McGrath# elif defined (X86_64) 12247f33cc3eb5ead7a79cae8c586e40d2f8b573eec1Roland McGrath# define arg0_offset ((long)(8*(current_personality ? RBX : RDI))) 12257f33cc3eb5ead7a79cae8c586e40d2f8b573eec1Roland McGrath# define arg1_offset ((long)(8*(current_personality ? RCX : RSI))) 1226ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath# elif defined (SH) 1227ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath# define arg0_offset (4*(REG_REG0+4)) 1228ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath# define arg1_offset (4*(REG_REG0+5)) 1229d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# else 1230d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg0_offset 0 1231d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg1_offset 4 1232ac971c27278e1d45bf12c1ba522c7507ba778144Roland McGrath# if defined ARM 1233e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg0(tcp, state, val) 0 1234e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# endif 1235d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# endif 1236d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1237d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathtypedef int arg_setup_state; 1238d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1239d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_setup(tcp, state) (0) 1240d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define arg_finish_change(tcp, state) 0 1241d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg0(tcp, cookie, valp) \ 1242d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath (upeek ((tcp)->pid, arg0_offset, (valp))) 1243d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath# define get_arg1(tcp, cookie, valp) \ 1244d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath (upeek ((tcp)->pid, arg1_offset, (valp))) 1245d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1246d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1247d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg0 (struct tcb *tcp, void *cookie, long val) 1248d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1249d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val); 1250d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1251d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1252d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstatic int 1253d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathset_arg1 (struct tcb *tcp, void *cookie, long val) 1254d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1255d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val); 1256d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1257d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1258d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 1259d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1260e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#ifndef restore_arg0 1261e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val)) 1262e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#endif 1263e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#ifndef restore_arg1 1264e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val)) 1265e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath#endif 1266d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1267d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint 1268d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathsetbpt(tcp) 1269d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstruct tcb *tcp; 1270d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1271d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath extern int change_syscall(struct tcb *, int); 1272d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath arg_setup_state state; 1273d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1274d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (tcp->flags & TCB_BPTSET) { 1275d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1276d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1277d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath } 1278d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1279d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath switch (tcp->scno) { 12809383c6c539af09303efe0a16dea55363b095f66eRoland McGrath#ifdef SYS_vfork 12819383c6c539af09303efe0a16dea55363b095f66eRoland McGrath case SYS_vfork: 12829383c6c539af09303efe0a16dea55363b095f66eRoland McGrath#endif 1283d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef SYS_fork 1284d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_fork: 12859b0982b5d3b84c845192ad8b7ad822f81cf4743aRoland McGrath#endif 12869b0982b5d3b84c845192ad8b7ad822f81cf4743aRoland McGrath#if defined SYS_fork || defined SYS_vfork 1287d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (arg_setup (tcp, &state) < 0 1288d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || get_arg0 (tcp, &state, &tcp->inst[0]) < 0 1289d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || get_arg1 (tcp, &state, &tcp->inst[1]) < 0 1290d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || change_syscall(tcp, SYS_clone) < 0 1291d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0 1292d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || set_arg1 (tcp, &state, 0) < 0 1293d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || arg_finish_change (tcp, &state) < 0) 1294d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1295d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->u_arg[0] = CLONE_PTRACE|SIGCHLD; 1296d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->u_arg[1] = 0; 1297d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags |= TCB_BPTSET; 1298d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1299d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 1300d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1301d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_clone: 1302d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#ifdef SYS_clone2 1303d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath case SYS_clone2: 1304d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 1305d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if ((tcp->u_arg[0] & CLONE_PTRACE) == 0 1306d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath && (arg_setup (tcp, &state) < 0 1307d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || set_arg0 (tcp, &state, tcp->u_arg[0] | CLONE_PTRACE) < 0 1308d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || arg_finish_change (tcp, &state) < 0)) 1309d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1310d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags |= TCB_BPTSET; 1311d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->inst[0] = tcp->u_arg[0]; 1312d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->inst[1] = tcp->u_arg[1]; 1313d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1314d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1315d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath default: 1316d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n", 1317d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->scno, tcp->pid); 1318d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath break; 1319d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath } 1320d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1321d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1322d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1323d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1324d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathint 1325d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathclearbpt(tcp) 1326d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrathstruct tcb *tcp; 1327d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath{ 1328d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath arg_setup_state state; 1329d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath if (arg_setup (tcp, &state) < 0 1330e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath || restore_arg0 (tcp, &state, tcp->inst[0]) < 0 1331e1df47ff9a7f3e1ed90969109258f2686f74ce0dRoland McGrath || restore_arg1 (tcp, &state, tcp->inst[1]) < 0 1332d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath || arg_finish_change (tcp, &state)) 1333d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return -1; 1334d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath tcp->flags &= ~TCB_BPTSET; 1335d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath return 0; 1336d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath} 1337d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1338d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#else 1339d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 134076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 134176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermansetbpt(tcp) 134276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 134376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 134476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 134576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 134676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC 134776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* We simply use the SunOS breakpoint code. */ 134876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13499ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 135076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA 0x30800000 /* ba,a 0 */ 135176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 135276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 135376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 135476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 135576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 135676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 135776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 135876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 135976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 13609ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tcp->baddr = regs.r_o7 + 8; 136176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 136276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0); 136376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if(errno) { 136476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 136576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 136676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 136776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 136876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 136976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * XXX - BRUTAL MODE ON 137076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We cannot set a real BPT in the child, since it will not be 137176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * traced at the moment it will reach the trap and would probably 137276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * die with a core dump. 137376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Thus, we are force our way in by taking out two instructions 137476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * and insert an eternal loop instead, in expectance of the SIGSTOP 137576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * generated by out PTRACE_ATTACH. 137676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Of cause, if we evaporate ourselves in the middle of all this... 137776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 137876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 137976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOPA); 138076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if(errno) { 138176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 138276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 138376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 138476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 138576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 138676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !SPARC */ 13878b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#ifdef IA64 13887b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (ia32) { 13897b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman# define LOOP 0x0000feeb 13907b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 13917b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "PANIC: bpt already set in pid %u\n", 13927b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->pid); 13937b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 13947b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 13957b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (upeek(tcp->pid, PT_CR_IIP, &tcp->baddr) < 0) 13967b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 13977b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (debug) 13987b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "[%d] setting bpt at %lx\n", 13997b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->pid, tcp->baddr); 14007b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, 14017b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman (char *) tcp->baddr, 0); 14027b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (errno) { 14037b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 14047b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 14057b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 14067b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 14077b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (errno) { 14087b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 14097b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 14107b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 14117b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->flags |= TCB_BPTSET; 14127b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } else { 14137b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman /* 14147b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * Our strategy here is to replace the bundle that 14157b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * contained the clone() syscall with a bundle of the 14167b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * form: 14177b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * 14187b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * { 1: br 1b; br 1b; br 1b } 14197b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * 14207b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * This ensures that the newly forked child will loop 14217b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * endlessly until we've got a chance to attach to it. 14227b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman */ 14238b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman# define LOOP0 0x0000100000000017 14248b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman# define LOOP1 0x4000000000200000 14258b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman unsigned long addr, ipsr; 14268b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid_t pid; 14278b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 14288b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid = tcp->pid; 14298b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(pid, PT_CR_IPSR, &ipsr) < 0) 14308b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 14318b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(pid, PT_CR_IIP, &addr) < 0) 14328b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 14337b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman /* store "ri" in low two bits */ 14347b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->baddr = addr | ((ipsr >> 41) & 0x3); 14358b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 14368b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman errno = 0; 14377b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0, 14387b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 0); 14397b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8, 14407b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 0); 14418b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (errno) { 14428b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 14438b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 14448b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 14458b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 14468b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman errno = 0; 14478b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0); 14488b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1); 14498b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (errno) { 14508b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 14518b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 14528b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 14538b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tcp->flags |= TCB_BPTSET; 14548b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 14558b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#else /* !IA64 */ 145676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 14570e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#if defined (I386) || defined(X86_64) 145876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP 0x0000feeb 145976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K) 146076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP 0x60fe0000 146176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA) 14624dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0xc3ffffff 146376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC) 14641e85cf9cb1b0cf3773bbd361bce57379d30b4940Roland McGrath#define LOOP 0x48000000 146576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined(ARM) 14669a8a37f2b28d1c0d3f57951fd5aeeb96ff7d2f16Wichert Akkerman#define LOOP 0xEAFFFFFE 1467f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS) 14684dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0x1000ffff 14694dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390) 14704dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0xa7f40000 /* BRC 15,0 */ 147110a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#elif defined(S390X) 147210a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#define LOOP 0xa7f4000000000000UL /* BRC 15,0 */ 1473c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1474c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#define LOOP 0xe81f1ff7 /* b,l,n <loc>,r0 */ 1475ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1476ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#ifdef __LITTLE_ENDIAN__ 1477ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#define LOOP 0x0000affe 1478ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#else 1479ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#define LOOP 0xfeaf0000 1480ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#endif 148176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 148276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture 148376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 148476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 148576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 148676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid); 148776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 148876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 148976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined (I386) 149076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &tcp->baddr) < 0) 149176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 14920e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined (X86_64) 14930e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (upeek(tcp->pid, 8*RIP, &tcp->baddr) < 0) 14940e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return -1; 149576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K) 149676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &tcp->baddr) < 0) 149776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 149876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA) 149976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 150076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ARM) 150176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1502f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined (MIPS) 1503f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman return -1; /* FIXME: I do not know what i do - Flo */ 150476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC) 1505eb285359906700f46b22cf4f9911695034313736Roland McGrath if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &tcp->baddr) < 0) 150676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 150710a88d09ebe283d0dd2ba5deccfe50dc20ea5821Michal Ludvig#elif defined(S390) || defined(S390X) 15084dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman if (upeek(tcp->pid,PT_PSWADDR, &tcp->baddr) < 0) 15094dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman return -1; 1510c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1511c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (upeek(tcp->pid, PT_IAOQ0, &tcp->baddr) < 0) 1512c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return -1; 1513c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tcp->baddr &= ~0x03; 1514ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1515ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (upeek(tcp->pid, 4*REG_PC, &tcp->baddr) < 0) 1516ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman return -1; 151776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 151876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture 151976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 152076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 152176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr); 152276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0); 152376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 152476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 152576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 152676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 152776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 152876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 152976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 153076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 153176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 153276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 153376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15348b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#endif /* !IA64 */ 153576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */ 153676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 153776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 153876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 153976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC /* This code is slightly sparc specific */ 154076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1541e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 154276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define BPT 0x91d02001 /* ta 1 */ 154376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP 0x10800000 /* ba 0 */ 154476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA 0x30800000 /* ba,a 0 */ 154576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define NOP 0x01000000 154676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if LOOPA 154776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[1] = {LOOPA}; 154876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 154976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[2] = {LOOP, NOP}; 155076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 155176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 155276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 155376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 155476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 155576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 155676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 155776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 155876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 155976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 156076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->baddr = regs.r_o7 + 8; 156176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr, 156276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof tcp->inst, (char *)tcp->inst) < 0) { 156376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_READTEXT, ...)"); 156476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 156576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 156676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 156776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 156876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * XXX - BRUTAL MODE ON 156976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We cannot set a real BPT in the child, since it will not be 157076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * traced at the moment it will reach the trap and would probably 157176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * die with a core dump. 157276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Thus, we are force our way in by taking out two instructions 157376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * and insert an eternal loop in stead, in expectance of the SIGSTOP 157476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * generated by out PTRACE_ATTACH. 157576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Of cause, if we evaporate ourselves in the middle of all this... 157676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 157776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 157876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof loopdeloop, (char *) loopdeloop) < 0) { 157976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)"); 158076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 158176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 158276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 158376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 158476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */ 158576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 158676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 158776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 158876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 158976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 159076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 159176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanclearbpt(tcp) 159276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 159376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 159476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 159576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 15960e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#if defined(I386) || defined(X86_64) 159776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long eip; 1598faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(POWERPC) 159976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 1600faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68K) 160176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 1602faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA) 160376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 1604c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1605c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman long iaoq; 1606ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1607ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman long pc; 1608faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* architecture */ 160976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 161076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC 161176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Again, we borrow the SunOS breakpoint code. */ 161276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 161376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 161476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 161576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 161676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 161776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 161876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if(errno) { 161976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 162076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 162176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 162276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 1623faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(IA64) 16247b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (ia32) { 16257b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman unsigned long addr; 16267b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 16277b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (debug) 16287b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 16297b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 16307b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 16317b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 16327b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 16337b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman errno = 0; 16347b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 16357b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (errno) { 16367b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 16377b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 16387b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 16397b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 16407b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 16417b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (upeek(tcp->pid, PT_CR_IIP, &addr) < 0) 16427b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 16437b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (addr != tcp->baddr) { 16447b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman /* The breakpoint has not been reached yet. */ 16457b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (debug) 16467b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, 16477b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 16487b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman addr, tcp->baddr); 16497b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return 0; 16507b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 16517b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } else { 16528b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman unsigned long addr, ipsr; 16538b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid_t pid; 16548b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 16558b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid = tcp->pid; 16568b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 16578b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(pid, PT_CR_IPSR, &ipsr) < 0) 16588b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 16598b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(pid, PT_CR_IIP, &addr) < 0) 16608b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 16618b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 16628b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman /* restore original bundle: */ 16638b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman errno = 0; 16648b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]); 16658b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]); 16668b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (errno) { 16678b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)"); 16688b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 16698b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 16708b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 16718b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman /* restore original "ri" in ipsr: */ 16728b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41); 16738b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman errno = 0; 16748b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr); 16758b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (errno) { 16768b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)"); 16778b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 16788b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 16798b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 16808b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 16818b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 16828b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (addr != (tcp->baddr & ~0x3)) { 16838b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman /* the breakpoint has not been reached yet. */ 16848b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (debug) 16858b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 16868b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman addr, tcp->baddr); 16878b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return 0; 16888b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 16898b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 1690faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#else /* !IA64 && ! SPARC */ 169176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 169276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 169376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 169476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 169576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 169676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 169776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 169876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 169976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 170076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 170176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 170276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 170376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 170476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 170576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 170676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386 170776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &eip) < 0) 170876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 170976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (eip != tcp->baddr) { 171076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 171176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 171276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 171376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 171476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman eip, tcp->baddr); 171576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 171676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 17170e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig#elif defined(X86_64) 17180e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (upeek(tcp->pid, 8*RIP, &eip) < 0) 17190e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return -1; 17200e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (eip != tcp->baddr) { 17210e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig /* The breakpoint has not been reached yet. */ 17220e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig if (debug) 17230e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig fprintf(stderr, 17240e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 17250e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig eip, tcp->baddr); 17260e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig return 0; 17270e035502d28ef981636abde3139247e6fb2bfcceMichal Ludvig } 1728c792698a99b640e7d256e8692c992bd967f0c5b2Wichert Akkerman#elif defined(POWERPC) 1729eb285359906700f46b22cf4f9911695034313736Roland McGrath if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) 173076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 173176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 173276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 173476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 173576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 173676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 173776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1738faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68K) 173976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) 174076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 174176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 174276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 174376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 174476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 174576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 174676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 174776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1748faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA) 174976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, REG_PC, &pc) < 0) 175076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 175176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 175276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 175376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 175476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 175576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 175676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 175776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1758c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1759c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (upeek(tcp->pid, PT_IAOQ0, &iaoq) < 0) 1760c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return -1; 1761c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman iaoq &= ~0x03; 1762c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) { 1763c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman /* The breakpoint has not been reached yet. */ 1764c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (debug) 1765c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n", 1766c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman iaoq, tcp->baddr); 1767c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return 0; 1768c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman } 1769c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman iaoq = tcp->baddr | 3; 1770c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman /* We should be pointing at a 'ldi -1000,r1' in glibc, so it is 1771c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit 1772c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman * has no significant effect. 1773c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman */ 1774c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq); 1775c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq); 1776ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman#elif defined(SH) 1777ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (upeek(tcp->pid, 4*REG_PC, &pc) < 0) 1778ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman return -1; 1779ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (pc != tcp->baddr) { 1780ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman /* The breakpoint has not been reached yet. */ 1781ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman if (debug) 1782ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 1783ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman pc, tcp->baddr); 1784ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman return 0; 1785ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman } 1786ccef63782c10d9ce9da77ef7530861a3d14b1300Wichert Akkerman 1787faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* arch */ 1788faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* !SPARC && !IA64 */ 178976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 179076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 179176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 179276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC 179376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 179476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA 1795e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 179676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 179776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 179876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 179976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 180076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 180176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 180276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 180376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof tcp->inst, (char *) tcp->inst) < 0) { 180476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)"); 180576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 180676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 180776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 180876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 180976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA 181076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 181176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Since we don't have a single instruction breakpoint, we may have 181276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * to adjust the program counter after removing the our `breakpoint'. 181376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 181476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 181576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbpt: ptrace(PTRACE_GETREGS, ...)"); 181676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 181776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 181876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((regs.r_pc < tcp->baddr) || 181976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (regs.r_pc > tcp->baddr + 4)) { 182076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet */ 182176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 182276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 182376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "NOTE: PC not at bpt (pc %#x baddr %#x)\n", 182476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc, tcp->parent->baddr); 182576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 182676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 182776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (regs.r_pc != tcp->baddr) 182876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 182976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n", 183076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc, tcp->baddr); 183176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 183276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc = tcp->baddr; 183376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) { 183476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbpt: ptrace(PTRACE_SETREGS, ...)"); 183576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 183676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 183776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LOOPA */ 183876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */ 183976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 184076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 184176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 184276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 184376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1844d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath#endif 1845d81f1d9aac84cbed9d9dcde84fa44f8b1f9b6a66Roland McGrath 1846bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 184776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 184876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 184976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 185076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 185176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetex(pid, hdr) 185276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 185376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct exec *hdr; 185476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 185576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 185676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 185776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; n < sizeof *hdr; n += 4) { 185876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long res; 185976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(pid, uoff(u_exdata) + n, &res) < 0) 186076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 186176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(((char *) hdr) + n, &res, 4); 186276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 186376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) { 186476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n", 186576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_magic, hdr->a_toolversion, hdr->a_machtype); 186676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n", 186776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry); 186876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 186976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 187076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 187176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 187276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 187376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfixvfork(tcp) 187476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 187576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 187676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 187776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 187876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Change `vfork' in a freshly exec'ed dynamically linked 187976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * executable's (internal) symbol table to plain old `fork' 188076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 188176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 188276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct exec hdr; 188376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic dyn; 188476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic_2 ld; 188576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *strtab, *cp; 188676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 188776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getex(pid, &hdr) < 0) 188876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 188976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!hdr.a_dynamic) 189076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 189176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 189276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) { 189376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read DYNAMIC\n"); 189476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 189576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 189676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) { 189776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read link_dynamic_2\n"); 189876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 189976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 190076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) { 190176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "fixvfork: out of memory\n"); 190276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 190376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 190476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 190576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 190676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 190776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 190876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 190976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 191076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[symbol: %s]\n", cp); 191176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cp += strlen(cp)+1; 191276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 191376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 191476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 191576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 191676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strcmp(cp, "_vfork") == 0) { 191776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 191876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "fixvfork: FOUND _vfork\n"); 191976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strcpy(cp, "_fork"); 192076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 192176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 192276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cp += strlen(cp)+1; 192376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 192476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cp < strtab + ld.ld_symb_size) 192576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 192676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Write entire symbol table back to avoid 192776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * memory alignment bugs in ptrace 192876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 192976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 193076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 193176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 193276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 193376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 193476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 193576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 193676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerr: 193776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 193876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 193976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 194076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 194176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 1942