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