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#ifndef HAVE_ANDROID_OS
41#include <sys/user.h>
42#endif
43#include <sys/param.h>
44#include <fcntl.h>
45#if HAVE_SYS_UIO_H
46#include <sys/uio.h>
47#endif
48#ifdef SUNOS4
49#include <machine/reg.h>
50#include <a.out.h>
51#include <link.h>
52#endif /* SUNOS4 */
53
54#ifdef HAVE_ANDROID_OS
55#include "syscall-android.h"
56#endif
57
58#if defined(linux) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1))
59#include <linux/ptrace.h>
60#endif
61
62#if defined(LINUX) && defined(IA64)
63# include <asm/ptrace_offsets.h>
64# include <asm/rse.h>
65#endif
66
67#ifdef HAVE_SYS_REG_H
68#include <sys/reg.h>
69# define PTRACE_PEEKUSR PTRACE_PEEKUSER
70#elif defined(HAVE_LINUX_PTRACE_H)
71#undef PTRACE_SYSCALL
72# ifdef HAVE_STRUCT_IA64_FPREG
73#  define ia64_fpreg XXX_ia64_fpreg
74# endif
75# ifdef HAVE_STRUCT_PT_ALL_USER_REGS
76#  define pt_all_user_regs XXX_pt_all_user_regs
77# endif
78#include <linux/ptrace.h>
79# undef ia64_fpreg
80# undef pt_all_user_regs
81#endif
82
83#ifdef SUNOS4_KERNEL_ARCH_KLUDGE
84#include <sys/utsname.h>
85#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
86
87#if defined(LINUXSPARC) && defined (SPARC64)
88# undef PTRACE_GETREGS
89# define PTRACE_GETREGS PTRACE_GETREGS64
90# undef PTRACE_SETREGS
91# define PTRACE_SETREGS PTRACE_SETREGS64
92#endif
93
94/* macros */
95#ifndef MAX
96#define MAX(a,b)		(((a) > (b)) ? (a) : (b))
97#endif
98#ifndef MIN
99#define MIN(a,b)		(((a) < (b)) ? (a) : (b))
100#endif
101
102int
103tv_nz(a)
104struct timeval *a;
105{
106	return a->tv_sec || a->tv_usec;
107}
108
109int
110tv_cmp(a, b)
111struct timeval *a, *b;
112{
113	if (a->tv_sec < b->tv_sec
114	    || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
115		return -1;
116	if (a->tv_sec > b->tv_sec
117	    || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
118		return 1;
119	return 0;
120}
121
122double
123tv_float(tv)
124struct timeval *tv;
125{
126	return tv->tv_sec + tv->tv_usec/1000000.0;
127}
128
129void
130tv_add(tv, a, b)
131struct timeval *tv, *a, *b;
132{
133	tv->tv_sec = a->tv_sec + b->tv_sec;
134	tv->tv_usec = a->tv_usec + b->tv_usec;
135	if (tv->tv_usec >= 1000000) {
136		tv->tv_sec++;
137		tv->tv_usec -= 1000000;
138	}
139}
140
141void
142tv_sub(tv, a, b)
143struct timeval *tv, *a, *b;
144{
145	tv->tv_sec = a->tv_sec - b->tv_sec;
146	tv->tv_usec = a->tv_usec - b->tv_usec;
147	if (((long) tv->tv_usec) < 0) {
148		tv->tv_sec--;
149		tv->tv_usec += 1000000;
150	}
151}
152
153void
154tv_div(tv, a, n)
155struct timeval *tv, *a;
156int n;
157{
158	tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
159	tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
160	tv->tv_usec %= 1000000;
161}
162
163void
164tv_mul(tv, a, n)
165struct timeval *tv, *a;
166int n;
167{
168	tv->tv_usec = a->tv_usec * n;
169	tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000;
170	tv->tv_usec %= 1000000;
171}
172
173const char *
174xlookup(const struct xlat *xlat, int val)
175{
176	for (; xlat->str != NULL; xlat++)
177		if (xlat->val == val)
178			return xlat->str;
179	return NULL;
180}
181
182/*
183 * Generic ptrace wrapper which tracks ESRCH errors
184 * by setting tcp->ptrace_errno to ESRCH.
185 *
186 * We assume that ESRCH indicates likely process death (SIGKILL?),
187 * modulo bugs where process somehow ended up not stopped.
188 * Unfortunately kernel uses ESRCH for that case too. Oh well.
189 *
190 * Currently used by upeek() only.
191 * TODO: use this in all other ptrace() calls while decoding.
192 */
193long
194do_ptrace(int request, struct tcb *tcp, void *addr, void *data)
195{
196	long l;
197
198	errno = 0;
199	l = ptrace(request, tcp->pid, addr, (long) data);
200	/* Non-ESRCH errors might be our invalid reg/mem accesses,
201	 * we do not record them. */
202	if (errno == ESRCH)
203		tcp->ptrace_errno = ESRCH;
204	return l;
205}
206
207/*
208 * Used when we want to unblock stopped traced process.
209 * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL.
210 * Returns 0 on success or if error was ESRCH
211 * (presumably process was killed while we talk to it).
212 * Otherwise prints error message and returns -1.
213 */
214int
215ptrace_restart(int op, struct tcb *tcp, int sig)
216{
217	int err;
218	const char *msg;
219
220	errno = 0;
221	ptrace(op, tcp->pid, (void *) 1, (long) sig);
222	err = errno;
223	if (!err || err == ESRCH)
224		return 0;
225
226	tcp->ptrace_errno = err;
227	msg = "SYSCALL";
228	if (op == PTRACE_CONT)
229		msg = "CONT";
230	if (op == PTRACE_DETACH)
231		msg = "DETACH";
232	fprintf(stderr, "strace: ptrace(PTRACE_%s,1,%d): %s\n",
233			msg, sig, strerror(err));
234	return -1;
235}
236
237/*
238 * Print entry in struct xlat table, if there.
239 */
240void
241printxval(const struct xlat *xlat, int val, const char *dflt)
242{
243	const char *str = xlookup(xlat, val);
244
245	if (str)
246		tprintf("%s", str);
247	else
248		tprintf("%#x /* %s */", val, dflt);
249}
250
251#if HAVE_LONG_LONG
252/*
253 * Print 64bit argument at position llarg and return the index of the next
254 * argument.
255 */
256int
257printllval(struct tcb *tcp, const char *format, int llarg)
258{
259# if defined(FREEBSD) \
260     || (defined(LINUX) && defined(POWERPC) && !defined(POWERPC64)) \
261     || defined (LINUX_MIPSO32)
262	/* Align 64bit argument to 64bit boundary.  */
263	if (llarg % 2) llarg++;
264# endif
265# if defined LINUX && (defined X86_64 || defined POWERPC64)
266	if (current_personality == 0) {
267		tprintf(format, tcp->u_arg[llarg]);
268		llarg++;
269	} else {
270#  ifdef POWERPC64
271		/* Align 64bit argument to 64bit boundary.  */
272		if (llarg % 2) llarg++;
273#  endif
274		tprintf(format, LONG_LONG(tcp->u_arg[llarg], tcp->u_arg[llarg + 1]));
275		llarg += 2;
276	}
277# elif defined IA64 || defined ALPHA
278	tprintf(format, tcp->u_arg[llarg]);
279	llarg++;
280# elif defined LINUX_MIPSN32
281	tprintf(format, tcp->ext_arg[llarg]);
282	llarg++;
283# else
284	tprintf(format, LONG_LONG(tcp->u_arg[llarg], tcp->u_arg[llarg + 1]));
285	llarg += 2;
286# endif
287	return llarg;
288}
289#endif
290
291/*
292 * Interpret `xlat' as an array of flags
293 * print the entries whose bits are on in `flags'
294 * return # of flags printed.
295 */
296int
297addflags(xlat, flags)
298const struct xlat *xlat;
299int flags;
300{
301	int n;
302
303	for (n = 0; xlat->str; xlat++) {
304		if (xlat->val && (flags & xlat->val) == xlat->val) {
305			tprintf("|%s", xlat->str);
306			flags &= ~xlat->val;
307			n++;
308		}
309	}
310	if (flags) {
311		tprintf("|%#x", flags);
312		n++;
313	}
314	return n;
315}
316
317/*
318 * Interpret `xlat' as an array of flags/
319 * Print to static string the entries whose bits are on in `flags'
320 * Return static string.
321 */
322const char *
323sprintflags(const char *prefix, const struct xlat *xlat, int flags)
324{
325	static char outstr[1024];
326	int found = 0;
327
328	strcpy(outstr, prefix);
329
330	for (; xlat->str; xlat++) {
331		if ((flags & xlat->val) == xlat->val) {
332			if (found)
333				strcat(outstr, "|");
334			strcat(outstr, xlat->str);
335			flags &= ~xlat->val;
336			found = 1;
337		}
338	}
339	if (flags) {
340		if (found)
341			strcat(outstr, "|");
342		sprintf(outstr + strlen(outstr), "%#x", flags);
343	}
344
345	return outstr;
346}
347
348int
349printflags(const struct xlat *xlat, int flags, const char *dflt)
350{
351	int n;
352	const char *sep;
353
354	if (flags == 0 && xlat->val == 0) {
355		tprintf("%s", xlat->str);
356		return 1;
357	}
358
359	sep = "";
360	for (n = 0; xlat->str; xlat++) {
361		if (xlat->val && (flags & xlat->val) == xlat->val) {
362			tprintf("%s%s", sep, xlat->str);
363			flags &= ~xlat->val;
364			sep = "|";
365			n++;
366		}
367	}
368
369	if (n) {
370		if (flags) {
371			tprintf("%s%#x", sep, flags);
372			n++;
373		}
374	} else {
375		if (flags) {
376			tprintf("%#x", flags);
377			if (dflt)
378				tprintf(" /* %s */", dflt);
379		} else {
380			if (dflt)
381				tprintf("0");
382		}
383	}
384
385	return n;
386}
387
388void
389printnum(struct tcb *tcp, long addr, const char *fmt)
390{
391	long num;
392
393	if (!addr) {
394		tprintf("NULL");
395		return;
396	}
397	if (umove(tcp, addr, &num) < 0) {
398		tprintf("%#lx", addr);
399		return;
400	}
401	tprintf("[");
402	tprintf(fmt, num);
403	tprintf("]");
404}
405
406void
407printnum_int(struct tcb *tcp, long addr, const char *fmt)
408{
409	int num;
410
411	if (!addr) {
412		tprintf("NULL");
413		return;
414	}
415	if (umove(tcp, addr, &num) < 0) {
416		tprintf("%#lx", addr);
417		return;
418	}
419	tprintf("[");
420	tprintf(fmt, num);
421	tprintf("]");
422}
423
424void
425printfd(struct tcb *tcp, int fd)
426{
427	tprintf("%d", fd);
428}
429
430void
431printuid(text, uid)
432const char *text;
433unsigned long uid;
434{
435	tprintf("%s", text);
436	tprintf((uid == -1) ? "%ld" : "%lu", uid);
437}
438
439static char path[MAXPATHLEN + 1];
440
441/*
442 * Quote string `instr' of length `size'
443 * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
444 * If `len' < 0, treat `instr' as a NUL-terminated string
445 * and quote at most (`size' - 1) bytes.
446 */
447static int
448string_quote(const char *instr, char *outstr, int len, int size)
449{
450	const unsigned char *ustr = (const unsigned char *) instr;
451	char *s = outstr;
452	int usehex = 0, c, i;
453
454	if (xflag > 1)
455		usehex = 1;
456	else if (xflag) {
457		/* Check for presence of symbol which require
458		   to hex-quote the whole string. */
459		for (i = 0; i < size; ++i) {
460			c = ustr[i];
461			/* Check for NUL-terminated string. */
462			if (len < 0) {
463				if (c == '\0')
464					break;
465				/* Quote at most size - 1 bytes. */
466				if (i == size - 1)
467					continue;
468			}
469			if (!isprint(c) && !isspace(c)) {
470				usehex = 1;
471				break;
472			}
473		}
474	}
475
476	*s++ = '\"';
477
478	if (usehex) {
479		/* Hex-quote the whole string. */
480		for (i = 0; i < size; ++i) {
481			c = ustr[i];
482			/* Check for NUL-terminated string. */
483			if (len < 0) {
484				if (c == '\0')
485					break;
486				/* Quote at most size - 1 bytes. */
487				if (i == size - 1)
488					continue;
489			}
490			sprintf(s, "\\x%02x", c);
491			s += 4;
492		}
493	} else {
494		for (i = 0; i < size; ++i) {
495			c = ustr[i];
496			/* Check for NUL-terminated string. */
497			if (len < 0) {
498				if (c == '\0')
499					break;
500				/* Quote at most size - 1 bytes. */
501				if (i == size - 1)
502					continue;
503			}
504			switch (c) {
505				case '\"': case '\\':
506					*s++ = '\\';
507					*s++ = c;
508					break;
509				case '\f':
510					*s++ = '\\';
511					*s++ = 'f';
512					break;
513				case '\n':
514					*s++ = '\\';
515					*s++ = 'n';
516					break;
517				case '\r':
518					*s++ = '\\';
519					*s++ = 'r';
520					break;
521				case '\t':
522					*s++ = '\\';
523					*s++ = 't';
524					break;
525				case '\v':
526					*s++ = '\\';
527					*s++ = 'v';
528					break;
529				default:
530					if (isprint(c))
531						*s++ = c;
532					else if (i + 1 < size
533						 && isdigit(ustr[i + 1])) {
534						sprintf(s, "\\%03o", c);
535						s += 4;
536					} else {
537						sprintf(s, "\\%o", c);
538						s += strlen(s);
539					}
540					break;
541			}
542		}
543	}
544
545	*s++ = '\"';
546	*s = '\0';
547
548	/* Return nonzero if the string was unterminated.  */
549	return i == size;
550}
551
552/*
553 * Print path string specified by address `addr' and length `n'.
554 * If path length exceeds `n', append `...' to the output.
555 */
556void
557printpathn(struct tcb *tcp, long addr, int n)
558{
559	if (!addr) {
560		tprintf("NULL");
561		return;
562	}
563
564	/* Cap path length to the path buffer size,
565	   and NUL-terminate the buffer. */
566	if (n > sizeof path - 1)
567		n = sizeof path - 1;
568	path[n] = '\0';
569
570	/* Fetch one byte more to find out whether path length > n. */
571	if (umovestr(tcp, addr, n + 1, path) < 0)
572		tprintf("%#lx", addr);
573	else {
574		static char outstr[4*(sizeof path - 1) + sizeof "\"...\""];
575		int trunc = (path[n] != '\0');
576
577		if (trunc)
578			path[n] = '\0';
579		(void) string_quote(path, outstr, -1, n + 1);
580		if (trunc)
581			strcat(outstr, "...");
582		tprintf("%s", outstr);
583	}
584}
585
586void
587printpath(struct tcb *tcp, long addr)
588{
589	printpathn(tcp, addr, sizeof path - 1);
590}
591
592/*
593 * Print string specified by address `addr' and length `len'.
594 * If `len' < 0, treat the string as a NUL-terminated string.
595 * If string length exceeds `max_strlen', append `...' to the output.
596 */
597void
598printstr(struct tcb *tcp, long addr, int len)
599{
600	static char *str = NULL;
601	static char *outstr;
602	int size;
603
604	if (!addr) {
605		tprintf("NULL");
606		return;
607	}
608	/* Allocate static buffers if they are not allocated yet. */
609	if (!str)
610		str = malloc(max_strlen + 1);
611	if (!outstr)
612		outstr = malloc(4 * max_strlen + sizeof "\"...\"");
613	if (!str || !outstr) {
614		fprintf(stderr, "out of memory\n");
615		tprintf("%#lx", addr);
616		return;
617	}
618
619	if (len < 0) {
620		/*
621		 * Treat as a NUL-terminated string: fetch one byte more
622		 * because string_quote() quotes one byte less.
623		 */
624		size = max_strlen + 1;
625		str[max_strlen] = '\0';
626		if (umovestr(tcp, addr, size, str) < 0) {
627			tprintf("%#lx", addr);
628			return;
629		}
630	}
631	else {
632		size = MIN(len, max_strlen);
633		if (umoven(tcp, addr, size, str) < 0) {
634			tprintf("%#lx", addr);
635			return;
636		}
637	}
638
639	if (string_quote(str, outstr, len, size) &&
640	    (len < 0 || len > max_strlen))
641		strcat(outstr, "...");
642
643	tprintf("%s", outstr);
644}
645
646#if HAVE_SYS_UIO_H
647void
648dumpiov(tcp, len, addr)
649struct tcb * tcp;
650int len;
651long addr;
652{
653#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
654	union {
655		struct { u_int32_t base; u_int32_t len; } *iov32;
656		struct { u_int64_t base; u_int64_t len; } *iov64;
657	} iovu;
658#define iov iovu.iov64
659#define sizeof_iov \
660  (personality_wordsize[current_personality] == 4 \
661   ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64))
662#define iov_iov_base(i) \
663  (personality_wordsize[current_personality] == 4 \
664   ? (u_int64_t) iovu.iov32[i].base : iovu.iov64[i].base)
665#define iov_iov_len(i) \
666  (personality_wordsize[current_personality] == 4 \
667   ? (u_int64_t) iovu.iov32[i].len : iovu.iov64[i].len)
668#else
669	struct iovec *iov;
670#define sizeof_iov sizeof(*iov)
671#define iov_iov_base(i) iov[i].iov_base
672#define iov_iov_len(i) iov[i].iov_len
673#endif
674	int i;
675	unsigned long size;
676
677	size = sizeof_iov * (unsigned long) len;
678	if (size / sizeof_iov != len
679	    || (iov = malloc(size)) == NULL) {
680		fprintf(stderr, "out of memory\n");
681		return;
682	}
683	if (umoven(tcp, addr, size, (char *) iov) >= 0) {
684		for (i = 0; i < len; i++) {
685			/* include the buffer number to make it easy to
686			 * match up the trace with the source */
687			tprintf(" * %lu bytes in buffer %d\n",
688				(unsigned long)iov_iov_len(i), i);
689			dumpstr(tcp, (long) iov_iov_base(i),
690				iov_iov_len(i));
691		}
692	}
693	free((char *) iov);
694#undef sizeof_iov
695#undef iov_iov_base
696#undef iov_iov_len
697#undef iov
698}
699#endif
700
701void
702dumpstr(tcp, addr, len)
703struct tcb *tcp;
704long addr;
705int len;
706{
707	static int strsize = -1;
708	static unsigned char *str;
709	static char outstr[80];
710	char *s;
711	int i, j;
712
713	if (strsize < len) {
714		if (str)
715			free(str);
716		if ((str = malloc(len)) == NULL) {
717			fprintf(stderr, "out of memory\n");
718			return;
719		}
720		strsize = len;
721	}
722
723	if (umoven(tcp, addr, len, (char *) str) < 0)
724		return;
725
726	for (i = 0; i < len; i += 16) {
727		s = outstr;
728		sprintf(s, " | %05x ", i);
729		s += 9;
730		for (j = 0; j < 16; j++) {
731			if (j == 8)
732				*s++ = ' ';
733			if (i + j < len) {
734				sprintf(s, " %02x", str[i + j]);
735				s += 3;
736			}
737			else {
738				*s++ = ' '; *s++ = ' '; *s++ = ' ';
739			}
740		}
741		*s++ = ' '; *s++ = ' ';
742		for (j = 0; j < 16; j++) {
743			if (j == 8)
744				*s++ = ' ';
745			if (i + j < len) {
746				if (isprint(str[i + j]))
747					*s++ = str[i + j];
748				else
749					*s++ = '.';
750			}
751			else
752				*s++ = ' ';
753		}
754		tprintf("%s |\n", outstr);
755	}
756}
757
758#define PAGMASK	(~(PAGSIZ - 1))
759/*
760 * move `len' bytes of data from process `pid'
761 * at address `addr' to our space at `laddr'
762 */
763int
764umoven(struct tcb *tcp, long addr, int len, char *laddr)
765{
766#ifdef LINUX
767	int pid = tcp->pid;
768	int n, m;
769	int started = 0;
770	union {
771		long val;
772		char x[sizeof(long)];
773	} u;
774
775	if (addr & (sizeof(long) - 1)) {
776		/* addr not a multiple of sizeof(long) */
777		n = addr - (addr & -sizeof(long)); /* residue */
778		addr &= -sizeof(long); /* residue */
779		errno = 0;
780		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
781		if (errno) {
782			if (started && (errno==EPERM || errno==EIO)) {
783				/* Ran into 'end of memory' - stupid "printpath" */
784				return 0;
785			}
786			/* But if not started, we had a bogus address. */
787			if (addr != 0 && errno != EIO && errno != ESRCH)
788				perror("ptrace: umoven");
789			return -1;
790		}
791		started = 1;
792		memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
793		addr += sizeof(long), laddr += m, len -= m;
794	}
795	while (len) {
796		errno = 0;
797		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
798		if (errno) {
799			if (started && (errno==EPERM || errno==EIO)) {
800				/* Ran into 'end of memory' - stupid "printpath" */
801				return 0;
802			}
803			if (addr != 0 && errno != EIO && errno != ESRCH)
804				perror("ptrace: umoven");
805			return -1;
806		}
807		started = 1;
808		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
809		addr += sizeof(long), laddr += m, len -= m;
810	}
811#endif /* LINUX */
812
813#ifdef SUNOS4
814	int pid = tcp->pid;
815	int n;
816
817	while (len) {
818		n = MIN(len, PAGSIZ);
819		n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
820		if (ptrace(PTRACE_READDATA, pid,
821			   (char *) addr, len, laddr) < 0) {
822			if (errno != ESRCH) {
823				perror("umoven: ptrace(PTRACE_READDATA, ...)");
824				abort();
825			}
826			return -1;
827		}
828		len -= n;
829		addr += n;
830		laddr += n;
831	}
832#endif /* SUNOS4 */
833
834#ifdef USE_PROCFS
835#ifdef HAVE_MP_PROCFS
836	int fd = tcp->pfd_as;
837#else
838	int fd = tcp->pfd;
839#endif
840	lseek(fd, addr, SEEK_SET);
841	if (read(fd, laddr, len) == -1)
842		return -1;
843#endif /* USE_PROCFS */
844
845	return 0;
846}
847
848/*
849 * like `umove' but make the additional effort of looking
850 * for a terminating zero byte.
851 */
852int
853umovestr(struct tcb *tcp, long addr, int len, char *laddr)
854{
855#ifdef USE_PROCFS
856#ifdef HAVE_MP_PROCFS
857	int fd = tcp->pfd_as;
858#else
859	int fd = tcp->pfd;
860#endif
861	/* Some systems (e.g. FreeBSD) can be upset if we read off the
862	   end of valid memory,  avoid this by trying to read up
863	   to page boundaries.  But we don't know what a page is (and
864	   getpagesize(2) (if it exists) doesn't necessarily return
865	   hardware page size).  Assume all pages >= 1024 (a-historical
866	   I know) */
867
868	int page = 1024; 	/* How to find this? */
869	int move = page - (addr & (page - 1));
870	int left = len;
871
872	lseek(fd, addr, SEEK_SET);
873
874	while (left) {
875		if (move > left) move = left;
876		if ((move = read(fd, laddr, move)) <= 0)
877			return left != len ? 0 : -1;
878		if (memchr (laddr, 0, move)) break;
879		left -= move;
880		laddr += move;
881		addr += move;
882		move = page;
883	}
884#else /* !USE_PROCFS */
885	int started = 0;
886	int pid = tcp->pid;
887	int i, n, m;
888	union {
889		long val;
890		char x[sizeof(long)];
891	} u;
892
893	if (addr & (sizeof(long) - 1)) {
894		/* addr not a multiple of sizeof(long) */
895		n = addr - (addr & -sizeof(long)); /* residue */
896		addr &= -sizeof(long); /* residue */
897		errno = 0;
898		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
899		if (errno) {
900			if (started && (errno==EPERM || errno==EIO)) {
901				/* Ran into 'end of memory' - stupid "printpath" */
902				return 0;
903			}
904			if (addr != 0 && errno != EIO && errno != ESRCH)
905				perror("umovestr");
906			return -1;
907		}
908		started = 1;
909		memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len));
910		while (n & (sizeof(long) - 1))
911			if (u.x[n++] == '\0')
912				return 0;
913		addr += sizeof(long), laddr += m, len -= m;
914	}
915	while (len) {
916		errno = 0;
917		u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
918		if (errno) {
919			if (started && (errno==EPERM || errno==EIO)) {
920				/* Ran into 'end of memory' - stupid "printpath" */
921				return 0;
922			}
923			if (addr != 0 && errno != EIO && errno != ESRCH)
924				perror("umovestr");
925			return -1;
926		}
927		started = 1;
928		memcpy(laddr, u.x, m = MIN(sizeof(long), len));
929		for (i = 0; i < sizeof(long); i++)
930			if (u.x[i] == '\0')
931				return 0;
932
933		addr += sizeof(long), laddr += m, len -= m;
934	}
935#endif /* !USE_PROCFS */
936	return 0;
937}
938
939#ifdef LINUX
940# if !defined (SPARC) && !defined(SPARC64)
941#  define PTRACE_WRITETEXT	101
942#  define PTRACE_WRITEDATA	102
943# endif /* !SPARC && !SPARC64 */
944#endif /* LINUX */
945
946#ifdef SUNOS4
947
948static int
949uload(cmd, pid, addr, len, laddr)
950int cmd;
951int pid;
952long addr;
953int len;
954char *laddr;
955{
956	int peek, poke;
957	int n, m;
958	union {
959		long val;
960		char x[sizeof(long)];
961	} u;
962
963	if (cmd == PTRACE_WRITETEXT) {
964		peek = PTRACE_PEEKTEXT;
965		poke = PTRACE_POKETEXT;
966	}
967	else {
968		peek = PTRACE_PEEKDATA;
969		poke = PTRACE_POKEDATA;
970	}
971	if (addr & (sizeof(long) - 1)) {
972		/* addr not a multiple of sizeof(long) */
973		n = addr - (addr & -sizeof(long)); /* residue */
974		addr &= -sizeof(long);
975		errno = 0;
976		u.val = ptrace(peek, pid, (char *) addr, 0);
977		if (errno) {
978			perror("uload: POKE");
979			return -1;
980		}
981		memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len));
982		if (ptrace(poke, pid, (char *)addr, u.val) < 0) {
983			perror("uload: POKE");
984			return -1;
985		}
986		addr += sizeof(long), laddr += m, len -= m;
987	}
988	while (len) {
989		if (len < sizeof(long))
990			u.val = ptrace(peek, pid, (char *) addr, 0);
991		memcpy(u.x, laddr, m = MIN(sizeof(long), len));
992		if (ptrace(poke, pid, (char *) addr, u.val) < 0) {
993			perror("uload: POKE");
994			return -1;
995		}
996		addr += sizeof(long), laddr += m, len -= m;
997	}
998	return 0;
999}
1000
1001int
1002tload(pid, addr, len, laddr)
1003int pid;
1004int addr, len;
1005char *laddr;
1006{
1007	return uload(PTRACE_WRITETEXT, pid, addr, len, laddr);
1008}
1009
1010int
1011dload(pid, addr, len, laddr)
1012int pid;
1013int addr;
1014int len;
1015char *laddr;
1016{
1017	return uload(PTRACE_WRITEDATA, pid, addr, len, laddr);
1018}
1019
1020#endif /* SUNOS4 */
1021
1022#ifndef USE_PROCFS
1023
1024int
1025upeek(tcp, off, res)
1026struct tcb *tcp;
1027long off;
1028long *res;
1029{
1030	long val;
1031
1032# ifdef SUNOS4_KERNEL_ARCH_KLUDGE
1033	{
1034		static int is_sun4m = -1;
1035		struct utsname name;
1036
1037		/* Round up the usual suspects. */
1038		if (is_sun4m == -1) {
1039			if (uname(&name) < 0) {
1040				perror("upeek: uname?");
1041				exit(1);
1042			}
1043			is_sun4m = strcmp(name.machine, "sun4m") == 0;
1044			if (is_sun4m) {
1045				const struct xlat *x;
1046
1047				for (x = struct_user_offsets; x->str; x++)
1048					x->val += 1024;
1049			}
1050		}
1051		if (is_sun4m)
1052			off += 1024;
1053	}
1054# endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
1055	errno = 0;
1056	val = do_ptrace(PTRACE_PEEKUSER, tcp, (char *) off, 0);
1057	if (val == -1 && errno) {
1058		if (errno != ESRCH) {
1059			char buf[60];
1060			sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)", tcp->pid, off);
1061			perror(buf);
1062		}
1063		return -1;
1064	}
1065	*res = val;
1066	return 0;
1067}
1068
1069#endif /* !USE_PROCFS */
1070
1071void
1072printcall(struct tcb *tcp)
1073{
1074#define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \
1075			   sizeof(long) == 8 ? "[????????????????] " : \
1076			   NULL /* crash */)
1077
1078#ifdef LINUX
1079# ifdef I386
1080	long eip;
1081
1082	if (upeek(tcp, 4*EIP, &eip) < 0) {
1083		PRINTBADPC;
1084		return;
1085	}
1086	tprintf("[%08lx] ", eip);
1087
1088# elif defined(S390) || defined(S390X)
1089	long psw;
1090	if(upeek(tcp,PT_PSWADDR,&psw) < 0) {
1091		PRINTBADPC;
1092		return;
1093	}
1094#  ifdef S390
1095	tprintf("[%08lx] ", psw);
1096#  elif S390X
1097	tprintf("[%16lx] ", psw);
1098#  endif
1099
1100# elif defined(X86_64)
1101	long rip;
1102
1103	if (upeek(tcp, 8*RIP, &rip) < 0) {
1104		PRINTBADPC;
1105		return;
1106	}
1107	tprintf("[%16lx] ", rip);
1108# elif defined(IA64)
1109	long ip;
1110
1111	if (upeek(tcp, PT_B0, &ip) < 0) {
1112		PRINTBADPC;
1113		return;
1114	}
1115	tprintf("[%08lx] ", ip);
1116# elif defined(POWERPC)
1117	long pc;
1118
1119	if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) {
1120		PRINTBADPC;
1121		return;
1122	}
1123#  ifdef POWERPC64
1124	tprintf("[%016lx] ", pc);
1125#  else
1126	tprintf("[%08lx] ", pc);
1127#  endif
1128# elif defined(M68K)
1129	long pc;
1130
1131	if (upeek(tcp, 4*PT_PC, &pc) < 0) {
1132		tprintf ("[????????] ");
1133		return;
1134	}
1135	tprintf("[%08lx] ", pc);
1136# elif defined(ALPHA)
1137	long pc;
1138
1139	if (upeek(tcp, REG_PC, &pc) < 0) {
1140		tprintf ("[????????????????] ");
1141		return;
1142	}
1143	tprintf("[%08lx] ", pc);
1144# elif defined(SPARC) || defined(SPARC64)
1145	struct pt_regs regs;
1146	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0) {
1147		PRINTBADPC;
1148		return;
1149	}
1150#  if defined(SPARC64)
1151	tprintf("[%08lx] ", regs.tpc);
1152#  else
1153	tprintf("[%08lx] ", regs.pc);
1154#  endif
1155# elif defined(HPPA)
1156	long pc;
1157
1158	if(upeek(tcp,PT_IAOQ0,&pc) < 0) {
1159		tprintf ("[????????] ");
1160		return;
1161	}
1162	tprintf("[%08lx] ", pc);
1163# elif defined(MIPS)
1164	long pc;
1165
1166	if (upeek(tcp, REG_EPC, &pc) < 0) {
1167		tprintf ("[????????] ");
1168		return;
1169	}
1170	tprintf("[%08lx] ", pc);
1171# elif defined(SH)
1172	long pc;
1173
1174	if (upeek(tcp, 4*REG_PC, &pc) < 0) {
1175		tprintf ("[????????] ");
1176		return;
1177	}
1178	tprintf("[%08lx] ", pc);
1179# elif defined(SH64)
1180	long pc;
1181
1182	if (upeek(tcp, REG_PC, &pc) < 0) {
1183		tprintf ("[????????????????] ");
1184		return;
1185	}
1186	tprintf("[%08lx] ", pc);
1187# elif defined(ARM)
1188	long pc;
1189
1190	if (upeek(tcp, 4*15, &pc) < 0) {
1191		PRINTBADPC;
1192		return;
1193	}
1194	tprintf("[%08lx] ", pc);
1195# elif defined(AVR32)
1196	long pc;
1197
1198	if (upeek(tcp, REG_PC, &pc) < 0) {
1199		tprintf("[????????] ");
1200		return;
1201	}
1202	tprintf("[%08lx] ", pc);
1203# elif defined(BFIN)
1204	long pc;
1205
1206	if (upeek(tcp, PT_PC, &pc) < 0) {
1207		PRINTBADPC;
1208		return;
1209	}
1210	tprintf("[%08lx] ", pc);
1211#elif defined(CRISV10)
1212	long pc;
1213
1214	if (upeek(tcp, 4*PT_IRP, &pc) < 0) {
1215		PRINTBADPC;
1216		return;
1217	}
1218	tprintf("[%08lx] ", pc);
1219#elif defined(CRISV32)
1220	long pc;
1221
1222	if (upeek(tcp, 4*PT_ERP, &pc) < 0) {
1223		PRINTBADPC;
1224		return;
1225	}
1226	tprintf("[%08lx] ", pc);
1227# endif /* architecture */
1228#endif /* LINUX */
1229
1230#ifdef SUNOS4
1231	struct regs regs;
1232
1233	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) &regs, 0) < 0) {
1234		perror("printcall: ptrace(PTRACE_GETREGS, ...)");
1235		PRINTBADPC;
1236		return;
1237	}
1238	tprintf("[%08x] ", regs.r_o7);
1239#endif /* SUNOS4 */
1240
1241#ifdef SVR4
1242	/* XXX */
1243	PRINTBADPC;
1244#endif
1245
1246#ifdef FREEBSD
1247	struct reg regs;
1248	pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
1249	tprintf("[%08x] ", regs.r_eip);
1250#endif /* FREEBSD */
1251}
1252
1253
1254/*
1255 * These #if's are huge, please indent them correctly.
1256 * It's easy to get confused otherwise.
1257 */
1258#ifndef USE_PROCFS
1259
1260#ifdef LINUX
1261
1262#  include "syscall.h"
1263
1264#  include <sys/syscall.h>
1265#  ifndef CLONE_PTRACE
1266#   define CLONE_PTRACE    0x00002000
1267#  endif
1268#  ifndef CLONE_VFORK
1269#   define CLONE_VFORK     0x00004000
1270#  endif
1271#  ifndef CLONE_VM
1272#   define CLONE_VM        0x00000100
1273#  endif
1274#  ifndef CLONE_STOPPED
1275#   define CLONE_STOPPED   0x02000000
1276#  endif
1277
1278#  ifdef IA64
1279
1280/* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32
1281   subsystem has them for x86... */
1282#   define SYS_fork	2
1283#   define SYS_vfork	190
1284
1285typedef unsigned long *arg_setup_state;
1286
1287static int
1288arg_setup(struct tcb *tcp, arg_setup_state *state)
1289{
1290	unsigned long cfm, sof, sol;
1291	long bsp;
1292
1293	if (ia32) {
1294		/* Satisfy a false GCC warning.  */
1295		*state = NULL;
1296		return 0;
1297	}
1298
1299	if (upeek(tcp, PT_AR_BSP, &bsp) < 0)
1300		return -1;
1301	if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
1302		return -1;
1303
1304	sof = (cfm >> 0) & 0x7f;
1305	sol = (cfm >> 7) & 0x7f;
1306	bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol);
1307
1308	*state = (unsigned long *) bsp;
1309	return 0;
1310}
1311
1312#   define arg_finish_change(tcp, state)	0
1313
1314#   ifdef SYS_fork
1315static int
1316get_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp)
1317{
1318	int ret;
1319
1320	if (ia32)
1321		ret = upeek (tcp, PT_R11, valp);
1322	else
1323		ret = umoven (tcp,
1324			      (unsigned long) ia64_rse_skip_regs(*state, 0),
1325			      sizeof(long), (void *) valp);
1326	return ret;
1327}
1328
1329static int
1330get_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp)
1331{
1332	int ret;
1333
1334	if (ia32)
1335		ret = upeek (tcp, PT_R9, valp);
1336	else
1337		ret = umoven (tcp,
1338			      (unsigned long) ia64_rse_skip_regs(*state, 1),
1339			      sizeof(long), (void *) valp);
1340	return ret;
1341}
1342#   endif
1343
1344static int
1345set_arg0 (struct tcb *tcp, arg_setup_state *state, long val)
1346{
1347	int req = PTRACE_POKEDATA;
1348	void *ap;
1349
1350	if (ia32) {
1351		ap = (void *) (intptr_t) PT_R11;	 /* r11 == EBX */
1352		req = PTRACE_POKEUSER;
1353	} else
1354		ap = ia64_rse_skip_regs(*state, 0);
1355	errno = 0;
1356	ptrace(req, tcp->pid, ap, val);
1357	return errno ? -1 : 0;
1358}
1359
1360static int
1361set_arg1 (struct tcb *tcp, arg_setup_state *state, long val)
1362{
1363	int req = PTRACE_POKEDATA;
1364	void *ap;
1365
1366	if (ia32) {
1367		ap = (void *) (intptr_t) PT_R9;		/* r9 == ECX */
1368		req = PTRACE_POKEUSER;
1369	} else
1370		ap = ia64_rse_skip_regs(*state, 1);
1371	errno = 0;
1372	ptrace(req, tcp->pid, ap, val);
1373	return errno ? -1 : 0;
1374}
1375
1376/* ia64 does not return the input arguments from functions (and syscalls)
1377   according to ia64 RSE (Register Stack Engine) behavior.  */
1378
1379#   define restore_arg0(tcp, state, val) ((void) (state), 0)
1380#   define restore_arg1(tcp, state, val) ((void) (state), 0)
1381
1382#  elif defined (SPARC) || defined (SPARC64)
1383
1384typedef struct pt_regs arg_setup_state;
1385
1386#   define arg_setup(tcp, state) \
1387    (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0))
1388#   define arg_finish_change(tcp, state) \
1389    (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0))
1390
1391#   define get_arg0(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O0], 0)
1392#   define get_arg1(tcp, state, valp) (*(valp) = (state)->u_regs[U_REG_O1], 0)
1393#   define set_arg0(tcp, state, val) ((state)->u_regs[U_REG_O0] = (val), 0)
1394#   define set_arg1(tcp, state, val) ((state)->u_regs[U_REG_O1] = (val), 0)
1395#   define restore_arg0(tcp, state, val) 0
1396
1397#  else /* other architectures */
1398
1399#   if defined S390 || defined S390X
1400/* Note: this is only true for the `clone' system call, which handles
1401   arguments specially.  We could as well say that its first two arguments
1402   are swapped relative to other architectures, but that would just be
1403   another #ifdef in the calls.  */
1404#    define arg0_offset	PT_GPR3
1405#    define arg1_offset	PT_ORIGGPR2
1406#    define restore_arg0(tcp, state, val) ((void) (state), 0)
1407#    define restore_arg1(tcp, state, val) ((void) (state), 0)
1408#    define arg0_index	1
1409#    define arg1_index	0
1410#   elif defined (ALPHA) || defined (MIPS)
1411#    define arg0_offset	REG_A0
1412#    define arg1_offset	(REG_A0+1)
1413#   elif defined (AVR32)
1414#    define arg0_offset	(REG_R12)
1415#    define arg1_offset	(REG_R11)
1416#   elif defined (POWERPC)
1417#    define arg0_offset	(sizeof(unsigned long)*PT_R3)
1418#    define arg1_offset	(sizeof(unsigned long)*PT_R4)
1419#    define restore_arg0(tcp, state, val) ((void) (state), 0)
1420#   elif defined (HPPA)
1421#    define arg0_offset	 PT_GR26
1422#    define arg1_offset	 (PT_GR26-4)
1423#   elif defined (X86_64)
1424#    define arg0_offset	((long)(8*(current_personality ? RBX : RDI)))
1425#    define arg1_offset	((long)(8*(current_personality ? RCX : RSI)))
1426#   elif defined (SH)
1427#    define arg0_offset	(4*(REG_REG0+4))
1428#    define arg1_offset	(4*(REG_REG0+5))
1429#   elif defined (SH64)
1430    /* ABI defines arg0 & 1 in r2 & r3 */
1431#    define arg0_offset   (REG_OFFSET+16)
1432#    define arg1_offset   (REG_OFFSET+24)
1433#    define restore_arg0(tcp, state, val) 0
1434#   elif defined CRISV10 || defined CRISV32
1435#    define arg0_offset   (4*PT_R11)
1436#    define arg1_offset   (4*PT_ORIG_R10)
1437#    define restore_arg0(tcp, state, val) 0
1438#    define restore_arg1(tcp, state, val) 0
1439#    define arg0_index   1
1440#    define arg1_index   0
1441#   else
1442#    define arg0_offset	0
1443#    define arg1_offset	4
1444#    if defined ARM
1445#     define restore_arg0(tcp, state, val) 0
1446#    endif
1447#   endif
1448
1449typedef int arg_setup_state;
1450
1451#   define arg_setup(tcp, state) (0)
1452#   define arg_finish_change(tcp, state)	0
1453#   define get_arg0(tcp, cookie, valp) \
1454    (upeek ((tcp), arg0_offset, (valp)))
1455#   define get_arg1(tcp, cookie, valp) \
1456    (upeek ((tcp), arg1_offset, (valp)))
1457
1458static int
1459set_arg0 (struct tcb *tcp, void *cookie, long val)
1460{
1461	return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val);
1462}
1463
1464static int
1465set_arg1 (struct tcb *tcp, void *cookie, long val)
1466{
1467	return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val);
1468}
1469
1470#  endif /* architectures */
1471
1472#  ifndef restore_arg0
1473#   define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val))
1474#  endif
1475#  ifndef restore_arg1
1476#   define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val))
1477#  endif
1478
1479#  ifndef arg0_index
1480#   define arg0_index 0
1481#   define arg1_index 1
1482#  endif
1483
1484int
1485setbpt(struct tcb *tcp)
1486{
1487	static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone };
1488	arg_setup_state state;
1489
1490	if (tcp->flags & TCB_BPTSET) {
1491		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1492		return -1;
1493	}
1494
1495	/*
1496	 * It's a silly kludge to initialize this with a search at runtime.
1497	 * But it's better than maintaining another magic thing in the
1498	 * godforsaken tables.
1499	 */
1500	if (clone_scno[current_personality] == 0) {
1501		int i;
1502		for (i = 0; i < nsyscalls; ++i)
1503			if (sysent[i].sys_func == sys_clone) {
1504				clone_scno[current_personality] = i;
1505				break;
1506			}
1507	}
1508
1509	switch (known_scno(tcp)) {
1510#  ifdef SYS_vfork
1511	case SYS_vfork:
1512#  endif
1513#  ifdef SYS_fork
1514	case SYS_fork:
1515#  endif
1516#  if defined SYS_fork || defined SYS_vfork
1517		if (arg_setup (tcp, &state) < 0
1518		    || get_arg0 (tcp, &state, &tcp->inst[0]) < 0
1519		    || get_arg1 (tcp, &state, &tcp->inst[1]) < 0
1520		    || change_syscall(tcp, clone_scno[current_personality]) < 0
1521		    || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0
1522		    || set_arg1 (tcp, &state, 0) < 0
1523		    || arg_finish_change (tcp, &state) < 0)
1524			return -1;
1525		tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD;
1526		tcp->u_arg[arg1_index] = 0;
1527		tcp->flags |= TCB_BPTSET;
1528		return 0;
1529#  endif
1530
1531	case SYS_clone:
1532#  ifdef SYS_clone2
1533	case SYS_clone2:
1534#  endif
1535		/* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)'
1536		   contrary to x86 SYS_vfork above.  Even on x86 we turn the
1537		   vfork semantics into plain fork - each application must not
1538		   depend on the vfork specifics according to POSIX.  We would
1539		   hang waiting for the parent resume otherwise.  We need to
1540		   clear also CLONE_VM but only in the CLONE_VFORK case as
1541		   otherwise we would break pthread_create.  */
1542
1543		if ((arg_setup (tcp, &state) < 0
1544		    || set_arg0 (tcp, &state,
1545				 (tcp->u_arg[arg0_index] | CLONE_PTRACE)
1546				 & ~(tcp->u_arg[arg0_index] & CLONE_VFORK
1547				     ? CLONE_VFORK | CLONE_VM : 0)) < 0
1548		    || arg_finish_change (tcp, &state) < 0))
1549			return -1;
1550		tcp->flags |= TCB_BPTSET;
1551		tcp->inst[0] = tcp->u_arg[arg0_index];
1552		tcp->inst[1] = tcp->u_arg[arg1_index];
1553		return 0;
1554
1555	default:
1556		fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n",
1557			tcp->scno, tcp->pid);
1558		break;
1559	}
1560
1561	return -1;
1562}
1563
1564int
1565clearbpt(tcp)
1566struct tcb *tcp;
1567{
1568	arg_setup_state state;
1569	if (arg_setup (tcp, &state) < 0
1570	    || restore_arg0 (tcp, &state, tcp->inst[0]) < 0
1571	    || restore_arg1 (tcp, &state, tcp->inst[1]) < 0
1572	    || arg_finish_change (tcp, &state))
1573		if (errno != ESRCH) return -1;
1574	tcp->flags &= ~TCB_BPTSET;
1575	return 0;
1576}
1577
1578# else /* !defined LINUX */
1579
1580int
1581setbpt(tcp)
1582struct tcb *tcp;
1583{
1584#  ifdef SUNOS4
1585#   ifdef SPARC	/* This code is slightly sparc specific */
1586
1587	struct regs regs;
1588#    define BPT	0x91d02001	/* ta	1 */
1589#    define LOOP	0x10800000	/* ba	0 */
1590#    define LOOPA	0x30800000	/* ba,a	0 */
1591#    define NOP	0x01000000
1592#    if LOOPA
1593	static int loopdeloop[1] = {LOOPA};
1594#    else
1595	static int loopdeloop[2] = {LOOP, NOP};
1596#    endif
1597
1598	if (tcp->flags & TCB_BPTSET) {
1599		fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1600		return -1;
1601	}
1602	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1603		perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
1604		return -1;
1605	}
1606	tcp->baddr = regs.r_o7 + 8;
1607	if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr,
1608				sizeof tcp->inst, (char *)tcp->inst) < 0) {
1609		perror("setbpt: ptrace(PTRACE_READTEXT, ...)");
1610		return -1;
1611	}
1612
1613	/*
1614	 * XXX - BRUTAL MODE ON
1615	 * We cannot set a real BPT in the child, since it will not be
1616	 * traced at the moment it will reach the trap and would probably
1617	 * die with a core dump.
1618	 * Thus, we are force our way in by taking out two instructions
1619	 * and insert an eternal loop in stead, in expectance of the SIGSTOP
1620	 * generated by out PTRACE_ATTACH.
1621	 * Of cause, if we evaporate ourselves in the middle of all this...
1622	 */
1623	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
1624			sizeof loopdeloop, (char *) loopdeloop) < 0) {
1625		perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)");
1626		return -1;
1627	}
1628	tcp->flags |= TCB_BPTSET;
1629
1630#   endif /* SPARC */
1631#  endif /* SUNOS4 */
1632
1633	return 0;
1634}
1635
1636int
1637clearbpt(tcp)
1638struct tcb *tcp;
1639{
1640#  ifdef SUNOS4
1641#   ifdef SPARC
1642
1643#    if !LOOPA
1644	struct regs regs;
1645#    endif
1646
1647	if (!(tcp->flags & TCB_BPTSET)) {
1648		fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
1649		return -1;
1650	}
1651	if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
1652				sizeof tcp->inst, (char *) tcp->inst) < 0) {
1653		perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)");
1654		return -1;
1655	}
1656	tcp->flags &= ~TCB_BPTSET;
1657
1658#    if !LOOPA
1659	/*
1660	 * Since we don't have a single instruction breakpoint, we may have
1661	 * to adjust the program counter after removing our `breakpoint'.
1662	 */
1663	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1664		perror("clearbpt: ptrace(PTRACE_GETREGS, ...)");
1665		return -1;
1666	}
1667	if ((regs.r_pc < tcp->baddr) ||
1668				(regs.r_pc > tcp->baddr + 4)) {
1669		/* The breakpoint has not been reached yet */
1670		if (debug)
1671			fprintf(stderr,
1672				"NOTE: PC not at bpt (pc %#x baddr %#x)\n",
1673					regs.r_pc, tcp->baddr);
1674		return 0;
1675	}
1676	if (regs.r_pc != tcp->baddr)
1677		if (debug)
1678			fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n",
1679				regs.r_pc, tcp->baddr);
1680
1681	regs.r_pc = tcp->baddr;
1682	if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0) {
1683		perror("clearbpt: ptrace(PTRACE_SETREGS, ...)");
1684		return -1;
1685	}
1686#    endif /* LOOPA */
1687#   endif /* SPARC */
1688#  endif /* SUNOS4 */
1689
1690	return 0;
1691}
1692
1693# endif /* !defined LINUX */
1694
1695#endif /* !USE_PROCFS */
1696
1697
1698#ifdef SUNOS4
1699
1700static int
1701getex(tcp, hdr)
1702struct tcb *tcp;
1703struct exec *hdr;
1704{
1705	int n;
1706
1707	for (n = 0; n < sizeof *hdr; n += 4) {
1708		long res;
1709		if (upeek(tcp, uoff(u_exdata) + n, &res) < 0)
1710			return -1;
1711		memcpy(((char *) hdr) + n, &res, 4);
1712	}
1713	if (debug) {
1714		fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n",
1715			hdr->a_magic, hdr->a_toolversion, hdr->a_machtype);
1716		fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n",
1717			hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry);
1718	}
1719	return 0;
1720}
1721
1722int
1723fixvfork(tcp)
1724struct tcb *tcp;
1725{
1726	int pid = tcp->pid;
1727	/*
1728	 * Change `vfork' in a freshly exec'ed dynamically linked
1729	 * executable's (internal) symbol table to plain old `fork'
1730	 */
1731
1732	struct exec hdr;
1733	struct link_dynamic dyn;
1734	struct link_dynamic_2 ld;
1735	char *strtab, *cp;
1736
1737	if (getex(tcp, &hdr) < 0)
1738		return -1;
1739	if (!hdr.a_dynamic)
1740		return -1;
1741
1742	if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) {
1743		fprintf(stderr, "Cannot read DYNAMIC\n");
1744		return -1;
1745	}
1746	if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) {
1747		fprintf(stderr, "Cannot read link_dynamic_2\n");
1748		return -1;
1749	}
1750	if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) {
1751		fprintf(stderr, "out of memory\n");
1752		return -1;
1753	}
1754	if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
1755					(int)ld.ld_symb_size, strtab) < 0)
1756		goto err;
1757
1758	for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
1759		if (strcmp(cp, "_vfork") == 0) {
1760			if (debug)
1761				fprintf(stderr, "fixvfork: FOUND _vfork\n");
1762			strcpy(cp, "_fork");
1763			break;
1764		}
1765		cp += strlen(cp)+1;
1766	}
1767	if (cp < strtab + ld.ld_symb_size)
1768		/*
1769		 * Write entire symbol table back to avoid
1770		 * memory alignment bugs in ptrace
1771		 */
1772		if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
1773					(int)ld.ld_symb_size, strtab) < 0)
1774			goto err;
1775
1776	free(strtab);
1777	return 0;
1778
1779err:
1780	free(strtab);
1781	return -1;
1782}
1783
1784#endif /* SUNOS4 */
1785