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