util.c revision 7b3346be42d6a1f539e95d385ee498f8b3c529f8
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 3876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/user.h> 3976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/param.h> 4076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <fcntl.h> 411d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H 421d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#include <sys/uio.h> 431d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 4476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 4576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <machine/reg.h> 4676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <a.out.h> 4776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <link.h> 4876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 4936915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman 5043a7482edbc7142b91e95d7aedeb9d121fc4880fWichert Akkerman#if defined(linux) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1)) 5176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <linux/ptrace.h> 5236915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#endif 5336915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman 548b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#if defined(LINUX) && defined(IA64) 558b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#include <asm/ptrace_offsets.h> 568b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#endif 578b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 5836915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#ifdef HAVE_SYS_REG_H 5936915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#include <sys/reg.h> 6036915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman# define PTRACE_PEEKUSR PTRACE_PEEKUSER 61faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(HAVE_LINUX_PTRACE_H) 62faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#undef PTRACE_SYSCALL 63faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#include <linux/ptrace.h> 642e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#endif 652e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman 6676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE 6776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/utsname.h> 6876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 6976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 709ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#if defined(LINUX) && defined(SPARC) 719ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 729ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#include <asm/reg.h> 739ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 749ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#if !defined(__GLIBC__) 7576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 7676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <linux/unistd.h> 7776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 7876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define _hack_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\ 7976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman type5,arg5,syscall) \ 8076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantype name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ 8176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ \ 8276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long __res; \ 8376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman\ 8476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman__asm__ volatile ("or %%g0, %1, %%o0\n\t" \ 8576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %2, %%o1\n\t" \ 8676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %3, %%o2\n\t" \ 8776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %4, %%o3\n\t" \ 8876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %5, %%o4\n\t" \ 8976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %6, %%g1\n\t" \ 9076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "t 0x10\n\t" \ 9176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "bcc 1f\n\t" \ 9276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %%o0, %0\n\t" \ 9376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "sub %%g0, %%o0, %0\n\t" \ 9476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "1:\n\t" \ 9576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman : "=r" (__res) \ 9676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman : "0" ((long)(arg1)),"1" ((long)(arg2)), \ 9776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "2" ((long)(arg3)),"3" ((long)(arg4)),"4" ((long)(arg5)), \ 9876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "i" (__NR_##syscall) \ 9976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman : "g1", "o0", "o1", "o2", "o3", "o4"); \ 10076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanif (__res>=0) \ 10176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return (type) __res; \ 10276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerrno = -__res; \ 10376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanreturn -1; \ 10476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 10576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,int,__addr2,ptrace) 10776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define _ptrace 10976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 11176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1129ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 1139ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 11476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* macros */ 11576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MAX 11676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MAX(a,b) (((a) > (b)) ? (a) : (b)) 11776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 11876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MIN 11976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MIN(a,b) (((a) < (b)) ? (a) : (b)) 12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 12176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 12376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_tv(tv, a, b) 12476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv; 12576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint a; 12676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint b; 12776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 12876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a; 12976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = b; 13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 13176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 13376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_nz(a) 13476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a; 13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return a->tv_sec || a->tv_usec; 13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 13876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 14076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_cmp(a, b) 14176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a, *b; 14276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 14376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (a->tv_sec < b->tv_sec 14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec)) 14576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (a->tv_sec > b->tv_sec 14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec)) 14876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 14976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 15076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 15176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandouble 15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_float(tv) 15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv; 15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tv->tv_sec + tv->tv_usec/1000000.0; 15776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 15876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 16076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_add(tv, a, b) 16176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b; 16276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 16376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec + b->tv_sec; 16476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec + b->tv_usec; 16576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tv->tv_usec > 1000000) { 16676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec++; 16776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec -= 1000000; 16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 16976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 17276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_sub(tv, a, b) 17376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b; 17476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec - b->tv_sec; 17676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec - b->tv_usec; 17776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (((long) tv->tv_usec) < 0) { 17876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec--; 17976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec += 1000000; 18076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 18176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 18276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 18376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_div(tv, a, n) 18576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a; 18676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 18776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 18876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n; 18976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000; 19076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 19176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 19276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 19376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 19476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_mul(tv, a, n) 19576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a; 19676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 19876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec * n; 19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec * n + a->tv_usec / 1000000; 20076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 20176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 20276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 20376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar * 20476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanxlookup(xlat, val) 20576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat; 20676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint val; 20776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 20876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (; xlat->str != NULL; xlat++) 20976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val == val) 21076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return xlat->str; 21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 21576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Print entry in struct xlat table, if there. 21676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 21776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 21876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintxval(xlat, val, dflt) 21976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat; 22076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint val; 22176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *dflt; 22276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 22376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *str = xlookup(xlat, val); 22476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 22576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 22676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", str); 22776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 22876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#x /* %s */", val, dflt); 22976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 23076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interpret `xlat' as an array of flags 23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * print the entries whose bits are on in `flags' 23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * return # of flags printed. 23576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 23676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 23776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanaddflags(xlat, flags) 23876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat; 23976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags; 24076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 24176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 24376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 24476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 24576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%s", xlat->str); 24676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 24776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 24876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 24976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 25076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags) { 25176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%#x", flags); 25276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 25376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 25476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 25576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 25676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 25776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 25876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintflags(xlat, flags) 25976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat; 26076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags; 26176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 26276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 26376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *sep; 26476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 26576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags == 0 && xlat->val == 0) { 26676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", xlat->str); 26776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 26876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 26976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 27076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = ""; 27176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 27276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 27376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s%s", sep, xlat->str); 27476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 27576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = "|"; 27676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 27776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 27876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 27976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags) { 28076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s%#x", sep, flags); 28176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 28276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 28376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 28476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 28576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 28676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 28776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintnum(tcp, addr, fmt) 28876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 28976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 29076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *fmt; 29176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 29276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int num; 29376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 29476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 29576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 29676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 29776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 29876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, addr, &num) < 0) { 29976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 30076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 30176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 30276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("["); 30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf(fmt, num); 30476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("]"); 30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 30676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 30776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic char path[MAXPATHLEN + 1]; 30876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 30976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 31076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstring_quote(str) 31176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *str; 31276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 31376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char buf[2 * MAXPATHLEN + 1]; 31476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s; 31576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 31676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!strpbrk(str, "\"\'\\")) { 31776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("\"%s\"", str); 31876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 31976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 32076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (s = buf; *str; str++) { 32176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (*str) { 32276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\"': case '\'': case '\\': 32376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = *str; break; 32476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 32576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = *str; break; 32676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 32776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 32876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s = '\0'; 32976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("\"%s\"", buf); 33076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 33176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 33276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 33376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpath(tcp, addr) 33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 33676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 33776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umovestr(tcp, addr, MAXPATHLEN, path) < 0) 33876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 33976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 34076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman string_quote(path); 34176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 34276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 34376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 34476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 34576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpathn(tcp, addr, n) 34676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 34776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 34876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 34976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 35076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umovestr(tcp, addr, n, path) < 0) 35176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 35276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 35376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman path[n] = '\0'; 35476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman string_quote(path); 35576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 35676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 35776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 35876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 35976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintstr(tcp, addr, len) 36076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 36176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 36276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 36376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 36476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static unsigned char *str = NULL; 36576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char *outstr; 36676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, n, c, usehex; 36776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s, *outend; 36876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 36976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 37076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 37176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 37276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 37376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!str) { 37476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((str = malloc(max_strlen)) == NULL 37576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (outstr = malloc(2*max_strlen)) == NULL) { 37676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "printstr: no memory\n"); 37776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 37876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 37976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 38076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 3812e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman outend = outstr + max_strlen * 2 - 10; 38276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0) { 38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = max_strlen; 38476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umovestr(tcp, addr, n, (char *) str) < 0) { 38576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 38676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 38776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 38876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 38976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 39076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, max_strlen); 39176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, addr, n, (char *) str) < 0) { 39276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 39376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 39476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 39576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 39676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 39776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usehex = 0; 39876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xflag > 1) 39976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usehex = 1; 40076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (xflag) { 40176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 40276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman c = str[i]; 40376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0 && c == '\0') 40476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 40576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!isprint(c) && !isspace(c)) { 40676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usehex = 1; 40776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 40876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 40976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 41076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 41176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 41276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s = outstr; 41376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\"'; 41476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 41576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (usehex) { 41676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 41776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman c = str[i]; 41876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0 && c == '\0') 41976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 42076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, "\\x%02x", c); 42176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 4; 42276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (s > outend) 42376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 42476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 42576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 42676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 42776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 42876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman c = str[i]; 42976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0 && c == '\0') 43076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 43176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (c) { 43276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\"': case '\'': case '\\': 43376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = c; break; 43476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\f': 43576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'f'; break; 43676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\n': 43776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'n'; break; 43876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\r': 43976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'r'; break; 44076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\t': 44176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 't'; break; 44276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\v': 44376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'v'; break; 44476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 44576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isprint(c)) 44676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = c; 44776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (i < n - 1 && isdigit(str[i + 1])) { 44876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, "\\%03o", c); 44976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 4; 45076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 45176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 45276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, "\\%o", c); 45376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += strlen(s); 45476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 45576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 45676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 45776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (s > outend) 45876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 45976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 46076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 46176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 46276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\"'; 46376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i < len || (len < 0 && (i == n || s > outend))) { 46476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '.'; *s++ = '.'; *s++ = '.'; 46576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 46676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s = '\0'; 46776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", outstr); 46876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 46976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 4701d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#if HAVE_SYS_UIO_H 4711d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesvoid 4721d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesdumpiov(tcp, len, addr) 4731d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesstruct tcb * tcp; 4741d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesint len; 4751d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hugheslong addr; 4761d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes{ 4771d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes struct iovec *iov; 4781d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes int i; 4791d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 4801d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 4811d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes if ((iov = (struct iovec *) malloc(len * sizeof *iov)) == NULL) { 4821d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes fprintf(stderr, "dump: No memory"); 4831d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes return; 4841d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 4851d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes if (umoven(tcp, addr, 4861d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes len * sizeof *iov, (char *) iov) >= 0) { 4871d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 4881d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes for (i = 0; i < len; i++) { 4891d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes /* include the buffer number to make it easy to 4901d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes * match up the trace with the source */ 4911d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes tprintf(" * %lu bytes in buffer %d\n", 4921d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes (unsigned long)iov[i].iov_len, i); 4931d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes dumpstr(tcp, (long) iov[i].iov_base, 4941d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes iov[i].iov_len); 4951d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 4961d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes } 4971d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes free((char *) iov); 4981d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 4991d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes} 5001d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 5011d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes 50276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 50376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandumpstr(tcp, addr, len) 50476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 50576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 50676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 50776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 50876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int strsize = -1; 50976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static unsigned char *str; 51076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char outstr[80]; 51176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s; 51276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 51376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 51476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strsize < len) { 51576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 51676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(str); 51776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((str = malloc(len)) == NULL) { 51876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "dump: no memory\n"); 51976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 52076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 52176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strsize = len; 52276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 52376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 52476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, addr, len, (char *) str) < 0) 52576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 52676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 52776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < len; i += 16) { 52876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s = outstr; 52976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " | %05x ", i); 53076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 9; 53176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 53276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 53376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 53476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 53576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " %02x", str[i + j]); 53676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 3; 53776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 53876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 53976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; *s++ = ' '; 54076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 54176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 54276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; 54376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 54476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 54576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 54676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 54776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isprint(str[i + j])) 54876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = str[i + j]; 54976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 55076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '.'; 55176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 55276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 55376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 55476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 55576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s |\n", outstr); 55676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 55776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 55876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 55976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PAGMASK (~(PAGSIZ - 1)) 56076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 56176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * move `len' bytes of data from process `pid' 56276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * at address `addr' to our space at `laddr' 56376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 56476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 56576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumoven(tcp, addr, len, laddr) 56676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 56776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 56876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 56976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 57076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 57176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 57276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 57376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 57476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 5755daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 57676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 57776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 57876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 57976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 58076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 58176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 58276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 58376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 58476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 58576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 58676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 58776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 5885daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 58976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 59076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 59176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 5925daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman /* But if not started, we had a bogus address. */ 59376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("ptrace: umoven"); 59476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 59576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 5965daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 59776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 59876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 59976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 60076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 60176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 60276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 60376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 6045daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 60576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 60676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 60776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 60876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("ptrace: umoven"); 60976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 61076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 6115daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 61276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 61376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 61476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 61576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 61676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 61776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 61876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 61976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 62076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 62176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 62276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 62376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 62476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 62576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 62676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 62876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 62976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 63076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 63176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 63276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 63376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umoven"); 63476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 63576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 63676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 63776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 63876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 63976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 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, m = MIN(sizeof(long), len)); 64776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 64876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 64976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !oldway */ 65076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 65176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 65276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 65376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, PAGSIZ); 65476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 65576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_READDATA, pid, 65676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (char *) addr, len, laddr) < 0) { 65776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umoven: ptrace(PTRACE_READDATA, ...)"); 65876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman abort(); 65976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 66076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 66176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len -= n; 66276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += n; 66376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman laddr += n; 66476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 66576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !oldway */ 66676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 66776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 668bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 669ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 670aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd_as; 6719ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 672aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd; 67376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 674aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes lseek(fd, addr, SEEK_SET); 675aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (read(fd, laddr, len) == -1) 67676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 677bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 67876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 67976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 68076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 68176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 68276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 68376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * like `umove' but make the additional effort of looking 68476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * for a terminating zero byte. 68576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 68676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 68776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumovestr(tcp, addr, len, laddr) 68876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 68976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 69076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 69176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 69276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 693bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 694aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#ifdef HAVE_MP_PROCFS 695aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd_as; 696aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#else 697aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int fd = tcp->pfd; 698aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes#endif 699aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes /* Some systems (e.g. FreeBSD) can be upset if we read off the 700aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes end of valid memory, avoid this by trying to read up 701aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes to page boundaries. But we don't know what a page is (and 702aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes getpagesize(2) (if it exists) doesn't necessarily return 703aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes hardware page size). Assume all pages >= 1024 (a-historical 704aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes I know) */ 705aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 706aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int page = 1024; /* How to find this? */ 707aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int move = page - (addr & (page - 1)); 708aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes int left = len; 709aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 710aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes lseek(fd, addr, SEEK_SET); 711aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes 712aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes while (left) { 713aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (move > left) move = left; 714aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if ((move = read(fd, laddr, move)) == -1) 715aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return left != len ? 0 : -1; 716aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes if (memchr (laddr, 0, move)) break; 717aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes left -= move; 718aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes laddr += move; 719aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes addr += move; 720aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes move = page; 721aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes } 722bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 7235daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 72476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 72576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, n, m; 72676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 72776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 72876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 72976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 73076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 73176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 73276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 73376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 73476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 73576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 73676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 73776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 7385daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 73976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 74076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 74176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 74276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umovestr"); 74376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 7455daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len)); 74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (n & (sizeof(long) - 1)) 74876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[n++] == '\0') 74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 75176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 75276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 75376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 75576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 7565daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 75776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 75876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 76076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umovestr"); 76176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 76276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 7635daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 76476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 76576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < sizeof(long); i++) 76676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[i] == '\0') 76776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 77076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 771bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 772aa09c6b01ee425d419cdae4389fad0a06da489efJohn Hughes return 0; 77376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 77476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 77576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 77676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SPARC 77776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITETEXT 101 77876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITEDATA 102 77976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !SPARC */ 78076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 78176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 78276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 78376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 78476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 78576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanuload(cmd, pid, addr, len, laddr) 78676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint cmd; 78776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 78876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 78976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 79076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 79176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 79276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 79376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 79476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 79576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 79676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, PAGSIZ); 79776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 79876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) { 79976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: ptrace(PTRACE_WRITE, ...)"); 80076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 80176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 80276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len -= n; 80376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += n; 80476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman laddr += n; 80576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 80676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 80776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int peek, poke; 80876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 80976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 81076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 81176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 81276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 81376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 81476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cmd == PTRACE_WRITETEXT) { 81576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKTEXT; 81676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKETEXT; 81776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 81876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 81976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKDATA; 82076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKEDATA; 82176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 82276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 82376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 82476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 82576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); 82676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 82776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(peek, pid, (char *) addr, 0); 82876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 82976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: POKE"); 83076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 83176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 83276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len)); 83376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(poke, pid, (char *)addr, u.val) < 0) { 83476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: POKE"); 83576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 83676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 83776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 83876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 83976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 84076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < sizeof(long)) 84176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(peek, pid, (char *) addr, 0); 84276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(u.x, laddr, m = MIN(sizeof(long), 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#endif 85076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 85176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 85276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 85376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 85476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantload(pid, addr, len, laddr) 85576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 85676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr, len; 85776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 85876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 85976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return uload(PTRACE_WRITETEXT, pid, addr, len, laddr); 86076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 86176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 86276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 86376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandload(pid, addr, len, laddr) 86476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 86576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr; 86676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 86776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 86876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 86976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return uload(PTRACE_WRITEDATA, pid, addr, len, laddr); 87076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 87176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 87276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 87376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 874bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 87576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 87676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 87776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanupeek(pid, off, res) 87876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 87976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong off; 88076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong *res; 88176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 88276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 88376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 88476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE 88576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman { 88676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int is_sun4m = -1; 88776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct utsname name; 88876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 88976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Round up the usual suspects. */ 89076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m == -1) { 89176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (uname(&name) < 0) { 89276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("upeek: uname?"); 89376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 89476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 89576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman is_sun4m = strcmp(name.machine, "sun4m") == 0; 89676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) { 89776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman extern struct xlat struct_user_offsets[]; 89876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct xlat *x; 89976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 90076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (x = struct_user_offsets; x->str; x++) 90176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman x->val += 1024; 90276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 90376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 90476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) 90576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman off += 1024; 90676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 90776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 90876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 90976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman val = ptrace(PTRACE_PEEKUSER, pid, (char *) off, 0); 91076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (val == -1 && errno) { 91176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("upeek: ptrace(PTRACE_PEEKUSER, ... )"); 91276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 91376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 91476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *res = val; 91576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 91676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 91776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 918bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 91976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 92076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong 92176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetpc(tcp) 92276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 92376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 92476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 92576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 92676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 927f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#if defined(I386) 92876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &pc) < 0) 92976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 9308b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#elif defined(IA64) 9318b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(tcp->pid, PT_B0, &pc) < 0) 9328b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 933f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ARM) 93476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*15, &pc) < 0) 93576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 936f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(POWERPC) 93776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_NIP, &pc) < 0) 93876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 939f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(M68k) 94076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) 94176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 942f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ALPHA) 94376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, REG_PC, &pc) < 0) 94476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 945f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS) 946f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman if (upeek(tcp->pid, REG_EPC, &pc) < 0) 947f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman return -1; 948f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(SPARC) 9499ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) 95176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 9529ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman pc = regs.r_pc; 9534dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390) 9544dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman if(upeek(tcp->pid,PT_PSWADDR,&pc) < 0) 955c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 956c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) 957c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return -1; 9587a0b649aeace5c1e1efe4a1d7b1ae6e3a87e0d44Wichert Akkerman#endif 95976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pc; 96076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 96176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 96276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 96376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 96476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Return current program counter for `pid' 96576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Assumes PC is never 0xffffffff 96676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 96776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct regs regs; 96876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 96976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 97076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("getpc: ptrace(PTRACE_GETREGS, ...)"); 97176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 97276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 97376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return regs.r_pc; 97476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 97576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 97676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 97776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* XXX */ 97876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 97976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */ 98076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 981bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 982bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct reg regs; 983bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 984bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return regs.r_eip; 985bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 98676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 98976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintcall(tcp) 99076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 99376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 99476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386 99576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long eip; 99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &eip) < 0) { 99876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[????????] "); 99976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 100076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 100176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", eip); 1002faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(IA62) 10038b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman long ip; 10048b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 10058b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(tcp->pid, PT_B0, &ip) < 0) { 10068b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tprintf("[????????] "); 10078b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return; 10088b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 10098b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tprintf("[%08lx] ", ip); 1010faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(POWERPC) 101176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 101276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 101376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_NIP, &pc) < 0) { 101476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 101576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 101676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 101776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 1018faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68k) 101976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 102076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 102176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) { 102276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 102376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 102476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 102576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 1026faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA) 102776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 102876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 102976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, REG_PC, &pc) < 0) { 103076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 103176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 103276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 103376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 1034faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(SPARC) 10359ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 103676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) { 103776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[????????] "); 103876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 103976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 10409ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tprintf("[%08lx] ", regs.r_pc); 1041c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1042c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman long pc; 1043c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman 1044c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) { 1045c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tprintf ("[????????] "); 1046c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return; 1047c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman } 1048c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tprintf("[%08lx] ", pc); 104975c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman#elif defined(MIPS) 105075c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman long pc; 105175c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman 105275c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman if (upeek(tcp->pid, REG_EPC, &pc) < 0) { 105375c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman tprintf ("[????????] "); 105475c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman return; 105575c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman } 105675c422b3a8c2eecc403f14a00e14f7675149dd07Wichert Akkerman tprintf("[%08lx] ", pc); 1057faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* !architecture */ 105876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 105976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 106076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 106176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct regs regs; 106276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 106376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 106476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("printcall: ptrace(PTRACE_GETREGS, ...)"); 106576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[????????] "); 106676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 106776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 106876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08x] ", regs.r_o7); 106976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 107076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 107176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 107276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* XXX */ 107376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[????????] "); 107476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 107576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1076bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1077bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct reg regs; 1078bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 1079bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tprintf("[%08x] ", regs.r_eip); 1080bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 108176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 108276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1083bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 108476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 108576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 108676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermansetbpt(tcp) 108776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 108876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 108976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 109076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 109176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC 109276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* We simply use the SunOS breakpoint code. */ 109376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10949ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 109576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA 0x30800000 /* ba,a 0 */ 109676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 109776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 109876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 109976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 110076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 110176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 110276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 110376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 110476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 11059ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tcp->baddr = regs.r_o7 + 8; 110676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 110776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0); 110876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if(errno) { 110976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 111076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 111176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 111276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 111376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 111476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * XXX - BRUTAL MODE ON 111576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We cannot set a real BPT in the child, since it will not be 111676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * traced at the moment it will reach the trap and would probably 111776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * die with a core dump. 111876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Thus, we are force our way in by taking out two instructions 111976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * and insert an eternal loop instead, in expectance of the SIGSTOP 112076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * generated by out PTRACE_ATTACH. 112176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Of cause, if we evaporate ourselves in the middle of all this... 112276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 112376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 112476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOPA); 112576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if(errno) { 112676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 112776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 112876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 112976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 113076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 113176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !SPARC */ 11328b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#ifdef IA64 11337b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (ia32) { 11347b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman# define LOOP 0x0000feeb 11357b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 11367b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "PANIC: bpt already set in pid %u\n", 11377b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->pid); 11387b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 11397b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 11407b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (upeek(tcp->pid, PT_CR_IIP, &tcp->baddr) < 0) 11417b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 11427b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (debug) 11437b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "[%d] setting bpt at %lx\n", 11447b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->pid, tcp->baddr); 11457b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, 11467b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman (char *) tcp->baddr, 0); 11477b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (errno) { 11487b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 11497b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 11507b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 11517b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 11527b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (errno) { 11537b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 11547b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 11557b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 11567b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->flags |= TCB_BPTSET; 11577b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } else { 11587b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman /* 11597b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * XXX Use break instead! 11607b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * 11617b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * Our strategy here is to replace the bundle that 11627b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * contained the clone() syscall with a bundle of the 11637b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * form: 11647b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * 11657b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * { 1: br 1b; br 1b; br 1b } 11667b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * 11677b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * This ensures that the newly forked child will loop 11687b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman * endlessly until we've got a chance to attach to it. 11697b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman */ 11708b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman# define LOOP0 0x0000100000000017 11718b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman# define LOOP1 0x4000000000200000 11728b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman unsigned long addr, ipsr; 11738b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid_t pid; 11748b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 11758b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid = tcp->pid; 11768b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(pid, PT_CR_IPSR, &ipsr) < 0) 11778b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 11788b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(pid, PT_CR_IIP, &addr) < 0) 11798b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 11807b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman /* store "ri" in low two bits */ 11817b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->baddr = addr | ((ipsr >> 41) & 0x3); 11828b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 11838b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman errno = 0; 11847b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0, 11857b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 0); 11867b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8, 11877b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 0); 11888b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (errno) { 11898b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 11908b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 11918b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 11928b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 11938b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman errno = 0; 11948b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0); 11958b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1); 11968b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (errno) { 11978b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 11988b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 11998b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 12008b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tcp->flags |= TCB_BPTSET; 12018b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 12028b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#else /* !IA64 */ 120376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 120476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined (I386) 120576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP 0x0000feeb 120676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K) 120776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP 0x60fe0000 120876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA) 12094dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0xc3ffffff 121076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC) 12114dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0x0000feeb 121276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined(ARM) 12139a8a37f2b28d1c0d3f57951fd5aeeb96ff7d2f16Wichert Akkerman#define LOOP 0xEAFFFFFE 1214f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS) 12154dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0x1000ffff 12164dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390) 12174dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0xa7f40000 /* BRC 15,0 */ 1218c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1219c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#define LOOP 0xe81f1ff7 /* b,l,n <loc>,r0 */ 122076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 122176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture 122276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 122376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 122476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 122576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid); 122676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 122776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 122876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined (I386) 122976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &tcp->baddr) < 0) 123076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 123176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K) 123276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &tcp->baddr) < 0) 123376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 123476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA) 123576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 123676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ARM) 123776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1238f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined (MIPS) 1239f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman return -1; /* FIXME: I do not know what i do - Flo */ 124076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC) 124176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_NIP, &tcp->baddr) < 0) 124276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 12434dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390) 12444dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman if (upeek(tcp->pid,PT_PSWADDR, &tcp->baddr) < 0) 12454dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman return -1; 1246c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1247c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (upeek(tcp->pid, PT_IAOQ0, &tcp->baddr) < 0) 1248c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return -1; 1249c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman tcp->baddr &= ~0x03; 125076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 125176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture 125276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 125376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 125476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr); 125576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0); 125676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 125776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 125876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 125976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 126076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 126176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 126276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 126376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 126476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 126576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 126676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12678b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#endif /* !IA64 */ 126876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */ 126976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 127076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 127176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 127276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC /* This code is slightly sparc specific */ 127376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1274e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 127576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define BPT 0x91d02001 /* ta 1 */ 127676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP 0x10800000 /* ba 0 */ 127776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA 0x30800000 /* ba,a 0 */ 127876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define NOP 0x01000000 127976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if LOOPA 128076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[1] = {LOOPA}; 128176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 128276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[2] = {LOOP, NOP}; 128376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 128476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 128576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 128676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 128776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 128876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 128976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 129076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 129176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 129276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 129376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->baddr = regs.r_o7 + 8; 129476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr, 129576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof tcp->inst, (char *)tcp->inst) < 0) { 129676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_READTEXT, ...)"); 129776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 129876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 129976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 130076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 130176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * XXX - BRUTAL MODE ON 130276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We cannot set a real BPT in the child, since it will not be 130376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * traced at the moment it will reach the trap and would probably 130476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * die with a core dump. 130576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Thus, we are force our way in by taking out two instructions 130676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * and insert an eternal loop in stead, in expectance of the SIGSTOP 130776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * generated by out PTRACE_ATTACH. 130876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Of cause, if we evaporate ourselves in the middle of all this... 130976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 131076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 131176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof loopdeloop, (char *) loopdeloop) < 0) { 131276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)"); 131376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 131476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 131576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 131676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 131776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */ 131876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 131976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 132076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 132176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 132276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 132376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 132476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanclearbpt(tcp) 132576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 132676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 132776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 132876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 1329faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#if defined(I386) 133076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long eip; 1331faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(POWERPC) 133276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 1333faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68K) 133476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 1335faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA) 133676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 1337c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1338c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman long iaoq; 1339faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* architecture */ 134076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 134176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC 134276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Again, we borrow the SunOS breakpoint code. */ 134376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 134476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 134576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 134676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 134776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 134876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 134976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if(errno) { 135076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 135176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 135276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 135376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 1354faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(IA64) 13557b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (ia32) { 13567b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman unsigned long addr; 13577b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 13587b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (debug) 13597b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 13607b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 13617b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 13627b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 13637b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 13647b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman errno = 0; 13657b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 13667b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (errno) { 13677b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 13687b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 13697b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 13707b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 13717b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 13727b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (upeek(tcp->pid, PT_CR_IIP, &addr) < 0) 13737b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return -1; 13747b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (addr != tcp->baddr) { 13757b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman /* The breakpoint has not been reached yet. */ 13767b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman if (debug) 13777b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman fprintf(stderr, 13787b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 13797b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman addr, tcp->baddr); 13807b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman return 0; 13817b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } 13827b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman } else { 13838b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman unsigned long addr, ipsr; 13848b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid_t pid; 13858b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 13868b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman pid = tcp->pid; 13878b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 13888b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(pid, PT_CR_IPSR, &ipsr) < 0) 13898b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 13908b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (upeek(pid, PT_CR_IIP, &addr) < 0) 13918b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 13928b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 13938b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman /* restore original bundle: */ 13948b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman errno = 0; 13958b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]); 13968b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]); 13978b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (errno) { 13988b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)"); 13998b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 14008b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 14018b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 14028b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman /* restore original "ri" in ipsr: */ 14038b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41); 14048b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman errno = 0; 14058b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr); 14068b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (errno) { 14078b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)"); 14088b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return -1; 14098b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 14108b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 14118b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 14128b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman 14138b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (addr != (tcp->baddr & ~0x3)) { 14148b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman /* the breakpoint has not been reached yet. */ 14158b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman if (debug) 14168b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 14178b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman addr, tcp->baddr); 14188b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman return 0; 14198b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 14208b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 1421faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#else /* !IA64 && ! SPARC */ 142276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 142376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 142476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 142576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 142676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 142776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 142876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 142976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 143076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 143176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 143276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 143376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 143476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 143576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 143676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 143776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386 143876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &eip) < 0) 143976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 144076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (eip != tcp->baddr) { 144176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 144276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 144376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 144476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 144576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman eip, tcp->baddr); 144676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 144776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1448c792698a99b640e7d256e8692c992bd967f0c5b2Wichert Akkerman#elif defined(POWERPC) 144976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_NIP, &pc) < 0) 145076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 145176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 145276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 145376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 145476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 145576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 145676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 145776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1458faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(M68K) 145976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) 146076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 146176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 146276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 146376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 146476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 146576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 146676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 146776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1468faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#elif defined(ALPHA) 146976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, REG_PC, &pc) < 0) 147076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 147176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 147276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 147376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 147476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 147576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 147676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 147776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1478c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman#elif defined(HPPA) 1479c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (upeek(tcp->pid, PT_IAOQ0, &iaoq) < 0) 1480c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return -1; 1481c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman iaoq &= ~0x03; 1482c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) { 1483c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman /* The breakpoint has not been reached yet. */ 1484c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman if (debug) 1485c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n", 1486c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman iaoq, tcp->baddr); 1487c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman return 0; 1488c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman } 1489c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman iaoq = tcp->baddr | 3; 1490c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman /* We should be pointing at a 'ldi -1000,r1' in glibc, so it is 1491c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit 1492c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman * has no significant effect. 1493c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman */ 1494c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq); 1495c1652e2095fcd9ac62cf2669ef6aec5fd0052851Wichert Akkerman ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq); 1496faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* arch */ 1497faf722234dc8af97776f94fdda7e100fb60650a2Wichert Akkerman#endif /* !SPARC && !IA64 */ 149876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 149976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 150076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 150176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC 150276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 150376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA 1504e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 150576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 150676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 150776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 150876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 150976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 151076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 151176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 151276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof tcp->inst, (char *) tcp->inst) < 0) { 151376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)"); 151476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 151576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 151676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 151776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 151876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA 151976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 152076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Since we don't have a single instruction breakpoint, we may have 152176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * to adjust the program counter after removing the our `breakpoint'. 152276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 152376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 152476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbpt: ptrace(PTRACE_GETREGS, ...)"); 152576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 152676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 152776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((regs.r_pc < tcp->baddr) || 152876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (regs.r_pc > tcp->baddr + 4)) { 152976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet */ 153076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 153176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 153276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "NOTE: PC not at bpt (pc %#x baddr %#x)\n", 153376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc, tcp->parent->baddr); 153476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 153576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 153676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (regs.r_pc != tcp->baddr) 153776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 153876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n", 153976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc, tcp->baddr); 154076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 154176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc = tcp->baddr; 154276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) { 154376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbpt: ptrace(PTRACE_SETREGS, ...)"); 154476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 154576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 154676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LOOPA */ 154776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */ 154876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 154976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 155076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 155176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 155276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1553bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 155476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 155576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 155676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 155776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 155876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetex(pid, hdr) 155976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 156076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct exec *hdr; 156176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 156276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 156376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 156476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; n < sizeof *hdr; n += 4) { 156576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long res; 156676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(pid, uoff(u_exdata) + n, &res) < 0) 156776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 156876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(((char *) hdr) + n, &res, 4); 156976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 157076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) { 157176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n", 157276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_magic, hdr->a_toolversion, hdr->a_machtype); 157376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n", 157476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry); 157576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 157676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 157776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 157876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 157976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 158076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfixvfork(tcp) 158176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 158276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 158376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 158476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 158576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Change `vfork' in a freshly exec'ed dynamically linked 158676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * executable's (internal) symbol table to plain old `fork' 158776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 158876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 158976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct exec hdr; 159076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic dyn; 159176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic_2 ld; 159276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *strtab, *cp; 159376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 159476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getex(pid, &hdr) < 0) 159576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 159676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!hdr.a_dynamic) 159776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 159876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 159976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) { 160076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read DYNAMIC\n"); 160176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 160276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 160376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) { 160476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read link_dynamic_2\n"); 160576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 160676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 160776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) { 160876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "fixvfork: out of memory\n"); 160976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 161076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 161176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 161276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 161376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 161476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 161576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 161676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 161776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[symbol: %s]\n", cp); 161876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cp += strlen(cp)+1; 161976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 162076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 162176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 162276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 162376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strcmp(cp, "_vfork") == 0) { 162476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 162576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "fixvfork: FOUND _vfork\n"); 162676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strcpy(cp, "_fork"); 162776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 162876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 162976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cp += strlen(cp)+1; 163076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 163176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cp < strtab + ld.ld_symb_size) 163276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 163376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Write entire symbol table back to avoid 163476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * memory alignment bugs in ptrace 163576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 163676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 163776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 163876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 163976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 164076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 164176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 164276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 164376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerr: 164476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 164576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 164676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 164776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 164876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 1649