util.c revision f535b54bc40373c81b13df0975aef4212dacbbde
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
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#ifndef USE_PROCFS
1380
1381#if defined LINUX
1382
1383#include "syscall.h"
1384
1385#include <sys/syscall.h>
1386#ifndef CLONE_PTRACE
1387# define CLONE_PTRACE    0x00002000
1388#endif
1389#ifndef CLONE_VFORK
1390# define CLONE_VFORK     0x00004000
1391#endif
1392#ifndef CLONE_VM
1393# define CLONE_VM        0x00000100
1394#endif
1395#ifndef CLONE_STOPPED
1396# define CLONE_STOPPED   0x02000000
1397#endif
1398
1399#ifdef IA64
1400
1401/* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32
1402   subsystem has them for x86... */
1403#define SYS_fork	2
1404#define SYS_vfork	190
1405
1406typedef unsigned long *arg_setup_state;
1407
1408static int
1409arg_setup(struct tcb *tcp, arg_setup_state *state)
1410{
1411	unsigned long cfm, sof, sol;
1412	long bsp;
1413
1414	if (ia32) {
1415		/* Satisfy a false GCC warning.  */
1416		*state = NULL;
1417		return 0;
1418	}
1419
1420	if (upeek(tcp, PT_AR_BSP, &bsp) < 0)
1421		return -1;
1422	if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
1423		return -1;
1424
1425	sof = (cfm >> 0) & 0x7f;
1426	sol = (cfm >> 7) & 0x7f;
1427	bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol);
1428
1429	*state = (unsigned long *) bsp;
1430	return 0;
1431}
1432
1433# define arg_finish_change(tcp, state)	0
1434
1435#ifdef SYS_fork
1436static int
1437get_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp)
1438{
1439	int ret;
1440
1441	if (ia32)
1442		ret = upeek (tcp, PT_R11, valp);
1443	else
1444		ret = umoven (tcp,
1445			      (unsigned long) ia64_rse_skip_regs(*state, 0),
1446			      sizeof(long), (void *) valp);
1447	return ret;
1448}
1449
1450static int
1451get_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp)
1452{
1453	int ret;
1454
1455	if (ia32)
1456		ret = upeek (tcp, PT_R9, valp);
1457	else
1458		ret = umoven (tcp,
1459			      (unsigned long) ia64_rse_skip_regs(*state, 1),
1460			      sizeof(long), (void *) valp);
1461	return ret;
1462}
1463#endif
1464
1465static int
1466set_arg0 (struct tcb *tcp, arg_setup_state *state, long val)
1467{
1468	int req = PTRACE_POKEDATA;
1469	void *ap;
1470
1471	if (ia32) {
1472		ap = (void *) (intptr_t) PT_R11;	 /* r11 == EBX */
1473		req = PTRACE_POKEUSER;
1474	} else
1475		ap = ia64_rse_skip_regs(*state, 0);
1476	errno = 0;
1477	ptrace(req, tcp->pid, ap, val);
1478	return errno ? -1 : 0;
1479}
1480
1481static int
1482set_arg1 (struct tcb *tcp, arg_setup_state *state, long val)
1483{
1484	int req = PTRACE_POKEDATA;
1485	void *ap;
1486
1487	if (ia32) {
1488		ap = (void *) (intptr_t) PT_R9;		/* r9 == ECX */
1489		req = PTRACE_POKEUSER;
1490	} else
1491		ap = ia64_rse_skip_regs(*state, 1);
1492	errno = 0;
1493	ptrace(req, tcp->pid, ap, val);
1494	return errno ? -1 : 0;
1495}
1496
1497/* ia64 does not return the input arguments from functions (and syscalls)
1498   according to ia64 RSE (Register Stack Engine) behavior.  */
1499
1500# define restore_arg0(tcp, state, val) ((void) (state), 0)
1501# define restore_arg1(tcp, state, val) ((void) (state), 0)
1502
1503#elif defined (SPARC) || defined (SPARC64)
1504
1505typedef struct regs arg_setup_state;
1506
1507# define arg_setup(tcp, state) \
1508  (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0))
1509# define arg_finish_change(tcp, state) \
1510  (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0))
1511
1512# define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0)
1513# define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0)
1514# define set_arg0(tcp, state, val) ((state)->r_o0 = (val), 0)
1515# define set_arg1(tcp, state, val) ((state)->r_o1 = (val), 0)
1516# define restore_arg0(tcp, state, val) 0
1517
1518#else
1519
1520# if defined S390 || defined S390X
1521/* Note: this is only true for the `clone' system call, which handles
1522   arguments specially.  We could as well say that its first two arguments
1523   are swapped relative to other architectures, but that would just be
1524   another #ifdef in the calls.  */
1525#  define arg0_offset	PT_GPR3
1526#  define arg1_offset	PT_ORIGGPR2
1527#  define restore_arg0(tcp, state, val) ((void) (state), 0)
1528#  define restore_arg1(tcp, state, val) ((void) (state), 0)
1529#  define arg0_index	1
1530#  define arg1_index	0
1531# elif defined (ALPHA) || defined (MIPS)
1532#  define arg0_offset	REG_A0
1533#  define arg1_offset	(REG_A0+1)
1534# elif defined (POWERPC)
1535#  define arg0_offset	(sizeof(unsigned long)*PT_R3)
1536#  define arg1_offset	(sizeof(unsigned long)*PT_R4)
1537#  define restore_arg0(tcp, state, val) ((void) (state), 0)
1538# elif defined (HPPA)
1539#  define arg0_offset	 PT_GR26
1540#  define arg1_offset	 (PT_GR26-4)
1541# elif defined (X86_64)
1542#  define arg0_offset	((long)(8*(current_personality ? RBX : RDI)))
1543#  define arg1_offset	((long)(8*(current_personality ? RCX : RSI)))
1544# elif defined (SH)
1545#  define arg0_offset	(4*(REG_REG0+4))
1546#  define arg1_offset	(4*(REG_REG0+5))
1547# elif defined (SH64)
1548   /* ABI defines arg0 & 1 in r2 & r3 */
1549#  define arg0_offset   (REG_OFFSET+16)
1550#  define arg1_offset   (REG_OFFSET+24)
1551#  define restore_arg0(tcp, state, val) 0
1552# else
1553#  define arg0_offset	0
1554#  define arg1_offset	4
1555#  if defined ARM
1556#   define restore_arg0(tcp, state, val) 0
1557#  endif
1558# endif
1559
1560typedef int arg_setup_state;
1561
1562# define arg_setup(tcp, state) (0)
1563# define arg_finish_change(tcp, state)	0
1564# define get_arg0(tcp, cookie, valp) \
1565  (upeek ((tcp), arg0_offset, (valp)))
1566# define get_arg1(tcp, cookie, valp) \
1567  (upeek ((tcp), arg1_offset, (valp)))
1568
1569static int
1570set_arg0 (struct tcb *tcp, void *cookie, long val)
1571{
1572	return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val);
1573}
1574
1575static int
1576set_arg1 (struct tcb *tcp, void *cookie, long val)
1577{
1578	return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val);
1579}
1580
1581#endif
1582
1583#ifndef restore_arg0
1584# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val))
1585#endif
1586#ifndef restore_arg1
1587# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val))
1588#endif
1589
1590#ifndef arg0_index
1591# define arg0_index 0
1592# define arg1_index 1
1593#endif
1594
1595int
1596setbpt(tcp)
1597struct tcb *tcp;
1598{
1599	static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone };
1600	extern int change_syscall(struct tcb *, int);
1601	arg_setup_state state;
1602
1603	if (tcp->flags & TCB_BPTSET) {
1604		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1605		return -1;
1606	}
1607
1608	/*
1609	 * It's a silly kludge to initialize this with a search at runtime.
1610	 * But it's better than maintaining another magic thing in the
1611	 * godforsaken tables.
1612	 */
1613	if (clone_scno[current_personality] == 0) {
1614		int i;
1615		for (i = 0; i < nsyscalls; ++i)
1616			if (sysent[i].sys_func == sys_clone) {
1617				clone_scno[current_personality] = i;
1618				break;
1619			}
1620	}
1621
1622	switch (known_scno(tcp)) {
1623#ifdef SYS_vfork
1624	case SYS_vfork:
1625#endif
1626#ifdef SYS_fork
1627	case SYS_fork:
1628#endif
1629#if defined SYS_fork || defined SYS_vfork
1630		if (arg_setup (tcp, &state) < 0
1631		    || get_arg0 (tcp, &state, &tcp->inst[0]) < 0
1632		    || get_arg1 (tcp, &state, &tcp->inst[1]) < 0
1633		    || change_syscall(tcp, clone_scno[current_personality]) < 0
1634		    || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0
1635		    || set_arg1 (tcp, &state, 0) < 0
1636		    || arg_finish_change (tcp, &state) < 0)
1637			return -1;
1638		tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD;
1639		tcp->u_arg[arg1_index] = 0;
1640		tcp->flags |= TCB_BPTSET;
1641		return 0;
1642#endif
1643
1644	case SYS_clone:
1645#ifdef SYS_clone2
1646	case SYS_clone2:
1647#endif
1648		/* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)'
1649		   contrary to x86 SYS_vfork above.  Even on x86 we turn the
1650		   vfork semantics into plain fork - each application must not
1651		   depend on the vfork specifics according to POSIX.  We would
1652		   hang waiting for the parent resume otherwise.  We need to
1653		   clear also CLONE_VM but only in the CLONE_VFORK case as
1654		   otherwise we would break pthread_create.  */
1655
1656		if ((arg_setup (tcp, &state) < 0
1657		    || set_arg0 (tcp, &state,
1658				 (tcp->u_arg[arg0_index] | CLONE_PTRACE)
1659				 & ~(tcp->u_arg[arg0_index] & CLONE_VFORK
1660				     ? CLONE_VFORK | CLONE_VM : 0)) < 0
1661		    || arg_finish_change (tcp, &state) < 0))
1662		    return -1;
1663		tcp->flags |= TCB_BPTSET;
1664		tcp->inst[0] = tcp->u_arg[arg0_index];
1665		tcp->inst[1] = tcp->u_arg[arg1_index];
1666		return 0;
1667
1668	default:
1669		fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n",
1670			tcp->scno, tcp->pid);
1671		break;
1672	}
1673
1674	return -1;
1675}
1676
1677int
1678clearbpt(tcp)
1679struct tcb *tcp;
1680{
1681	arg_setup_state state;
1682	if (arg_setup (tcp, &state) < 0
1683	    || restore_arg0 (tcp, &state, tcp->inst[0]) < 0
1684	    || restore_arg1 (tcp, &state, tcp->inst[1]) < 0
1685	    || arg_finish_change (tcp, &state))
1686		return -1;
1687	tcp->flags &= ~TCB_BPTSET;
1688	return 0;
1689}
1690
1691#else
1692
1693int
1694setbpt(tcp)
1695struct tcb *tcp;
1696{
1697
1698#ifdef LINUX
1699#if defined (SPARC) || defined (SPARC64)
1700	/* We simply use the SunOS breakpoint code. */
1701
1702	struct regs regs;
1703	unsigned long inst;
1704#define LOOPA	0x30800000	/* ba,a	0 */
1705
1706	if (tcp->flags & TCB_BPTSET) {
1707		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1708		return -1;
1709	}
1710	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1711		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
1712		return -1;
1713	}
1714	tcp->baddr = regs.r_o7 + 8;
1715	errno = 0;
1716	tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0);
1717	if(errno) {
1718		perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1719		return -1;
1720	}
1721
1722	/*
1723	 * XXX - BRUTAL MODE ON
1724	 * We cannot set a real BPT in the child, since it will not be
1725	 * traced at the moment it will reach the trap and would probably
1726	 * die with a core dump.
1727	 * Thus, we are force our way in by taking out two instructions
1728	 * and insert an eternal loop instead, in expectance of the SIGSTOP
1729	 * generated by out PTRACE_ATTACH.
1730	 * Of cause, if we evaporate ourselves in the middle of all this...
1731	 */
1732	errno = 0;
1733	inst = LOOPA;
1734#if defined (SPARC64)
1735	inst <<= 32;
1736	inst |= (tcp->inst[0] & 0xffffffffUL);
1737#endif
1738	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, inst);
1739	if(errno) {
1740		perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1741		return -1;
1742	}
1743	tcp->flags |= TCB_BPTSET;
1744
1745#else /* !SPARC && !SPARC64 */
1746#ifdef IA64
1747	if (ia32) {
1748#		define LOOP	0x0000feeb
1749		if (tcp->flags & TCB_BPTSET) {
1750			fprintf(stderr, "PANIC: bpt already set in pid %u\n",
1751				tcp->pid);
1752			return -1;
1753		}
1754		if (upeek(tcp, PT_CR_IIP, &tcp->baddr) < 0)
1755			return -1;
1756		if (debug)
1757			fprintf(stderr, "[%d] setting bpt at %lx\n",
1758				tcp->pid, tcp->baddr);
1759		tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid,
1760				      (char *) tcp->baddr, 0);
1761		if (errno) {
1762			perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1763			return -1;
1764		}
1765		ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
1766		if (errno) {
1767			perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1768			return -1;
1769		}
1770		tcp->flags |= TCB_BPTSET;
1771	} else {
1772		/*
1773		 * Our strategy here is to replace the bundle that
1774		 * contained the clone() syscall with a bundle of the
1775		 * form:
1776		 *
1777		 *	{ 1: br 1b; br 1b; br 1b }
1778		 *
1779		 * This ensures that the newly forked child will loop
1780		 * endlessly until we've got a chance to attach to it.
1781		 */
1782#		define LOOP0	0x0000100000000017
1783#		define LOOP1	0x4000000000200000
1784		unsigned long addr, ipsr;
1785		pid_t pid;
1786
1787		pid = tcp->pid;
1788		if (upeek(tcp, PT_CR_IPSR, &ipsr) < 0)
1789			return -1;
1790		if (upeek(tcp, PT_CR_IIP, &addr) < 0)
1791			return -1;
1792		/* store "ri" in low two bits */
1793		tcp->baddr = addr | ((ipsr >> 41) & 0x3);
1794
1795		errno = 0;
1796		tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0,
1797				      0);
1798		tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8,
1799				      0);
1800		if (errno) {
1801			perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1802			return -1;
1803		}
1804
1805		errno = 0;
1806		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0);
1807		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1);
1808		if (errno) {
1809			perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1810			return -1;
1811		}
1812		tcp->flags |= TCB_BPTSET;
1813	}
1814#else /* !IA64 */
1815
1816#if defined (I386) || defined(X86_64)
1817#define LOOP	0x0000feeb
1818#elif defined (M68K)
1819#define LOOP	0x60fe0000
1820#elif defined (ALPHA)
1821#define LOOP	0xc3ffffff
1822#elif defined (POWERPC)
1823#define LOOP	0x48000000
1824#elif defined(ARM)
1825#define LOOP	0xEAFFFFFE
1826#elif defined(MIPS)
1827#define LOOP	0x1000ffff
1828#elif defined(S390)
1829#define LOOP	0xa7f40000	/* BRC 15,0 */
1830#elif defined(S390X)
1831#define LOOP   0xa7f4000000000000UL /* BRC 15,0 */
1832#elif defined(HPPA)
1833#define LOOP	0xe81f1ff7	/* b,l,n <loc>,r0 */
1834#elif defined(SH)
1835#ifdef __LITTLE_ENDIAN__
1836#define LOOP   0x0000affe
1837#else
1838#define LOOP   0xfeaf0000
1839#endif
1840#else
1841#error unknown architecture
1842#endif
1843
1844	if (tcp->flags & TCB_BPTSET) {
1845		fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid);
1846		return -1;
1847	}
1848#if defined (I386)
1849	if (upeek(tcp, 4*EIP, &tcp->baddr) < 0)
1850		return -1;
1851#elif defined (X86_64)
1852	if (upeek(tcp, 8*RIP, &tcp->baddr) < 0)
1853		return -1;
1854#elif defined (M68K)
1855	if (upeek(tcp, 4*PT_PC, &tcp->baddr) < 0)
1856	  return -1;
1857#elif defined (ALPHA)
1858	return -1;
1859#elif defined (ARM)
1860	return -1;
1861#elif defined (MIPS)
1862	return -1;		/* FIXME: I do not know what i do - Flo */
1863#elif defined (POWERPC)
1864	if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &tcp->baddr) < 0)
1865		return -1;
1866#elif defined(S390) || defined(S390X)
1867	if (upeek(tcp,PT_PSWADDR, &tcp->baddr) < 0)
1868		return -1;
1869#elif defined(HPPA)
1870	if (upeek(tcp, PT_IAOQ0, &tcp->baddr) < 0)
1871		return -1;
1872	tcp->baddr &= ~0x03;
1873#elif defined(SH)
1874	if (upeek(tcp, 4*REG_PC, &tcp->baddr) < 0)
1875		return -1;
1876#else
1877#error unknown architecture
1878#endif
1879	if (debug)
1880		fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr);
1881	tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0);
1882	if (errno) {
1883		perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1884		return -1;
1885	}
1886	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
1887	if (errno) {
1888		perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1889		return -1;
1890	}
1891	tcp->flags |= TCB_BPTSET;
1892
1893#endif /* !IA64 */
1894#endif /* SPARC || SPARC64 */
1895#endif /* LINUX */
1896
1897#ifdef SUNOS4
1898#ifdef SPARC	/* This code is slightly sparc specific */
1899
1900	struct regs regs;
1901#define BPT	0x91d02001	/* ta	1 */
1902#define LOOP	0x10800000	/* ba	0 */
1903#define LOOPA	0x30800000	/* ba,a	0 */
1904#define NOP	0x01000000
1905#if LOOPA
1906	static int loopdeloop[1] = {LOOPA};
1907#else
1908	static int loopdeloop[2] = {LOOP, NOP};
1909#endif
1910
1911	if (tcp->flags & TCB_BPTSET) {
1912		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1913		return -1;
1914	}
1915	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1916		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
1917		return -1;
1918	}
1919	tcp->baddr = regs.r_o7 + 8;
1920	if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr,
1921				sizeof tcp->inst, (char *)tcp->inst) < 0) {
1922		perror("setbpt: ptrace(PTRACE_READTEXT, ...)");
1923		return -1;
1924	}
1925
1926	/*
1927	 * XXX - BRUTAL MODE ON
1928	 * We cannot set a real BPT in the child, since it will not be
1929	 * traced at the moment it will reach the trap and would probably
1930	 * die with a core dump.
1931	 * Thus, we are force our way in by taking out two instructions
1932	 * and insert an eternal loop in stead, in expectance of the SIGSTOP
1933	 * generated by out PTRACE_ATTACH.
1934	 * Of cause, if we evaporate ourselves in the middle of all this...
1935	 */
1936	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
1937			sizeof loopdeloop, (char *) loopdeloop) < 0) {
1938		perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)");
1939		return -1;
1940	}
1941	tcp->flags |= TCB_BPTSET;
1942
1943#endif /* SPARC */
1944#endif /* SUNOS4 */
1945
1946	return 0;
1947}
1948
1949int
1950clearbpt(tcp)
1951struct tcb *tcp;
1952{
1953
1954#ifdef LINUX
1955#if defined(I386) || defined(X86_64)
1956	long eip;
1957#elif defined(POWERPC)
1958	long pc;
1959#elif defined(M68K)
1960	long pc;
1961#elif defined(ALPHA)
1962	long pc;
1963#elif defined(HPPA)
1964	long iaoq;
1965#elif defined(SH)
1966	long pc;
1967#endif /* architecture */
1968
1969#if defined (SPARC) || defined (SPARC64)
1970	/* Again, we borrow the SunOS breakpoint code. */
1971	if (!(tcp->flags & TCB_BPTSET)) {
1972		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
1973		return -1;
1974	}
1975	errno = 0;
1976	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
1977	if(errno) {
1978		perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
1979		return -1;
1980	}
1981	tcp->flags &= ~TCB_BPTSET;
1982#elif defined(IA64)
1983	if (ia32) {
1984		unsigned long addr;
1985
1986		if (debug)
1987			fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
1988		if (!(tcp->flags & TCB_BPTSET)) {
1989			fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
1990			return -1;
1991		}
1992		errno = 0;
1993		ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
1994		if (errno) {
1995			perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
1996			return -1;
1997		}
1998		tcp->flags &= ~TCB_BPTSET;
1999
2000		if (upeek(tcp, PT_CR_IIP, &addr) < 0)
2001			return -1;
2002		if (addr != tcp->baddr) {
2003			/* The breakpoint has not been reached yet.  */
2004			if (debug)
2005				fprintf(stderr,
2006					"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2007						addr, tcp->baddr);
2008			return 0;
2009		}
2010	} else {
2011		unsigned long addr, ipsr;
2012		pid_t pid;
2013
2014		pid = tcp->pid;
2015
2016		if (upeek(tcp, PT_CR_IPSR, &ipsr) < 0)
2017			return -1;
2018		if (upeek(tcp, PT_CR_IIP, &addr) < 0)
2019			return -1;
2020
2021		/* restore original bundle: */
2022		errno = 0;
2023		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]);
2024		ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]);
2025		if (errno) {
2026			perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)");
2027			return -1;
2028		}
2029
2030		/* restore original "ri" in ipsr: */
2031		ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41);
2032		errno = 0;
2033		ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr);
2034		if (errno) {
2035			perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)");
2036			return -1;
2037		}
2038
2039		tcp->flags &= ~TCB_BPTSET;
2040
2041		if (addr != (tcp->baddr & ~0x3)) {
2042			/* the breakpoint has not been reached yet.  */
2043			if (debug)
2044				fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2045					addr, tcp->baddr);
2046			return 0;
2047		}
2048	}
2049#else /* !IA64  && !SPARC && !SPARC64 */
2050
2051	if (debug)
2052		fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
2053	if (!(tcp->flags & TCB_BPTSET)) {
2054		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
2055		return -1;
2056	}
2057	errno = 0;
2058	ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
2059	if (errno) {
2060		perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
2061		return -1;
2062	}
2063	tcp->flags &= ~TCB_BPTSET;
2064
2065#ifdef I386
2066	if (upeek(tcp, 4*EIP, &eip) < 0)
2067		return -1;
2068	if (eip != tcp->baddr) {
2069		/* The breakpoint has not been reached yet.  */
2070		if (debug)
2071			fprintf(stderr,
2072				"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2073					eip, tcp->baddr);
2074		return 0;
2075	}
2076#elif defined(X86_64)
2077	if (upeek(tcp, 8*RIP, &eip) < 0)
2078		return -1;
2079	if (eip != tcp->baddr) {
2080		/* The breakpoint has not been reached yet.  */
2081		if (debug)
2082			fprintf(stderr,
2083				"NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2084					eip, tcp->baddr);
2085		return 0;
2086	}
2087#elif defined(POWERPC)
2088	if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0)
2089		return -1;
2090	if (pc != tcp->baddr) {
2091		/* The breakpoint has not been reached yet.  */
2092		if (debug)
2093			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2094				pc, tcp->baddr);
2095		return 0;
2096	}
2097#elif defined(M68K)
2098	if (upeek(tcp, 4*PT_PC, &pc) < 0)
2099		return -1;
2100	if (pc != tcp->baddr) {
2101		/* The breakpoint has not been reached yet.  */
2102		if (debug)
2103			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2104				pc, tcp->baddr);
2105		return 0;
2106	}
2107#elif defined(ALPHA)
2108	if (upeek(tcp, REG_PC, &pc) < 0)
2109		return -1;
2110	if (pc != tcp->baddr) {
2111		/* The breakpoint has not been reached yet.  */
2112		if (debug)
2113			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2114				pc, tcp->baddr);
2115		return 0;
2116	}
2117#elif defined(HPPA)
2118	if (upeek(tcp, PT_IAOQ0, &iaoq) < 0)
2119		return -1;
2120	iaoq &= ~0x03;
2121	if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) {
2122		/* The breakpoint has not been reached yet.  */
2123		if (debug)
2124			fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n",
2125				iaoq, tcp->baddr);
2126		return 0;
2127	}
2128	iaoq = tcp->baddr | 3;
2129	/* We should be pointing at a 'ldi -1000,r1' in glibc, so it is
2130	 * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit
2131	 * has no significant effect.
2132	 */
2133	ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq);
2134	ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq);
2135#elif defined(SH)
2136	if (upeek(tcp, 4*REG_PC, &pc) < 0)
2137		return -1;
2138	if (pc != tcp->baddr) {
2139		/* The breakpoint has not been reached yet.  */
2140		if (debug)
2141			fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
2142				pc, tcp->baddr);
2143		return 0;
2144	}
2145
2146#endif /* arch */
2147#endif /* !SPARC && !SPARC64 && !IA64 */
2148#endif /* LINUX */
2149
2150#ifdef SUNOS4
2151#ifdef SPARC
2152
2153#if !LOOPA
2154	struct regs regs;
2155#endif
2156
2157	if (!(tcp->flags & TCB_BPTSET)) {
2158		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
2159		return -1;
2160	}
2161	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
2162				sizeof tcp->inst, (char *) tcp->inst) < 0) {
2163		perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)");
2164		return -1;
2165	}
2166	tcp->flags &= ~TCB_BPTSET;
2167
2168#if !LOOPA
2169	/*
2170	 * Since we don't have a single instruction breakpoint, we may have
2171	 * to adjust the program counter after removing the our `breakpoint'.
2172	 */
2173	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
2174		perror("clearbpt: ptrace(PTRACE_GETREGS, ...)");
2175		return -1;
2176	}
2177	if ((regs.r_pc < tcp->baddr) ||
2178				(regs.r_pc > tcp->baddr + 4)) {
2179		/* The breakpoint has not been reached yet */
2180		if (debug)
2181			fprintf(stderr,
2182				"NOTE: PC not at bpt (pc %#x baddr %#x)\n",
2183					regs.r_pc, tcp->parent->baddr);
2184		return 0;
2185	}
2186	if (regs.r_pc != tcp->baddr)
2187		if (debug)
2188			fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n",
2189				regs.r_pc, tcp->baddr);
2190
2191	regs.r_pc = tcp->baddr;
2192	if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0) {
2193		perror("clearbpt: ptrace(PTRACE_SETREGS, ...)");
2194		return -1;
2195	}
2196#endif /* LOOPA */
2197#endif /* SPARC */
2198#endif /* SUNOS4 */
2199
2200	return 0;
2201}
2202
2203#endif
2204
2205#endif /* !USE_PROCFS */
2206
2207#ifdef SUNOS4
2208
2209static int
2210getex(tcp, hdr)
2211struct tcb *tcp;
2212struct exec *hdr;
2213{
2214	int n;
2215
2216	for (n = 0; n < sizeof *hdr; n += 4) {
2217		long res;
2218		if (upeek(tcp, uoff(u_exdata) + n, &res) < 0)
2219			return -1;
2220		memcpy(((char *) hdr) + n, &res, 4);
2221	}
2222	if (debug) {
2223		fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n",
2224			hdr->a_magic, hdr->a_toolversion, hdr->a_machtype);
2225		fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n",
2226			hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry);
2227	}
2228	return 0;
2229}
2230
2231int
2232fixvfork(tcp)
2233struct tcb *tcp;
2234{
2235	int pid = tcp->pid;
2236	/*
2237	 * Change `vfork' in a freshly exec'ed dynamically linked
2238	 * executable's (internal) symbol table to plain old `fork'
2239	 */
2240
2241	struct exec hdr;
2242	struct link_dynamic dyn;
2243	struct link_dynamic_2 ld;
2244	char *strtab, *cp;
2245
2246	if (getex(tcp, &hdr) < 0)
2247		return -1;
2248	if (!hdr.a_dynamic)
2249		return -1;
2250
2251	if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) {
2252		fprintf(stderr, "Cannot read DYNAMIC\n");
2253		return -1;
2254	}
2255	if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) {
2256		fprintf(stderr, "Cannot read link_dynamic_2\n");
2257		return -1;
2258	}
2259	if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) {
2260		fprintf(stderr, "out of memory\n");
2261		return -1;
2262	}
2263	if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
2264					(int)ld.ld_symb_size, strtab) < 0)
2265		goto err;
2266
2267#if 0
2268	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
2269		fprintf(stderr, "[symbol: %s]\n", cp);
2270		cp += strlen(cp)+1;
2271	}
2272	return 0;
2273#endif
2274	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
2275		if (strcmp(cp, "_vfork") == 0) {
2276			if (debug)
2277				fprintf(stderr, "fixvfork: FOUND _vfork\n");
2278			strcpy(cp, "_fork");
2279			break;
2280		}
2281		cp += strlen(cp)+1;
2282	}
2283	if (cp < strtab + ld.ld_symb_size)
2284		/*
2285		 * Write entire symbol table back to avoid
2286		 * memory alignment bugs in ptrace
2287		 */
2288		if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
2289					(int)ld.ld_symb_size, strtab) < 0)
2290			goto err;
2291
2292	free(strtab);
2293	return 0;
2294
2295err:
2296	free(strtab);
2297	return -1;
2298}
2299
2300#endif /* SUNOS4 */
2301