util.c revision 7b3082206c5ea5ea41259c8b013138c6f6b6463a
1/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 *                     Linux for s390 port by D.J. Barrow
8 *                    <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 *    derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 *	$Id$
34 */
35
36#include "defs.h"
37
38#include <signal.h>
39#include <sys/syscall.h>
40#include <sys/user.h>
41#include <sys/param.h>
42#include <fcntl.h>
43#if HAVE_SYS_UIO_H
44#include <sys/uio.h>
45#endif
46#ifdef SUNOS4
47#include <machine/reg.h>
48#include <a.out.h>
49#include <link.h>
50#endif /* SUNOS4 */
51
52#if defined(linux) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1))
53#include <linux/ptrace.h>
54#endif
55
56#if defined(LINUX) && defined(IA64)
57# include <asm/ptrace_offsets.h>
58# include <asm/rse.h>
59#endif
60
61#ifdef HAVE_SYS_REG_H
62#include <sys/reg.h>
63# define PTRACE_PEEKUSR PTRACE_PEEKUSER
64#elif defined(HAVE_LINUX_PTRACE_H)
65#undef PTRACE_SYSCALL
66#include <linux/ptrace.h>
67#endif
68
69#ifdef SUNOS4_KERNEL_ARCH_KLUDGE
70#include <sys/utsname.h>
71#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
72
73#if defined(LINUX) && defined(SPARC)
74
75#include <asm/reg.h>
76
77#if !defined(__GLIBC__)
78
79#include <linux/unistd.h>
80
81#define _hack_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\
82          type5,arg5,syscall) \
83type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
84{ \
85      long __res; \
86\
87__asm__ volatile ("or %%g0, %1, %%o0\n\t" \
88                  "or %%g0, %2, %%o1\n\t" \
89                  "or %%g0, %3, %%o2\n\t" \
90                  "or %%g0, %4, %%o3\n\t" \
91                  "or %%g0, %5, %%o4\n\t" \
92                  "or %%g0, %6, %%g1\n\t" \
93                  "t 0x10\n\t" \
94                  "bcc 1f\n\t" \
95                  "or %%g0, %%o0, %0\n\t" \
96                  "sub %%g0, %%o0, %0\n\t" \
97                  "1:\n\t" \
98                  : "=r" (__res) \
99                  : "0" ((long)(arg1)),"1" ((long)(arg2)), \
100                    "2" ((long)(arg3)),"3" ((long)(arg4)),"4" ((long)(arg5)), \
101                    "i" (__NR_##syscall)  \
102                  : "g1", "o0", "o1", "o2", "o3", "o4"); \
103if (__res>=0) \
104        return (type) __res; \
105errno = -__res; \
106return -1; \
107}
108
109static _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,int,__addr2,ptrace)
110
111#define _ptrace
112
113#endif
114
115#endif
116
117/* macros */
118#ifndef MAX
119#define MAX(a,b)		(((a) > (b)) ? (a) : (b))
120#endif
121#ifndef MIN
122#define MIN(a,b)		(((a) < (b)) ? (a) : (b))
123#endif
124
125void
126tv_tv(tv, a, b)
127struct timeval *tv;
128int a;
129int b;
130{
131	tv->tv_sec = a;
132	tv->tv_usec = b;
133}
134
135int
136tv_nz(a)
137struct timeval *a;
138{
139	return a->tv_sec || a->tv_usec;
140}
141
142int
143tv_cmp(a, b)
144struct timeval *a, *b;
145{
146	if (a->tv_sec < b->tv_sec
147	    || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
148		return -1;
149	if (a->tv_sec > b->tv_sec
150	    || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
151		return 1;
152	return 0;
153}
154
155double
156tv_float(tv)
157struct timeval *tv;
158{
159	return tv->tv_sec + tv->tv_usec/1000000.0;
160}
161
162void
163tv_add(tv, a, b)
164struct timeval *tv, *a, *b;
165{
166	tv->tv_sec = a->tv_sec + b->tv_sec;
167	tv->tv_usec = a->tv_usec + b->tv_usec;
168	if (tv->tv_usec > 1000000) {
169		tv->tv_sec++;
170		tv->tv_usec -= 1000000;
171	}
172}
173
174void
175tv_sub(tv, a, b)
176struct timeval *tv, *a, *b;
177{
178	tv->tv_sec = a->tv_sec - b->tv_sec;
179	tv->tv_usec = a->tv_usec - b->tv_usec;
180	if (((long) tv->tv_usec) < 0) {
181		tv->tv_sec--;
182		tv->tv_usec += 1000000;
183	}
184}
185
186void
187tv_div(tv, a, n)
188struct timeval *tv, *a;
189int n;
190{
191	tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
192	tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
193	tv->tv_usec %= 1000000;
194}
195
196void
197tv_mul(tv, a, n)
198struct timeval *tv, *a;
199int n;
200{
201	tv->tv_usec = a->tv_usec * n;
202	tv->tv_sec = a->tv_sec * n + a->tv_usec / 1000000;
203	tv->tv_usec %= 1000000;
204}
205
206char *
207xlookup(xlat, val)
208struct xlat *xlat;
209int val;
210{
211	for (; xlat->str != NULL; xlat++)
212		if (xlat->val == val)
213			return xlat->str;
214	return NULL;
215}
216
217/*
218 * Print entry in struct xlat table, if there.
219 */
220void
221printxval(xlat, val, dflt)
222struct xlat *xlat;
223int val;
224char *dflt;
225{
226	char *str = xlookup(xlat, val);
227
228	if (str)
229		tprintf("%s", str);
230	else
231		tprintf("%#x /* %s */", val, dflt);
232}
233
234/*
235 * Interpret `xlat' as an array of flags
236 * print the entries whose bits are on in `flags'
237 * return # of flags printed.
238 */
239int
240addflags(xlat, flags)
241struct xlat *xlat;
242int flags;
243{
244	int n;
245
246	for (n = 0; xlat->str; xlat++) {
247		if (xlat->val && (flags & xlat->val) == xlat->val) {
248			tprintf("|%s", xlat->str);
249			flags &= ~xlat->val;
250			n++;
251		}
252	}
253	if (flags) {
254		tprintf("|%#x", flags);
255		n++;
256	}
257	return n;
258}
259
260int
261printflags(xlat, flags)
262struct xlat *xlat;
263int flags;
264{
265	int n;
266	char *sep;
267
268	if (flags == 0 && xlat->val == 0) {
269		tprintf("%s", xlat->str);
270		return 1;
271	}
272
273	sep = "";
274	for (n = 0; xlat->str; xlat++) {
275		if (xlat->val && (flags & xlat->val) == xlat->val) {
276			tprintf("%s%s", sep, xlat->str);
277			flags &= ~xlat->val;
278			sep = "|";
279			n++;
280		}
281	}
282	if (flags) {
283		tprintf("%s%#x", sep, flags);
284		n++;
285	}
286	return n;
287}
288
289void
290printnum(tcp, addr, fmt)
291struct tcb *tcp;
292long addr;
293char *fmt;
294{
295	long num;
296
297	if (!addr) {
298		tprintf("NULL");
299		return;
300	}
301	if (umove(tcp, addr, &num) < 0) {
302		tprintf("%#lx", addr);
303		return;
304	}
305	tprintf("[");
306	tprintf(fmt, num);
307	tprintf("]");
308}
309
310static char path[MAXPATHLEN + 1];
311
312void
313string_quote(str)
314char *str;
315{
316	char buf[2 * MAXPATHLEN + 1];
317	char *s;
318
319	if (!strpbrk(str, "\"\'\\")) {
320		tprintf("\"%s\"", str);
321		return;
322	}
323	for (s = buf; *str; str++) {
324		switch (*str) {
325		case '\"': case '\'': case '\\':
326			*s++ = '\\'; *s++ = *str; break;
327		default:
328			*s++ = *str; break;
329		}
330	}
331	*s = '\0';
332	tprintf("\"%s\"", buf);
333}
334
335void
336printpath(tcp, addr)
337struct tcb *tcp;
338long addr;
339{
340	if (umovestr(tcp, addr, MAXPATHLEN, path) < 0)
341		tprintf("%#lx", addr);
342	else
343		string_quote(path);
344	return;
345}
346
347void
348printpathn(tcp, addr, n)
349struct tcb *tcp;
350long addr;
351int n;
352{
353	if (umovestr(tcp, addr, n, path) < 0)
354		tprintf("%#lx", addr);
355	else {
356		path[n] = '\0';
357		string_quote(path);
358	}
359}
360
361void
362printstr(tcp, addr, len)
363struct tcb *tcp;
364long addr;
365int len;
366{
367	static unsigned char *str = NULL;
368	static char *outstr;
369	int i, n, c, usehex;
370	char *s, *outend;
371
372	if (!addr) {
373		tprintf("NULL");
374		return;
375	}
376	if (!str) {
377		if ((str = malloc(max_strlen)) == NULL
378		    || (outstr = malloc(2*max_strlen)) == NULL) {
379			fprintf(stderr, "printstr: no memory\n");
380			tprintf("%#lx", addr);
381			return;
382		}
383	}
384	outend = outstr + max_strlen * 2 - 10;
385	if (len < 0) {
386		n = max_strlen;
387		if (umovestr(tcp, addr, n, (char *) str) < 0) {
388			tprintf("%#lx", addr);
389			return;
390		}
391	}
392	else {
393		n = MIN(len, max_strlen);
394		if (umoven(tcp, addr, n, (char *) str) < 0) {
395			tprintf("%#lx", addr);
396			return;
397		}
398	}
399
400	usehex = 0;
401	if (xflag > 1)
402		usehex = 1;
403	else if (xflag) {
404		for (i = 0; i < n; i++) {
405			c = str[i];
406			if (len < 0 && c == '\0')
407				break;
408			if (!isprint(c) && !isspace(c)) {
409				usehex = 1;
410				break;
411			}
412		}
413	}
414
415	s = outstr;
416	*s++ = '\"';
417
418	if (usehex) {
419		for (i = 0; i < n; i++) {
420			c = str[i];
421			if (len < 0 && c == '\0')
422				break;
423			sprintf(s, "\\x%02x", c);
424			s += 4;
425			if (s > outend)
426				break;
427		}
428	}
429	else {
430		for (i = 0; i < n; i++) {
431			c = str[i];
432			if (len < 0 && c == '\0')
433				break;
434			switch (c) {
435			case '\"': case '\'': case '\\':
436				*s++ = '\\'; *s++ = c; break;
437			case '\f':
438				*s++ = '\\'; *s++ = 'f'; break;
439			case '\n':
440				*s++ = '\\'; *s++ = 'n'; break;
441			case '\r':
442				*s++ = '\\'; *s++ = 'r'; break;
443			case '\t':
444				*s++ = '\\'; *s++ = 't'; break;
445			case '\v':
446				*s++ = '\\'; *s++ = 'v'; break;
447			default:
448				if (isprint(c))
449					*s++ = c;
450				else if (i < n - 1 && isdigit(str[i + 1])) {
451					sprintf(s, "\\%03o", c);
452					s += 4;
453				}
454				else {
455					sprintf(s, "\\%o", c);
456					s += strlen(s);
457				}
458				break;
459			}
460			if (s > outend)
461				break;
462		}
463	}
464
465	*s++ = '\"';
466	if (i < len || (len < 0 && (i == n || s > outend))) {
467		*s++ = '.'; *s++ = '.'; *s++ = '.';
468	}
469	*s = '\0';
470	tprintf("%s", outstr);
471}
472
473#if HAVE_SYS_UIO_H
474void
475dumpiov(tcp, len, addr)
476struct tcb * tcp;
477int len;
478long addr;
479{
480	struct iovec *iov;
481	int i;
482
483
484	if ((iov = (struct iovec *) malloc(len * sizeof *iov)) == NULL) {
485		fprintf(stderr, "dump: No memory");
486		return;
487	}
488	if (umoven(tcp, addr,
489		   len * sizeof *iov, (char *) iov) >= 0) {
490
491		for (i = 0; i < len; i++) {
492                        /* include the buffer number to make it easy to
493                         * match up the trace with the source */
494                        tprintf(" * %lu bytes in buffer %d\n",
495                                (unsigned long)iov[i].iov_len, i);
496                        dumpstr(tcp, (long) iov[i].iov_base,
497                                iov[i].iov_len);
498                }
499	}
500	free((char *) iov);
501
502}
503#endif
504
505void
506dumpstr(tcp, addr, len)
507struct tcb *tcp;
508long addr;
509int len;
510{
511	static int strsize = -1;
512	static unsigned char *str;
513	static char outstr[80];
514	char *s;
515	int i, j;
516
517	if (strsize < len) {
518		if (str)
519			free(str);
520		if ((str = malloc(len)) == NULL) {
521			fprintf(stderr, "dump: no memory\n");
522			return;
523		}
524		strsize = len;
525	}
526
527	if (umoven(tcp, addr, len, (char *) str) < 0)
528		return;
529
530	for (i = 0; i < len; i += 16) {
531		s = outstr;
532		sprintf(s, " | %05x ", i);
533		s += 9;
534		for (j = 0; j < 16; j++) {
535			if (j == 8)
536				*s++ = ' ';
537			if (i + j < len) {
538				sprintf(s, " %02x", str[i + j]);
539				s += 3;
540			}
541			else {
542				*s++ = ' '; *s++ = ' '; *s++ = ' ';
543			}
544		}
545		*s++ = ' '; *s++ = ' ';
546		for (j = 0; j < 16; j++) {
547			if (j == 8)
548				*s++ = ' ';
549			if (i + j < len) {
550				if (isprint(str[i + j]))
551					*s++ = str[i + j];
552				else
553					*s++ = '.';
554			}
555			else
556				*s++ = ' ';
557		}
558		tprintf("%s |\n", outstr);
559	}
560}
561
562#define PAGMASK	(~(PAGSIZ - 1))
563/*
564 * move `len' bytes of data from process `pid'
565 * at address `addr' to our space at `laddr'
566 */
567int
568umoven(tcp, addr, len, laddr)
569struct tcb *tcp;
570long addr;
571int len;
572char *laddr;
573{
574
575#ifdef LINUX
576	int pid = tcp->pid;
577	int n, m;
578	int started = 0;
579	union {
580		long val;
581		char x[sizeof(long)];
582	} u;
583
584	if (addr & (sizeof(long) - 1)) {
585		/* addr not a multiple of sizeof(long) */
586		n = addr - (addr & -sizeof(long)); /* residue */
587		addr &= -sizeof(long); /* residue */
588		errno = 0;
589		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
590		if (errno) {
591			if (started && (errno==EPERM || errno==EIO)) {
592				/* Ran into 'end of memory' - stupid "printpath" */
593				return 0;
594			}
595			/* But if not started, we had a bogus address. */
596			perror("ptrace: umoven");
597			return -1;
598		}
599		started = 1;
600		memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
601		addr += sizeof(long), laddr += m, len -= m;
602	}
603	while (len) {
604		errno = 0;
605		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
606		if (errno) {
607			if (started && (errno==EPERM || errno==EIO)) {
608				/* Ran into 'end of memory' - stupid "printpath" */
609				return 0;
610			}
611			perror("ptrace: umoven");
612			return -1;
613		}
614		started = 1;
615		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
616		addr += sizeof(long), laddr += m, len -= m;
617	}
618#endif /* LINUX */
619
620#ifdef SUNOS4
621	int pid = tcp->pid;
622#if 0
623	int n, m;
624	union {
625		long val;
626		char x[sizeof(long)];
627	} u;
628
629	if (addr & (sizeof(long) - 1)) {
630		/* addr not a multiple of sizeof(long) */
631		n = addr - (addr & -sizeof(long)); /* residue */
632		addr &= -sizeof(long); /* residue */
633		errno = 0;
634		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
635		if (errno) {
636			perror("umoven");
637			return -1;
638		}
639		memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
640		addr += sizeof(long), laddr += m, len -= m;
641	}
642	while (len) {
643		errno = 0;
644		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
645		if (errno) {
646			perror("umoven");
647			return -1;
648		}
649		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
650		addr += sizeof(long), laddr += m, len -= m;
651	}
652#else /* !oldway */
653	int n;
654
655	while (len) {
656		n = MIN(len, PAGSIZ);
657		n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
658		if (ptrace(PTRACE_READDATA, pid,
659			   (char *) addr, len, laddr) < 0) {
660			perror("umoven: ptrace(PTRACE_READDATA, ...)");
661			abort();
662			return -1;
663		}
664		len -= n;
665		addr += n;
666		laddr += n;
667	}
668#endif /* !oldway */
669#endif /* SUNOS4 */
670
671#ifdef USE_PROCFS
672#ifdef HAVE_MP_PROCFS
673	int fd = tcp->pfd_as;
674#else
675	int fd = tcp->pfd;
676#endif
677	lseek(fd, addr, SEEK_SET);
678	if (read(fd, laddr, len) == -1)
679		return -1;
680#endif /* USE_PROCFS */
681
682	return 0;
683}
684
685/*
686 * like `umove' but make the additional effort of looking
687 * for a terminating zero byte.
688 */
689int
690umovestr(tcp, addr, len, laddr)
691struct tcb *tcp;
692long addr;
693int len;
694char *laddr;
695{
696#ifdef USE_PROCFS
697#ifdef HAVE_MP_PROCFS
698	int fd = tcp->pfd_as;
699#else
700	int fd = tcp->pfd;
701#endif
702	/* Some systems (e.g. FreeBSD) can be upset if we read off the
703	   end of valid memory,  avoid this by trying to read up
704	   to page boundaries.  But we don't know what a page is (and
705	   getpagesize(2) (if it exists) doesn't necessarily return
706	   hardware page size).  Assume all pages >= 1024 (a-historical
707	   I know) */
708
709	int page = 1024; 	/* How to find this? */
710	int move = page - (addr & (page - 1));
711	int left = len;
712
713	lseek(fd, addr, SEEK_SET);
714
715	while (left) {
716		if (move > left) move = left;
717		if ((move = read(fd, laddr, move)) <= 0)
718			return left != len ? 0 : -1;
719		if (memchr (laddr, 0, move)) break;
720		left -= move;
721		laddr += move;
722		addr += move;
723		move = page;
724	}
725#else /* !USE_PROCFS */
726	int started = 0;
727	int pid = tcp->pid;
728	int i, n, m;
729	union {
730		long val;
731		char x[sizeof(long)];
732	} u;
733
734	if (addr & (sizeof(long) - 1)) {
735		/* addr not a multiple of sizeof(long) */
736		n = addr - (addr & -sizeof(long)); /* residue */
737		addr &= -sizeof(long); /* residue */
738		errno = 0;
739		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
740		if (errno) {
741			if (started && (errno==EPERM || errno==EIO)) {
742				/* Ran into 'end of memory' - stupid "printpath" */
743				return 0;
744			}
745			perror("umovestr");
746			return -1;
747		}
748		started = 1;
749		memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len));
750		while (n & (sizeof(long) - 1))
751			if (u.x[n++] == '\0')
752				return 0;
753		addr += sizeof(long), laddr += m, len -= m;
754	}
755	while (len) {
756		errno = 0;
757		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
758		if (errno) {
759			if (started && (errno==EPERM || errno==EIO)) {
760				/* Ran into 'end of memory' - stupid "printpath" */
761				return 0;
762			}
763			perror("umovestr");
764			return -1;
765		}
766		started = 1;
767		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
768		for (i = 0; i < sizeof(long); i++)
769			if (u.x[i] == '\0')
770				return 0;
771
772		addr += sizeof(long), laddr += m, len -= m;
773	}
774#endif /* !USE_PROCFS */
775	return 0;
776}
777
778#ifdef LINUX
779#ifndef SPARC
780#define PTRACE_WRITETEXT	101
781#define PTRACE_WRITEDATA	102
782#endif /* !SPARC */
783#endif /* LINUX */
784
785#ifdef SUNOS4
786
787static int
788uload(cmd, pid, addr, len, laddr)
789int cmd;
790int pid;
791long addr;
792int len;
793char *laddr;
794{
795#if 0
796	int n;
797
798	while (len) {
799		n = MIN(len, PAGSIZ);
800		n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
801		if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) {
802			perror("uload: ptrace(PTRACE_WRITE, ...)");
803			return -1;
804		}
805		len -= n;
806		addr += n;
807		laddr += n;
808	}
809#else
810	int peek, poke;
811	int n, m;
812	union {
813		long val;
814		char x[sizeof(long)];
815	} u;
816
817	if (cmd == PTRACE_WRITETEXT) {
818		peek = PTRACE_PEEKTEXT;
819		poke = PTRACE_POKETEXT;
820	}
821	else {
822		peek = PTRACE_PEEKDATA;
823		poke = PTRACE_POKEDATA;
824	}
825	if (addr & (sizeof(long) - 1)) {
826		/* addr not a multiple of sizeof(long) */
827		n = addr - (addr & -sizeof(long)); /* residue */
828		addr &= -sizeof(long);
829		errno = 0;
830		u.val = ptrace(peek, pid, (char *) addr, 0);
831		if (errno) {
832			perror("uload: POKE");
833			return -1;
834		}
835		memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len));
836		if (ptrace(poke, pid, (char *)addr, u.val) < 0) {
837			perror("uload: POKE");
838			return -1;
839		}
840		addr += sizeof(long), laddr += m, len -= m;
841	}
842	while (len) {
843		if (len < sizeof(long))
844			u.val = ptrace(peek, pid, (char *) addr, 0);
845		memcpy(u.x, laddr, m = MIN(sizeof(long), len));
846		if (ptrace(poke, pid, (char *) addr, u.val) < 0) {
847			perror("uload: POKE");
848			return -1;
849		}
850		addr += sizeof(long), laddr += m, len -= m;
851	}
852#endif
853	return 0;
854}
855
856int
857tload(pid, addr, len, laddr)
858int pid;
859int addr, len;
860char *laddr;
861{
862	return uload(PTRACE_WRITETEXT, pid, addr, len, laddr);
863}
864
865int
866dload(pid, addr, len, laddr)
867int pid;
868int addr;
869int len;
870char *laddr;
871{
872	return uload(PTRACE_WRITEDATA, pid, addr, len, laddr);
873}
874
875#endif /* SUNOS4 */
876
877#ifndef USE_PROCFS
878
879int
880upeek(pid, off, res)
881int pid;
882long off;
883long *res;
884{
885	long val;
886
887#ifdef SUNOS4_KERNEL_ARCH_KLUDGE
888	{
889		static int is_sun4m = -1;
890		struct utsname name;
891
892		/* Round up the usual suspects. */
893		if (is_sun4m == -1) {
894			if (uname(&name) < 0) {
895				perror("upeek: uname?");
896				exit(1);
897			}
898			is_sun4m = strcmp(name.machine, "sun4m") == 0;
899			if (is_sun4m) {
900				extern struct xlat struct_user_offsets[];
901				struct xlat *x;
902
903				for (x = struct_user_offsets; x->str; x++)
904					x->val += 1024;
905			}
906		}
907		if (is_sun4m)
908			off += 1024;
909	}
910#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
911	errno = 0;
912	val = ptrace(PTRACE_PEEKUSER, pid, (char *) off, 0);
913	if (val == -1 && errno) {
914		char buf[60];
915		sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)",pid,off);
916		perror(buf);
917		return -1;
918	}
919	*res = val;
920	return 0;
921}
922
923#endif /* !USE_PROCFS */
924
925long
926getpc(tcp)
927struct tcb *tcp;
928{
929
930#ifdef LINUX
931	long pc;
932#if defined(I386)
933	if (upeek(tcp->pid, 4*EIP, &pc) < 0)
934		return -1;
935#elif defined(X86_64)
936	if (upeek(tcp->pid, 8*RIP, &pc) < 0)
937		return -1;
938#elif defined(IA64)
939	if (upeek(tcp->pid, PT_B0, &pc) < 0)
940		return -1;
941#elif defined(ARM)
942	if (upeek(tcp->pid, 4*15, &pc) < 0)
943		return -1;
944#elif defined(POWERPC)
945	if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0)
946		return -1;
947#elif defined(M68k)
948	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
949		return -1;
950#elif defined(ALPHA)
951	if (upeek(tcp->pid, REG_PC, &pc) < 0)
952		return -1;
953#elif defined(MIPS)
954 	if (upeek(tcp->pid, REG_EPC, &pc) < 0)
955 		return -1;
956#elif defined(SPARC)
957	struct regs regs;
958	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
959		return -1;
960	pc = regs.r_pc;
961#elif defined(S390) || defined(S390X)
962	if(upeek(tcp->pid,PT_PSWADDR,&pc) < 0)
963		return -1;
964#elif defined(HPPA)
965	if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0)
966		return -1;
967#elif defined(SH)
968       if (upeek(tcp->pid, 4*REG_PC ,&pc) < 0)
969               return -1;
970#endif
971	return pc;
972#endif /* LINUX */
973
974#ifdef SUNOS4
975	/*
976	 * Return current program counter for `pid'
977	 * Assumes PC is never 0xffffffff
978	 */
979	struct regs regs;
980
981	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
982		perror("getpc: ptrace(PTRACE_GETREGS, ...)");
983		return -1;
984	}
985	return regs.r_pc;
986#endif /* SUNOS4 */
987
988#ifdef SVR4
989	/* XXX */
990	return 0;
991#endif /* SVR4 */
992
993#ifdef FREEBSD
994	struct reg regs;
995	pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
996	return regs.r_eip;
997#endif /* FREEBSD */
998}
999
1000void
1001printcall(tcp)
1002struct tcb *tcp;
1003{
1004
1005#ifdef LINUX
1006#ifdef I386
1007	long eip;
1008
1009	if (upeek(tcp->pid, 4*EIP, &eip) < 0) {
1010		tprintf("[????????] ");
1011		return;
1012	}
1013	tprintf("[%08lx] ", eip);
1014#elif defined(X86_64)
1015	long rip;
1016
1017	if (upeek(tcp->pid, 8*RIP, &rip) < 0) {
1018		tprintf("[????????] ");
1019		return;
1020	}
1021	tprintf("[%16lx] ", rip);
1022#elif defined(IA62)
1023	long ip;
1024
1025	if (upeek(tcp->pid, PT_B0, &ip) < 0) {
1026		tprintf("[????????] ");
1027		return;
1028	}
1029	tprintf("[%08lx] ", ip);
1030#elif defined(POWERPC)
1031	long pc;
1032
1033	if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) {
1034		tprintf ("[????????] ");
1035		return;
1036	}
1037	tprintf("[%08lx] ", pc);
1038#elif defined(M68k)
1039	long pc;
1040
1041	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) {
1042		tprintf ("[????????] ");
1043		return;
1044	}
1045	tprintf("[%08lx] ", pc);
1046#elif defined(ALPHA)
1047	long pc;
1048
1049	if (upeek(tcp->pid, REG_PC, &pc) < 0) {
1050		tprintf ("[????????] ");
1051		return;
1052	}
1053	tprintf("[%08lx] ", pc);
1054#elif defined(SPARC)
1055	struct regs regs;
1056	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0) {
1057		tprintf("[????????] ");
1058		return;
1059	}
1060	tprintf("[%08lx] ", regs.r_pc);
1061#elif defined(HPPA)
1062	long pc;
1063
1064	if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) {
1065		tprintf ("[????????] ");
1066		return;
1067	}
1068	tprintf("[%08lx] ", pc);
1069#elif defined(MIPS)
1070	long pc;
1071
1072	if (upeek(tcp->pid, REG_EPC, &pc) < 0) {
1073		tprintf ("[????????] ");
1074		return;
1075	}
1076	tprintf("[%08lx] ", pc);
1077#elif defined(SH)
1078       long pc;
1079
1080       if (upeek(tcp->pid, 4*REG_PC, &pc) < 0) {
1081               tprintf ("[????????] ");
1082               return;
1083       }
1084       tprintf("[%08lx] ", pc);
1085#endif /* !architecture */
1086#endif /* LINUX */
1087
1088#ifdef SUNOS4
1089	struct regs regs;
1090
1091	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
1092		perror("printcall: ptrace(PTRACE_GETREGS, ...)");
1093		tprintf("[????????] ");
1094		return;
1095	}
1096	tprintf("[%08x] ", regs.r_o7);
1097#endif /* SUNOS4 */
1098
1099#ifdef SVR4
1100	/* XXX */
1101	tprintf("[????????] ");
1102#endif
1103
1104#ifdef FREEBSD
1105	struct reg regs;
1106	pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
1107	tprintf("[%08x] ", regs.r_eip);
1108#endif /* FREEBSD */
1109}
1110
1111#ifndef USE_PROCFS
1112
1113#if defined LINUX
1114
1115#include <sys/syscall.h>
1116#ifndef CLONE_PTRACE
1117# define CLONE_PTRACE    0x00002000
1118#endif
1119
1120#ifdef IA64
1121
1122typedef unsigned long *arg_setup_state;
1123
1124static int
1125arg_setup(struct tcb *tcp, arg_setup_state *state)
1126{
1127	unsigned long *bsp, cfm, sof, sol;
1128
1129	if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) < 0)
1130		return -1;
1131	if (upeek(tcp->pid, PT_CFM, (long *) &cfm) < 0)
1132		return -1;
1133
1134	sof = (cfm >> 0) & 0x7f;
1135	sol = (cfm >> 7) & 0x7f;
1136	bsp = ia64_rse_skip_regs(bsp, -sof + sol);
1137
1138	*state = bsp;
1139	return 0;
1140}
1141
1142# define arg_finish_change(tcp, state)	0
1143
1144#ifdef SYS_fork
1145static int
1146get_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp)
1147{
1148	return umoven (tcp, (unsigned long) ia64_rse_skip_regs(*state, 0),
1149		       sizeof(long), (void *) valp);
1150}
1151
1152static int
1153get_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp)
1154{
1155	return umoven (tcp, (unsigned long) ia64_rse_skip_regs(*state, 1),
1156		       sizeof(long), (void *) valp);
1157}
1158#endif
1159
1160static int
1161set_arg0 (struct tcb *tcp, arg_setup_state *state, long val)
1162{
1163	unsigned long *ap;
1164	ap = ia64_rse_skip_regs(*state, 0);
1165	errno = 0;
1166	ptrace(PTRACE_POKEDATA, tcp->pid, (void *) ap, val);
1167	return errno ? -1 : 0;
1168}
1169
1170static int
1171set_arg1 (struct tcb *tcp, arg_setup_state *state, long val)
1172{
1173	unsigned long *ap;
1174	ap = ia64_rse_skip_regs(*state, 1);
1175	errno = 0;
1176	ptrace(PTRACE_POKEDATA, tcp->pid, (void *) ap, val);
1177	return errno ? -1 : 0;
1178}
1179
1180#elif defined (SPARC)
1181
1182typedef struct regs arg_setup_state;
1183
1184# define arg_setup(tcp, state) \
1185  (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0))
1186# define arg_finish_change(tcp, state) \
1187  (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0))
1188
1189# define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0)
1190# define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0)
1191# define set_arg0(tcp, state, val) ((state)->r_o0 = (val), 0)
1192# define set_arg1(tcp, state, val) ((state)->r_o1 = (val), 0)
1193# define restore_arg0(tcp, state, val) 0
1194
1195#else
1196
1197# if defined S390 || defined S390X
1198/* Note: this is only true for the `clone' system call, which handles
1199   arguments specially.  We could as well say that its first two arguments
1200   are swapped relative to other architectures, but that would just be
1201   another #ifdef in the calls.  */
1202#  define arg0_offset	PT_GPR3
1203#  define arg1_offset	PT_ORIGGPR2
1204#  define restore_arg0(tcp, state, val) ((void) (state), 0)
1205#  define restore_arg1(tcp, state, val) ((void) (state), 0)
1206# elif defined (ALPHA) || defined (MIPS)
1207#  define arg0_offset	REG_A0
1208#  define arg1_offset	(REG_A0+1)
1209# elif defined (POWERPC)
1210#  define arg0_offset	(sizeof(unsigned long)*PT_R3)
1211#  define arg1_offset	(sizeof(unsigned long)*PT_R4)
1212#  define restore_arg0(tcp, state, val) ((void) (state), 0)
1213# elif defined (HPPA)
1214#  define arg0_offset	 PT_GR26
1215#  define arg1_offset	 (PT_GR26-4)
1216# elif defined (X86_64)
1217#  define arg0_offset	((long)(8*(current_personality ? RBX : RDI)))
1218#  define arg1_offset	((long)(8*(current_personality ? RCX : RSI)))
1219# else
1220#  define arg0_offset	0
1221#  define arg1_offset	4
1222#  if defined SH || defined ARM
1223#   define restore_arg0(tcp, state, val) 0
1224#  endif
1225# endif
1226
1227typedef int arg_setup_state;
1228
1229# define arg_setup(tcp, state) (0)
1230# define arg_finish_change(tcp, state)	0
1231# define get_arg0(tcp, cookie, valp) \
1232  (upeek ((tcp)->pid, arg0_offset, (valp)))
1233# define get_arg1(tcp, cookie, valp) \
1234  (upeek ((tcp)->pid, arg1_offset, (valp)))
1235
1236static int
1237set_arg0 (struct tcb *tcp, void *cookie, long val)
1238{
1239	return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val);
1240}
1241
1242static int
1243set_arg1 (struct tcb *tcp, void *cookie, long val)
1244{
1245	return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val);
1246}
1247
1248#endif
1249
1250#ifndef restore_arg0
1251# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val))
1252#endif
1253#ifndef restore_arg1
1254# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val))
1255#endif
1256
1257int
1258setbpt(tcp)
1259struct tcb *tcp;
1260{
1261	extern int change_syscall(struct tcb *, int);
1262	arg_setup_state state;
1263
1264	if (tcp->flags & TCB_BPTSET) {
1265		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1266		return -1;
1267	}
1268
1269	switch (tcp->scno) {
1270#ifdef SYS_vfork
1271	case SYS_vfork:
1272#endif
1273#ifdef SYS_fork
1274	case SYS_fork:
1275#endif
1276#if defined SYS_fork || defined SYS_vfork
1277		if (arg_setup (tcp, &state) < 0
1278		    || get_arg0 (tcp, &state, &tcp->inst[0]) < 0
1279		    || get_arg1 (tcp, &state, &tcp->inst[1]) < 0
1280		    || change_syscall(tcp, SYS_clone) < 0
1281		    || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0
1282		    || set_arg1 (tcp, &state, 0) < 0
1283		    || arg_finish_change (tcp, &state) < 0)
1284			return -1;
1285		tcp->u_arg[0] = CLONE_PTRACE|SIGCHLD;
1286		tcp->u_arg[1] = 0;
1287		tcp->flags |= TCB_BPTSET;
1288		return 0;
1289#endif
1290
1291	case SYS_clone:
1292#ifdef SYS_clone2
1293	case SYS_clone2:
1294#endif
1295		if ((tcp->u_arg[0] & CLONE_PTRACE) == 0
1296		    && (arg_setup (tcp, &state) < 0
1297			|| set_arg0 (tcp, &state, tcp->u_arg[0] | CLONE_PTRACE) < 0
1298			|| arg_finish_change (tcp, &state) < 0))
1299			return -1;
1300		tcp->flags |= TCB_BPTSET;
1301		tcp->inst[0] = tcp->u_arg[0];
1302		tcp->inst[1] = tcp->u_arg[1];
1303		return 0;
1304
1305	default:
1306		fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n",
1307			tcp->scno, tcp->pid);
1308		break;
1309	}
1310
1311	return -1;
1312}
1313
1314int
1315clearbpt(tcp)
1316struct tcb *tcp;
1317{
1318	arg_setup_state state;
1319	if (arg_setup (tcp, &state) < 0
1320	    || restore_arg0 (tcp, &state, tcp->inst[0]) < 0
1321	    || restore_arg1 (tcp, &state, tcp->inst[1]) < 0
1322	    || arg_finish_change (tcp, &state))
1323		return -1;
1324	tcp->flags &= ~TCB_BPTSET;
1325	return 0;
1326}
1327
1328#else
1329
1330int
1331setbpt(tcp)
1332struct tcb *tcp;
1333{
1334
1335#ifdef LINUX
1336#ifdef SPARC
1337	/* We simply use the SunOS breakpoint code. */
1338
1339	struct regs regs;
1340#define LOOPA	0x30800000	/* ba,a	0 */
1341
1342	if (tcp->flags & TCB_BPTSET) {
1343		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1344		return -1;
1345	}
1346	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1347		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
1348		return -1;
1349	}
1350	tcp->baddr = regs.r_o7 + 8;
1351	errno = 0;
1352	tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0);
1353	if(errno) {
1354		perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1355		return -1;
1356	}
1357
1358	/*
1359	 * XXX - BRUTAL MODE ON
1360	 * We cannot set a real BPT in the child, since it will not be
1361	 * traced at the moment it will reach the trap and would probably
1362	 * die with a core dump.
1363	 * Thus, we are force our way in by taking out two instructions
1364	 * and insert an eternal loop instead, in expectance of the SIGSTOP
1365	 * generated by out PTRACE_ATTACH.
1366	 * Of cause, if we evaporate ourselves in the middle of all this...
1367	 */
1368	errno = 0;
1369	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOPA);
1370	if(errno) {
1371		perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1372		return -1;
1373	}
1374	tcp->flags |= TCB_BPTSET;
1375
1376#else /* !SPARC */
1377#ifdef IA64
1378	if (ia32) {
1379#		define LOOP	0x0000feeb
1380		if (tcp->flags & TCB_BPTSET) {
1381			fprintf(stderr, "PANIC: bpt already set in pid %u\n",
1382				tcp->pid);
1383			return -1;
1384		}
1385		if (upeek(tcp->pid, PT_CR_IIP, &tcp->baddr) < 0)
1386			return -1;
1387		if (debug)
1388			fprintf(stderr, "[%d] setting bpt at %lx\n",
1389				tcp->pid, tcp->baddr);
1390		tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid,
1391				      (char *) tcp->baddr, 0);
1392		if (errno) {
1393			perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1394			return -1;
1395		}
1396		ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
1397		if (errno) {
1398			perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1399			return -1;
1400		}
1401		tcp->flags |= TCB_BPTSET;
1402	} else {
1403		/*
1404		 * Our strategy here is to replace the bundle that
1405		 * contained the clone() syscall with a bundle of the
1406		 * form:
1407		 *
1408		 *	{ 1: br 1b; br 1b; br 1b }
1409		 *
1410		 * This ensures that the newly forked child will loop
1411		 * endlessly until we've got a chance to attach to it.
1412		 */
1413#		define LOOP0	0x0000100000000017
1414#		define LOOP1	0x4000000000200000
1415		unsigned long addr, ipsr;
1416		pid_t pid;
1417
1418		pid = tcp->pid;
1419		if (upeek(pid, PT_CR_IPSR, &ipsr) < 0)
1420			return -1;
1421		if (upeek(pid, PT_CR_IIP, &addr) < 0)
1422			return -1;
1423		/* store "ri" in low two bits */
1424		tcp->baddr = addr | ((ipsr >> 41) & 0x3);
1425
1426		errno = 0;
1427		tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0,
1428				      0);
1429		tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8,
1430				      0);
1431		if (errno) {
1432			perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1433			return -1;
1434		}
1435
1436		errno = 0;
1437		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0);
1438		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1);
1439		if (errno) {
1440			perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1441			return -1;
1442		}
1443		tcp->flags |= TCB_BPTSET;
1444	}
1445#else /* !IA64 */
1446
1447#if defined (I386) || defined(X86_64)
1448#define LOOP	0x0000feeb
1449#elif defined (M68K)
1450#define LOOP	0x60fe0000
1451#elif defined (ALPHA)
1452#define LOOP	0xc3ffffff
1453#elif defined (POWERPC)
1454#define LOOP	0x48000000
1455#elif defined(ARM)
1456#define LOOP	0xEAFFFFFE
1457#elif defined(MIPS)
1458#define LOOP	0x1000ffff
1459#elif defined(S390)
1460#define LOOP	0xa7f40000	/* BRC 15,0 */
1461#elif defined(S390X)
1462#define LOOP   0xa7f4000000000000UL /* BRC 15,0 */
1463#elif defined(HPPA)
1464#define LOOP	0xe81f1ff7	/* b,l,n <loc>,r0 */
1465#elif defined(SH)
1466#ifdef __LITTLE_ENDIAN__
1467#define LOOP   0x0000affe
1468#else
1469#define LOOP   0xfeaf0000
1470#endif
1471#else
1472#error unknown architecture
1473#endif
1474
1475	if (tcp->flags & TCB_BPTSET) {
1476		fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid);
1477		return -1;
1478	}
1479#if defined (I386)
1480	if (upeek(tcp->pid, 4*EIP, &tcp->baddr) < 0)
1481		return -1;
1482#elif defined (X86_64)
1483	if (upeek(tcp->pid, 8*RIP, &tcp->baddr) < 0)
1484		return -1;
1485#elif defined (M68K)
1486	if (upeek(tcp->pid, 4*PT_PC, &tcp->baddr) < 0)
1487	  return -1;
1488#elif defined (ALPHA)
1489	return -1;
1490#elif defined (ARM)
1491	return -1;
1492#elif defined (MIPS)
1493	return -1;		/* FIXME: I do not know what i do - Flo */
1494#elif defined (POWERPC)
1495	if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &tcp->baddr) < 0)
1496		return -1;
1497#elif defined(S390) || defined(S390X)
1498	if (upeek(tcp->pid,PT_PSWADDR, &tcp->baddr) < 0)
1499		return -1;
1500#elif defined(HPPA)
1501	if (upeek(tcp->pid, PT_IAOQ0, &tcp->baddr) < 0)
1502		return -1;
1503	tcp->baddr &= ~0x03;
1504#elif defined(SH)
1505       if (upeek(tcp->pid, 4*REG_PC, &tcp->baddr) < 0)
1506               return -1;
1507#else
1508#error unknown architecture
1509#endif
1510	if (debug)
1511		fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr);
1512	tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0);
1513	if (errno) {
1514		perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1515		return -1;
1516	}
1517	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
1518	if (errno) {
1519		perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1520		return -1;
1521	}
1522	tcp->flags |= TCB_BPTSET;
1523
1524#endif /* !IA64 */
1525#endif /* SPARC */
1526#endif /* LINUX */
1527
1528#ifdef SUNOS4
1529#ifdef SPARC	/* This code is slightly sparc specific */
1530
1531	struct regs regs;
1532#define BPT	0x91d02001	/* ta	1 */
1533#define LOOP	0x10800000	/* ba	0 */
1534#define LOOPA	0x30800000	/* ba,a	0 */
1535#define NOP	0x01000000
1536#if LOOPA
1537	static int loopdeloop[1] = {LOOPA};
1538#else
1539	static int loopdeloop[2] = {LOOP, NOP};
1540#endif
1541
1542	if (tcp->flags & TCB_BPTSET) {
1543		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1544		return -1;
1545	}
1546	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1547		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
1548		return -1;
1549	}
1550	tcp->baddr = regs.r_o7 + 8;
1551	if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr,
1552				sizeof tcp->inst, (char *)tcp->inst) < 0) {
1553		perror("setbpt: ptrace(PTRACE_READTEXT, ...)");
1554		return -1;
1555	}
1556
1557	/*
1558	 * XXX - BRUTAL MODE ON
1559	 * We cannot set a real BPT in the child, since it will not be
1560	 * traced at the moment it will reach the trap and would probably
1561	 * die with a core dump.
1562	 * Thus, we are force our way in by taking out two instructions
1563	 * and insert an eternal loop in stead, in expectance of the SIGSTOP
1564	 * generated by out PTRACE_ATTACH.
1565	 * Of cause, if we evaporate ourselves in the middle of all this...
1566	 */
1567	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
1568			sizeof loopdeloop, (char *) loopdeloop) < 0) {
1569		perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)");
1570		return -1;
1571	}
1572	tcp->flags |= TCB_BPTSET;
1573
1574#endif /* SPARC */
1575#endif /* SUNOS4 */
1576
1577	return 0;
1578}
1579
1580int
1581clearbpt(tcp)
1582struct tcb *tcp;
1583{
1584
1585#ifdef LINUX
1586#if defined(I386) || defined(X86_64)
1587	long eip;
1588#elif defined(POWERPC)
1589	long pc;
1590#elif defined(M68K)
1591	long pc;
1592#elif defined(ALPHA)
1593	long pc;
1594#elif defined(HPPA)
1595	long iaoq;
1596#elif defined(SH)
1597       long pc;
1598#endif /* architecture */
1599
1600#ifdef SPARC
1601	/* Again, we borrow the SunOS breakpoint code. */
1602	if (!(tcp->flags & TCB_BPTSET)) {
1603		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
1604		return -1;
1605	}
1606	errno = 0;
1607	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
1608	if(errno) {
1609		perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
1610		return -1;
1611	}
1612	tcp->flags &= ~TCB_BPTSET;
1613#elif defined(IA64)
1614	if (ia32) {
1615		unsigned long addr;
1616
1617		if (debug)
1618			fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
1619		if (!(tcp->flags & TCB_BPTSET)) {
1620			fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
1621			return -1;
1622		}
1623		errno = 0;
1624		ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
1625		if (errno) {
1626			perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
1627			return -1;
1628		}
1629		tcp->flags &= ~TCB_BPTSET;
1630
1631		if (upeek(tcp->pid, PT_CR_IIP, &addr) < 0)
1632			return -1;
1633		if (addr != tcp->baddr) {
1634			/* The breakpoint has not been reached yet.  */
1635			if (debug)
1636				fprintf(stderr,
1637					"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1638						addr, tcp->baddr);
1639			return 0;
1640		}
1641	} else {
1642		unsigned long addr, ipsr;
1643		pid_t pid;
1644
1645		pid = tcp->pid;
1646
1647		if (upeek(pid, PT_CR_IPSR, &ipsr) < 0)
1648			return -1;
1649		if (upeek(pid, PT_CR_IIP, &addr) < 0)
1650			return -1;
1651
1652		/* restore original bundle: */
1653		errno = 0;
1654		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]);
1655		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]);
1656		if (errno) {
1657			perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)");
1658			return -1;
1659		}
1660
1661		/* restore original "ri" in ipsr: */
1662		ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41);
1663		errno = 0;
1664		ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr);
1665		if (errno) {
1666			perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)");
1667			return -1;
1668		}
1669
1670		tcp->flags &= ~TCB_BPTSET;
1671
1672		if (addr != (tcp->baddr & ~0x3)) {
1673			/* the breakpoint has not been reached yet.  */
1674			if (debug)
1675				fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1676					addr, tcp->baddr);
1677			return 0;
1678		}
1679	}
1680#else /* !IA64  && ! SPARC */
1681
1682	if (debug)
1683		fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
1684	if (!(tcp->flags & TCB_BPTSET)) {
1685		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
1686		return -1;
1687	}
1688	errno = 0;
1689	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
1690	if (errno) {
1691		perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
1692		return -1;
1693	}
1694	tcp->flags &= ~TCB_BPTSET;
1695
1696#ifdef I386
1697	if (upeek(tcp->pid, 4*EIP, &eip) < 0)
1698		return -1;
1699	if (eip != tcp->baddr) {
1700		/* The breakpoint has not been reached yet.  */
1701		if (debug)
1702			fprintf(stderr,
1703				"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1704					eip, tcp->baddr);
1705		return 0;
1706	}
1707#elif defined(X86_64)
1708	if (upeek(tcp->pid, 8*RIP, &eip) < 0)
1709		return -1;
1710	if (eip != tcp->baddr) {
1711		/* The breakpoint has not been reached yet.  */
1712		if (debug)
1713			fprintf(stderr,
1714				"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1715					eip, tcp->baddr);
1716		return 0;
1717	}
1718#elif defined(POWERPC)
1719	if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0)
1720		return -1;
1721	if (pc != tcp->baddr) {
1722		/* The breakpoint has not been reached yet.  */
1723		if (debug)
1724			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1725				pc, tcp->baddr);
1726		return 0;
1727	}
1728#elif defined(M68K)
1729	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
1730		return -1;
1731	if (pc != tcp->baddr) {
1732		/* The breakpoint has not been reached yet.  */
1733		if (debug)
1734			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1735				pc, tcp->baddr);
1736		return 0;
1737	}
1738#elif defined(ALPHA)
1739	if (upeek(tcp->pid, REG_PC, &pc) < 0)
1740		return -1;
1741	if (pc != tcp->baddr) {
1742		/* The breakpoint has not been reached yet.  */
1743		if (debug)
1744			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1745				pc, tcp->baddr);
1746		return 0;
1747	}
1748#elif defined(HPPA)
1749	if (upeek(tcp->pid, PT_IAOQ0, &iaoq) < 0)
1750		return -1;
1751	iaoq &= ~0x03;
1752	if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) {
1753		/* The breakpoint has not been reached yet.  */
1754		if (debug)
1755			fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n",
1756				iaoq, tcp->baddr);
1757		return 0;
1758	}
1759	iaoq = tcp->baddr | 3;
1760	/* We should be pointing at a 'ldi -1000,r1' in glibc, so it is
1761	 * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit
1762	 * has no significant effect.
1763	 */
1764	ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq);
1765	ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq);
1766#elif defined(SH)
1767       if (upeek(tcp->pid, 4*REG_PC, &pc) < 0)
1768               return -1;
1769        if (pc != tcp->baddr) {
1770                /* The breakpoint has not been reached yet.  */
1771                if (debug)
1772                        fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1773                                pc, tcp->baddr);
1774                return 0;
1775        }
1776
1777#endif /* arch */
1778#endif /* !SPARC && !IA64 */
1779#endif /* LINUX */
1780
1781#ifdef SUNOS4
1782#ifdef SPARC
1783
1784#if !LOOPA
1785	struct regs regs;
1786#endif
1787
1788	if (!(tcp->flags & TCB_BPTSET)) {
1789		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
1790		return -1;
1791	}
1792	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
1793				sizeof tcp->inst, (char *) tcp->inst) < 0) {
1794		perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)");
1795		return -1;
1796	}
1797	tcp->flags &= ~TCB_BPTSET;
1798
1799#if !LOOPA
1800	/*
1801	 * Since we don't have a single instruction breakpoint, we may have
1802	 * to adjust the program counter after removing the our `breakpoint'.
1803	 */
1804	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1805		perror("clearbpt: ptrace(PTRACE_GETREGS, ...)");
1806		return -1;
1807	}
1808	if ((regs.r_pc < tcp->baddr) ||
1809				(regs.r_pc > tcp->baddr + 4)) {
1810		/* The breakpoint has not been reached yet */
1811		if (debug)
1812			fprintf(stderr,
1813				"NOTE: PC not at bpt (pc %#x baddr %#x)\n",
1814					regs.r_pc, tcp->parent->baddr);
1815		return 0;
1816	}
1817	if (regs.r_pc != tcp->baddr)
1818		if (debug)
1819			fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n",
1820				regs.r_pc, tcp->baddr);
1821
1822	regs.r_pc = tcp->baddr;
1823	if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1824		perror("clearbpt: ptrace(PTRACE_SETREGS, ...)");
1825		return -1;
1826	}
1827#endif /* LOOPA */
1828#endif /* SPARC */
1829#endif /* SUNOS4 */
1830
1831	return 0;
1832}
1833
1834#endif
1835
1836#endif /* !USE_PROCFS */
1837
1838#ifdef SUNOS4
1839
1840static int
1841getex(pid, hdr)
1842int pid;
1843struct exec *hdr;
1844{
1845	int n;
1846
1847	for (n = 0; n < sizeof *hdr; n += 4) {
1848		long res;
1849		if (upeek(pid, uoff(u_exdata) + n, &res) < 0)
1850			return -1;
1851		memcpy(((char *) hdr) + n, &res, 4);
1852	}
1853	if (debug) {
1854		fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n",
1855			hdr->a_magic, hdr->a_toolversion, hdr->a_machtype);
1856		fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n",
1857			hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry);
1858	}
1859	return 0;
1860}
1861
1862int
1863fixvfork(tcp)
1864struct tcb *tcp;
1865{
1866	int pid = tcp->pid;
1867	/*
1868	 * Change `vfork' in a freshly exec'ed dynamically linked
1869	 * executable's (internal) symbol table to plain old `fork'
1870	 */
1871
1872	struct exec hdr;
1873	struct link_dynamic dyn;
1874	struct link_dynamic_2 ld;
1875	char *strtab, *cp;
1876
1877	if (getex(pid, &hdr) < 0)
1878		return -1;
1879	if (!hdr.a_dynamic)
1880		return -1;
1881
1882	if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) {
1883		fprintf(stderr, "Cannot read DYNAMIC\n");
1884		return -1;
1885	}
1886	if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) {
1887		fprintf(stderr, "Cannot read link_dynamic_2\n");
1888		return -1;
1889	}
1890	if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) {
1891		fprintf(stderr, "fixvfork: out of memory\n");
1892		return -1;
1893	}
1894	if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
1895					(int)ld.ld_symb_size, strtab) < 0)
1896		goto err;
1897
1898#if 0
1899	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
1900		fprintf(stderr, "[symbol: %s]\n", cp);
1901		cp += strlen(cp)+1;
1902	}
1903	return 0;
1904#endif
1905	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
1906		if (strcmp(cp, "_vfork") == 0) {
1907			if (debug)
1908				fprintf(stderr, "fixvfork: FOUND _vfork\n");
1909			strcpy(cp, "_fork");
1910			break;
1911		}
1912		cp += strlen(cp)+1;
1913	}
1914	if (cp < strtab + ld.ld_symb_size)
1915		/*
1916		 * Write entire symbol table back to avoid
1917		 * memory alignment bugs in ptrace
1918		 */
1919		if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
1920					(int)ld.ld_symb_size, strtab) < 0)
1921			goto err;
1922
1923	free(strtab);
1924	return 0;
1925
1926err:
1927	free(strtab);
1928	return -1;
1929}
1930
1931#endif /* SUNOS4 */
1932