util.c revision 9a8a37f2b28d1c0d3f57951fd5aeeb96ff7d2f16
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> 4176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 4276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <machine/reg.h> 4376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <a.out.h> 4476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <link.h> 4576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 4636915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman 4715dea97f8a05b2b67f5752137fe93e3cc20db6ecWichert Akkerman#if defined(linux) 4876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <linux/ptrace.h> 4936915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#endif 5036915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman 5136915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#ifdef HAVE_SYS_REG_H 5236915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman#include <sys/reg.h> 5336915a19e4806339b76209b20fdbd1091c126115Wichert Akkerman# define PTRACE_PEEKUSR PTRACE_PEEKUSER 542e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#endif 5576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 562e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#ifdef HAVE_SYS_PTRACE_H 572e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#include <sys/ptrace.h> 582e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman#endif 592e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman 6076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE 6176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/utsname.h> 6276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 6376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 649ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#if defined(LINUX) && defined(SPARC) 659ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 669ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#include <asm/reg.h> 679ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 689ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#if !defined(__GLIBC__) 6976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 7076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <linux/unistd.h> 7176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 7276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define _hack_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\ 7376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman type5,arg5,syscall) \ 7476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantype name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ 7576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ \ 7676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long __res; \ 7776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman\ 7876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman__asm__ volatile ("or %%g0, %1, %%o0\n\t" \ 7976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %2, %%o1\n\t" \ 8076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %3, %%o2\n\t" \ 8176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %4, %%o3\n\t" \ 8276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %5, %%o4\n\t" \ 8376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %6, %%g1\n\t" \ 8476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "t 0x10\n\t" \ 8576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "bcc 1f\n\t" \ 8676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "or %%g0, %%o0, %0\n\t" \ 8776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "sub %%g0, %%o0, %0\n\t" \ 8876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "1:\n\t" \ 8976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman : "=r" (__res) \ 9076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman : "0" ((long)(arg1)),"1" ((long)(arg2)), \ 9176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "2" ((long)(arg3)),"3" ((long)(arg4)),"4" ((long)(arg5)), \ 9276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "i" (__NR_##syscall) \ 9376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman : "g1", "o0", "o1", "o2", "o3", "o4"); \ 9476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanif (__res>=0) \ 9576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return (type) __res; \ 9676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerrno = -__res; \ 9776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanreturn -1; \ 9876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 9976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,int,__addr2,ptrace) 10176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define _ptrace 10376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 10576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1069ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 1079ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 10876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* macros */ 10976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MAX 11076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MAX(a,b) (((a) > (b)) ? (a) : (b)) 11176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 11276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef MIN 11376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define MIN(a,b) (((a) < (b)) ? (a) : (b)) 11476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 11576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 11776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_tv(tv, a, b) 11876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv; 11976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint a; 12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint b; 12176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 12276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a; 12376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = b; 12476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 12576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 12776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_nz(a) 12876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a; 12976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return a->tv_sec || a->tv_usec; 13176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 13276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 13476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_cmp(a, b) 13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *a, *b; 13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (a->tv_sec < b->tv_sec 13876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec)) 13976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 14076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (a->tv_sec > b->tv_sec 14176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec)) 14276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 14376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 14576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandouble 14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_float(tv) 14876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv; 14976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 15076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tv->tv_sec + tv->tv_usec/1000000.0; 15176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 15276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_add(tv, a, b) 15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b; 15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 15776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec + b->tv_sec; 15876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec + b->tv_usec; 15976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tv->tv_usec > 1000000) { 16076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec++; 16176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec -= 1000000; 16276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 16376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 16476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 16676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_sub(tv, a, b) 16776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a, *b; 16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 16976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec - b->tv_sec; 17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec - b->tv_usec; 17176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (((long) tv->tv_usec) < 0) { 17276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec--; 17376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec += 1000000; 17476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 17676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 17876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_div(tv, a, n) 17976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a; 18076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 18176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 18276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n; 18376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000; 18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 18576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 18676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 18776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 18876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantv_mul(tv, a, n) 18976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct timeval *tv, *a; 19076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 19176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 19276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec = a->tv_usec * n; 19376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_sec = a->tv_sec * n + a->tv_usec / 1000000; 19476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv->tv_usec %= 1000000; 19576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 19676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar * 19876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanxlookup(xlat, val) 19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat; 20076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint val; 20176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 20276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (; xlat->str != NULL; xlat++) 20376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val == val) 20476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return xlat->str; 20576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 20676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 20776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 20876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 20976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Print entry in struct xlat table, if there. 21076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintxval(xlat, val, dflt) 21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat; 21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint val; 21576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *dflt; 21676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 21776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *str = xlookup(xlat, val); 21876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 21976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 22076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", str); 22176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 22276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#x /* %s */", val, dflt); 22376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 22476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 22576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 22676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interpret `xlat' as an array of flags 22776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * print the entries whose bits are on in `flags' 22876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * return # of flags printed. 22976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 23076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanaddflags(xlat, flags) 23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat; 23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags; 23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 23576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 23676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 23776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 23876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 23976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%s", xlat->str); 24076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 24176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 24376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 24476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags) { 24576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("|%#x", flags); 24676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 24776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 24876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 24976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 25076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 25176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 25276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintflags(xlat, flags) 25376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct xlat *xlat; 25476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint flags; 25576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 25676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 25776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *sep; 25876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 25976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags == 0 && xlat->val == 0) { 26076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", xlat->str); 26176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 26276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 26376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 26476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = ""; 26576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; xlat->str; xlat++) { 26676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xlat->val && (flags & xlat->val) == xlat->val) { 26776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s%s", sep, xlat->str); 26876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman flags &= ~xlat->val; 26976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sep = "|"; 27076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 27176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 27276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 27376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (flags) { 27476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s%#x", sep, flags); 27576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n++; 27676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 27776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 27876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 27976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 28076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 28176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintnum(tcp, addr, fmt) 28276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 28376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 28476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *fmt; 28576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 28676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int num; 28776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 28876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 28976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 29076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 29176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 29276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, addr, &num) < 0) { 29376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 29476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 29576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 29676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("["); 29776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf(fmt, num); 29876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("]"); 29976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 30076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 30176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic char path[MAXPATHLEN + 1]; 30276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 30476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstring_quote(str) 30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *str; 30676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 30776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char buf[2 * MAXPATHLEN + 1]; 30876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s; 30976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 31076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!strpbrk(str, "\"\'\\")) { 31176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("\"%s\"", str); 31276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 31376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 31476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (s = buf; *str; str++) { 31576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (*str) { 31676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\"': case '\'': case '\\': 31776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = *str; break; 31876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 31976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = *str; break; 32076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 32176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 32276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s = '\0'; 32376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("\"%s\"", buf); 32476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 32576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 32676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 32776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpath(tcp, addr) 32876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 32976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 33076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 33176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umovestr(tcp, addr, MAXPATHLEN, path) < 0) 33276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 33376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman string_quote(path); 33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 33676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 33776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 33876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 33976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintpathn(tcp, addr, n) 34076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 34176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 34276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint n; 34376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 34476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umovestr(tcp, addr, n, path) < 0) 34576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 34676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 34776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman path[n] = '\0'; 34876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman string_quote(path); 34976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 35076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 35176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 35276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 35376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintstr(tcp, addr, len) 35476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 35576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 35676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 35776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 35876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static unsigned char *str = NULL; 35976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char *outstr; 36076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, n, c, usehex; 36176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s, *outend; 36276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 36376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!addr) { 36476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("NULL"); 36576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 36676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 36776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!str) { 36876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((str = malloc(max_strlen)) == NULL 36976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (outstr = malloc(2*max_strlen)) == NULL) { 37076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "printstr: no memory\n"); 37176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 37276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 37376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 37476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 3752e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman outend = outstr + max_strlen * 2 - 10; 37676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0) { 37776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = max_strlen; 37876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umovestr(tcp, addr, n, (char *) str) < 0) { 37976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 38076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 38176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 38276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 38476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, max_strlen); 38576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, addr, n, (char *) str) < 0) { 38676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%#lx", addr); 38776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 38876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 38976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 39076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 39176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usehex = 0; 39276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (xflag > 1) 39376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usehex = 1; 39476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (xflag) { 39576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 39676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman c = str[i]; 39776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0 && c == '\0') 39876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 39976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!isprint(c) && !isspace(c)) { 40076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usehex = 1; 40176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 40276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 40376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 40476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 40576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 40676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s = outstr; 40776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\"'; 40876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 40976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (usehex) { 41076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 41176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman c = str[i]; 41276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0 && c == '\0') 41376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 41476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, "\\x%02x", c); 41576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 4; 41676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (s > outend) 41776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 41876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 41976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 42076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 42176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 42276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman c = str[i]; 42376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < 0 && c == '\0') 42476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 42576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (c) { 42676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\"': case '\'': case '\\': 42776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = c; break; 42876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\f': 42976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'f'; break; 43076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\n': 43176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'n'; break; 43276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\r': 43376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'r'; break; 43476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\t': 43576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 't'; break; 43676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case '\v': 43776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\\'; *s++ = 'v'; break; 43876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 43976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isprint(c)) 44076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = c; 44176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (i < n - 1 && isdigit(str[i + 1])) { 44276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, "\\%03o", c); 44376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 4; 44476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 44576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 44676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, "\\%o", c); 44776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += strlen(s); 44876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 44976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 45076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 45176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (s > outend) 45276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 45376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 45476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 45576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 45676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '\"'; 45776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i < len || (len < 0 && (i == n || s > outend))) { 45876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '.'; *s++ = '.'; *s++ = '.'; 45976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 46076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s = '\0'; 46176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s", outstr); 46276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 46376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 46476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 46576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandumpstr(tcp, addr, len) 46676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 46776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 46876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 46976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 47076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int strsize = -1; 47176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static unsigned char *str; 47276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char outstr[80]; 47376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *s; 47476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 47576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 47676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strsize < len) { 47776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (str) 47876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(str); 47976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((str = malloc(len)) == NULL) { 48076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "dump: no memory\n"); 48176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 48276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 48376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strsize = len; 48476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 48576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 48676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, addr, len, (char *) str) < 0) 48776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 48876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 48976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < len; i += 16) { 49076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s = outstr; 49176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " | %05x ", i); 49276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 9; 49376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 49476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 49576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 49676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 49776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(s, " %02x", str[i + j]); 49876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman s += 3; 49976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 50076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 50176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; *s++ = ' '; 50276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 50376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 50476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; *s++ = ' '; 50576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (j = 0; j < 16; j++) { 50676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j == 8) 50776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 50876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i + j < len) { 50976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isprint(str[i + j])) 51076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = str[i + j]; 51176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 51276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = '.'; 51376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 51476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 51576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *s++ = ' '; 51676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 51776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s |\n", outstr); 51876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 51976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 52076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 52176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PAGMASK (~(PAGSIZ - 1)) 52276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 52376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * move `len' bytes of data from process `pid' 52476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * at address `addr' to our space at `laddr' 52576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 52676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 52776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumoven(tcp, addr, len, laddr) 52876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 52976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 53076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 53176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 53276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 53376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 53476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 53576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 53676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 5375daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 53876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 53976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 54076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 54176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 54276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 54376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 54476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 54576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 54676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 54776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 54876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 54976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 5505daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 55176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 55276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 55376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 5545daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman /* But if not started, we had a bogus address. */ 55576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("ptrace: umoven"); 55676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 55776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 5585daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 55976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 56076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 56176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 56276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 56376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 56476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 56576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 5665daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 56776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 56876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 56976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 57076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("ptrace: umoven"); 57176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 57276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 5735daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 57476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 57576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 57676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 57776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 57876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 57976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 58076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 58176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 58276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 58376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 58476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 58576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 58676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 58776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 58876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 58976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 59076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 59176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 59276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 59376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 59476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 59576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umoven"); 59676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 59776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 59876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 59976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 60076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 60176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 60276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 60376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 60476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 60576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umoven"); 60676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 60776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 60876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 60976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 61076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 61176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !oldway */ 61276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 61376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 61476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 61576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, PAGSIZ); 61676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 61776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_READDATA, pid, 61876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (char *) addr, len, laddr) < 0) { 61976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umoven: ptrace(PTRACE_READDATA, ...)"); 62076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman abort(); 62176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 62276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 62376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len -= n; 62476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += n; 62576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman laddr += n; 62676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !oldway */ 62876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 62976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 63076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 631ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 6329ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (pread(tcp->pfd_as, laddr, len, addr) == -1) 6339ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 6349ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 63576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 63676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We would like to use pread preferentially for speed 63776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * but even though SGI has it in their library, it no longer works. 63876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 63976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef MIPS 64076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#undef HAVE_PREAD 64176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 64276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_PREAD 64376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pread(tcp->pfd, laddr, len, addr) == -1) 64476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 64576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !HAVE_PREAD */ 64676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman lseek(tcp->pfd, addr, SEEK_SET); 64776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (read(tcp->pfd, laddr, len) == -1) 64876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 64976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_PREAD */ 650ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#endif /* HAVE_MP_PROCFS */ 65176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */ 65276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 65376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 65476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 65576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 65676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 65776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * like `umove' but make the additional effort of looking 65876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * for a terminating zero byte. 65976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 66076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 66176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanumovestr(tcp, addr, len, laddr) 66276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 66376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 66476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 66576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 66676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 66771bdaff3b7009ce6d7fa9d8dda569b758ae238afWichert Akkerman#ifdef SVR4 66876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return umoven(tcp, addr, len, laddr); 66976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !SVR4 */ 6705daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman int started = 0; 67176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 67276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, n, m; 67376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 67476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 67576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 67676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 67776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 67876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 67976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 68076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 68176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); /* residue */ 68276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 68376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 68476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 6855daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 68676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 68776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 68876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 68976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umovestr"); 69076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 69176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 6925daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 69376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len)); 69476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (n & (sizeof(long) - 1)) 69576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[n++] == '\0') 69676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 69776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 69876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 69976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 70076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 70176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 70276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 7035daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (started && (errno==EPERM || errno==EIO)) { 70476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Ran into 'end of memory' - stupid "printpath" */ 70576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 70676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 70776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("umovestr"); 70876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 70976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 7105daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman started = 1; 71176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 71276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < sizeof(long); i++) 71376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (u.x[i] == '\0') 71476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 71576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 71676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 71776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 71876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 71976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !SVR4 */ 72076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 72176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 72276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 72376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SPARC 72476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITETEXT 101 72576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define PTRACE_WRITEDATA 102 72676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !SPARC */ 72776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 72876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 72976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 73076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 73176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 73276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanuload(cmd, pid, addr, len, laddr) 73376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint cmd; 73476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 73576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong addr; 73676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 73776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 73876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 73976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 74076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 74176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 74276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 74376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(len, PAGSIZ); 74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 74576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) { 74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: ptrace(PTRACE_WRITE, ...)"); 74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 74876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len -= n; 75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += n; 75176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman laddr += n; 75276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 75376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int peek, poke; 75576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n, m; 75676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman union { 75776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 75876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char x[sizeof(long)]; 75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } u; 76076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 76176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cmd == PTRACE_WRITETEXT) { 76276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKTEXT; 76376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKETEXT; 76476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 76576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 76676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman peek = PTRACE_PEEKDATA; 76776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poke = PTRACE_POKEDATA; 76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (addr & (sizeof(long) - 1)) { 77076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* addr not a multiple of sizeof(long) */ 77176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = addr - (addr & -sizeof(long)); /* residue */ 77276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr &= -sizeof(long); 77376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 77476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(peek, pid, (char *) addr, 0); 77576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 77676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: POKE"); 77776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 77876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 77976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len)); 78076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(poke, pid, (char *)addr, u.val) < 0) { 78176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: POKE"); 78276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 78376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 78476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 78576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 78676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (len) { 78776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len < sizeof(long)) 78876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman u.val = ptrace(peek, pid, (char *) addr, 0); 78976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(u.x, laddr, m = MIN(sizeof(long), len)); 79076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(poke, pid, (char *) addr, u.val) < 0) { 79176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("uload: POKE"); 79276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 79376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 79476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr += sizeof(long), laddr += m, len -= m; 79576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 79676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 79776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 79876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 79976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 80076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 80176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantload(pid, addr, len, laddr) 80276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 80376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr, len; 80476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 80576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 80676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return uload(PTRACE_WRITETEXT, pid, addr, len, laddr); 80776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 80876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 80976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 81076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandload(pid, addr, len, laddr) 81176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 81276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint addr; 81376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint len; 81476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *laddr; 81576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 81676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return uload(PTRACE_WRITEDATA, pid, addr, len, laddr); 81776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 81876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 81976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 82076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 82176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SVR4 82276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 82376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 82476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanupeek(pid, off, res) 82576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 82676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong off; 82776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong *res; 82876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 82976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long val; 83076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 83176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4_KERNEL_ARCH_KLUDGE 83276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman { 83376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int is_sun4m = -1; 83476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct utsname name; 83576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 83676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Round up the usual suspects. */ 83776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m == -1) { 83876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (uname(&name) < 0) { 83976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("upeek: uname?"); 84076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 84176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 84276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman is_sun4m = strcmp(name.machine, "sun4m") == 0; 84376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) { 84476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman extern struct xlat struct_user_offsets[]; 84576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct xlat *x; 84676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 84776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (x = struct_user_offsets; x->str; x++) 84876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman x->val += 1024; 84976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 85076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 85176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (is_sun4m) 85276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman off += 1024; 85376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 85476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 85576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 85676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman val = ptrace(PTRACE_PEEKUSER, pid, (char *) off, 0); 85776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (val == -1 && errno) { 85876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("upeek: ptrace(PTRACE_PEEKUSER, ... )"); 85976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 86076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 86176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *res = val; 86276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 86376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 86476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 86576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !SVR4 */ 86676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 86776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanlong 86876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetpc(tcp) 86976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 87076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 87176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 87276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 87376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 874f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#if defined(I386) 87576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &pc) < 0) 87676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 877f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ARM) 87876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*15, &pc) < 0) 87976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 880f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(POWERPC) 88176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_NIP, &pc) < 0) 88276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 883f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(M68k) 88476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) 88576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 886f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(ALPHA) 88776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, REG_PC, &pc) < 0) 88876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 889f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS) 890f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman if (upeek(tcp->pid, REG_EPC, &pc) < 0) 891f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman return -1; 892f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(SPARC) 8939ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 89476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) 89576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 8969ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman pc = regs.r_pc; 8974dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390) 8984dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman if(upeek(tcp->pid,PT_PSWADDR,&pc) < 0) 8997a0b649aeace5c1e1efe4a1d7b1ae6e3a87e0d44Wichert Akkerman#endif 90076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pc; 90176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 90276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 90376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 90476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 90576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Return current program counter for `pid' 90676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Assumes PC is never 0xffffffff 90776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 90876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct regs regs; 90976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 91076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 91176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("getpc: ptrace(PTRACE_GETREGS, ...)"); 91276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 91376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 91476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return regs.r_pc; 91576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 91676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 91776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 91876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* XXX */ 91976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 92076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */ 92176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 92276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 92376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 92476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 92576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintcall(tcp) 92676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 92776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 92876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 92976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 93076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386 93176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long eip; 93276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 93376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &eip) < 0) { 93476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[????????] "); 93576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 93676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 93776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", eip); 93876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !I386K */ 93976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef POWERPC 94076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 94176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 94276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_NIP, &pc) < 0) { 94376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 94476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 94576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 94676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 94776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !POWERPC */ 94876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef M68K 94976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 95176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) { 95276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 95376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 95476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 95576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 95676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !M68K */ 95776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef ALPHA 95876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 95976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 96076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, REG_PC, &pc) < 0) { 96176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf ("[????????] "); 96276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 96376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 96476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08lx] ", pc); 96576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !ALPHA */ 96676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC 9679ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 96876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) { 96976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[????????] "); 97076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 97176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 9729ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tprintf("[%08lx] ", regs.r_pc); 97376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */ 97476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* ALPHA */ 97576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !M68K */ 97676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !POWERPC */ 97776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !I386 */ 97876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 97976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 98076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 98176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct regs regs; 98276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 98376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 98476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("printcall: ptrace(PTRACE_GETREGS, ...)"); 98576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[????????] "); 98676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[%08x] ", regs.r_o7); 98976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 99076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* XXX */ 99376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[????????] "); 99476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 99576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 99876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SVR4 99976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 100076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 100176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermansetbpt(tcp) 100276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 100376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 100476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 100576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 100676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC 100776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* We simply use the SunOS breakpoint code. */ 100876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10099ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct regs regs; 101076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA 0x30800000 /* ba,a 0 */ 101176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 101276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 101376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 101476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 101576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 101676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 101776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 101876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 101976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 10209ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tcp->baddr = regs.r_o7 + 8; 102176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 102276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0); 102376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if(errno) { 102476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 102576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 102676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 102776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 102876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 102976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * XXX - BRUTAL MODE ON 103076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We cannot set a real BPT in the child, since it will not be 103176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * traced at the moment it will reach the trap and would probably 103276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * die with a core dump. 103376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Thus, we are force our way in by taking out two instructions 103476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * and insert an eternal loop instead, in expectance of the SIGSTOP 103576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * generated by out PTRACE_ATTACH. 103676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Of cause, if we evaporate ourselves in the middle of all this... 103776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 103876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 103976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOPA); 104076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if(errno) { 104176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 104276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 104376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 104476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 104576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 104676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !SPARC */ 104776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 104876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined (I386) 104976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP 0x0000feeb 105076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K) 105176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP 0x60fe0000 105276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA) 10534dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0xc3ffffff 105476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC) 10554dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0x0000feeb 105676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined(ARM) 10579a8a37f2b28d1c0d3f57951fd5aeeb96ff7d2f16Wichert Akkerman#define LOOP 0xEAFFFFFE 1058f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined(MIPS) 10594dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0x1000ffff 10604dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390) 10614dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#define LOOP 0xa7f40000 /* BRC 15,0 */ 106276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 106376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture 106476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 106576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 106676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 106776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid); 106876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 106976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 107076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined (I386) 107176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &tcp->baddr) < 0) 107276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 107376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (M68K) 107476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &tcp->baddr) < 0) 107576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 107676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ALPHA) 107776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 107876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (ARM) 107976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 1080f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman#elif defined (MIPS) 1081f90da01fd19a7779d6ed9ad66605367ae43bb2fdWichert Akkerman return -1; /* FIXME: I do not know what i do - Flo */ 108276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#elif defined (POWERPC) 108376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_NIP, &tcp->baddr) < 0) 108476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 10854dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman#elif defined(S390) 10864dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman if (upeek(tcp->pid,PT_PSWADDR, &tcp->baddr) < 0) 10874dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman return -1; 108876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 108976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#error unknown architecture 109076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 109176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 109276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr); 109376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0); 109476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 109576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 109676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 109776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 109876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 109976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 110076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 110176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 110276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 110376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 110476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 110576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */ 110676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 110776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 110876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 110976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC /* This code is slightly sparc specific */ 111076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1111e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 111276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define BPT 0x91d02001 /* ta 1 */ 111376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOP 0x10800000 /* ba 0 */ 111476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define LOOPA 0x30800000 /* ba,a 0 */ 111576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define NOP 0x01000000 111676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if LOOPA 111776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[1] = {LOOPA}; 111876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 111976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int loopdeloop[2] = {LOOP, NOP}; 112076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 112176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 112276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 112376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 112476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 112576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 112676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 112776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 112876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 112976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 113076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->baddr = regs.r_o7 + 8; 113176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr, 113276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof tcp->inst, (char *)tcp->inst) < 0) { 113376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_READTEXT, ...)"); 113476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 113576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 113676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 113776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 113876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * XXX - BRUTAL MODE ON 113976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We cannot set a real BPT in the child, since it will not be 114076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * traced at the moment it will reach the trap and would probably 114176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * die with a core dump. 114276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Thus, we are force our way in by taking out two instructions 114376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * and insert an eternal loop in stead, in expectance of the SIGSTOP 114476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * generated by out PTRACE_ATTACH. 114576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Of cause, if we evaporate ourselves in the middle of all this... 114676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 114776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 114876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof loopdeloop, (char *) loopdeloop) < 0) { 114976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)"); 115076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 115176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 115276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_BPTSET; 115376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 115476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */ 115576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 115676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 115776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 115876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 115976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 116076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 116176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanclearbpt(tcp) 116276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 116376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 116476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 116576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 116676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386 116776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long eip; 116876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !I386 */ 116976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef POWERPC 117076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 117176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !POWERPC */ 117276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef M68K 117376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 117476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !M68K */ 117576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef ALPHA 117676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long pc; 117776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* ALPHA */ 117876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !M68K */ 117976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !POWERPC */ 118076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !I386 */ 118176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 118276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC 118376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Again, we borrow the SunOS breakpoint code. */ 118476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 118576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 118676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 118776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 118876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 118976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 119076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if(errno) { 119176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 119276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 119376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 119476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 119576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !SPARC */ 119676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 119776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 119876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 119976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 120076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 120176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 120276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 120376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 120476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 120576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno) { 120676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 120776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 120876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 120976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 121076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 121176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef I386 121276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*EIP, &eip) < 0) 121376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 121476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (eip != tcp->baddr) { 121576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 121676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 121776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 121876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 121976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman eip, tcp->baddr); 122076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 122176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 122276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !I386 */ 122376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef POWERPC 122476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_NIP, &pc) < 0) 122576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 122676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 122776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 122876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 122976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 123076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 123176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 123276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 123376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !POWERPC */ 123476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef M68K 123576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) 123676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 123776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 123876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 123976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 124076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 124176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 124276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 124376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 124476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !M68K */ 124576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef ALPHA 124676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(tcp->pid, REG_PC, &pc) < 0) 124776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 124876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pc != tcp->baddr) { 124976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet. */ 125076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 125176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 125276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc, tcp->baddr); 125376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 125476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 125576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* ALPHA */ 125676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !M68K */ 125776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !POWERPC */ 125876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !I386 */ 125976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !SPARC */ 126076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 126176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 126276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 126376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SPARC 126476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 126576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA 1266e6f876c49de4a5f535e476804e4627f8e0ecb869Wichert Akkerman struct regs regs; 126776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 126876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 126976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_BPTSET)) { 127076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 127176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 127276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 127376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 127476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sizeof tcp->inst, (char *) tcp->inst) < 0) { 127576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)"); 127676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 127776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 127876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_BPTSET; 127976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 128076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if !LOOPA 128176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 128276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Since we don't have a single instruction breakpoint, we may have 128376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * to adjust the program counter after removing the our `breakpoint'. 128476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 128576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 128676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbpt: ptrace(PTRACE_GETREGS, ...)"); 128776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 128876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 128976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((regs.r_pc < tcp->baddr) || 129076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (regs.r_pc > tcp->baddr + 4)) { 129176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The breakpoint has not been reached yet */ 129276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 129376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 129476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "NOTE: PC not at bpt (pc %#x baddr %#x)\n", 129576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc, tcp->parent->baddr); 129676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 129776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 129876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (regs.r_pc != tcp->baddr) 129976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 130076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n", 130176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc, tcp->baddr); 130276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 130376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman regs.r_pc = tcp->baddr; 130476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) { 130576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("clearbpt: ptrace(PTRACE_SETREGS, ...)"); 130676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 130776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 130876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LOOPA */ 130976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SPARC */ 131076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 131176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 131276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 131376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 131476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 131576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !SVR4 */ 131676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 131776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 131876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 131976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 132076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangetex(pid, hdr) 132176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 132276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct exec *hdr; 132376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 132476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 132576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 132676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (n = 0; n < sizeof *hdr; n += 4) { 132776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long res; 132876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (upeek(pid, uoff(u_exdata) + n, &res) < 0) 132976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 133076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman memcpy(((char *) hdr) + n, &res, 4); 133176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 133276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) { 133376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n", 133476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_magic, hdr->a_toolversion, hdr->a_machtype); 133576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n", 133676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry); 133776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 133876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 133976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 134076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 134176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 134276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfixvfork(tcp) 134376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 134476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 134576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid = tcp->pid; 134676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 134776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Change `vfork' in a freshly exec'ed dynamically linked 134876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * executable's (internal) symbol table to plain old `fork' 134976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 135076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 135176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct exec hdr; 135276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic dyn; 135376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct link_dynamic_2 ld; 135476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *strtab, *cp; 135576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 135676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getex(pid, &hdr) < 0) 135776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 135876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!hdr.a_dynamic) 135976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 136076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 136176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) { 136276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read DYNAMIC\n"); 136376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 136476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 136576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) { 136676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Cannot read link_dynamic_2\n"); 136776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 136876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 136976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) { 137076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "fixvfork: out of memory\n"); 137176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 137276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 137376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 137476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 137576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 137676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 137776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 137876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 137976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "[symbol: %s]\n", cp); 138076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cp += strlen(cp)+1; 138176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 138276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 138376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 138476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 138576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strcmp(cp, "_vfork") == 0) { 138676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 138776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "fixvfork: FOUND _vfork\n"); 138876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strcpy(cp, "_fork"); 138976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 139076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 139176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cp += strlen(cp)+1; 139276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 139376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cp < strtab + ld.ld_symb_size) 139476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 139576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Write entire symbol table back to avoid 139676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * memory alignment bugs in ptrace 139776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 139876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 139976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (int)ld.ld_symb_size, strtab) < 0) 140076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto err; 140176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 140276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 140376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 140476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 140576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanerr: 140676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free(strtab); 140776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 140876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 140976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 141076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 1411