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