process.c revision 87ea1f4fe68c6110a96a76f8601b3e204200082d
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 * Copyright (c) 2000 PocketPenguins Inc.  Linux for Hitachi SuperH
10 *                    port by Greg Banks <gbanks@pocketpenguins.com>
11
12 *
13 * All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 *    notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 *    notice, this list of conditions and the following disclaimer in the
22 *    documentation and/or other materials provided with the distribution.
23 * 3. The name of the author may not be used to endorse or promote products
24 *    derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 *	$Id$
38 */
39
40#include "defs.h"
41
42#include <fcntl.h>
43#include <sys/stat.h>
44#include <sys/time.h>
45#include <sys/wait.h>
46#include <sys/resource.h>
47#include <sys/utsname.h>
48#include <sys/user.h>
49#include <sys/syscall.h>
50#include <signal.h>
51#ifdef SUNOS4
52#include <machine/reg.h>
53#endif /* SUNOS4 */
54
55#ifdef FREEBSD
56#include <sys/ptrace.h>
57#endif
58
59#if HAVE_ASM_REG_H
60#if defined (SPARC) || defined (SPARC64)
61#  define fpq kernel_fpq
62#  define fq kernel_fq
63#  define fpu kernel_fpu
64#endif /* SPARC || SPARC64 */
65#include <asm/reg.h>
66#if defined (SPARC) || defined (SPARC64)
67#  undef fpq
68#  undef fq
69#  undef fpu
70#endif /* SPARC || SPARC64 */
71#endif /* HAVE_ASM_REG_H */
72
73#ifdef HAVE_SYS_REG_H
74# include <sys/reg.h>
75#ifndef PTRACE_PEEKUSR
76# define PTRACE_PEEKUSR PTRACE_PEEKUSER
77#endif
78#ifndef PTRACE_POKEUSR
79# define PTRACE_POKEUSR PTRACE_POKEUSER
80#endif
81#endif
82
83#ifdef HAVE_LINUX_PTRACE_H
84#undef PTRACE_SYSCALL
85# ifdef HAVE_STRUCT_IA64_FPREG
86#  define ia64_fpreg XXX_ia64_fpreg
87# endif
88# ifdef HAVE_STRUCT_PT_ALL_USER_REGS
89#  define pt_all_user_regs XXX_pt_all_user_regs
90# endif
91#include <linux/ptrace.h>
92# undef ia64_fpreg
93# undef pt_all_user_regs
94#endif
95
96#if defined (LINUX) && defined (SPARC64)
97# define r_pc r_tpc
98# undef PTRACE_GETREGS
99# define PTRACE_GETREGS PTRACE_GETREGS64
100# undef PTRACE_SETREGS
101# define PTRACE_SETREGS PTRACE_SETREGS64
102#endif /* LINUX && SPARC64 */
103
104#ifdef HAVE_LINUX_FUTEX_H
105#include <linux/futex.h>
106#endif
107#if defined LINUX
108# ifndef FUTEX_WAIT
109#  define FUTEX_WAIT 0
110# endif
111# ifndef FUTEX_WAKE
112#  define FUTEX_WAKE 1
113# endif
114# ifndef FUTEX_FD
115#  define FUTEX_FD 2
116# endif
117# ifndef FUTEX_REQUEUE
118#  define FUTEX_REQUEUE 3
119# endif
120#endif
121
122#ifdef LINUX
123#include <sched.h>
124#include <asm/posix_types.h>
125#undef GETGROUPS_T
126#define GETGROUPS_T __kernel_gid_t
127#undef GETGROUPS32_T
128#define GETGROUPS32_T __kernel_gid32_t
129#endif /* LINUX */
130
131#if defined(LINUX) && defined(IA64)
132# include <asm/ptrace_offsets.h>
133# include <asm/rse.h>
134#endif
135
136#ifdef HAVE_PRCTL
137#include <sys/prctl.h>
138#endif
139
140#ifndef WCOREDUMP
141#define WCOREDUMP(status) ((status) & 0200)
142#endif
143
144/* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
145#if defined(HAVE_PRCTL)
146static const struct xlat prctl_options[] = {
147#ifdef PR_MAXPROCS
148	{ PR_MAXPROCS,		"PR_MAXPROCS"		},
149#endif
150#ifdef PR_ISBLOCKED
151	{ PR_ISBLOCKED,		"PR_ISBLOCKED"		},
152#endif
153#ifdef PR_SETSTACKSIZE
154	{ PR_SETSTACKSIZE,	"PR_SETSTACKSIZE"	},
155#endif
156#ifdef PR_GETSTACKSIZE
157	{ PR_GETSTACKSIZE,	"PR_GETSTACKSIZE"	},
158#endif
159#ifdef PR_MAXPPROCS
160	{ PR_MAXPPROCS,		"PR_MAXPPROCS"		},
161#endif
162#ifdef PR_UNBLKONEXEC
163	{ PR_UNBLKONEXEC,	"PR_UNBLKONEXEC"	},
164#endif
165#ifdef PR_ATOMICSIM
166	{ PR_ATOMICSIM,		"PR_ATOMICSIM"		},
167#endif
168#ifdef PR_SETEXITSIG
169	{ PR_SETEXITSIG,	"PR_SETEXITSIG"		},
170#endif
171#ifdef PR_RESIDENT
172	{ PR_RESIDENT,		"PR_RESIDENT"		},
173#endif
174#ifdef PR_ATTACHADDR
175	{ PR_ATTACHADDR,	"PR_ATTACHADDR"		},
176#endif
177#ifdef PR_DETACHADDR
178	{ PR_DETACHADDR,	"PR_DETACHADDR"		},
179#endif
180#ifdef PR_TERMCHILD
181	{ PR_TERMCHILD,		"PR_TERMCHILD"		},
182#endif
183#ifdef PR_GETSHMASK
184	{ PR_GETSHMASK,		"PR_GETSHMASK"		},
185#endif
186#ifdef PR_GETNSHARE
187	{ PR_GETNSHARE,		"PR_GETNSHARE"		},
188#endif
189#if defined(PR_SET_PDEATHSIG)
190	{ PR_SET_PDEATHSIG,	"PR_SET_PDEATHSIG"	},
191#endif
192#ifdef PR_COREPID
193	{ PR_COREPID,		"PR_COREPID"		},
194#endif
195#ifdef PR_ATTACHADDRPERM
196	{ PR_ATTACHADDRPERM,	"PR_ATTACHADDRPERM"	},
197#endif
198#ifdef PR_PTHREADEXIT
199	{ PR_PTHREADEXIT,	"PR_PTHREADEXIT"	},
200#endif
201#ifdef PR_SET_PDEATHSIG
202	{ PR_SET_PDEATHSIG,	"PR_SET_PDEATHSIG"	},
203#endif
204#ifdef PR_GET_PDEATHSIG
205	{ PR_GET_PDEATHSIG,	"PR_GET_PDEATHSIG"	},
206#endif
207#ifdef PR_GET_DUMPABLE
208	{ PR_GET_DUMPABLE,	"PR_GET_DUMPABLE"	},
209#endif
210#ifdef PR_SET_DUMPABLE
211	{ PR_SET_DUMPABLE,	"PR_SET_DUMPABLE"	},
212#endif
213#ifdef PR_GET_UNALIGN
214	{ PR_GET_UNALIGN,	"PR_GET_UNALIGN"	},
215#endif
216#ifdef PR_SET_UNALIGN
217	{ PR_SET_UNALIGN,	"PR_SET_UNALIGN"	},
218#endif
219#ifdef PR_GET_KEEPCAPS
220	{ PR_GET_KEEPCAPS,	"PR_GET_KEEP_CAPS"	},
221#endif
222#ifdef PR_SET_KEEPCAPS
223	{ PR_SET_KEEPCAPS,	"PR_SET_KEEP_CAPS"	},
224#endif
225#ifdef PR_GET_FPEMU
226	{ PR_GET_FPEMU,		"PR_GET_FPEMU"		},
227#endif
228#ifdef PR_SET_FPEMU
229	{ PR_SET_FPEMU,		"PR_SET_FPEMU"		},
230#endif
231#ifdef PR_GET_FPEXC
232	{ PR_GET_FPEXC,		"PR_GET_FPEXC"		},
233#endif
234#ifdef PR_SET_FPEXC
235	{ PR_SET_FPEXC,		"PR_SET_FPEXC"		},
236#endif
237#ifdef PR_GET_TIMING
238	{ PR_GET_TIMING,	"PR_GET_TIMING"		},
239#endif
240#ifdef PR_SET_TIMING
241	{ PR_SET_TIMING,	"PR_SET_TIMING"		},
242#endif
243#ifdef PR_SET_NAME
244	{ PR_SET_NAME,		"PR_SET_NAME"		},
245#endif
246#ifdef PR_GET_NAME
247	{ PR_GET_NAME,		"PR_GET_NAME"		},
248#endif
249#ifdef PR_GET_ENDIAN
250	{ PR_GET_ENDIAN,	"PR_GET_ENDIAN"		},
251#endif
252#ifdef PR_SET_ENDIAN
253	{ PR_SET_ENDIAN,	"PR_SET_ENDIAN"		},
254#endif
255#ifdef PR_GET_SECCOMP
256	{ PR_GET_SECCOMP,	"PR_GET_SECCOMP"	},
257#endif
258#ifdef PR_SET_SECCOMP
259	{ PR_SET_SECCOMP,	"PR_SET_SECCOMP"	},
260#endif
261	{ 0,			NULL			},
262};
263
264
265static const char *
266unalignctl_string (unsigned int ctl)
267{
268	static char buf[16];
269
270	switch (ctl) {
271#ifdef PR_UNALIGN_NOPRINT
272	      case PR_UNALIGN_NOPRINT:
273		return "NOPRINT";
274#endif
275#ifdef PR_UNALIGN_SIGBUS
276	      case PR_UNALIGN_SIGBUS:
277		return "SIGBUS";
278#endif
279	      default:
280		break;
281	}
282	sprintf(buf, "%x", ctl);
283	return buf;
284}
285
286
287int
288sys_prctl(tcp)
289struct tcb *tcp;
290{
291	int i;
292
293	if (entering(tcp)) {
294		printxval(prctl_options, tcp->u_arg[0], "PR_???");
295		switch (tcp->u_arg[0]) {
296#ifdef PR_GETNSHARE
297		case PR_GETNSHARE:
298			break;
299#endif
300#ifdef PR_SET_PDEATHSIG
301		case PR_SET_PDEATHSIG:
302			tprintf(", %lu", tcp->u_arg[1]);
303			break;
304#endif
305#ifdef PR_GET_PDEATHSIG
306		case PR_GET_PDEATHSIG:
307			break;
308#endif
309#ifdef PR_SET_DUMPABLE
310		case PR_SET_DUMPABLE:
311			tprintf(", %lu", tcp->u_arg[1]);
312			break;
313#endif
314#ifdef PR_GET_DUMPABLE
315		case PR_GET_DUMPABLE:
316			break;
317#endif
318#ifdef PR_SET_UNALIGN
319		case PR_SET_UNALIGN:
320			tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
321			break;
322#endif
323#ifdef PR_GET_UNALIGN
324		case PR_GET_UNALIGN:
325			tprintf(", %#lx", tcp->u_arg[1]);
326			break;
327#endif
328#ifdef PR_SET_KEEPCAPS
329		case PR_SET_KEEPCAPS:
330			tprintf(", %lu", tcp->u_arg[1]);
331			break;
332#endif
333#ifdef PR_GET_KEEPCAPS
334		case PR_GET_KEEPCAPS:
335			break;
336#endif
337		default:
338			for (i = 1; i < tcp->u_nargs; i++)
339				tprintf(", %#lx", tcp->u_arg[i]);
340			break;
341		}
342	} else {
343		switch (tcp->u_arg[0]) {
344#ifdef PR_GET_PDEATHSIG
345		case PR_GET_PDEATHSIG:
346			if (umove(tcp, tcp->u_arg[1], &i) < 0)
347				tprintf(", %#lx", tcp->u_arg[1]);
348			else
349				tprintf(", {%u}", i);
350			break;
351#endif
352#ifdef PR_GET_DUMPABLE
353		case PR_GET_DUMPABLE:
354			return RVAL_UDECIMAL;
355#endif
356#ifdef PR_GET_UNALIGN
357		case PR_GET_UNALIGN:
358			if (syserror(tcp) || umove(tcp, tcp->u_arg[1], &i) < 0)
359				break;
360			tcp->auxstr = unalignctl_string(i);
361			return RVAL_STR;
362#endif
363#ifdef PR_GET_KEEPCAPS
364		case PR_GET_KEEPCAPS:
365			return RVAL_UDECIMAL;
366#endif
367		default:
368			break;
369		}
370	}
371	return 0;
372}
373
374#endif /* HAVE_PRCTL */
375
376#if defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
377int
378sys_gethostid(tcp)
379struct tcb *tcp;
380{
381	if (exiting(tcp))
382		return RVAL_HEX;
383	return 0;
384}
385#endif /* FREEBSD || SUNOS4 || SVR4 */
386
387int
388sys_sethostname(tcp)
389struct tcb *tcp;
390{
391	if (entering(tcp)) {
392		printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
393		tprintf(", %lu", tcp->u_arg[1]);
394	}
395	return 0;
396}
397
398#if defined(ALPHA) || defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
399int
400sys_gethostname(tcp)
401struct tcb *tcp;
402{
403	if (exiting(tcp)) {
404		if (syserror(tcp))
405			tprintf("%#lx", tcp->u_arg[0]);
406		else
407			printpath(tcp, tcp->u_arg[0]);
408		tprintf(", %lu", tcp->u_arg[1]);
409	}
410	return 0;
411}
412#endif /* ALPHA || FREEBSD || SUNOS4 || SVR4 */
413
414int
415sys_setdomainname(tcp)
416struct tcb *tcp;
417{
418	if (entering(tcp)) {
419		printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
420		tprintf(", %lu", tcp->u_arg[1]);
421	}
422	return 0;
423}
424
425#if !defined(LINUX)
426
427int
428sys_getdomainname(tcp)
429struct tcb *tcp;
430{
431	if (exiting(tcp)) {
432		if (syserror(tcp))
433			tprintf("%#lx", tcp->u_arg[0]);
434		else
435			printpath(tcp, tcp->u_arg[0]);
436		tprintf(", %lu", tcp->u_arg[1]);
437	}
438	return 0;
439}
440#endif /* !LINUX */
441
442int
443sys_exit(tcp)
444struct tcb *tcp;
445{
446	if (exiting(tcp)) {
447		fprintf(stderr, "_exit returned!\n");
448		return -1;
449	}
450	/* special case: we stop tracing this process, finish line now */
451	tprintf("%ld) ", tcp->u_arg[0]);
452	tabto(acolumn);
453	tprintf("= ?");
454	printtrailer(tcp);
455	return 0;
456}
457
458int
459internal_exit(tcp)
460struct tcb *tcp;
461{
462	if (entering(tcp)) {
463		tcp->flags |= TCB_EXITING;
464#ifdef __NR_exit_group
465# ifdef IA64
466		if (ia32) {
467			if (tcp->scno == 252)
468				tcp->flags |= TCB_GROUP_EXITING;
469		} else
470# endif
471		if (known_scno(tcp) == __NR_exit_group)
472			tcp->flags |= TCB_GROUP_EXITING;
473#endif
474	}
475	return 0;
476}
477
478/* TCP is creating a child we want to follow.
479   If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
480   If not, clear TCB_FOLLOWFORK, print an error, and return 1.  */
481static int
482fork_tcb(struct tcb *tcp)
483{
484	if (nprocs == tcbtabsize) {
485		if (expand_tcbtab()) {
486			tcp->flags &= ~TCB_FOLLOWFORK;
487			return 1;
488		}
489	}
490
491	tcp->flags |= TCB_FOLLOWFORK;
492	return 0;
493}
494
495#ifdef USE_PROCFS
496
497int
498sys_fork(tcp)
499struct tcb *tcp;
500{
501	if (exiting(tcp) && !syserror(tcp)) {
502		if (getrval2(tcp)) {
503			tcp->auxstr = "child process";
504			return RVAL_UDECIMAL | RVAL_STR;
505		}
506	}
507	return 0;
508}
509
510#if UNIXWARE > 2
511
512int
513sys_rfork(tcp)
514struct tcb *tcp;
515{
516	if (entering(tcp)) {
517		tprintf ("%ld", tcp->u_arg[0]);
518	}
519	else if (!syserror(tcp)) {
520		if (getrval2(tcp)) {
521			tcp->auxstr = "child process";
522			return RVAL_UDECIMAL | RVAL_STR;
523		}
524	}
525	return 0;
526}
527
528#endif
529
530int
531internal_fork(tcp)
532struct tcb *tcp;
533{
534	struct tcb *tcpchild;
535
536	if (exiting(tcp)) {
537#ifdef SYS_rfork
538		if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
539			return 0;
540#endif
541		if (getrval2(tcp))
542			return 0;
543		if (!followfork)
544			return 0;
545		if (fork_tcb(tcp))
546			return 0;
547		if (syserror(tcp))
548			return 0;
549		if ((tcpchild = alloctcb(tcp->u_rval)) == NULL)
550			return 0;
551		if (proc_open(tcpchild, 2) < 0)
552		  	droptcb(tcpchild);
553	}
554	return 0;
555}
556
557#else /* !USE_PROCFS */
558
559#ifdef LINUX
560
561/* defines copied from linux/sched.h since we can't include that
562 * ourselves (it conflicts with *lots* of libc includes)
563 */
564#define CSIGNAL         0x000000ff      /* signal mask to be sent at exit */
565#define CLONE_VM        0x00000100      /* set if VM shared between processes */
566#define CLONE_FS        0x00000200      /* set if fs info shared between processes */
567#define CLONE_FILES     0x00000400      /* set if open files shared between processes */
568#define CLONE_SIGHAND   0x00000800      /* set if signal handlers shared */
569#define CLONE_IDLETASK  0x00001000      /* kernel-only flag */
570#define CLONE_PTRACE    0x00002000      /* set if we want to let tracing continue on the child too */
571#define CLONE_VFORK     0x00004000      /* set if the parent wants the child to wake it up on mm_release */
572#define CLONE_PARENT    0x00008000      /* set if we want to have the same parent as the cloner */
573#define CLONE_THREAD	0x00010000	/* Same thread group? */
574#define CLONE_NEWNS	0x00020000	/* New namespace group? */
575#define CLONE_SYSVSEM	0x00040000	/* share system V SEM_UNDO semantics */
576#define CLONE_SETTLS	0x00080000	/* create a new TLS for the child */
577#define CLONE_PARENT_SETTID	0x00100000	/* set the TID in the parent */
578#define CLONE_CHILD_CLEARTID	0x00200000	/* clear the TID in the child */
579#define CLONE_DETACHED		0x00400000	/* parent wants no child-exit signal */
580#define CLONE_UNTRACED		0x00800000	/* set if the tracing process can't force CLONE_PTRACE on this clone */
581#define CLONE_CHILD_SETTID	0x01000000	/* set the TID in the child */
582
583static const struct xlat clone_flags[] = {
584    { CLONE_VM,		"CLONE_VM"	},
585    { CLONE_FS,		"CLONE_FS"	},
586    { CLONE_FILES,	"CLONE_FILES"	},
587    { CLONE_SIGHAND,	"CLONE_SIGHAND"	},
588    { CLONE_IDLETASK,	"CLONE_IDLETASK"},
589    { CLONE_PTRACE,	"CLONE_PTRACE"	},
590    { CLONE_VFORK,	"CLONE_VFORK"	},
591    { CLONE_PARENT,	"CLONE_PARENT"	},
592    { CLONE_THREAD,	"CLONE_THREAD" },
593    { CLONE_NEWNS,	"CLONE_NEWNS" },
594    { CLONE_SYSVSEM,	"CLONE_SYSVSEM" },
595    { CLONE_SETTLS,	"CLONE_SETTLS" },
596    { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
597    { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
598    { CLONE_DETACHED,	"CLONE_DETACHED" },
599    { CLONE_UNTRACED,	"CLONE_UNTRACED" },
600    { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
601    { 0,		NULL		},
602};
603
604# ifdef I386
605#  include <asm/ldt.h>
606#   ifdef HAVE_STRUCT_USER_DESC
607#    define modify_ldt_ldt_s user_desc
608#   endif
609extern void print_ldt_entry();
610# endif
611
612# if defined IA64
613#  define ARG_FLAGS	0
614#  define ARG_STACK	1
615#  define ARG_STACKSIZE	(known_scno(tcp) == SYS_clone2 ? 2 : -1)
616#  define ARG_PTID	(known_scno(tcp) == SYS_clone2 ? 3 : 2)
617#  define ARG_CTID	(known_scno(tcp) == SYS_clone2 ? 4 : 3)
618#  define ARG_TLS	(known_scno(tcp) == SYS_clone2 ? 5 : 4)
619# elif defined S390 || defined S390X
620#  define ARG_STACK	0
621#  define ARG_FLAGS	1
622#  define ARG_PTID	2
623#  define ARG_CTID	3
624#  define ARG_TLS	4
625# elif defined X86_64 || defined ALPHA
626#  define ARG_FLAGS	0
627#  define ARG_STACK	1
628#  define ARG_PTID	2
629#  define ARG_CTID	3
630#  define ARG_TLS	4
631# else
632#  define ARG_FLAGS	0
633#  define ARG_STACK	1
634#  define ARG_PTID	2
635#  define ARG_TLS	3
636#  define ARG_CTID	4
637# endif
638
639int
640sys_clone(tcp)
641struct tcb *tcp;
642{
643	if (exiting(tcp)) {
644		unsigned long flags = tcp->u_arg[ARG_FLAGS];
645		tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
646# ifdef ARG_STACKSIZE
647		if (ARG_STACKSIZE != -1)
648			tprintf("stack_size=%#lx, ",
649				tcp->u_arg[ARG_STACKSIZE]);
650# endif
651		tprintf("flags=");
652		printflags(clone_flags, flags &~ CSIGNAL, NULL);
653		if ((flags & CSIGNAL) != 0)
654			tprintf("|%s", signame(flags & CSIGNAL));
655		if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
656			      |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
657			return 0;
658		if (flags & CLONE_PARENT_SETTID)
659			tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
660		if (flags & CLONE_SETTLS) {
661# ifdef I386
662			struct modify_ldt_ldt_s copy;
663			if (umove(tcp, tcp->u_arg[ARG_TLS], &copy) != -1) {
664				tprintf(", {entry_number:%d, ",
665					copy.entry_number);
666				if (!verbose(tcp))
667					tprintf("...}");
668				else
669					print_ldt_entry(&copy);
670			}
671			else
672# endif
673				tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
674		}
675		if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
676			tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
677	}
678	return 0;
679}
680
681int
682sys_unshare(struct tcb *tcp)
683{
684	if (entering(tcp))
685		printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
686	return 0;
687}
688#endif
689
690int
691sys_fork(tcp)
692struct tcb *tcp;
693{
694	if (exiting(tcp))
695		return RVAL_UDECIMAL;
696	return 0;
697}
698
699int
700change_syscall(tcp, new)
701struct tcb *tcp;
702int new;
703{
704#if defined(LINUX)
705#if defined(I386)
706	/* Attempt to make vfork into fork, which we can follow. */
707	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
708		return -1;
709	return 0;
710#elif defined(X86_64)
711	/* Attempt to make vfork into fork, which we can follow. */
712	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
713		return -1;
714	return 0;
715#elif defined(POWERPC)
716	if (ptrace(PTRACE_POKEUSER, tcp->pid,
717		   (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
718		return -1;
719       return 0;
720#elif defined(S390) || defined(S390X)
721	/* s390 linux after 2.4.7 has a hook in entry.S to allow this */
722	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
723	        return -1;
724	return 0;
725#elif defined(M68K)
726	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
727	    	return -1;
728	return 0;
729#elif defined(SPARC) || defined(SPARC64)
730	struct regs regs;
731	if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
732		return -1;
733	regs.r_g1=new;
734	if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
735	    	return -1;
736	return 0;
737#elif defined(MIPS)
738	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
739	    	return -1;
740	return 0;
741#elif defined(ALPHA)
742	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
743	    	return -1;
744	return 0;
745#elif defined(BFIN)
746	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_P0), new)<0)
747		return -1;
748	return 0;
749#elif defined(IA64)
750	if (ia32) {
751		switch (new) {
752		      case 2: break;	/* x86 SYS_fork */
753		      case SYS_clone:	new = 120; break;
754		      default:
755			fprintf(stderr, "%s: unexpected syscall %d\n",
756				__FUNCTION__, new);
757			return -1;
758		}
759		if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
760			return -1;
761	} else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
762		return -1;
763	return 0;
764#elif defined(HPPA)
765	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
766	    	return -1;
767	return 0;
768#elif defined(SH)
769       if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
770               return -1;
771       return 0;
772#elif defined(SH64)
773       /* Top half of reg encodes the no. of args n as 0x1n.
774          Assume 0 args as kernel never actually checks... */
775       if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
776                                   0x100000 | new) < 0)
777                       return -1;
778       return 0;
779#elif defined(ARM)
780       /* Some kernels support this, some (pre-2.6.16 or so) don't.  */
781# ifndef PTRACE_SET_SYSCALL
782#  define PTRACE_SET_SYSCALL 23
783# endif
784
785       if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new) != 0)
786		return -1;
787
788       return 0;
789#else
790#warning Do not know how to handle change_syscall for this architecture
791#endif /* architecture */
792#endif /* LINUX */
793	return -1;
794}
795
796#if 0
797int
798setarg(tcp, argnum)
799	struct tcb *tcp;
800	int argnum;
801{
802#if defined (IA64)
803	{
804		unsigned long *bsp, *ap;
805
806		if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
807			return -1;
808
809		ap = ia64_rse_skip_regs(bsp, argnum);
810		errno = 0;
811		ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
812		if (errno)
813			return -1;
814
815	}
816#elif defined(I386)
817	{
818		ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
819		if (errno)
820			return -1;
821	}
822#elif defined(X86_64)
823	{
824		ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
825		if (errno)
826			return -1;
827	}
828#elif defined(POWERPC)
829#ifndef PT_ORIG_R3
830#define PT_ORIG_R3 34
831#endif
832	{
833		ptrace(PTRACE_POKEUSER, tcp->pid,
834		       (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
835		       tcp->u_arg[argnum]);
836		if (errno)
837			return -1;
838	}
839#elif defined(MIPS)
840	{
841		errno = 0;
842		if (argnum < 4)
843			ptrace(PTRACE_POKEUSER, tcp->pid,
844			       (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
845		else {
846			unsigned long *sp;
847
848			if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
849				return -1;
850
851			ptrace(PTRACE_POKEDATA, tcp->pid,
852			       (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
853		}
854		if (errno)
855			return -1;
856	}
857#elif defined(S390) || defined(S390X)
858        {
859		if(argnum <= 5)
860			ptrace(PTRACE_POKEUSER, tcp->pid,
861			       (char *) (argnum==0 ? PT_ORIGGPR2 :
862			       PT_GPR2 + argnum*sizeof(long)),
863			       tcp->u_arg[argnum]);
864		else
865			return -E2BIG;
866		if (errno)
867			return -1;
868        }
869#else
870# warning Sorry, setargs not implemented for this architecture.
871#endif
872	return 0;
873}
874#endif
875
876#if defined SYS_clone || defined SYS_clone2
877int
878internal_clone(tcp)
879struct tcb *tcp;
880{
881	struct tcb *tcpchild;
882	int pid;
883	if (entering(tcp)) {
884		if (!followfork)
885			return 0;
886		if (fork_tcb(tcp))
887			return 0;
888		if (setbpt(tcp) < 0)
889			return 0;
890	} else {
891		int bpt = tcp->flags & TCB_BPTSET;
892
893		if (!(tcp->flags & TCB_FOLLOWFORK))
894			return 0;
895
896		if (syserror(tcp)) {
897			if (bpt)
898				clearbpt(tcp);
899			return 0;
900		}
901
902		pid = tcp->u_rval;
903
904#ifdef CLONE_PTRACE		/* See new setbpt code.  */
905		tcpchild = pid2tcb(pid);
906		if (tcpchild != NULL) {
907			/* The child already reported its startup trap
908			   before the parent reported its syscall return.  */
909			if ((tcpchild->flags
910			     & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
911			    != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
912				fprintf(stderr, "\
913[preattached child %d of %d in weird state!]\n",
914					pid, tcp->pid);
915		}
916		else
917#endif
918		if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
919			if (bpt)
920				clearbpt(tcp);
921			kill(pid, SIGKILL); /* XXX */
922			return 0;
923		}
924
925#ifndef CLONE_PTRACE
926		/* Attach to the new child */
927		if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
928			if (bpt)
929				clearbpt(tcp);
930			perror("PTRACE_ATTACH");
931			fprintf(stderr, "Too late?\n");
932			droptcb(tcpchild);
933			return 0;
934		}
935#endif
936
937		if (bpt)
938			clearbpt(tcp);
939
940		tcpchild->flags |= TCB_ATTACHED;
941		/* Child has BPT too, must be removed on first occasion.  */
942		if (bpt) {
943			tcpchild->flags |= TCB_BPTSET;
944			tcpchild->baddr = tcp->baddr;
945			memcpy(tcpchild->inst, tcp->inst,
946				sizeof tcpchild->inst);
947		}
948		tcpchild->parent = tcp;
949 		tcp->nchildren++;
950		if (tcpchild->flags & TCB_SUSPENDED) {
951			/* The child was born suspended, due to our having
952			   forced CLONE_PTRACE.  */
953			if (bpt)
954				clearbpt(tcpchild);
955
956			tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
957			if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
958				perror("resume: ptrace(PTRACE_SYSCALL, ...)");
959				return -1;
960			}
961
962			if (!qflag)
963				fprintf(stderr, "\
964Process %u resumed (parent %d ready)\n",
965					pid, tcp->pid);
966		}
967		else {
968			if (!qflag)
969				fprintf(stderr, "Process %d attached\n", pid);
970		}
971
972#ifdef TCB_CLONE_THREAD
973		{
974			/*
975			 * Save the flags used in this call,
976			 * in case we point TCP to our parent below.
977			 */
978			int call_flags = tcp->u_arg[ARG_FLAGS];
979			if ((tcp->flags & TCB_CLONE_THREAD) &&
980			    tcp->parent != NULL) {
981				/* The parent in this clone is itself a
982				   thread belonging to another process.
983				   There is no meaning to the parentage
984				   relationship of the new child with the
985				   thread, only with the process.  We
986				   associate the new thread with our
987				   parent.  Since this is done for every
988				   new thread, there will never be a
989				   TCB_CLONE_THREAD process that has
990				   children.  */
991				--tcp->nchildren;
992				tcp = tcp->parent;
993				tcpchild->parent = tcp;
994				++tcp->nchildren;
995			}
996			if (call_flags & CLONE_THREAD) {
997				tcpchild->flags |= TCB_CLONE_THREAD;
998				++tcp->nclone_threads;
999			}
1000			if (call_flags & CLONE_DETACHED) {
1001				tcpchild->flags |= TCB_CLONE_DETACHED;
1002				++tcp->nclone_detached;
1003			}
1004		}
1005#endif
1006
1007 	}
1008	return 0;
1009}
1010#endif
1011
1012int
1013internal_fork(tcp)
1014struct tcb *tcp;
1015{
1016#ifdef LINUX
1017	/* We do special magic with clone for any clone or fork.  */
1018	return internal_clone(tcp);
1019#else
1020
1021	struct tcb *tcpchild;
1022	int pid;
1023	int dont_follow = 0;
1024
1025#ifdef SYS_vfork
1026	if (known_scno(tcp) == SYS_vfork) {
1027		/* Attempt to make vfork into fork, which we can follow. */
1028		if (change_syscall(tcp, SYS_fork) < 0)
1029			dont_follow = 1;
1030	}
1031#endif
1032	if (entering(tcp)) {
1033		if (!followfork || dont_follow)
1034			return 0;
1035		if (fork_tcb(tcp))
1036			return 0;
1037		if (setbpt(tcp) < 0)
1038			return 0;
1039  	}
1040	else {
1041		int bpt = tcp->flags & TCB_BPTSET;
1042
1043		if (!(tcp->flags & TCB_FOLLOWFORK))
1044			return 0;
1045		if (bpt)
1046			clearbpt(tcp);
1047
1048		if (syserror(tcp))
1049			return 0;
1050
1051		pid = tcp->u_rval;
1052		if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
1053			kill(pid, SIGKILL); /* XXX */
1054			return 0;
1055		}
1056#ifdef LINUX
1057#ifdef HPPA
1058		/* The child must have run before it can be attached. */
1059		/* This must be a bug in the parisc kernel, but I havn't
1060		 * identified it yet.  Seems to be an issue associated
1061		 * with attaching to a process (which sends it a signal)
1062		 * before that process has ever been scheduled.  When
1063		 * debugging, I started seeing crashes in
1064		 * arch/parisc/kernel/signal.c:do_signal(), apparently
1065		 * caused by r8 getting corrupt over the dequeue_signal()
1066		 * call.  Didn't make much sense though...
1067		 */
1068		{
1069			struct timeval tv;
1070			tv.tv_sec = 0;
1071			tv.tv_usec = 10000;
1072			select(0, NULL, NULL, NULL, &tv);
1073		}
1074#endif
1075		if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
1076			perror("PTRACE_ATTACH");
1077			fprintf(stderr, "Too late?\n");
1078			droptcb(tcpchild);
1079			return 0;
1080		}
1081#endif /* LINUX */
1082#ifdef SUNOS4
1083#ifdef oldway
1084		/* The child must have run before it can be attached. */
1085		{
1086			struct timeval tv;
1087			tv.tv_sec = 0;
1088			tv.tv_usec = 10000;
1089			select(0, NULL, NULL, NULL, &tv);
1090		}
1091		if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1092			perror("PTRACE_ATTACH");
1093			fprintf(stderr, "Too late?\n");
1094			droptcb(tcpchild);
1095			return 0;
1096		}
1097#else /* !oldway */
1098		/* Try to catch the new process as soon as possible. */
1099		{
1100			int i;
1101			for (i = 0; i < 1024; i++)
1102				if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1103					break;
1104			if (i == 1024) {
1105				perror("PTRACE_ATTACH");
1106				fprintf(stderr, "Too late?\n");
1107				droptcb(tcpchild);
1108				return 0;
1109			}
1110		}
1111#endif /* !oldway */
1112#endif /* SUNOS4 */
1113		tcpchild->flags |= TCB_ATTACHED;
1114		/* Child has BPT too, must be removed on first occasion */
1115		if (bpt) {
1116			tcpchild->flags |= TCB_BPTSET;
1117			tcpchild->baddr = tcp->baddr;
1118			memcpy(tcpchild->inst, tcp->inst,
1119				sizeof tcpchild->inst);
1120		}
1121		tcpchild->parent = tcp;
1122		tcp->nchildren++;
1123		if (!qflag)
1124			fprintf(stderr, "Process %d attached\n", pid);
1125	}
1126	return 0;
1127#endif
1128}
1129
1130#endif /* !USE_PROCFS */
1131
1132#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1133
1134int
1135sys_vfork(tcp)
1136struct tcb *tcp;
1137{
1138	if (exiting(tcp))
1139		return RVAL_UDECIMAL;
1140	return 0;
1141}
1142
1143#endif /* SUNOS4 || LINUX || FREEBSD */
1144
1145#ifndef LINUX
1146
1147static char idstr[16];
1148
1149int
1150sys_getpid(tcp)
1151struct tcb *tcp;
1152{
1153	if (exiting(tcp)) {
1154		sprintf(idstr, "ppid %lu", getrval2(tcp));
1155		tcp->auxstr = idstr;
1156		return RVAL_STR;
1157	}
1158	return 0;
1159}
1160
1161int
1162sys_getuid(tcp)
1163struct tcb *tcp;
1164{
1165	if (exiting(tcp)) {
1166		sprintf(idstr, "euid %lu", getrval2(tcp));
1167		tcp->auxstr = idstr;
1168		return RVAL_STR;
1169	}
1170	return 0;
1171}
1172
1173int
1174sys_getgid(tcp)
1175struct tcb *tcp;
1176{
1177	if (exiting(tcp)) {
1178		sprintf(idstr, "egid %lu", getrval2(tcp));
1179		tcp->auxstr = idstr;
1180		return RVAL_STR;
1181	}
1182	return 0;
1183}
1184
1185#endif /* !LINUX */
1186
1187#ifdef LINUX
1188
1189int
1190sys_setuid(tcp)
1191struct tcb *tcp;
1192{
1193	if (entering(tcp)) {
1194		tprintf("%u", (uid_t) tcp->u_arg[0]);
1195	}
1196	return 0;
1197}
1198
1199int
1200sys_setgid(tcp)
1201struct tcb *tcp;
1202{
1203	if (entering(tcp)) {
1204		tprintf("%u", (gid_t) tcp->u_arg[0]);
1205	}
1206	return 0;
1207}
1208
1209int
1210sys_getresuid(tcp)
1211    struct tcb *tcp;
1212{
1213	if (exiting(tcp)) {
1214		__kernel_uid_t uid;
1215		if (syserror(tcp))
1216			tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1217				tcp->u_arg[1], tcp->u_arg[2]);
1218		else {
1219			if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1220				tprintf("%#lx, ", tcp->u_arg[0]);
1221			else
1222				tprintf("[%lu], ", (unsigned long) uid);
1223			if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1224				tprintf("%#lx, ", tcp->u_arg[1]);
1225			else
1226				tprintf("[%lu], ", (unsigned long) uid);
1227			if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1228				tprintf("%#lx", tcp->u_arg[2]);
1229			else
1230				tprintf("[%lu]", (unsigned long) uid);
1231		}
1232	}
1233	return 0;
1234}
1235
1236int
1237sys_getresgid(tcp)
1238struct tcb *tcp;
1239{
1240	if (exiting(tcp)) {
1241		__kernel_gid_t gid;
1242		if (syserror(tcp))
1243			tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1244				tcp->u_arg[1], tcp->u_arg[2]);
1245		else {
1246			if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1247				tprintf("%#lx, ", tcp->u_arg[0]);
1248			else
1249				tprintf("[%lu], ", (unsigned long) gid);
1250			if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1251				tprintf("%#lx, ", tcp->u_arg[1]);
1252			else
1253				tprintf("[%lu], ", (unsigned long) gid);
1254			if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1255				tprintf("%#lx", tcp->u_arg[2]);
1256			else
1257				tprintf("[%lu]", (unsigned long) gid);
1258		}
1259	}
1260	return 0;
1261}
1262
1263#endif /* LINUX */
1264
1265int
1266sys_setreuid(tcp)
1267struct tcb *tcp;
1268{
1269	if (entering(tcp)) {
1270		printuid("", tcp->u_arg[0]);
1271		printuid(", ", tcp->u_arg[1]);
1272	}
1273	return 0;
1274}
1275
1276int
1277sys_setregid(tcp)
1278struct tcb *tcp;
1279{
1280	if (entering(tcp)) {
1281		printuid("", tcp->u_arg[0]);
1282		printuid(", ", tcp->u_arg[1]);
1283	}
1284	return 0;
1285}
1286
1287#if defined(LINUX) || defined(FREEBSD)
1288int
1289sys_setresuid(tcp)
1290     struct tcb *tcp;
1291{
1292	if (entering(tcp)) {
1293		printuid("", tcp->u_arg[0]);
1294		printuid(", ", tcp->u_arg[1]);
1295		printuid(", ", tcp->u_arg[2]);
1296	}
1297	return 0;
1298}
1299int
1300sys_setresgid(tcp)
1301     struct tcb *tcp;
1302{
1303	if (entering(tcp)) {
1304		printuid("", tcp->u_arg[0]);
1305		printuid(", ", tcp->u_arg[1]);
1306		printuid(", ", tcp->u_arg[2]);
1307	}
1308	return 0;
1309}
1310
1311#endif /* LINUX || FREEBSD */
1312
1313int
1314sys_setgroups(tcp)
1315struct tcb *tcp;
1316{
1317	if (entering(tcp)) {
1318		unsigned long len, size, start, cur, end, abbrev_end;
1319		GETGROUPS_T gid;
1320		int failed = 0;
1321
1322		len = tcp->u_arg[0];
1323		tprintf("%lu, ", len);
1324		if (len == 0) {
1325			tprintf("[]");
1326			return 0;
1327		}
1328		start = tcp->u_arg[1];
1329		if (start == 0) {
1330			tprintf("NULL");
1331			return 0;
1332		}
1333		size = len * sizeof(gid);
1334		end = start + size;
1335		if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1336			tprintf("%#lx", start);
1337			return 0;
1338		}
1339		if (abbrev(tcp)) {
1340			abbrev_end = start + max_strlen * sizeof(gid);
1341			if (abbrev_end < start)
1342				abbrev_end = end;
1343		} else {
1344			abbrev_end = end;
1345		}
1346		tprintf("[");
1347		for (cur = start; cur < end; cur += sizeof(gid)) {
1348			if (cur > start)
1349				tprintf(", ");
1350			if (cur >= abbrev_end) {
1351				tprintf("...");
1352				break;
1353			}
1354			if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1355				tprintf("?");
1356				failed = 1;
1357				break;
1358			}
1359			tprintf("%lu", (unsigned long) gid);
1360		}
1361		tprintf("]");
1362		if (failed)
1363			tprintf(" %#lx", tcp->u_arg[1]);
1364	}
1365	return 0;
1366}
1367
1368int
1369sys_getgroups(tcp)
1370struct tcb *tcp;
1371{
1372	unsigned long len;
1373
1374	if (entering(tcp)) {
1375		len = tcp->u_arg[0];
1376		tprintf("%lu, ", len);
1377	} else {
1378		unsigned long size, start, cur, end, abbrev_end;
1379		GETGROUPS_T gid;
1380		int failed = 0;
1381
1382		len = tcp->u_rval;
1383		if (len == 0) {
1384			tprintf("[]");
1385			return 0;
1386		}
1387		start = tcp->u_arg[1];
1388		if (start == 0) {
1389			tprintf("NULL");
1390			return 0;
1391		}
1392		if (tcp->u_arg[0] == 0) {
1393			tprintf("%#lx", start);
1394			return 0;
1395		}
1396		size = len * sizeof(gid);
1397		end = start + size;
1398		if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1399		    size / sizeof(gid) != len || end < start) {
1400			tprintf("%#lx", start);
1401			return 0;
1402		}
1403		if (abbrev(tcp)) {
1404			abbrev_end = start + max_strlen * sizeof(gid);
1405			if (abbrev_end < start)
1406				abbrev_end = end;
1407		} else {
1408			abbrev_end = end;
1409		}
1410		tprintf("[");
1411		for (cur = start; cur < end; cur += sizeof(gid)) {
1412			if (cur > start)
1413				tprintf(", ");
1414			if (cur >= abbrev_end) {
1415				tprintf("...");
1416				break;
1417			}
1418			if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1419				tprintf("?");
1420				failed = 1;
1421				break;
1422			}
1423			tprintf("%lu", (unsigned long) gid);
1424		}
1425		tprintf("]");
1426		if (failed)
1427			tprintf(" %#lx", tcp->u_arg[1]);
1428	}
1429	return 0;
1430}
1431
1432#ifdef LINUX
1433int
1434sys_setgroups32(tcp)
1435struct tcb *tcp;
1436{
1437	if (entering(tcp)) {
1438		unsigned long len, size, start, cur, end, abbrev_end;
1439		GETGROUPS32_T gid;
1440		int failed = 0;
1441
1442		len = tcp->u_arg[0];
1443		tprintf("%lu, ", len);
1444		if (len == 0) {
1445			tprintf("[]");
1446			return 0;
1447		}
1448		start = tcp->u_arg[1];
1449		if (start == 0) {
1450			tprintf("NULL");
1451			return 0;
1452		}
1453		size = len * sizeof(gid);
1454		end = start + size;
1455		if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1456			tprintf("%#lx", start);
1457			return 0;
1458		}
1459		if (abbrev(tcp)) {
1460			abbrev_end = start + max_strlen * sizeof(gid);
1461			if (abbrev_end < start)
1462				abbrev_end = end;
1463		} else {
1464			abbrev_end = end;
1465		}
1466		tprintf("[");
1467		for (cur = start; cur < end; cur += sizeof(gid)) {
1468			if (cur > start)
1469				tprintf(", ");
1470			if (cur >= abbrev_end) {
1471				tprintf("...");
1472				break;
1473			}
1474			if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1475				tprintf("?");
1476				failed = 1;
1477				break;
1478			}
1479			tprintf("%lu", (unsigned long) gid);
1480		}
1481		tprintf("]");
1482		if (failed)
1483			tprintf(" %#lx", tcp->u_arg[1]);
1484	}
1485	return 0;
1486}
1487
1488int
1489sys_getgroups32(tcp)
1490struct tcb *tcp;
1491{
1492	unsigned long len;
1493
1494	if (entering(tcp)) {
1495		len = tcp->u_arg[0];
1496		tprintf("%lu, ", len);
1497	} else {
1498		unsigned long size, start, cur, end, abbrev_end;
1499		GETGROUPS32_T gid;
1500		int failed = 0;
1501
1502		len = tcp->u_rval;
1503		if (len == 0) {
1504			tprintf("[]");
1505			return 0;
1506		}
1507		start = tcp->u_arg[1];
1508		if (start == 0) {
1509			tprintf("NULL");
1510			return 0;
1511		}
1512		size = len * sizeof(gid);
1513		end = start + size;
1514		if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1515		    size / sizeof(gid) != len || end < start) {
1516			tprintf("%#lx", start);
1517			return 0;
1518		}
1519		if (abbrev(tcp)) {
1520			abbrev_end = start + max_strlen * sizeof(gid);
1521			if (abbrev_end < start)
1522				abbrev_end = end;
1523		} else {
1524			abbrev_end = end;
1525		}
1526		tprintf("[");
1527		for (cur = start; cur < end; cur += sizeof(gid)) {
1528			if (cur > start)
1529				tprintf(", ");
1530			if (cur >= abbrev_end) {
1531				tprintf("...");
1532				break;
1533			}
1534			if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1535				tprintf("?");
1536				failed = 1;
1537				break;
1538			}
1539			tprintf("%lu", (unsigned long) gid);
1540		}
1541		tprintf("]");
1542		if (failed)
1543			tprintf(" %#lx", tcp->u_arg[1]);
1544	}
1545	return 0;
1546}
1547#endif /* LINUX */
1548
1549#if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
1550int
1551sys_setpgrp(tcp)
1552struct tcb *tcp;
1553{
1554	if (entering(tcp)) {
1555#ifndef SVR4
1556		tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1557#endif /* !SVR4 */
1558	}
1559	return 0;
1560}
1561#endif /* ALPHA || SUNOS4 || SVR4 */
1562
1563int
1564sys_getpgrp(tcp)
1565struct tcb *tcp;
1566{
1567	if (entering(tcp)) {
1568#ifndef SVR4
1569		tprintf("%lu", tcp->u_arg[0]);
1570#endif /* !SVR4 */
1571	}
1572	return 0;
1573}
1574
1575int
1576sys_getsid(tcp)
1577struct tcb *tcp;
1578{
1579	if (entering(tcp)) {
1580		tprintf("%lu", tcp->u_arg[0]);
1581	}
1582	return 0;
1583}
1584
1585int
1586sys_setsid(tcp)
1587struct tcb *tcp;
1588{
1589	return 0;
1590}
1591
1592int
1593sys_getpgid(tcp)
1594struct tcb *tcp;
1595{
1596	if (entering(tcp)) {
1597		tprintf("%lu", tcp->u_arg[0]);
1598	}
1599	return 0;
1600}
1601
1602int
1603sys_setpgid(tcp)
1604struct tcb *tcp;
1605{
1606	if (entering(tcp)) {
1607		tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1608	}
1609	return 0;
1610}
1611
1612#if UNIXWARE >= 2
1613
1614#include <sys/privilege.h>
1615
1616
1617static const struct xlat procpriv_cmds [] = {
1618	{ SETPRV,	"SETPRV"	},
1619	{ CLRPRV,	"CLRPRV"	},
1620	{ PUTPRV,	"PUTPRV"	},
1621	{ GETPRV,	"GETPRV"	},
1622	{ CNTPRV,	"CNTPRV"	},
1623	{ 0,		NULL		},
1624};
1625
1626
1627static const struct xlat procpriv_priv [] = {
1628	{ P_OWNER,	"P_OWNER"	},
1629	{ P_AUDIT,	"P_AUDIT"	},
1630	{ P_COMPAT,	"P_COMPAT"	},
1631	{ P_DACREAD,	"P_DACREAD"	},
1632	{ P_DACWRITE,	"P_DACWRITE"	},
1633	{ P_DEV,	"P_DEV"		},
1634	{ P_FILESYS,	"P_FILESYS"	},
1635	{ P_MACREAD,	"P_MACREAD"	},
1636	{ P_MACWRITE,	"P_MACWRITE"	},
1637	{ P_MOUNT,	"P_MOUNT"	},
1638	{ P_MULTIDIR,	"P_MULTIDIR"	},
1639	{ P_SETPLEVEL,	"P_SETPLEVEL"	},
1640	{ P_SETSPRIV,	"P_SETSPRIV"	},
1641	{ P_SETUID,	"P_SETUID"	},
1642	{ P_SYSOPS,	"P_SYSOPS"	},
1643	{ P_SETUPRIV,	"P_SETUPRIV"	},
1644	{ P_DRIVER,	"P_DRIVER"	},
1645	{ P_RTIME,	"P_RTIME"	},
1646	{ P_MACUPGRADE,	"P_MACUPGRADE"	},
1647	{ P_FSYSRANGE,	"P_FSYSRANGE"	},
1648	{ P_SETFLEVEL,	"P_SETFLEVEL"	},
1649	{ P_AUDITWR,	"P_AUDITWR"	},
1650	{ P_TSHAR,	"P_TSHAR"	},
1651	{ P_PLOCK,	"P_PLOCK"	},
1652	{ P_CORE,	"P_CORE"	},
1653	{ P_LOADMOD,	"P_LOADMOD"	},
1654	{ P_BIND,	"P_BIND"	},
1655	{ P_ALLPRIVS,	"P_ALLPRIVS"	},
1656	{ 0,		NULL		},
1657};
1658
1659
1660static const struct xlat procpriv_type [] = {
1661	{ PS_FIX,	"PS_FIX"	},
1662	{ PS_INH,	"PS_INH"	},
1663	{ PS_MAX,	"PS_MAX"	},
1664	{ PS_WKG,	"PS_WKG"	},
1665	{ 0,		NULL		},
1666};
1667
1668
1669static void
1670printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
1671{
1672	priv_t buf [128];
1673	int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1674	int dots = len > max;
1675	int i;
1676
1677	if (len > max) len = max;
1678
1679	if (len <= 0 ||
1680	    umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1681	{
1682		tprintf ("%#lx", addr);
1683		return;
1684	}
1685
1686	tprintf ("[");
1687
1688	for (i = 0; i < len; ++i) {
1689		const char *t, *p;
1690
1691		if (i) tprintf (", ");
1692
1693		if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1694		    (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1695		{
1696			tprintf ("%s|%s", t, p);
1697		}
1698		else {
1699			tprintf ("%#lx", buf [i]);
1700		}
1701	}
1702
1703	if (dots) tprintf (" ...");
1704
1705	tprintf ("]");
1706}
1707
1708
1709int
1710sys_procpriv(tcp)
1711struct tcb *tcp;
1712{
1713	if (entering(tcp)) {
1714		printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1715		switch (tcp->u_arg[0]) {
1716		    case CNTPRV:
1717			tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1718			break;
1719
1720		    case GETPRV:
1721			break;
1722
1723		    default:
1724			tprintf (", ");
1725			printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1726			tprintf (", %ld", tcp->u_arg[2]);
1727		}
1728	}
1729	else if (tcp->u_arg[0] == GETPRV) {
1730		if (syserror (tcp)) {
1731			tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1732		}
1733		else {
1734			tprintf (", ");
1735			printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1736			tprintf (", %ld", tcp->u_arg[2]);
1737		}
1738	}
1739
1740	return 0;
1741}
1742
1743#endif
1744
1745
1746static void
1747printargv(tcp, addr)
1748struct tcb *tcp;
1749long addr;
1750{
1751	union {
1752		int p32;
1753		long p64;
1754		char data[sizeof(long)];
1755	} cp;
1756	char *sep;
1757	int n = 0;
1758
1759	cp.p64 = 1;
1760	for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1761		if (umoven(tcp, addr, personality_wordsize[current_personality],
1762			   cp.data) < 0) {
1763			tprintf("%#lx", addr);
1764			return;
1765		}
1766		if (personality_wordsize[current_personality] == 4)
1767			cp.p64 = cp.p32;
1768		if (cp.p64 == 0)
1769			break;
1770		tprintf(sep);
1771		printstr(tcp, cp.p64, -1);
1772		addr += personality_wordsize[current_personality];
1773	}
1774	if (cp.p64)
1775		tprintf("%s...", sep);
1776}
1777
1778static void
1779printargc(fmt, tcp, addr)
1780char *fmt;
1781struct tcb *tcp;
1782long addr;
1783{
1784	int count;
1785	char *cp;
1786
1787	for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1788		addr += sizeof(char *);
1789	}
1790	tprintf(fmt, count, count == 1 ? "" : "s");
1791}
1792
1793#if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
1794int
1795sys_execv(tcp)
1796struct tcb *tcp;
1797{
1798	if (entering(tcp)) {
1799		printpath(tcp, tcp->u_arg[0]);
1800		if (!verbose(tcp))
1801			tprintf(", %#lx", tcp->u_arg[1]);
1802#if 0
1803		else if (abbrev(tcp))
1804			printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1805#endif
1806		else {
1807			tprintf(", [");
1808			printargv(tcp, tcp->u_arg[1]);
1809			tprintf("]");
1810		}
1811	}
1812	return 0;
1813}
1814#endif /* SPARC || SPARC64 || SUNOS4 */
1815
1816int
1817sys_execve(tcp)
1818struct tcb *tcp;
1819{
1820	if (entering(tcp)) {
1821		printpath(tcp, tcp->u_arg[0]);
1822		if (!verbose(tcp))
1823			tprintf(", %#lx", tcp->u_arg[1]);
1824#if 0
1825		else if (abbrev(tcp))
1826			printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1827#endif
1828		else {
1829			tprintf(", [");
1830			printargv(tcp, tcp->u_arg[1]);
1831			tprintf("]");
1832		}
1833		if (!verbose(tcp))
1834			tprintf(", %#lx", tcp->u_arg[2]);
1835		else if (abbrev(tcp))
1836			printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1837		else {
1838			tprintf(", [");
1839			printargv(tcp, tcp->u_arg[2]);
1840			tprintf("]");
1841		}
1842	}
1843	return 0;
1844}
1845
1846#if UNIXWARE > 2
1847
1848int sys_rexecve(tcp)
1849struct tcb *tcp;
1850{
1851	if (entering (tcp)) {
1852		sys_execve (tcp);
1853		tprintf (", %ld", tcp->u_arg[3]);
1854	}
1855	return 0;
1856}
1857
1858#endif
1859
1860int
1861internal_exec(tcp)
1862struct tcb *tcp;
1863{
1864#ifdef SUNOS4
1865	if (exiting(tcp) && !syserror(tcp) && followfork)
1866		fixvfork(tcp);
1867#endif /* SUNOS4 */
1868#if defined LINUX && defined TCB_WAITEXECVE
1869	if (exiting(tcp) && syserror(tcp))
1870		tcp->flags &= ~TCB_WAITEXECVE;
1871	else
1872		tcp->flags |= TCB_WAITEXECVE;
1873#endif /* LINUX && TCB_WAITEXECVE */
1874	return 0;
1875}
1876
1877#ifdef LINUX
1878#ifndef __WNOTHREAD
1879#define __WNOTHREAD	0x20000000
1880#endif
1881#ifndef __WALL
1882#define __WALL		0x40000000
1883#endif
1884#ifndef __WCLONE
1885#define __WCLONE	0x80000000
1886#endif
1887#endif /* LINUX */
1888
1889static const struct xlat wait4_options[] = {
1890	{ WNOHANG,	"WNOHANG"	},
1891#ifndef WSTOPPED
1892	{ WUNTRACED,	"WUNTRACED"	},
1893#endif
1894#ifdef WEXITED
1895	{ WEXITED,	"WEXITED"	},
1896#endif
1897#ifdef WTRAPPED
1898	{ WTRAPPED,	"WTRAPPED"	},
1899#endif
1900#ifdef WSTOPPED
1901	{ WSTOPPED,	"WSTOPPED"	},
1902#endif
1903#ifdef WCONTINUED
1904	{ WCONTINUED,	"WCONTINUED"	},
1905#endif
1906#ifdef WNOWAIT
1907	{ WNOWAIT,	"WNOWAIT"	},
1908#endif
1909#ifdef __WCLONE
1910	{ __WCLONE,	"__WCLONE"	},
1911#endif
1912#ifdef __WALL
1913	{ __WALL,	"__WALL"	},
1914#endif
1915#ifdef __WNOTHREAD
1916	{ __WNOTHREAD,	"__WNOTHREAD"	},
1917#endif
1918	{ 0,		NULL		},
1919};
1920
1921#if !defined WCOREFLAG && defined WCOREFLG
1922# define WCOREFLAG WCOREFLG
1923#endif
1924#ifndef WCOREFLAG
1925#define WCOREFLAG 0x80
1926#endif
1927
1928#ifndef W_STOPCODE
1929#define W_STOPCODE(sig)		((sig) << 8 | 0x7f)
1930#endif
1931#ifndef W_EXITCODE
1932#define W_EXITCODE(ret, sig)	((ret) << 8 | (sig))
1933#endif
1934
1935static int
1936printstatus(status)
1937int status;
1938{
1939	int exited = 0;
1940
1941	/*
1942	 * Here is a tricky presentation problem.  This solution
1943	 * is still not entirely satisfactory but since there
1944	 * are no wait status constructors it will have to do.
1945	 */
1946	if (WIFSTOPPED(status)) {
1947		tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1948			signame(WSTOPSIG(status)));
1949		status &= ~W_STOPCODE(WSTOPSIG(status));
1950	}
1951	else if (WIFSIGNALED(status)) {
1952		tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1953			signame(WTERMSIG(status)),
1954			WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1955		status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1956	}
1957	else if (WIFEXITED(status)) {
1958		tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1959			WEXITSTATUS(status));
1960		exited = 1;
1961		status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1962	}
1963	else {
1964		tprintf("[%#x]", status);
1965		return 0;
1966	}
1967
1968	if (status == 0)
1969		tprintf("]");
1970	else
1971		tprintf(" | %#x]", status);
1972
1973	return exited;
1974}
1975
1976static int
1977printwaitn(tcp, n, bitness)
1978struct tcb *tcp;
1979int n;
1980int bitness;
1981{
1982	int status;
1983	int exited = 0;
1984
1985	if (entering(tcp)) {
1986		/*
1987		 * Sign-extend a 32-bit value when that's what it is.
1988		 */
1989		long pid = tcp->u_arg[0];
1990		if (personality_wordsize[current_personality] < sizeof pid)
1991			pid = (long) (int) pid;
1992		tprintf("%ld, ", pid);
1993	} else {
1994		/* status */
1995		if (!tcp->u_arg[1])
1996			tprintf("NULL");
1997		else if (syserror(tcp) || tcp->u_rval == 0)
1998			tprintf("%#lx", tcp->u_arg[1]);
1999		else if (umove(tcp, tcp->u_arg[1], &status) < 0)
2000			tprintf("[?]");
2001		else
2002			exited = printstatus(status);
2003		/* options */
2004		tprintf(", ");
2005		printflags(wait4_options, tcp->u_arg[2], "W???");
2006		if (n == 4) {
2007			tprintf(", ");
2008			/* usage */
2009			if (!tcp->u_arg[3])
2010				tprintf("NULL");
2011#ifdef LINUX
2012			else if (tcp->u_rval > 0) {
2013#ifdef LINUX_64BIT
2014				if (bitness)
2015					printrusage32(tcp, tcp->u_arg[3]);
2016				else
2017#endif
2018					printrusage(tcp, tcp->u_arg[3]);
2019			}
2020#endif /* LINUX */
2021#ifdef SUNOS4
2022			else if (tcp->u_rval > 0 && exited)
2023				printrusage(tcp, tcp->u_arg[3]);
2024#endif /* SUNOS4 */
2025			else
2026				tprintf("%#lx", tcp->u_arg[3]);
2027		}
2028	}
2029	return 0;
2030}
2031
2032int
2033internal_wait(tcp, flagarg)
2034struct tcb *tcp;
2035int flagarg;
2036{
2037	int got_kids;
2038
2039#ifdef TCB_CLONE_THREAD
2040	if (tcp->flags & TCB_CLONE_THREAD)
2041		/* The children we wait for are our parent's children.  */
2042		got_kids = (tcp->parent->nchildren
2043			    > tcp->parent->nclone_detached);
2044	else
2045		got_kids = (tcp->nchildren > tcp->nclone_detached);
2046#else
2047	got_kids = tcp->nchildren > 0;
2048#endif
2049
2050	if (entering(tcp) && got_kids) {
2051		/* There are children that this parent should block for.
2052		   But ptrace made us the parent of the traced children
2053		   and the real parent will get ECHILD from the wait call.
2054
2055		   XXX If we attached with strace -f -p PID, then there
2056		   may be untraced dead children the parent could be reaping
2057		   now, but we make him block.  */
2058
2059		/* ??? WTA: fix bug with hanging children */
2060
2061		if (!(tcp->u_arg[flagarg] & WNOHANG)) {
2062			/*
2063			 * There are traced children.  We'll make the parent
2064			 * block to avoid a false ECHILD error due to our
2065			 * ptrace having stolen the children.  However,
2066			 * we shouldn't block if there are zombies to reap.
2067			 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
2068			 */
2069			struct tcb *child = NULL;
2070			if (tcp->nzombies > 0 &&
2071			    (tcp->u_arg[0] == -1 ||
2072			     (child = pid2tcb(tcp->u_arg[0])) == NULL))
2073				return 0;
2074			if (tcp->u_arg[0] > 0) {
2075				/*
2076				 * If the parent waits for a specified child
2077				 * PID, then it must get ECHILD right away
2078				 * if that PID is not one of its children.
2079				 * Make sure that the requested PID matches
2080				 * one of the parent's children that we are
2081				 * tracing, and don't suspend it otherwise.
2082				 */
2083				if (child == NULL)
2084					child = pid2tcb(tcp->u_arg[0]);
2085				if (child == NULL || child->parent != (
2086#ifdef TCB_CLONE_THREAD
2087					    (tcp->flags & TCB_CLONE_THREAD)
2088					    ? tcp->parent :
2089#endif
2090					    tcp) ||
2091				    (child->flags & TCB_EXITING))
2092					return 0;
2093			}
2094			tcp->flags |= TCB_SUSPENDED;
2095			tcp->waitpid = tcp->u_arg[0];
2096#ifdef TCB_CLONE_THREAD
2097			if (tcp->flags & TCB_CLONE_THREAD)
2098				tcp->parent->nclone_waiting++;
2099#endif
2100		}
2101	}
2102	if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
2103		if (tcp->u_arg[flagarg] & WNOHANG) {
2104			/* We must force a fake result of 0 instead of
2105			   the ECHILD error.  */
2106			extern int force_result();
2107			return force_result(tcp, 0, 0);
2108		}
2109	}
2110	else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2111		 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2112		/*
2113		 * We just reaped a child we don't know about,
2114		 * presumably a zombie we already droptcb'd.
2115		 */
2116		tcp->nzombies--;
2117	}
2118	return 0;
2119}
2120
2121#ifdef SVR4
2122
2123int
2124sys_wait(tcp)
2125struct tcb *tcp;
2126{
2127	if (exiting(tcp)) {
2128		/* The library wrapper stuffs this into the user variable. */
2129		if (!syserror(tcp))
2130			printstatus(getrval2(tcp));
2131	}
2132	return 0;
2133}
2134
2135#endif /* SVR4 */
2136
2137#ifdef FREEBSD
2138int
2139sys_wait(tcp)
2140struct tcb *tcp;
2141{
2142	int status;
2143
2144	if (exiting(tcp)) {
2145		if (!syserror(tcp)) {
2146			if (umove(tcp, tcp->u_arg[0], &status) < 0)
2147				tprintf("%#lx", tcp->u_arg[0]);
2148			else
2149				printstatus(status);
2150		}
2151	}
2152	return 0;
2153}
2154#endif
2155
2156int
2157sys_waitpid(tcp)
2158struct tcb *tcp;
2159{
2160	return printwaitn(tcp, 3, 0);
2161}
2162
2163int
2164sys_wait4(tcp)
2165struct tcb *tcp;
2166{
2167	return printwaitn(tcp, 4, 0);
2168}
2169
2170#ifdef ALPHA
2171int
2172sys_osf_wait4(tcp)
2173struct tcb *tcp;
2174{
2175	return printwaitn(tcp, 4, 1);
2176}
2177#endif
2178
2179#if defined SVR4 || defined LINUX
2180
2181static const struct xlat waitid_types[] = {
2182	{ P_PID,	"P_PID"		},
2183#ifdef P_PPID
2184	{ P_PPID,	"P_PPID"	},
2185#endif
2186	{ P_PGID,	"P_PGID"	},
2187#ifdef P_SID
2188	{ P_SID,	"P_SID"		},
2189#endif
2190#ifdef P_CID
2191	{ P_CID,	"P_CID"		},
2192#endif
2193#ifdef P_UID
2194	{ P_UID,	"P_UID"		},
2195#endif
2196#ifdef P_GID
2197	{ P_GID,	"P_GID"		},
2198#endif
2199	{ P_ALL,	"P_ALL"		},
2200#ifdef P_LWPID
2201	{ P_LWPID,	"P_LWPID"	},
2202#endif
2203	{ 0,		NULL		},
2204};
2205
2206int
2207sys_waitid(tcp)
2208struct tcb *tcp;
2209{
2210	siginfo_t si;
2211	int exited;
2212
2213	if (entering(tcp)) {
2214		printxval(waitid_types, tcp->u_arg[0], "P_???");
2215		tprintf(", %ld, ", tcp->u_arg[1]);
2216	}
2217	else {
2218		/* siginfo */
2219		exited = 0;
2220		if (!tcp->u_arg[2])
2221			tprintf("NULL");
2222		else if (syserror(tcp))
2223			tprintf("%#lx", tcp->u_arg[2]);
2224		else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2225			tprintf("{???}");
2226		else
2227			printsiginfo(&si, verbose (tcp));
2228		/* options */
2229		tprintf(", ");
2230		printflags(wait4_options, tcp->u_arg[3], "W???");
2231		if (tcp->u_nargs > 4) {
2232			/* usage */
2233			tprintf(", ");
2234			if (!tcp->u_arg[4])
2235				tprintf("NULL");
2236			else if (tcp->u_error)
2237				tprintf("%#lx", tcp->u_arg[4]);
2238			else
2239				printrusage(tcp, tcp->u_arg[4]);
2240		}
2241	}
2242	return 0;
2243}
2244
2245#endif /* SVR4 or LINUX */
2246
2247int
2248sys_alarm(tcp)
2249struct tcb *tcp;
2250{
2251	if (entering(tcp))
2252		tprintf("%lu", tcp->u_arg[0]);
2253	return 0;
2254}
2255
2256int
2257sys_uname(tcp)
2258struct tcb *tcp;
2259{
2260	struct utsname uname;
2261
2262	if (exiting(tcp)) {
2263		if (syserror(tcp) || !verbose(tcp))
2264			tprintf("%#lx", tcp->u_arg[0]);
2265		else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2266			tprintf("{...}");
2267		else if (!abbrev(tcp)) {
2268
2269			tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2270				uname.sysname, uname.nodename);
2271			tprintf("release=\"%s\", version=\"%s\", ",
2272				uname.release, uname.version);
2273			tprintf("machine=\"%s\"", uname.machine);
2274#ifdef LINUX
2275#ifndef __GLIBC__
2276			tprintf(", domainname=\"%s\"", uname.domainname);
2277#endif /* __GLIBC__ */
2278#endif /* LINUX */
2279			tprintf("}");
2280		}
2281		else
2282			tprintf("{sys=\"%s\", node=\"%s\", ...}",
2283				uname.sysname, uname.nodename);
2284	}
2285	return 0;
2286}
2287
2288#ifndef SVR4
2289
2290static const struct xlat ptrace_cmds[] = {
2291#ifndef FREEBSD
2292	{ PTRACE_TRACEME,	"PTRACE_TRACEME"	},
2293	{ PTRACE_PEEKTEXT,	"PTRACE_PEEKTEXT",	},
2294	{ PTRACE_PEEKDATA,	"PTRACE_PEEKDATA",	},
2295	{ PTRACE_PEEKUSER,	"PTRACE_PEEKUSER",	},
2296	{ PTRACE_POKETEXT,	"PTRACE_POKETEXT",	},
2297	{ PTRACE_POKEDATA,	"PTRACE_POKEDATA",	},
2298	{ PTRACE_POKEUSER,	"PTRACE_POKEUSER",	},
2299	{ PTRACE_CONT,		"PTRACE_CONT"		},
2300	{ PTRACE_KILL,		"PTRACE_KILL"		},
2301	{ PTRACE_SINGLESTEP,	"PTRACE_SINGLESTEP"	},
2302	{ PTRACE_ATTACH,	"PTRACE_ATTACH"		},
2303	{ PTRACE_DETACH,	"PTRACE_DETACH"		},
2304#ifdef PTRACE_GETREGS
2305	{ PTRACE_GETREGS,	"PTRACE_GETREGS"	},
2306#endif
2307#ifdef PTRACE_SETREGS
2308	{ PTRACE_SETREGS,	"PTRACE_SETREGS"	},
2309#endif
2310#ifdef PTRACE_GETFPREGS
2311	{ PTRACE_GETFPREGS,	"PTRACE_GETFPREGS",	},
2312#endif
2313#ifdef PTRACE_SETFPREGS
2314	{ PTRACE_SETFPREGS,	"PTRACE_SETFPREGS",	},
2315#endif
2316#ifdef PTRACE_GETFPXREGS
2317	{ PTRACE_GETFPXREGS,	"PTRACE_GETFPXREGS",	},
2318#endif
2319#ifdef PTRACE_SETFPXREGS
2320	{ PTRACE_SETFPXREGS,	"PTRACE_SETFPXREGS",	},
2321#endif
2322#ifdef PTRACE_GETVRREGS
2323	{ PTRACE_GETVRREGS,	"PTRACE_GETVRREGS",	},
2324#endif
2325#ifdef PTRACE_SETVRREGS
2326	{ PTRACE_SETVRREGS,	"PTRACE_SETVRREGS",	},
2327#endif
2328#ifdef SUNOS4
2329	{ PTRACE_READDATA,	"PTRACE_READDATA"	},
2330	{ PTRACE_WRITEDATA,	"PTRACE_WRITEDATA"	},
2331	{ PTRACE_READTEXT,	"PTRACE_READTEXT"	},
2332	{ PTRACE_WRITETEXT,	"PTRACE_WRITETEXT"	},
2333	{ PTRACE_GETFPAREGS,	"PTRACE_GETFPAREGS"	},
2334	{ PTRACE_SETFPAREGS,	"PTRACE_SETFPAREGS"	},
2335#ifdef SPARC
2336	{ PTRACE_GETWINDOW,	"PTRACE_GETWINDOW"	},
2337	{ PTRACE_SETWINDOW,	"PTRACE_SETWINDOW"	},
2338#else /* !SPARC */
2339	{ PTRACE_22,		"PTRACE_PTRACE_22"	},
2340	{ PTRACE_23,		"PTRACE_PTRACE_23"	},
2341#endif /* !SPARC */
2342#endif /* SUNOS4 */
2343	{ PTRACE_SYSCALL,	"PTRACE_SYSCALL"	},
2344#ifdef SUNOS4
2345	{ PTRACE_DUMPCORE,	"PTRACE_DUMPCORE"	},
2346#ifdef I386
2347	{ PTRACE_SETWRBKPT,	"PTRACE_SETWRBKPT"	},
2348	{ PTRACE_SETACBKPT,	"PTRACE_SETACBKPT"	},
2349	{ PTRACE_CLRDR7,	"PTRACE_CLRDR7"		},
2350#else /* !I386 */
2351	{ PTRACE_26,		"PTRACE_26"		},
2352	{ PTRACE_27,		"PTRACE_27"		},
2353	{ PTRACE_28,		"PTRACE_28"		},
2354#endif /* !I386 */
2355	{ PTRACE_GETUCODE,	"PTRACE_GETUCODE"	},
2356#endif /* SUNOS4 */
2357#else /* FREEBSD */
2358	{ PT_TRACE_ME,		"PT_TRACE_ME"		},
2359	{ PT_READ_I,		"PT_READ_I"		},
2360	{ PT_READ_D,		"PT_READ_D"		},
2361	{ PT_WRITE_I,		"PT_WRITE_I"		},
2362	{ PT_WRITE_D,		"PT_WRITE_D"		},
2363#ifdef PT_READ_U
2364	{ PT_READ_U,		"PT_READ_U"		},
2365#endif
2366	{ PT_CONTINUE,		"PT_CONTINUE"		},
2367	{ PT_KILL,		"PT_KILL"		},
2368	{ PT_STEP,		"PT_STEP"		},
2369	{ PT_ATTACH,		"PT_ATTACH"		},
2370	{ PT_DETACH,		"PT_DETACH"		},
2371	{ PT_GETREGS,		"PT_GETREGS"		},
2372	{ PT_SETREGS,		"PT_SETREGS"		},
2373	{ PT_GETFPREGS,		"PT_GETFPREGS"		},
2374	{ PT_SETFPREGS,		"PT_SETFPREGS"		},
2375	{ PT_GETDBREGS,		"PT_GETDBREGS"		},
2376	{ PT_SETDBREGS,		"PT_SETDBREGS"		},
2377#endif /* FREEBSD */
2378	{ 0,			NULL			},
2379};
2380
2381#ifndef FREEBSD
2382#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2383static
2384#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2385const struct xlat struct_user_offsets[] = {
2386#ifdef LINUX
2387#if defined(S390) || defined(S390X)
2388	{ PT_PSWMASK,		"psw_mask"				},
2389	{ PT_PSWADDR,		"psw_addr"				},
2390	{ PT_GPR0,		"gpr0"					},
2391	{ PT_GPR1,		"gpr1"					},
2392	{ PT_GPR2,		"gpr2"					},
2393	{ PT_GPR3,		"gpr3"					},
2394	{ PT_GPR4,		"gpr4"					},
2395	{ PT_GPR5,		"gpr5"					},
2396	{ PT_GPR6,		"gpr6"					},
2397	{ PT_GPR7,		"gpr7"					},
2398	{ PT_GPR8,		"gpr8"					},
2399	{ PT_GPR9,		"gpr9"					},
2400	{ PT_GPR10,		"gpr10"					},
2401	{ PT_GPR11,		"gpr11"					},
2402	{ PT_GPR12,		"gpr12"					},
2403	{ PT_GPR13,		"gpr13"					},
2404	{ PT_GPR14,		"gpr14"					},
2405	{ PT_GPR15,		"gpr15"					},
2406	{ PT_ACR0,		"acr0"					},
2407	{ PT_ACR1,		"acr1"					},
2408	{ PT_ACR2,		"acr2"					},
2409	{ PT_ACR3,		"acr3"					},
2410	{ PT_ACR4,		"acr4"					},
2411	{ PT_ACR5,		"acr5"					},
2412	{ PT_ACR6,		"acr6"					},
2413	{ PT_ACR7,		"acr7"					},
2414	{ PT_ACR8,		"acr8"					},
2415	{ PT_ACR9,		"acr9"					},
2416	{ PT_ACR10,		"acr10"					},
2417	{ PT_ACR11,		"acr11"					},
2418	{ PT_ACR12,		"acr12"					},
2419	{ PT_ACR13,		"acr13"					},
2420	{ PT_ACR14,		"acr14"					},
2421	{ PT_ACR15,		"acr15"					},
2422	{ PT_ORIGGPR2,		"orig_gpr2"				},
2423	{ PT_FPC,		"fpc"					},
2424#if defined(S390)
2425	{ PT_FPR0_HI,		"fpr0.hi"				},
2426	{ PT_FPR0_LO,		"fpr0.lo"				},
2427	{ PT_FPR1_HI,		"fpr1.hi"				},
2428	{ PT_FPR1_LO,		"fpr1.lo"				},
2429	{ PT_FPR2_HI,		"fpr2.hi"				},
2430	{ PT_FPR2_LO,		"fpr2.lo"				},
2431	{ PT_FPR3_HI,		"fpr3.hi"				},
2432	{ PT_FPR3_LO,		"fpr3.lo"				},
2433	{ PT_FPR4_HI,		"fpr4.hi"				},
2434	{ PT_FPR4_LO,		"fpr4.lo"				},
2435	{ PT_FPR5_HI,		"fpr5.hi"				},
2436	{ PT_FPR5_LO,		"fpr5.lo"				},
2437	{ PT_FPR6_HI,		"fpr6.hi"				},
2438	{ PT_FPR6_LO,		"fpr6.lo"				},
2439	{ PT_FPR7_HI,		"fpr7.hi"				},
2440	{ PT_FPR7_LO,		"fpr7.lo"				},
2441	{ PT_FPR8_HI,		"fpr8.hi"				},
2442	{ PT_FPR8_LO,		"fpr8.lo"				},
2443	{ PT_FPR9_HI,		"fpr9.hi"				},
2444	{ PT_FPR9_LO,		"fpr9.lo"				},
2445	{ PT_FPR10_HI,		"fpr10.hi"				},
2446	{ PT_FPR10_LO,		"fpr10.lo"				},
2447	{ PT_FPR11_HI,		"fpr11.hi"				},
2448	{ PT_FPR11_LO,		"fpr11.lo"				},
2449	{ PT_FPR12_HI,		"fpr12.hi"				},
2450	{ PT_FPR12_LO,		"fpr12.lo"				},
2451	{ PT_FPR13_HI,		"fpr13.hi"				},
2452	{ PT_FPR13_LO,		"fpr13.lo"				},
2453	{ PT_FPR14_HI,		"fpr14.hi"				},
2454	{ PT_FPR14_LO,		"fpr14.lo"				},
2455	{ PT_FPR15_HI,		"fpr15.hi"				},
2456	{ PT_FPR15_LO,		"fpr15.lo"				},
2457#endif
2458#if defined(S390X)
2459	{ PT_FPR0,		"fpr0"					},
2460	{ PT_FPR1,		"fpr1"					},
2461	{ PT_FPR2,		"fpr2"					},
2462	{ PT_FPR3,		"fpr3"					},
2463	{ PT_FPR4,		"fpr4"					},
2464	{ PT_FPR5,		"fpr5"					},
2465	{ PT_FPR6,		"fpr6"					},
2466	{ PT_FPR7,		"fpr7"					},
2467	{ PT_FPR8,		"fpr8"					},
2468	{ PT_FPR9,		"fpr9"					},
2469	{ PT_FPR10,		"fpr10"					},
2470	{ PT_FPR11,		"fpr11"					},
2471	{ PT_FPR12,		"fpr12"					},
2472	{ PT_FPR13,		"fpr13"					},
2473	{ PT_FPR14,		"fpr14"					},
2474	{ PT_FPR15,		"fpr15"					},
2475#endif
2476	{ PT_CR_9,		"cr9"					},
2477	{ PT_CR_10,		"cr10"					},
2478	{ PT_CR_11,		"cr11"					},
2479	{ PT_IEEE_IP,           "ieee_exception_ip"                     },
2480#endif
2481#if defined(SPARC)
2482	/* XXX No support for these offsets yet. */
2483#elif defined(HPPA)
2484	/* XXX No support for these offsets yet. */
2485#elif defined(POWERPC)
2486#ifndef PT_ORIG_R3
2487#define PT_ORIG_R3 34
2488#endif
2489#define REGSIZE (sizeof(unsigned long))
2490	{ REGSIZE*PT_R0,		"r0"				},
2491	{ REGSIZE*PT_R1,		"r1"				},
2492	{ REGSIZE*PT_R2,		"r2"				},
2493	{ REGSIZE*PT_R3,		"r3"				},
2494	{ REGSIZE*PT_R4,		"r4"				},
2495	{ REGSIZE*PT_R5,		"r5"				},
2496	{ REGSIZE*PT_R6,		"r6"				},
2497	{ REGSIZE*PT_R7,		"r7"				},
2498	{ REGSIZE*PT_R8,		"r8"				},
2499	{ REGSIZE*PT_R9,		"r9"				},
2500	{ REGSIZE*PT_R10,		"r10"				},
2501	{ REGSIZE*PT_R11,		"r11"				},
2502	{ REGSIZE*PT_R12,		"r12"				},
2503	{ REGSIZE*PT_R13,		"r13"				},
2504	{ REGSIZE*PT_R14,		"r14"				},
2505	{ REGSIZE*PT_R15,		"r15"				},
2506	{ REGSIZE*PT_R16,		"r16"				},
2507	{ REGSIZE*PT_R17,		"r17"				},
2508	{ REGSIZE*PT_R18,		"r18"				},
2509	{ REGSIZE*PT_R19,		"r19"				},
2510	{ REGSIZE*PT_R20,		"r20"				},
2511	{ REGSIZE*PT_R21,		"r21"				},
2512	{ REGSIZE*PT_R22,		"r22"				},
2513	{ REGSIZE*PT_R23,		"r23"				},
2514	{ REGSIZE*PT_R24,		"r24"				},
2515	{ REGSIZE*PT_R25,		"r25"				},
2516	{ REGSIZE*PT_R26,		"r26"				},
2517	{ REGSIZE*PT_R27,		"r27"				},
2518	{ REGSIZE*PT_R28,		"r28"				},
2519	{ REGSIZE*PT_R29,		"r29"				},
2520	{ REGSIZE*PT_R30,		"r30"				},
2521	{ REGSIZE*PT_R31,		"r31"				},
2522	{ REGSIZE*PT_NIP,		"NIP"				},
2523	{ REGSIZE*PT_MSR,		"MSR"				},
2524	{ REGSIZE*PT_ORIG_R3,		"ORIG_R3"			},
2525	{ REGSIZE*PT_CTR,		"CTR"				},
2526	{ REGSIZE*PT_LNK,		"LNK"				},
2527	{ REGSIZE*PT_XER,		"XER"				},
2528	{ REGSIZE*PT_CCR,		"CCR"				},
2529	{ REGSIZE*PT_FPR0,		"FPR0"				},
2530#undef REGSIZE
2531#else
2532#ifdef ALPHA
2533	{ 0,			"r0"					},
2534	{ 1,			"r1"					},
2535	{ 2,			"r2"					},
2536	{ 3,			"r3"					},
2537	{ 4,			"r4"					},
2538	{ 5,			"r5"					},
2539	{ 6,			"r6"					},
2540	{ 7,			"r7"					},
2541	{ 8,			"r8"					},
2542	{ 9,			"r9"					},
2543	{ 10,			"r10"					},
2544	{ 11,			"r11"					},
2545	{ 12,			"r12"					},
2546	{ 13,			"r13"					},
2547	{ 14,			"r14"					},
2548	{ 15,			"r15"					},
2549	{ 16,			"r16"					},
2550	{ 17,			"r17"					},
2551	{ 18,			"r18"					},
2552	{ 19,			"r19"					},
2553	{ 20,			"r20"					},
2554	{ 21,			"r21"					},
2555	{ 22,			"r22"					},
2556	{ 23,			"r23"					},
2557	{ 24,			"r24"					},
2558	{ 25,			"r25"					},
2559	{ 26,			"r26"					},
2560	{ 27,			"r27"					},
2561	{ 28,			"r28"					},
2562	{ 29,			"gp"					},
2563	{ 30,			"fp"					},
2564	{ 31,			"zero"					},
2565	{ 32,			"fp0"					},
2566	{ 33,			"fp"					},
2567	{ 34,			"fp2"					},
2568	{ 35,			"fp3"					},
2569	{ 36,			"fp4"					},
2570	{ 37,			"fp5"					},
2571	{ 38,			"fp6"					},
2572	{ 39,			"fp7"					},
2573	{ 40,			"fp8"					},
2574	{ 41,			"fp9"					},
2575	{ 42,			"fp10"					},
2576	{ 43,			"fp11"					},
2577	{ 44,			"fp12"					},
2578	{ 45,			"fp13"					},
2579	{ 46,			"fp14"					},
2580	{ 47,			"fp15"					},
2581	{ 48,			"fp16"					},
2582	{ 49,			"fp17"					},
2583	{ 50,			"fp18"					},
2584	{ 51,			"fp19"					},
2585	{ 52,			"fp20"					},
2586	{ 53,			"fp21"					},
2587	{ 54,			"fp22"					},
2588	{ 55,			"fp23"					},
2589	{ 56,			"fp24"					},
2590	{ 57,			"fp25"					},
2591	{ 58,			"fp26"					},
2592	{ 59,			"fp27"					},
2593	{ 60,			"fp28"					},
2594	{ 61,			"fp29"					},
2595	{ 62,			"fp30"					},
2596	{ 63,			"fp31"					},
2597	{ 64,			"pc"					},
2598#else /* !ALPHA */
2599#ifdef IA64
2600	{ PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2601	{ PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2602	{ PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2603	{ PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2604	{ PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2605	{ PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2606	{ PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2607	{ PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2608	{ PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2609	{ PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2610	{ PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2611	{ PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2612	{ PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2613	{ PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2614	{ PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2615	{ PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2616	{ PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2617	{ PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2618	{ PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2619	{ PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2620	{ PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2621	{ PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2622	{ PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2623	{ PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2624	{ PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2625	{ PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2626	{ PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2627	{ PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2628	{ PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2629	{ PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2630	{ PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2631	{ PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2632	/* switch stack: */
2633	{ PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2634	{ PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2635	{ PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2636	{ PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2637	{ PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2638	{ PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2639	{ PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2640	{ PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2641	{ PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2642	{ PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2643	{ PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2644	{ PT_B4, "b4" }, { PT_B5, "b5" },
2645	{ PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2646	/* pt_regs */
2647	{ PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2648	{ PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2649	{ PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2650	{ PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2651	{ PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2652	{ PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2653	{ PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2654	{ PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2655	{ PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2656	{ PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2657	{ PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2658	{ PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2659	{ PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2660	{ PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2661	{ PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2662	{ PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2663	{ PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2664# ifdef PT_AR_CSD
2665	{ PT_AR_CSD, "ar.csd" },
2666# endif
2667# ifdef PT_AR_SSD
2668	{ PT_AR_SSD, "ar.ssd" },
2669# endif
2670	{ PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2671#else /* !IA64 */
2672#ifdef I386
2673	{ 4*EBX,		"4*EBX"					},
2674	{ 4*ECX,		"4*ECX"					},
2675	{ 4*EDX,		"4*EDX"					},
2676	{ 4*ESI,		"4*ESI"					},
2677	{ 4*EDI,		"4*EDI"					},
2678	{ 4*EBP,		"4*EBP"					},
2679	{ 4*EAX,		"4*EAX"					},
2680	{ 4*DS,			"4*DS"					},
2681	{ 4*ES,			"4*ES"					},
2682	{ 4*FS,			"4*FS"					},
2683	{ 4*GS,			"4*GS"					},
2684	{ 4*ORIG_EAX,		"4*ORIG_EAX"				},
2685	{ 4*EIP,		"4*EIP"					},
2686	{ 4*CS,			"4*CS"					},
2687	{ 4*EFL,		"4*EFL"					},
2688	{ 4*UESP,		"4*UESP"				},
2689	{ 4*SS,			"4*SS"					},
2690#else /* !I386 */
2691#ifdef X86_64
2692	{ 8*R15, 		"8*R15"					},
2693	{ 8*R14, 		"8*R14"					},
2694	{ 8*R13, 		"8*R13"					},
2695	{ 8*R12, 		"8*R12"					},
2696	{ 8*RBP,		"8*RBP"					},
2697	{ 8*RBX,		"8*RBX"					},
2698	{ 8*R11,		"8*R11"					},
2699	{ 8*R10,		"8*R10"					},
2700	{ 8*R9,			"8*R9"					},
2701	{ 8*R8,			"8*R8"					},
2702	{ 8*RAX,		"8*RAX"					},
2703	{ 8*RCX,		"8*RCX"					},
2704	{ 8*RDX,		"8*RDX"					},
2705	{ 8*RSI,		"8*RSI"					},
2706	{ 8*RDI,		"8*RDI"					},
2707#if 0
2708	{ DS,			"DS"					},
2709	{ ES,			"ES"					},
2710	{ FS,			"FS"					},
2711	{ GS,			"GS"					},
2712#endif
2713	{ 8*ORIG_RAX,		"8*ORIG_RAX"				},
2714	{ 8*RIP,		"8*RIP"					},
2715	{ 8*CS,			"8*CS"					},
2716	{ 8*EFLAGS,		"8*EFL"					},
2717	{ 8*RSP,		"8*RSP"					},
2718	{ 8*SS,			"8*SS"					},
2719#endif
2720#ifdef M68K
2721	{ 4*PT_D1,		"4*PT_D1"				},
2722	{ 4*PT_D2,		"4*PT_D2"				},
2723	{ 4*PT_D3,		"4*PT_D3"				},
2724	{ 4*PT_D4,		"4*PT_D4"				},
2725	{ 4*PT_D5,		"4*PT_D5"				},
2726	{ 4*PT_D6,		"4*PT_D6"				},
2727	{ 4*PT_D7,		"4*PT_D7"				},
2728	{ 4*PT_A0,		"4*PT_A0"				},
2729	{ 4*PT_A1,		"4*PT_A1"				},
2730	{ 4*PT_A2,		"4*PT_A2"				},
2731	{ 4*PT_A3,		"4*PT_A3"				},
2732	{ 4*PT_A4,		"4*PT_A4"				},
2733	{ 4*PT_A5,		"4*PT_A5"				},
2734	{ 4*PT_A6,		"4*PT_A6"				},
2735	{ 4*PT_D0,		"4*PT_D0"				},
2736	{ 4*PT_USP,		"4*PT_USP"				},
2737	{ 4*PT_ORIG_D0,		"4*PT_ORIG_D0"				},
2738	{ 4*PT_SR,		"4*PT_SR"				},
2739	{ 4*PT_PC,		"4*PT_PC"				},
2740#endif /* M68K */
2741#endif /* !I386 */
2742#ifdef SH
2743       { 4*REG_REG0,           "4*REG_REG0"                            },
2744       { 4*(REG_REG0+1),       "4*REG_REG1"                            },
2745       { 4*(REG_REG0+2),       "4*REG_REG2"                            },
2746       { 4*(REG_REG0+3),       "4*REG_REG3"                            },
2747       { 4*(REG_REG0+4),       "4*REG_REG4"                            },
2748       { 4*(REG_REG0+5),       "4*REG_REG5"                            },
2749       { 4*(REG_REG0+6),       "4*REG_REG6"                            },
2750       { 4*(REG_REG0+7),       "4*REG_REG7"                            },
2751       { 4*(REG_REG0+8),       "4*REG_REG8"                            },
2752       { 4*(REG_REG0+9),       "4*REG_REG9"                            },
2753       { 4*(REG_REG0+10),      "4*REG_REG10"                           },
2754       { 4*(REG_REG0+11),      "4*REG_REG11"                           },
2755       { 4*(REG_REG0+12),      "4*REG_REG12"                           },
2756       { 4*(REG_REG0+13),      "4*REG_REG13"                           },
2757       { 4*(REG_REG0+14),      "4*REG_REG14"                           },
2758       { 4*REG_REG15,          "4*REG_REG15"                           },
2759       { 4*REG_PC,             "4*REG_PC"                              },
2760       { 4*REG_PR,             "4*REG_PR"                              },
2761       { 4*REG_SR,             "4*REG_SR"                              },
2762       { 4*REG_GBR,            "4*REG_GBR"                             },
2763       { 4*REG_MACH,           "4*REG_MACH"                            },
2764       { 4*REG_MACL,           "4*REG_MACL"                            },
2765       { 4*REG_SYSCALL,        "4*REG_SYSCALL"                         },
2766       { 4*REG_FPUL,           "4*REG_FPUL"                            },
2767       { 4*REG_FPREG0,         "4*REG_FPREG0"                          },
2768       { 4*(REG_FPREG0+1),     "4*REG_FPREG1"                          },
2769       { 4*(REG_FPREG0+2),     "4*REG_FPREG2"                          },
2770       { 4*(REG_FPREG0+3),     "4*REG_FPREG3"                          },
2771       { 4*(REG_FPREG0+4),     "4*REG_FPREG4"                          },
2772       { 4*(REG_FPREG0+5),     "4*REG_FPREG5"                          },
2773       { 4*(REG_FPREG0+6),     "4*REG_FPREG6"                          },
2774       { 4*(REG_FPREG0+7),     "4*REG_FPREG7"                          },
2775       { 4*(REG_FPREG0+8),     "4*REG_FPREG8"                          },
2776       { 4*(REG_FPREG0+9),     "4*REG_FPREG9"                          },
2777       { 4*(REG_FPREG0+10),    "4*REG_FPREG10"                         },
2778       { 4*(REG_FPREG0+11),    "4*REG_FPREG11"                         },
2779       { 4*(REG_FPREG0+12),    "4*REG_FPREG12"                         },
2780       { 4*(REG_FPREG0+13),    "4*REG_FPREG13"                         },
2781       { 4*(REG_FPREG0+14),    "4*REG_FPREG14"                         },
2782       { 4*REG_FPREG15,        "4*REG_FPREG15"                         },
2783#ifdef REG_XDREG0
2784       { 4*REG_XDREG0,         "4*REG_XDREG0"                          },
2785       { 4*(REG_XDREG0+2),     "4*REG_XDREG2"                          },
2786       { 4*(REG_XDREG0+4),     "4*REG_XDREG4"                          },
2787       { 4*(REG_XDREG0+6),     "4*REG_XDREG6"                          },
2788       { 4*(REG_XDREG0+8),     "4*REG_XDREG8"                          },
2789       { 4*(REG_XDREG0+10),    "4*REG_XDREG10"                         },
2790       { 4*(REG_XDREG0+12),    "4*REG_XDREG12"                         },
2791       { 4*REG_XDREG14,        "4*REG_XDREG14"                         },
2792#endif
2793       { 4*REG_FPSCR,          "4*REG_FPSCR"                           },
2794#endif /* SH */
2795#ifdef SH64
2796	{ 0,		        "PC(L)"				        },
2797	{ 4,	                "PC(U)"				        },
2798	{ 8, 	                "SR(L)"	  	         		},
2799	{ 12,               	"SR(U)"     				},
2800	{ 16,            	"syscall no.(L)" 			},
2801	{ 20,            	"syscall_no.(U)"			},
2802	{ 24,            	"R0(L)"     				},
2803	{ 28,            	"R0(U)"     				},
2804	{ 32,            	"R1(L)"     				},
2805	{ 36,            	"R1(U)"     				},
2806	{ 40,            	"R2(L)"     				},
2807	{ 44,            	"R2(U)"     				},
2808	{ 48,            	"R3(L)"     				},
2809	{ 52,            	"R3(U)"     				},
2810	{ 56,            	"R4(L)"     				},
2811	{ 60,            	"R4(U)"     				},
2812	{ 64,            	"R5(L)"     				},
2813	{ 68,            	"R5(U)"     				},
2814	{ 72,            	"R6(L)"     				},
2815	{ 76,            	"R6(U)"     				},
2816	{ 80,            	"R7(L)"     				},
2817	{ 84,            	"R7(U)"     				},
2818	{ 88,            	"R8(L)"     				},
2819	{ 92,            	"R8(U)"     				},
2820	{ 96,            	"R9(L)"     				},
2821	{ 100,           	"R9(U)"     				},
2822	{ 104,           	"R10(L)"     				},
2823	{ 108,           	"R10(U)"     				},
2824	{ 112,           	"R11(L)"     				},
2825	{ 116,           	"R11(U)"     				},
2826	{ 120,           	"R12(L)"     				},
2827	{ 124,           	"R12(U)"     				},
2828	{ 128,           	"R13(L)"     				},
2829	{ 132,           	"R13(U)"     				},
2830	{ 136,           	"R14(L)"     				},
2831	{ 140,           	"R14(U)"     				},
2832	{ 144,           	"R15(L)"     				},
2833	{ 148,           	"R15(U)"     				},
2834	{ 152,           	"R16(L)"     				},
2835	{ 156,           	"R16(U)"     				},
2836	{ 160,           	"R17(L)"     				},
2837	{ 164,           	"R17(U)"     				},
2838	{ 168,           	"R18(L)"     				},
2839	{ 172,           	"R18(U)"     				},
2840	{ 176,           	"R19(L)"     				},
2841	{ 180,           	"R19(U)"     				},
2842	{ 184,           	"R20(L)"     				},
2843	{ 188,           	"R20(U)"     				},
2844	{ 192,           	"R21(L)"     				},
2845	{ 196,           	"R21(U)"     				},
2846	{ 200,           	"R22(L)"     				},
2847	{ 204,           	"R22(U)"     				},
2848	{ 208,           	"R23(L)"     				},
2849	{ 212,           	"R23(U)"     				},
2850	{ 216,           	"R24(L)"     				},
2851	{ 220,           	"R24(U)"     				},
2852	{ 224,           	"R25(L)"     				},
2853	{ 228,           	"R25(U)"     				},
2854	{ 232,           	"R26(L)"     				},
2855	{ 236,           	"R26(U)"     				},
2856	{ 240,           	"R27(L)"     				},
2857	{ 244,           	"R27(U)"     				},
2858	{ 248,           	"R28(L)"     				},
2859	{ 252,           	"R28(U)"     				},
2860	{ 256,           	"R29(L)"     				},
2861	{ 260,           	"R29(U)"     				},
2862	{ 264,           	"R30(L)"     				},
2863	{ 268,           	"R30(U)"     				},
2864	{ 272,           	"R31(L)"     				},
2865	{ 276,           	"R31(U)"     				},
2866	{ 280,           	"R32(L)"     				},
2867	{ 284,           	"R32(U)"     				},
2868	{ 288,           	"R33(L)"     				},
2869	{ 292,           	"R33(U)"     				},
2870	{ 296,           	"R34(L)"     				},
2871	{ 300,           	"R34(U)"     				},
2872	{ 304,           	"R35(L)"     				},
2873	{ 308,           	"R35(U)"     				},
2874	{ 312,           	"R36(L)"     				},
2875	{ 316,           	"R36(U)"     				},
2876	{ 320,           	"R37(L)"     				},
2877	{ 324,           	"R37(U)"     				},
2878	{ 328,           	"R38(L)"     				},
2879	{ 332,           	"R38(U)"     				},
2880	{ 336,           	"R39(L)"     				},
2881	{ 340,           	"R39(U)"     				},
2882	{ 344,           	"R40(L)"     				},
2883	{ 348,           	"R40(U)"     				},
2884	{ 352,           	"R41(L)"     				},
2885	{ 356,           	"R41(U)"     				},
2886	{ 360,           	"R42(L)"     				},
2887	{ 364,           	"R42(U)"     				},
2888	{ 368,           	"R43(L)"     				},
2889	{ 372,           	"R43(U)"     				},
2890	{ 376,           	"R44(L)"     				},
2891	{ 380,           	"R44(U)"     				},
2892	{ 384,           	"R45(L)"     				},
2893	{ 388,           	"R45(U)"     				},
2894	{ 392,           	"R46(L)"     				},
2895	{ 396,           	"R46(U)"     				},
2896	{ 400,           	"R47(L)"     				},
2897	{ 404,           	"R47(U)"     				},
2898	{ 408,           	"R48(L)"     				},
2899	{ 412,           	"R48(U)"     				},
2900	{ 416,           	"R49(L)"     				},
2901	{ 420,           	"R49(U)"     				},
2902	{ 424,           	"R50(L)"     				},
2903	{ 428,           	"R50(U)"     				},
2904	{ 432,           	"R51(L)"     				},
2905	{ 436,           	"R51(U)"     				},
2906	{ 440,           	"R52(L)"     				},
2907	{ 444,           	"R52(U)"     				},
2908	{ 448,           	"R53(L)"     				},
2909	{ 452,           	"R53(U)"     				},
2910	{ 456,           	"R54(L)"     				},
2911	{ 460,           	"R54(U)"     				},
2912	{ 464,           	"R55(L)"     				},
2913	{ 468,           	"R55(U)"     				},
2914	{ 472,           	"R56(L)"     				},
2915	{ 476,           	"R56(U)"     				},
2916	{ 480,           	"R57(L)"     				},
2917	{ 484,           	"R57(U)"     				},
2918	{ 488,           	"R58(L)"     				},
2919	{ 492,           	"R58(U)"     				},
2920	{ 496,           	"R59(L)"     				},
2921	{ 500,           	"R59(U)"     				},
2922	{ 504,           	"R60(L)"     				},
2923	{ 508,           	"R60(U)"     				},
2924	{ 512,           	"R61(L)"     				},
2925	{ 516,           	"R61(U)"     				},
2926	{ 520,           	"R62(L)"     				},
2927	{ 524,           	"R62(U)"     				},
2928	{ 528,                  "TR0(L)"                                },
2929	{ 532,                  "TR0(U)"                                },
2930	{ 536,                  "TR1(L)"                                },
2931	{ 540,                  "TR1(U)"                                },
2932	{ 544,                  "TR2(L)"                                },
2933	{ 548,                  "TR2(U)"                                },
2934	{ 552,                  "TR3(L)"                                },
2935	{ 556,                  "TR3(U)"                                },
2936	{ 560,                  "TR4(L)"                                },
2937	{ 564,                  "TR4(U)"                                },
2938	{ 568,                  "TR5(L)"                                },
2939	{ 572,                  "TR5(U)"                                },
2940	{ 576,                  "TR6(L)"                                },
2941	{ 580,                  "TR6(U)"                                },
2942	{ 584,                  "TR7(L)"                                },
2943	{ 588,                  "TR7(U)"                                },
2944        /* This entry is in case pt_regs contains dregs (depends on
2945           the kernel build options). */
2946	{ uoff(regs),	        "offsetof(struct user, regs)"	        },
2947	{ uoff(fpu),	        "offsetof(struct user, fpu)"	        },
2948#endif
2949#ifdef ARM
2950	{ uoff(regs.ARM_r0),	"r0"					},
2951	{ uoff(regs.ARM_r1),	"r1"					},
2952	{ uoff(regs.ARM_r2),	"r2"					},
2953	{ uoff(regs.ARM_r3),	"r3"					},
2954	{ uoff(regs.ARM_r4),	"r4"					},
2955	{ uoff(regs.ARM_r5),	"r5"					},
2956	{ uoff(regs.ARM_r6),	"r6"					},
2957	{ uoff(regs.ARM_r7),	"r7"					},
2958	{ uoff(regs.ARM_r8),	"r8"					},
2959	{ uoff(regs.ARM_r9),	"r9"					},
2960	{ uoff(regs.ARM_r10),	"r10"					},
2961	{ uoff(regs.ARM_fp),	"fp"					},
2962	{ uoff(regs.ARM_ip),	"ip"					},
2963	{ uoff(regs.ARM_sp),	"sp"					},
2964	{ uoff(regs.ARM_lr),	"lr"					},
2965	{ uoff(regs.ARM_pc),	"pc"					},
2966	{ uoff(regs.ARM_cpsr),	"cpsr"					},
2967#endif
2968
2969#ifdef MIPS
2970	{ 0,			"r0"					},
2971	{ 1,			"r1"					},
2972	{ 2,			"r2"					},
2973	{ 3,			"r3"					},
2974	{ 4,			"r4"					},
2975	{ 5,			"r5"					},
2976	{ 6,			"r6"					},
2977	{ 7,			"r7"					},
2978	{ 8,			"r8"					},
2979	{ 9,			"r9"					},
2980	{ 10,			"r10"					},
2981	{ 11,			"r11"					},
2982	{ 12,			"r12"					},
2983	{ 13,			"r13"					},
2984	{ 14,			"r14"					},
2985	{ 15,			"r15"					},
2986	{ 16,			"r16"					},
2987	{ 17,			"r17"					},
2988	{ 18,			"r18"					},
2989	{ 19,			"r19"					},
2990	{ 20,			"r20"					},
2991	{ 21,			"r21"					},
2992	{ 22,			"r22"					},
2993	{ 23,			"r23"					},
2994	{ 24,			"r24"					},
2995	{ 25,			"r25"					},
2996	{ 26,			"r26"					},
2997	{ 27,			"r27"					},
2998	{ 28,			"r28"					},
2999	{ 29,			"r29"					},
3000	{ 30,			"r30"					},
3001	{ 31,			"r31"					},
3002	{ 32,			"f0"					},
3003	{ 33,			"f1"					},
3004	{ 34,			"f2"					},
3005	{ 35,			"f3"					},
3006	{ 36,			"f4"					},
3007	{ 37,			"f5"					},
3008	{ 38,			"f6"					},
3009	{ 39,			"f7"					},
3010	{ 40,			"f8"					},
3011	{ 41,			"f9"					},
3012	{ 42,			"f10"					},
3013	{ 43,			"f11"					},
3014	{ 44,			"f12"					},
3015	{ 45,			"f13"					},
3016	{ 46,			"f14"					},
3017	{ 47,			"f15"					},
3018	{ 48,			"f16"					},
3019	{ 49,			"f17"					},
3020	{ 50,			"f18"					},
3021	{ 51,			"f19"					},
3022	{ 52,			"f20"					},
3023	{ 53,			"f21"					},
3024	{ 54,			"f22"					},
3025	{ 55,			"f23"					},
3026	{ 56,			"f24"					},
3027	{ 57,			"f25"					},
3028	{ 58,			"f26"					},
3029	{ 59,			"f27"					},
3030	{ 60,			"f28"					},
3031	{ 61,			"f29"					},
3032	{ 62,			"f30"					},
3033	{ 63,			"f31"					},
3034	{ 64,			"pc"					},
3035	{ 65,			"cause"					},
3036	{ 66,			"badvaddr"				},
3037	{ 67,			"mmhi"					},
3038	{ 68,			"mmlo"					},
3039	{ 69,			"fpcsr"					},
3040	{ 70,			"fpeir"					},
3041#endif
3042
3043#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(BFIN)
3044	{ uoff(u_fpvalid),	"offsetof(struct user, u_fpvalid)"	},
3045#endif
3046#if  defined(I386) || defined(X86_64)
3047	{ uoff(i387),		"offsetof(struct user, i387)"		},
3048#else /* !I386 */
3049#ifdef M68K
3050	{ uoff(m68kfp),		"offsetof(struct user, m68kfp)"		},
3051#endif /* M68K */
3052#endif /* !I386 */
3053	{ uoff(u_tsize),	"offsetof(struct user, u_tsize)"	},
3054	{ uoff(u_dsize),	"offsetof(struct user, u_dsize)"	},
3055	{ uoff(u_ssize),	"offsetof(struct user, u_ssize)"	},
3056#if !defined(SPARC64)
3057	{ uoff(start_code),	"offsetof(struct user, start_code)"	},
3058#endif
3059#ifdef SH64
3060	{ uoff(start_data),	"offsetof(struct user, start_data)"	},
3061#endif
3062#if !defined(SPARC64)
3063	{ uoff(start_stack),	"offsetof(struct user, start_stack)"	},
3064#endif
3065	{ uoff(signal),		"offsetof(struct user, signal)"		},
3066#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
3067	{ uoff(reserved),	"offsetof(struct user, reserved)"	},
3068#endif
3069#if !defined(SPARC64)
3070	{ uoff(u_ar0),		"offsetof(struct user, u_ar0)"		},
3071#endif
3072#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN)
3073	{ uoff(u_fpstate),	"offsetof(struct user, u_fpstate)"	},
3074#endif
3075	{ uoff(magic),		"offsetof(struct user, magic)"		},
3076	{ uoff(u_comm),		"offsetof(struct user, u_comm)"		},
3077#if defined(I386) || defined(X86_64)
3078	{ uoff(u_debugreg),	"offsetof(struct user, u_debugreg)"	},
3079#endif /* I386 */
3080#endif /* !IA64 */
3081#endif /* !ALPHA */
3082#endif /* !POWERPC/!SPARC */
3083#endif /* LINUX */
3084#ifdef SUNOS4
3085	{ uoff(u_pcb),		"offsetof(struct user, u_pcb)"		},
3086	{ uoff(u_procp),	"offsetof(struct user, u_procp)"	},
3087	{ uoff(u_ar0),		"offsetof(struct user, u_ar0)"		},
3088	{ uoff(u_comm[0]),	"offsetof(struct user, u_comm[0])"	},
3089	{ uoff(u_arg[0]),	"offsetof(struct user, u_arg[0])"	},
3090	{ uoff(u_ap),		"offsetof(struct user, u_ap)"		},
3091	{ uoff(u_qsave),	"offsetof(struct user, u_qsave)"	},
3092	{ uoff(u_rval1),	"offsetof(struct user, u_rval1)"	},
3093	{ uoff(u_rval2),	"offsetof(struct user, u_rval2)"	},
3094	{ uoff(u_error),	"offsetof(struct user, u_error)"	},
3095	{ uoff(u_eosys),	"offsetof(struct user, u_eosys)"	},
3096	{ uoff(u_ssave),	"offsetof(struct user, u_ssave)"	},
3097	{ uoff(u_signal[0]),	"offsetof(struct user, u_signal)"	},
3098	{ uoff(u_sigmask[0]),	"offsetof(struct user, u_sigmask)"	},
3099	{ uoff(u_sigonstack),	"offsetof(struct user, u_sigonstack)"	},
3100	{ uoff(u_sigintr),	"offsetof(struct user, u_sigintr)"	},
3101	{ uoff(u_sigreset),	"offsetof(struct user, u_sigreset)"	},
3102	{ uoff(u_oldmask),	"offsetof(struct user, u_oldmask)"	},
3103	{ uoff(u_code),		"offsetof(struct user, u_code)"		},
3104	{ uoff(u_addr),		"offsetof(struct user, u_addr)"		},
3105	{ uoff(u_sigstack),	"offsetof(struct user, u_sigstack)"	},
3106	{ uoff(u_ofile),	"offsetof(struct user, u_ofile)"	},
3107	{ uoff(u_pofile),	"offsetof(struct user, u_pofile)"	},
3108	{ uoff(u_ofile_arr[0]),	"offsetof(struct user, u_ofile_arr[0])"	},
3109	{ uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3110	{ uoff(u_lastfile),	"offsetof(struct user, u_lastfile)"	},
3111	{ uoff(u_cwd),		"offsetof(struct user, u_cwd)"		},
3112	{ uoff(u_cdir),		"offsetof(struct user, u_cdir)"		},
3113	{ uoff(u_rdir),		"offsetof(struct user, u_rdir)"		},
3114	{ uoff(u_cmask),	"offsetof(struct user, u_cmask)"	},
3115	{ uoff(u_ru),		"offsetof(struct user, u_ru)"		},
3116	{ uoff(u_cru),		"offsetof(struct user, u_cru)"		},
3117	{ uoff(u_timer[0]),	"offsetof(struct user, u_timer[0])"	},
3118	{ uoff(u_XXX[0]),	"offsetof(struct user, u_XXX[0])"	},
3119	{ uoff(u_ioch),		"offsetof(struct user, u_ioch)"		},
3120	{ uoff(u_start),	"offsetof(struct user, u_start)"	},
3121	{ uoff(u_acflag),	"offsetof(struct user, u_acflag)"	},
3122	{ uoff(u_prof.pr_base),	"offsetof(struct user, u_prof.pr_base)"	},
3123	{ uoff(u_prof.pr_size),	"offsetof(struct user, u_prof.pr_size)"	},
3124	{ uoff(u_prof.pr_off),	"offsetof(struct user, u_prof.pr_off)"	},
3125	{ uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3126	{ uoff(u_rlimit[0]),	"offsetof(struct user, u_rlimit)"	},
3127	{ uoff(u_exdata.Ux_A),	"offsetof(struct user, u_exdata.Ux_A)"	},
3128	{ uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3129	{ uoff(u_lofault),	"offsetof(struct user, u_lofault)"	},
3130#endif /* SUNOS4 */
3131#ifndef HPPA
3132	{ sizeof(struct user),	"sizeof(struct user)"			},
3133#endif
3134	{ 0,			NULL					},
3135};
3136#endif
3137
3138int
3139sys_ptrace(tcp)
3140struct tcb *tcp;
3141{
3142	const struct xlat *x;
3143	long addr;
3144
3145	if (entering(tcp)) {
3146		printxval(ptrace_cmds, tcp->u_arg[0],
3147#ifndef FREEBSD
3148			  "PTRACE_???"
3149#else
3150			  "PT_???"
3151#endif
3152			);
3153		tprintf(", %lu, ", tcp->u_arg[1]);
3154		addr = tcp->u_arg[2];
3155#ifndef FREEBSD
3156		if (tcp->u_arg[0] == PTRACE_PEEKUSER
3157			|| tcp->u_arg[0] == PTRACE_POKEUSER) {
3158			for (x = struct_user_offsets; x->str; x++) {
3159				if (x->val >= addr)
3160					break;
3161			}
3162			if (!x->str)
3163				tprintf("%#lx, ", addr);
3164			else if (x->val > addr && x != struct_user_offsets) {
3165				x--;
3166				tprintf("%s + %ld, ", x->str, addr - x->val);
3167			}
3168			else
3169				tprintf("%s, ", x->str);
3170		}
3171		else
3172#endif
3173			tprintf("%#lx, ", tcp->u_arg[2]);
3174#ifdef LINUX
3175		switch (tcp->u_arg[0]) {
3176#ifndef IA64
3177		case PTRACE_PEEKDATA:
3178		case PTRACE_PEEKTEXT:
3179		case PTRACE_PEEKUSER:
3180			break;
3181#endif
3182		case PTRACE_CONT:
3183		case PTRACE_SINGLESTEP:
3184		case PTRACE_SYSCALL:
3185		case PTRACE_DETACH:
3186			printsignal(tcp->u_arg[3]);
3187			break;
3188		default:
3189			tprintf("%#lx", tcp->u_arg[3]);
3190			break;
3191		}
3192	} else {
3193		switch (tcp->u_arg[0]) {
3194		case PTRACE_PEEKDATA:
3195		case PTRACE_PEEKTEXT:
3196		case PTRACE_PEEKUSER:
3197#ifdef IA64
3198			return RVAL_HEX;
3199#else
3200			printnum(tcp, tcp->u_arg[3], "%#lx");
3201			break;
3202#endif
3203		}
3204	}
3205#endif /* LINUX */
3206#ifdef SUNOS4
3207		if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3208			tcp->u_arg[0] == PTRACE_WRITETEXT) {
3209			tprintf("%lu, ", tcp->u_arg[3]);
3210			printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3211		} else if (tcp->u_arg[0] != PTRACE_READDATA &&
3212				tcp->u_arg[0] != PTRACE_READTEXT) {
3213			tprintf("%#lx", tcp->u_arg[3]);
3214		}
3215	} else {
3216		if (tcp->u_arg[0] == PTRACE_READDATA ||
3217			tcp->u_arg[0] == PTRACE_READTEXT) {
3218			tprintf("%lu, ", tcp->u_arg[3]);
3219			printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3220		}
3221	}
3222#endif /* SUNOS4 */
3223#ifdef FREEBSD
3224		tprintf("%lu", tcp->u_arg[3]);
3225	}
3226#endif /* FREEBSD */
3227	return 0;
3228}
3229
3230#endif /* !SVR4 */
3231
3232#ifdef LINUX
3233# ifndef FUTEX_CMP_REQUEUE
3234#  define FUTEX_CMP_REQUEUE 4
3235# endif
3236# ifndef FUTEX_WAKE_OP
3237#  define FUTEX_WAKE_OP 5
3238# endif
3239# ifndef FUTEX_LOCK_PI
3240#  define FUTEX_LOCK_PI 6
3241#  define FUTEX_UNLOCK_PI 7
3242#  define FUTEX_TRYLOCK_PI 8
3243# endif
3244# ifndef FUTEX_WAIT_BITSET
3245#  define FUTEX_WAIT_BITSET 9
3246# endif
3247# ifndef FUTEX_WAKE_BITSET
3248#  define FUTEX_WAKE_BITSET 10
3249# endif
3250# ifndef FUTEX_PRIVATE_FLAG
3251#  define FUTEX_PRIVATE_FLAG 128
3252# endif
3253static const struct xlat futexops[] = {
3254	{ FUTEX_WAIT,					"FUTEX_WAIT" },
3255	{ FUTEX_WAKE,					"FUTEX_WAKE" },
3256	{ FUTEX_FD,					"FUTEX_FD" },
3257	{ FUTEX_REQUEUE,				"FUTEX_REQUEUE" },
3258	{ FUTEX_CMP_REQUEUE,				"FUTEX_CMP_REQUEUE" },
3259	{ FUTEX_WAKE_OP,				"FUTEX_WAKE_OP" },
3260	{ FUTEX_LOCK_PI,				"FUTEX_LOCK_PI" },
3261	{ FUTEX_UNLOCK_PI,				"FUTEX_UNLOCK_PI" },
3262	{ FUTEX_TRYLOCK_PI,				"FUTEX_TRYLOCK_PI" },
3263	{ FUTEX_WAIT_BITSET,				"FUTEX_WAIT_BITSET" },
3264	{ FUTEX_WAKE_BITSET,				"FUTEX_WAKE_BITSET" },
3265	{ FUTEX_WAIT|FUTEX_PRIVATE_FLAG,		"FUTEX_WAIT_PRIVATE" },
3266	{ FUTEX_WAKE|FUTEX_PRIVATE_FLAG,		"FUTEX_WAKE_PRIVATE" },
3267	{ FUTEX_FD|FUTEX_PRIVATE_FLAG,			"FUTEX_FD_PRIVATE" },
3268	{ FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG,		"FUTEX_REQUEUE_PRIVATE" },
3269	{ FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG,		"FUTEX_CMP_REQUEUE_PRIVATE" },
3270	{ FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG,		"FUTEX_WAKE_OP_PRIVATE" },
3271	{ FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG,		"FUTEX_LOCK_PI_PRIVATE" },
3272	{ FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG,		"FUTEX_UNLOCK_PI_PRIVATE" },
3273	{ FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG,		"FUTEX_TRYLOCK_PI_PRIVATE" },
3274	{ FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG,		"FUTEX_WAIT_BITSET_PRIVATE" },
3275	{ FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG,		"FUTEX_WAKE_BITSET_PRIVATE" },
3276	{ 0,						NULL }
3277};
3278#ifndef FUTEX_OP_SET
3279# define FUTEX_OP_SET		0
3280# define FUTEX_OP_ADD		1
3281# define FUTEX_OP_OR		2
3282# define FUTEX_OP_ANDN		3
3283# define FUTEX_OP_XOR		4
3284# define FUTEX_OP_CMP_EQ	0
3285# define FUTEX_OP_CMP_NE	1
3286# define FUTEX_OP_CMP_LT	2
3287# define FUTEX_OP_CMP_LE	3
3288# define FUTEX_OP_CMP_GT	4
3289# define FUTEX_OP_CMP_GE	5
3290#endif
3291static const struct xlat futexwakeops[] = {
3292	{ FUTEX_OP_SET,		"FUTEX_OP_SET" },
3293	{ FUTEX_OP_ADD,		"FUTEX_OP_ADD" },
3294	{ FUTEX_OP_OR,		"FUTEX_OP_OR" },
3295	{ FUTEX_OP_ANDN,	"FUTEX_OP_ANDN" },
3296	{ FUTEX_OP_XOR,		"FUTEX_OP_XOR" },
3297	{ 0,			NULL }
3298};
3299static const struct xlat futexwakecmps[] = {
3300	{ FUTEX_OP_CMP_EQ,	"FUTEX_OP_CMP_EQ" },
3301	{ FUTEX_OP_CMP_NE,	"FUTEX_OP_CMP_NE" },
3302	{ FUTEX_OP_CMP_LT,	"FUTEX_OP_CMP_LT" },
3303	{ FUTEX_OP_CMP_LE,	"FUTEX_OP_CMP_LE" },
3304	{ FUTEX_OP_CMP_GT,	"FUTEX_OP_CMP_GT" },
3305	{ FUTEX_OP_CMP_GE,	"FUTEX_OP_CMP_GE" },
3306	{ 0,			NULL }
3307};
3308
3309int
3310sys_futex(tcp)
3311struct tcb *tcp;
3312{
3313    if (entering(tcp)) {
3314	long int cmd = tcp->u_arg[1] & 127;
3315	tprintf("%p, ", (void *) tcp->u_arg[0]);
3316	printxval(futexops, tcp->u_arg[1], "FUTEX_???");
3317	tprintf(", %ld", tcp->u_arg[2]);
3318	if (cmd == FUTEX_WAKE_BITSET)
3319		tprintf(", %lx", tcp->u_arg[5]);
3320	else if (cmd == FUTEX_WAIT) {
3321		tprintf(", ");
3322		printtv(tcp, tcp->u_arg[3]);
3323	} else if (cmd == FUTEX_WAIT_BITSET) {
3324		tprintf(", ");
3325		printtv(tcp, tcp->u_arg[3]);
3326		tprintf(", %lx", tcp->u_arg[5]);
3327	} else if (cmd == FUTEX_REQUEUE)
3328		tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3329	else if (cmd == FUTEX_CMP_REQUEUE)
3330		tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3331	else if (cmd == FUTEX_WAKE_OP) {
3332		tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3333		if ((tcp->u_arg[5] >> 28) & 8)
3334			tprintf("FUTEX_OP_OPARG_SHIFT|");
3335		printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3336		tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3337		if ((tcp->u_arg[5] >> 24) & 8)
3338			tprintf("FUTEX_OP_OPARG_SHIFT|");
3339		printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3340		tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3341	}
3342    }
3343    return 0;
3344}
3345
3346static void
3347print_affinitylist(tcp, list, len)
3348struct tcb *tcp;
3349long list;
3350unsigned int len;
3351{
3352    int first = 1;
3353    tprintf(" {");
3354    while (len >= sizeof (unsigned long)) {
3355	unsigned long w;
3356	umove(tcp, list, &w);
3357	tprintf("%s %lx", first ? "" : ",", w);
3358	first = 0;
3359	len -= sizeof (unsigned long);
3360	list += sizeof(unsigned long);
3361    }
3362    tprintf(" }");
3363}
3364
3365int
3366sys_sched_setaffinity(tcp)
3367struct tcb *tcp;
3368{
3369    if (entering(tcp)) {
3370	tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3371	print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3372    }
3373    return 0;
3374}
3375
3376int
3377sys_sched_getaffinity(tcp)
3378struct tcb *tcp;
3379{
3380    if (entering(tcp)) {
3381	tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3382    } else {
3383	if (tcp->u_rval == -1)
3384	    tprintf("%#lx", tcp->u_arg[2]);
3385	else
3386	    print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3387    }
3388    return 0;
3389}
3390
3391static const struct xlat schedulers[] = {
3392	{ SCHED_OTHER,	"SCHED_OTHER" },
3393	{ SCHED_RR,	"SCHED_RR" },
3394	{ SCHED_FIFO,	"SCHED_FIFO" },
3395	{ 0,		NULL }
3396};
3397
3398int
3399sys_sched_getscheduler(tcp)
3400struct tcb *tcp;
3401{
3402    if (entering(tcp)) {
3403	tprintf("%d", (int) tcp->u_arg[0]);
3404    } else if (! syserror(tcp)) {
3405	tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3406	if (tcp->auxstr != NULL)
3407	    return RVAL_STR;
3408    }
3409    return 0;
3410}
3411
3412int
3413sys_sched_setscheduler(tcp)
3414struct tcb *tcp;
3415{
3416    if (entering(tcp)) {
3417	struct sched_param p;
3418	tprintf("%d, ", (int) tcp->u_arg[0]);
3419	printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3420	if (umove(tcp, tcp->u_arg[2], &p) < 0)
3421	    tprintf(", %#lx", tcp->u_arg[2]);
3422	else
3423	    tprintf(", { %d }", p.__sched_priority);
3424    }
3425    return 0;
3426}
3427
3428int
3429sys_sched_getparam(tcp)
3430struct tcb *tcp;
3431{
3432    if (entering(tcp)) {
3433	    tprintf("%d, ", (int) tcp->u_arg[0]);
3434    } else {
3435	struct sched_param p;
3436	if (umove(tcp, tcp->u_arg[1], &p) < 0)
3437	    tprintf("%#lx", tcp->u_arg[1]);
3438	else
3439	    tprintf("{ %d }", p.__sched_priority);
3440    }
3441    return 0;
3442}
3443
3444int
3445sys_sched_setparam(tcp)
3446struct tcb *tcp;
3447{
3448    if (entering(tcp)) {
3449	struct sched_param p;
3450	if (umove(tcp, tcp->u_arg[1], &p) < 0)
3451	    tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3452	else
3453	    tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3454    }
3455    return 0;
3456}
3457
3458int
3459sys_sched_get_priority_min(tcp)
3460struct tcb *tcp;
3461{
3462    if (entering(tcp)) {
3463	printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3464    }
3465    return 0;
3466}
3467
3468#ifdef X86_64
3469#include <asm/prctl.h>
3470
3471static const struct xlat archvals[] = {
3472	{ ARCH_SET_GS,		"ARCH_SET_GS"		},
3473	{ ARCH_SET_FS,		"ARCH_SET_FS"		},
3474	{ ARCH_GET_FS,		"ARCH_GET_FS"		},
3475	{ ARCH_GET_GS,		"ARCH_GET_GS"		},
3476	{ 0,			NULL			},
3477};
3478
3479int
3480sys_arch_prctl(tcp)
3481struct tcb *tcp;
3482{
3483    if (entering(tcp)) {
3484	printxval(archvals, tcp->u_arg[0], "ARCH_???");
3485	if (tcp->u_arg[0] == ARCH_SET_GS
3486	    || tcp->u_arg[0] == ARCH_SET_FS)
3487	    tprintf(", %#lx", tcp->u_arg[1]);
3488    } else {
3489	if (tcp->u_arg[0] == ARCH_GET_GS
3490	    || tcp->u_arg[0] == ARCH_GET_FS) {
3491	    long int v;
3492	    if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3493		tprintf(", [%#lx]", v);
3494	    else
3495		tprintf(", %#lx", tcp->u_arg[1]);
3496	}
3497    }
3498    return 0;
3499}
3500#endif
3501
3502
3503int
3504sys_getcpu(tcp)
3505struct tcb *tcp;
3506{
3507	if (exiting(tcp)) {
3508		unsigned u;
3509		if (tcp->u_arg[0] == 0)
3510			tprintf("NULL, ");
3511		else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3512			tprintf("%#lx, ", tcp->u_arg[0]);
3513		else
3514			tprintf("[%u], ", u);
3515		if (tcp->u_arg[1] == 0)
3516			tprintf("NULL, ");
3517		else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3518			tprintf("%#lx, ", tcp->u_arg[1]);
3519		else
3520			tprintf("[%u], ", u);
3521		tprintf("%#lx", tcp->u_arg[2]);
3522	}
3523	return 0;
3524}
3525
3526#endif
3527