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