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