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