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