process.c revision 1ff463d15412de77fcf5b8ca1cf43c63dce1dbe1
1/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 *                     Linux for s390 port by D.J. Barrow
8 *                    <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
9 * Copyright (c) 2000 PocketPenguins Inc.  Linux for Hitachi SuperH
10 *                    port by Greg Banks <gbanks@pocketpenguins.com>
11
12 *
13 * All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 *    notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 *    notice, this list of conditions and the following disclaimer in the
22 *    documentation and/or other materials provided with the distribution.
23 * 3. The name of the author may not be used to endorse or promote products
24 *    derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 *	$Id$
38 */
39
40#include "defs.h"
41
42#include <fcntl.h>
43#include <sys/stat.h>
44#include <sys/time.h>
45#include <sys/wait.h>
46#include <sys/resource.h>
47#include <sys/utsname.h>
48#include <sys/user.h>
49#include <sys/syscall.h>
50#include <signal.h>
51
52#ifdef HAVE_SYS_REG_H
53# include <sys/reg.h>
54# ifndef PTRACE_PEEKUSR
55#  define PTRACE_PEEKUSR PTRACE_PEEKUSER
56# endif
57# ifndef PTRACE_POKEUSR
58#  define PTRACE_POKEUSR PTRACE_POKEUSER
59# endif
60#endif
61
62#ifdef HAVE_LINUX_PTRACE_H
63# undef PTRACE_SYSCALL
64# ifdef HAVE_STRUCT_IA64_FPREG
65#  define ia64_fpreg XXX_ia64_fpreg
66# endif
67# ifdef HAVE_STRUCT_PT_ALL_USER_REGS
68#  define pt_all_user_regs XXX_pt_all_user_regs
69# endif
70# include <linux/ptrace.h>
71# undef ia64_fpreg
72# undef pt_all_user_regs
73#endif
74
75#if defined(SPARC64)
76# define r_pc r_tpc
77# undef PTRACE_GETREGS
78# define PTRACE_GETREGS PTRACE_GETREGS64
79# undef PTRACE_SETREGS
80# define PTRACE_SETREGS PTRACE_SETREGS64
81#endif
82
83#ifdef HAVE_LINUX_FUTEX_H
84# include <linux/futex.h>
85#endif
86#ifndef FUTEX_WAIT
87# define FUTEX_WAIT 0
88#endif
89#ifndef FUTEX_WAKE
90# define FUTEX_WAKE 1
91#endif
92#ifndef FUTEX_FD
93# define FUTEX_FD 2
94#endif
95#ifndef FUTEX_REQUEUE
96# define FUTEX_REQUEUE 3
97#endif
98
99#include <sched.h>
100#include <asm/posix_types.h>
101#undef GETGROUPS_T
102#define GETGROUPS_T __kernel_gid_t
103#undef GETGROUPS32_T
104#define GETGROUPS32_T __kernel_gid32_t
105
106#if defined(IA64)
107# include <asm/ptrace_offsets.h>
108# include <asm/rse.h>
109#endif
110
111#ifdef HAVE_PRCTL
112# include <sys/prctl.h>
113
114static const struct xlat prctl_options[] = {
115#ifdef PR_MAXPROCS
116	{ PR_MAXPROCS,		"PR_MAXPROCS"		},
117#endif
118#ifdef PR_ISBLOCKED
119	{ PR_ISBLOCKED,		"PR_ISBLOCKED"		},
120#endif
121#ifdef PR_SETSTACKSIZE
122	{ PR_SETSTACKSIZE,	"PR_SETSTACKSIZE"	},
123#endif
124#ifdef PR_GETSTACKSIZE
125	{ PR_GETSTACKSIZE,	"PR_GETSTACKSIZE"	},
126#endif
127#ifdef PR_MAXPPROCS
128	{ PR_MAXPPROCS,		"PR_MAXPPROCS"		},
129#endif
130#ifdef PR_UNBLKONEXEC
131	{ PR_UNBLKONEXEC,	"PR_UNBLKONEXEC"	},
132#endif
133#ifdef PR_ATOMICSIM
134	{ PR_ATOMICSIM,		"PR_ATOMICSIM"		},
135#endif
136#ifdef PR_SETEXITSIG
137	{ PR_SETEXITSIG,	"PR_SETEXITSIG"		},
138#endif
139#ifdef PR_RESIDENT
140	{ PR_RESIDENT,		"PR_RESIDENT"		},
141#endif
142#ifdef PR_ATTACHADDR
143	{ PR_ATTACHADDR,	"PR_ATTACHADDR"		},
144#endif
145#ifdef PR_DETACHADDR
146	{ PR_DETACHADDR,	"PR_DETACHADDR"		},
147#endif
148#ifdef PR_TERMCHILD
149	{ PR_TERMCHILD,		"PR_TERMCHILD"		},
150#endif
151#ifdef PR_GETSHMASK
152	{ PR_GETSHMASK,		"PR_GETSHMASK"		},
153#endif
154#ifdef PR_GETNSHARE
155	{ PR_GETNSHARE,		"PR_GETNSHARE"		},
156#endif
157#ifdef PR_COREPID
158	{ PR_COREPID,		"PR_COREPID"		},
159#endif
160#ifdef PR_ATTACHADDRPERM
161	{ PR_ATTACHADDRPERM,	"PR_ATTACHADDRPERM"	},
162#endif
163#ifdef PR_PTHREADEXIT
164	{ PR_PTHREADEXIT,	"PR_PTHREADEXIT"	},
165#endif
166#ifdef PR_SET_PDEATHSIG
167	{ PR_SET_PDEATHSIG,	"PR_SET_PDEATHSIG"	},
168#endif
169#ifdef PR_GET_PDEATHSIG
170	{ PR_GET_PDEATHSIG,	"PR_GET_PDEATHSIG"	},
171#endif
172#ifdef PR_GET_DUMPABLE
173	{ PR_GET_DUMPABLE,	"PR_GET_DUMPABLE"	},
174#endif
175#ifdef PR_SET_DUMPABLE
176	{ PR_SET_DUMPABLE,	"PR_SET_DUMPABLE"	},
177#endif
178#ifdef PR_GET_UNALIGN
179	{ PR_GET_UNALIGN,	"PR_GET_UNALIGN"	},
180#endif
181#ifdef PR_SET_UNALIGN
182	{ PR_SET_UNALIGN,	"PR_SET_UNALIGN"	},
183#endif
184#ifdef PR_GET_KEEPCAPS
185	{ PR_GET_KEEPCAPS,	"PR_GET_KEEPCAPS"	},
186#endif
187#ifdef PR_SET_KEEPCAPS
188	{ PR_SET_KEEPCAPS,	"PR_SET_KEEPCAPS"	},
189#endif
190#ifdef PR_GET_FPEMU
191	{ PR_GET_FPEMU,		"PR_GET_FPEMU"		},
192#endif
193#ifdef PR_SET_FPEMU
194	{ PR_SET_FPEMU,		"PR_SET_FPEMU"		},
195#endif
196#ifdef PR_GET_FPEXC
197	{ PR_GET_FPEXC,		"PR_GET_FPEXC"		},
198#endif
199#ifdef PR_SET_FPEXC
200	{ PR_SET_FPEXC,		"PR_SET_FPEXC"		},
201#endif
202#ifdef PR_GET_TIMING
203	{ PR_GET_TIMING,	"PR_GET_TIMING"		},
204#endif
205#ifdef PR_SET_TIMING
206	{ PR_SET_TIMING,	"PR_SET_TIMING"		},
207#endif
208#ifdef PR_SET_NAME
209	{ PR_SET_NAME,		"PR_SET_NAME"		},
210#endif
211#ifdef PR_GET_NAME
212	{ PR_GET_NAME,		"PR_GET_NAME"		},
213#endif
214#ifdef PR_GET_ENDIAN
215	{ PR_GET_ENDIAN,	"PR_GET_ENDIAN"		},
216#endif
217#ifdef PR_SET_ENDIAN
218	{ PR_SET_ENDIAN,	"PR_SET_ENDIAN"		},
219#endif
220#ifdef PR_GET_SECCOMP
221	{ PR_GET_SECCOMP,	"PR_GET_SECCOMP"	},
222#endif
223#ifdef PR_SET_SECCOMP
224	{ PR_SET_SECCOMP,	"PR_SET_SECCOMP"	},
225#endif
226#ifdef PR_GET_TSC
227	{ PR_GET_TSC,		"PR_GET_TSC"		},
228#endif
229#ifdef PR_SET_TSC
230	{ PR_SET_TSC,		"PR_SET_TSC"		},
231#endif
232#ifdef PR_GET_SECUREBITS
233	{ PR_GET_SECUREBITS,	"PR_GET_SECUREBITS"	},
234#endif
235#ifdef PR_SET_SECUREBITS
236	{ PR_SET_SECUREBITS,	"PR_SET_SECUREBITS"	},
237#endif
238	{ 0,			NULL			},
239};
240
241static const char *
242unalignctl_string(unsigned int ctl)
243{
244	static char buf[sizeof(int)*2 + 2];
245
246	switch (ctl) {
247#ifdef PR_UNALIGN_NOPRINT
248		case PR_UNALIGN_NOPRINT:
249			return "NOPRINT";
250#endif
251#ifdef PR_UNALIGN_SIGBUS
252		case PR_UNALIGN_SIGBUS:
253			return "SIGBUS";
254#endif
255		default:
256			break;
257	}
258	sprintf(buf, "%x", ctl);
259	return buf;
260}
261
262int
263sys_prctl(struct tcb *tcp)
264{
265	int i;
266
267	if (entering(tcp)) {
268		printxval(prctl_options, tcp->u_arg[0], "PR_???");
269		switch (tcp->u_arg[0]) {
270#ifdef PR_GETNSHARE
271		case PR_GETNSHARE:
272			break;
273#endif
274#ifdef PR_SET_PDEATHSIG
275		case PR_SET_PDEATHSIG:
276			tprintf(", %lu", tcp->u_arg[1]);
277			break;
278#endif
279#ifdef PR_GET_PDEATHSIG
280		case PR_GET_PDEATHSIG:
281			break;
282#endif
283#ifdef PR_SET_DUMPABLE
284		case PR_SET_DUMPABLE:
285			tprintf(", %lu", tcp->u_arg[1]);
286			break;
287#endif
288#ifdef PR_GET_DUMPABLE
289		case PR_GET_DUMPABLE:
290			break;
291#endif
292#ifdef PR_SET_UNALIGN
293		case PR_SET_UNALIGN:
294			tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
295			break;
296#endif
297#ifdef PR_GET_UNALIGN
298		case PR_GET_UNALIGN:
299			tprintf(", %#lx", tcp->u_arg[1]);
300			break;
301#endif
302#ifdef PR_SET_KEEPCAPS
303		case PR_SET_KEEPCAPS:
304			tprintf(", %lu", tcp->u_arg[1]);
305			break;
306#endif
307#ifdef PR_GET_KEEPCAPS
308		case PR_GET_KEEPCAPS:
309			break;
310#endif
311		default:
312			for (i = 1; i < tcp->u_nargs; i++)
313				tprintf(", %#lx", tcp->u_arg[i]);
314			break;
315		}
316	} else {
317		switch (tcp->u_arg[0]) {
318#ifdef PR_GET_PDEATHSIG
319		case PR_GET_PDEATHSIG:
320			if (umove(tcp, tcp->u_arg[1], &i) < 0)
321				tprintf(", %#lx", tcp->u_arg[1]);
322			else
323				tprintf(", {%u}", i);
324			break;
325#endif
326#ifdef PR_GET_DUMPABLE
327		case PR_GET_DUMPABLE:
328			return RVAL_UDECIMAL;
329#endif
330#ifdef PR_GET_UNALIGN
331		case PR_GET_UNALIGN:
332			if (syserror(tcp) || umove(tcp, tcp->u_arg[1], &i) < 0)
333				break;
334			tcp->auxstr = unalignctl_string(i);
335			return RVAL_STR;
336#endif
337#ifdef PR_GET_KEEPCAPS
338		case PR_GET_KEEPCAPS:
339			return RVAL_UDECIMAL;
340#endif
341		default:
342			break;
343		}
344	}
345	return 0;
346}
347#endif /* HAVE_PRCTL */
348
349int
350sys_sethostname(struct tcb *tcp)
351{
352	if (entering(tcp)) {
353		printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
354		tprintf(", %lu", tcp->u_arg[1]);
355	}
356	return 0;
357}
358
359#if defined(ALPHA)
360int
361sys_gethostname(struct tcb *tcp)
362{
363	if (exiting(tcp)) {
364		if (syserror(tcp))
365			tprintf("%#lx", tcp->u_arg[0]);
366		else
367			printpath(tcp, tcp->u_arg[0]);
368		tprintf(", %lu", tcp->u_arg[1]);
369	}
370	return 0;
371}
372#endif
373
374int
375sys_setdomainname(struct tcb *tcp)
376{
377	if (entering(tcp)) {
378		printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
379		tprintf(", %lu", tcp->u_arg[1]);
380	}
381	return 0;
382}
383
384int
385sys_exit(struct tcb *tcp)
386{
387	if (exiting(tcp)) {
388		fprintf(stderr, "_exit returned!\n");
389		return -1;
390	}
391	/* special case: we stop tracing this process, finish line now */
392	tprintf("%ld) ", tcp->u_arg[0]);
393	tabto();
394	tprints("= ?\n");
395	printing_tcp = NULL;
396	return 0;
397}
398
399/* defines copied from linux/sched.h since we can't include that
400 * ourselves (it conflicts with *lots* of libc includes)
401 */
402#define CSIGNAL         0x000000ff      /* signal mask to be sent at exit */
403#define CLONE_VM        0x00000100      /* set if VM shared between processes */
404#define CLONE_FS        0x00000200      /* set if fs info shared between processes */
405#define CLONE_FILES     0x00000400      /* set if open files shared between processes */
406#define CLONE_SIGHAND   0x00000800      /* set if signal handlers shared */
407#define CLONE_IDLETASK  0x00001000      /* kernel-only flag */
408#define CLONE_PTRACE    0x00002000      /* set if we want to let tracing continue on the child too */
409#define CLONE_VFORK     0x00004000      /* set if the parent wants the child to wake it up on mm_release */
410#define CLONE_PARENT    0x00008000      /* set if we want to have the same parent as the cloner */
411#define CLONE_THREAD	0x00010000	/* Same thread group? */
412#define CLONE_NEWNS	0x00020000	/* New namespace group? */
413#define CLONE_SYSVSEM	0x00040000	/* share system V SEM_UNDO semantics */
414#define CLONE_SETTLS	0x00080000	/* create a new TLS for the child */
415#define CLONE_PARENT_SETTID	0x00100000	/* set the TID in the parent */
416#define CLONE_CHILD_CLEARTID	0x00200000	/* clear the TID in the child */
417#define CLONE_UNTRACED		0x00800000	/* set if the tracing process can't force CLONE_PTRACE on this clone */
418#define CLONE_CHILD_SETTID	0x01000000	/* set the TID in the child */
419#define CLONE_STOPPED		0x02000000	/* Start in stopped state */
420#define CLONE_NEWUTS		0x04000000	/* New utsname group? */
421#define CLONE_NEWIPC		0x08000000	/* New ipcs */
422#define CLONE_NEWUSER		0x10000000	/* New user namespace */
423#define CLONE_NEWPID		0x20000000	/* New pid namespace */
424#define CLONE_NEWNET		0x40000000	/* New network namespace */
425#define CLONE_IO		0x80000000	/* Clone io context */
426
427static const struct xlat clone_flags[] = {
428    { CLONE_VM,		"CLONE_VM"	},
429    { CLONE_FS,		"CLONE_FS"	},
430    { CLONE_FILES,	"CLONE_FILES"	},
431    { CLONE_SIGHAND,	"CLONE_SIGHAND"	},
432    { CLONE_IDLETASK,	"CLONE_IDLETASK"},
433    { CLONE_PTRACE,	"CLONE_PTRACE"	},
434    { CLONE_VFORK,	"CLONE_VFORK"	},
435    { CLONE_PARENT,	"CLONE_PARENT"	},
436    { CLONE_THREAD,	"CLONE_THREAD" },
437    { CLONE_NEWNS,	"CLONE_NEWNS" },
438    { CLONE_SYSVSEM,	"CLONE_SYSVSEM" },
439    { CLONE_SETTLS,	"CLONE_SETTLS" },
440    { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
441    { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
442    { CLONE_UNTRACED,	"CLONE_UNTRACED" },
443    { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
444    { CLONE_STOPPED,	"CLONE_STOPPED" },
445    { CLONE_NEWUTS,	"CLONE_NEWUTS" },
446    { CLONE_NEWIPC,	"CLONE_NEWIPC" },
447    { CLONE_NEWUSER,	"CLONE_NEWUSER" },
448    { CLONE_NEWPID,	"CLONE_NEWPID" },
449    { CLONE_NEWNET,	"CLONE_NEWNET" },
450    { CLONE_IO,		"CLONE_IO" },
451    { 0,		NULL		},
452};
453
454# ifdef I386
455#  include <asm/ldt.h>
456#   ifdef HAVE_STRUCT_USER_DESC
457#    define modify_ldt_ldt_s user_desc
458#   endif
459extern void print_ldt_entry();
460# endif
461
462# if defined IA64
463#  define ARG_FLAGS	0
464#  define ARG_STACK	1
465#  define ARG_STACKSIZE	(tcp->scno == SYS_clone2 ? 2 : -1)
466#  define ARG_PTID	(tcp->scno == SYS_clone2 ? 3 : 2)
467#  define ARG_CTID	(tcp->scno == SYS_clone2 ? 4 : 3)
468#  define ARG_TLS	(tcp->scno == SYS_clone2 ? 5 : 4)
469# elif defined S390 || defined S390X || defined CRISV10 || defined CRISV32
470#  define ARG_STACK	0
471#  define ARG_FLAGS	1
472#  define ARG_PTID	2
473#  define ARG_CTID	3
474#  define ARG_TLS	4
475# elif defined X86_64 || defined ALPHA
476#  define ARG_FLAGS	0
477#  define ARG_STACK	1
478#  define ARG_PTID	2
479#  define ARG_CTID	3
480#  define ARG_TLS	4
481# else
482#  define ARG_FLAGS	0
483#  define ARG_STACK	1
484#  define ARG_PTID	2
485#  define ARG_TLS	3
486#  define ARG_CTID	4
487# endif
488
489int
490sys_clone(struct tcb *tcp)
491{
492	if (exiting(tcp)) {
493		const char *sep = "|";
494		unsigned long flags = tcp->u_arg[ARG_FLAGS];
495		tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
496# ifdef ARG_STACKSIZE
497		if (ARG_STACKSIZE != -1)
498			tprintf("stack_size=%#lx, ",
499				tcp->u_arg[ARG_STACKSIZE]);
500# endif
501		tprints("flags=");
502		if (!printflags(clone_flags, flags &~ CSIGNAL, NULL))
503			sep = "";
504		if ((flags & CSIGNAL) != 0)
505			tprintf("%s%s", sep, signame(flags & CSIGNAL));
506		if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
507			      |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
508			return 0;
509		if (flags & CLONE_PARENT_SETTID)
510			tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
511		if (flags & CLONE_SETTLS) {
512# ifdef I386
513			struct modify_ldt_ldt_s copy;
514			if (umove(tcp, tcp->u_arg[ARG_TLS], &copy) != -1) {
515				tprintf(", {entry_number:%d, ",
516					copy.entry_number);
517				if (!verbose(tcp))
518					tprints("...}");
519				else
520					print_ldt_entry(&copy);
521			}
522			else
523# endif
524				tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
525		}
526		if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
527			tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
528	}
529	return 0;
530}
531
532int
533sys_unshare(struct tcb *tcp)
534{
535	if (entering(tcp))
536		printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
537	return 0;
538}
539
540int
541sys_fork(struct tcb *tcp)
542{
543	if (exiting(tcp))
544		return RVAL_UDECIMAL;
545	return 0;
546}
547
548int
549change_syscall(struct tcb *tcp, int new)
550{
551#if defined(I386)
552	/* Attempt to make vfork into fork, which we can follow. */
553	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
554		return -1;
555	return 0;
556#elif defined(X86_64)
557	/* Attempt to make vfork into fork, which we can follow. */
558	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
559		return -1;
560	return 0;
561#elif defined(POWERPC)
562	if (ptrace(PTRACE_POKEUSER, tcp->pid,
563		   (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
564		return -1;
565	return 0;
566#elif defined(S390) || defined(S390X)
567	/* s390 linux after 2.4.7 has a hook in entry.S to allow this */
568	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new) < 0)
569		return -1;
570	return 0;
571#elif defined(M68K)
572	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new) < 0)
573		return -1;
574	return 0;
575#elif defined(SPARC) || defined(SPARC64)
576	struct pt_regs regs;
577	if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0) < 0)
578		return -1;
579	regs.u_regs[U_REG_G1] = new;
580	if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0) < 0)
581		return -1;
582	return 0;
583#elif defined(MIPS)
584	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new) < 0)
585		return -1;
586	return 0;
587#elif defined(ALPHA)
588	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new) < 0)
589		return -1;
590	return 0;
591#elif defined(AVR32)
592	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R8), new) < 0)
593		return -1;
594	return 0;
595#elif defined(BFIN)
596	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_P0), new) < 0)
597		return -1;
598	return 0;
599#elif defined(IA64)
600	if (ia32) {
601		switch (new) {
602		case 2:
603			break;	/* x86 SYS_fork */
604		case SYS_clone:
605			new = 120;
606			break;
607		default:
608			fprintf(stderr, "%s: unexpected syscall %d\n",
609				__FUNCTION__, new);
610			return -1;
611		}
612		if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new) < 0)
613			return -1;
614	} else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new) < 0)
615		return -1;
616	return 0;
617#elif defined(HPPA)
618	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new) < 0)
619		return -1;
620	return 0;
621#elif defined(SH)
622	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new) < 0)
623		return -1;
624	return 0;
625#elif defined(SH64)
626	/* Top half of reg encodes the no. of args n as 0x1n.
627	   Assume 0 args as kernel never actually checks... */
628	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
629				0x100000 | new) < 0)
630		return -1;
631	return 0;
632#elif defined(CRISV10) || defined(CRISV32)
633	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_R9), new) < 0)
634		return -1;
635	return 0;
636#elif defined(ARM)
637	/* Some kernels support this, some (pre-2.6.16 or so) don't.  */
638# ifndef PTRACE_SET_SYSCALL
639#  define PTRACE_SET_SYSCALL 23
640# endif
641
642	if (ptrace(PTRACE_SET_SYSCALL, tcp->pid, 0, new & 0xffff) != 0)
643		return -1;
644
645	return 0;
646#elif defined(TILE)
647	if (ptrace(PTRACE_POKEUSER, tcp->pid,
648		   (char*)PTREGS_OFFSET_REG(0),
649		   new) != 0)
650		return -1;
651	return 0;
652#elif defined(MICROBLAZE)
653	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR(0)), new) < 0)
654		return -1;
655	return 0;
656#else
657#warning Do not know how to handle change_syscall for this architecture
658#endif /* architecture */
659	return -1;
660}
661
662int
663internal_fork(struct tcb *tcp)
664{
665	if ((ptrace_setoptions
666	    & (PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK))
667	   == (PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK))
668		return 0;
669
670	if (!followfork)
671		return 0;
672
673	if (entering(tcp)) {
674		/*
675		 * We won't see the new child if clone is called with
676		 * CLONE_UNTRACED, so we keep the same logic with that option
677		 * and don't trace it.
678		 */
679		if ((sysent[tcp->scno].sys_func == sys_clone) &&
680		    (tcp->u_arg[ARG_FLAGS] & CLONE_UNTRACED))
681			return 0;
682		setbpt(tcp);
683	} else {
684		if (tcp->flags & TCB_BPTSET)
685			clearbpt(tcp);
686	}
687	return 0;
688}
689
690int
691sys_vfork(struct tcb *tcp)
692{
693	if (exiting(tcp))
694		return RVAL_UDECIMAL;
695	return 0;
696}
697
698int sys_getuid(struct tcb *tcp)
699{
700	if (exiting(tcp))
701		tcp->u_rval = (uid_t) tcp->u_rval;
702	return RVAL_UDECIMAL;
703}
704
705int sys_setfsuid(struct tcb *tcp)
706{
707	if (entering(tcp))
708		tprintf("%u", (uid_t) tcp->u_arg[0]);
709	else
710		tcp->u_rval = (uid_t) tcp->u_rval;
711	return RVAL_UDECIMAL;
712}
713
714int
715sys_setuid(struct tcb *tcp)
716{
717	if (entering(tcp)) {
718		tprintf("%u", (uid_t) tcp->u_arg[0]);
719	}
720	return 0;
721}
722
723int
724sys_getresuid(struct tcb *tcp)
725{
726	if (exiting(tcp)) {
727		__kernel_uid_t uid;
728		if (syserror(tcp))
729			tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
730				tcp->u_arg[1], tcp->u_arg[2]);
731		else {
732			if (umove(tcp, tcp->u_arg[0], &uid) < 0)
733				tprintf("%#lx, ", tcp->u_arg[0]);
734			else
735				tprintf("[%lu], ", (unsigned long) uid);
736			if (umove(tcp, tcp->u_arg[1], &uid) < 0)
737				tprintf("%#lx, ", tcp->u_arg[1]);
738			else
739				tprintf("[%lu], ", (unsigned long) uid);
740			if (umove(tcp, tcp->u_arg[2], &uid) < 0)
741				tprintf("%#lx", tcp->u_arg[2]);
742			else
743				tprintf("[%lu]", (unsigned long) uid);
744		}
745	}
746	return 0;
747}
748
749int
750sys_setreuid(struct tcb *tcp)
751{
752	if (entering(tcp)) {
753		printuid("", tcp->u_arg[0]);
754		printuid(", ", tcp->u_arg[1]);
755	}
756	return 0;
757}
758
759int
760sys_setresuid(struct tcb *tcp)
761{
762	if (entering(tcp)) {
763		printuid("", tcp->u_arg[0]);
764		printuid(", ", tcp->u_arg[1]);
765		printuid(", ", tcp->u_arg[2]);
766	}
767	return 0;
768}
769
770int
771sys_setgroups(struct tcb *tcp)
772{
773	if (entering(tcp)) {
774		unsigned long len, size, start, cur, end, abbrev_end;
775		GETGROUPS_T gid;
776		int failed = 0;
777
778		len = tcp->u_arg[0];
779		tprintf("%lu, ", len);
780		if (len == 0) {
781			tprints("[]");
782			return 0;
783		}
784		start = tcp->u_arg[1];
785		if (start == 0) {
786			tprints("NULL");
787			return 0;
788		}
789		size = len * sizeof(gid);
790		end = start + size;
791		if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
792			tprintf("%#lx", start);
793			return 0;
794		}
795		if (abbrev(tcp)) {
796			abbrev_end = start + max_strlen * sizeof(gid);
797			if (abbrev_end < start)
798				abbrev_end = end;
799		} else {
800			abbrev_end = end;
801		}
802		tprints("[");
803		for (cur = start; cur < end; cur += sizeof(gid)) {
804			if (cur > start)
805				tprints(", ");
806			if (cur >= abbrev_end) {
807				tprints("...");
808				break;
809			}
810			if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
811				tprints("?");
812				failed = 1;
813				break;
814			}
815			tprintf("%lu", (unsigned long) gid);
816		}
817		tprints("]");
818		if (failed)
819			tprintf(" %#lx", tcp->u_arg[1]);
820	}
821	return 0;
822}
823
824int
825sys_getgroups(struct tcb *tcp)
826{
827	unsigned long len;
828
829	if (entering(tcp)) {
830		len = tcp->u_arg[0];
831		tprintf("%lu, ", len);
832	} else {
833		unsigned long size, start, cur, end, abbrev_end;
834		GETGROUPS_T gid;
835		int failed = 0;
836
837		len = tcp->u_rval;
838		if (len == 0) {
839			tprints("[]");
840			return 0;
841		}
842		start = tcp->u_arg[1];
843		if (start == 0) {
844			tprints("NULL");
845			return 0;
846		}
847		if (tcp->u_arg[0] == 0) {
848			tprintf("%#lx", start);
849			return 0;
850		}
851		size = len * sizeof(gid);
852		end = start + size;
853		if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
854		    size / sizeof(gid) != len || end < start) {
855			tprintf("%#lx", start);
856			return 0;
857		}
858		if (abbrev(tcp)) {
859			abbrev_end = start + max_strlen * sizeof(gid);
860			if (abbrev_end < start)
861				abbrev_end = end;
862		} else {
863			abbrev_end = end;
864		}
865		tprints("[");
866		for (cur = start; cur < end; cur += sizeof(gid)) {
867			if (cur > start)
868				tprints(", ");
869			if (cur >= abbrev_end) {
870				tprints("...");
871				break;
872			}
873			if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
874				tprints("?");
875				failed = 1;
876				break;
877			}
878			tprintf("%lu", (unsigned long) gid);
879		}
880		tprints("]");
881		if (failed)
882			tprintf(" %#lx", tcp->u_arg[1]);
883	}
884	return 0;
885}
886
887int
888sys_setgroups32(struct tcb *tcp)
889{
890	if (entering(tcp)) {
891		unsigned long len, size, start, cur, end, abbrev_end;
892		GETGROUPS32_T gid;
893		int failed = 0;
894
895		len = tcp->u_arg[0];
896		tprintf("%lu, ", len);
897		if (len == 0) {
898			tprints("[]");
899			return 0;
900		}
901		start = tcp->u_arg[1];
902		if (start == 0) {
903			tprints("NULL");
904			return 0;
905		}
906		size = len * sizeof(gid);
907		end = start + size;
908		if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
909			tprintf("%#lx", start);
910			return 0;
911		}
912		if (abbrev(tcp)) {
913			abbrev_end = start + max_strlen * sizeof(gid);
914			if (abbrev_end < start)
915				abbrev_end = end;
916		} else {
917			abbrev_end = end;
918		}
919		tprints("[");
920		for (cur = start; cur < end; cur += sizeof(gid)) {
921			if (cur > start)
922				tprints(", ");
923			if (cur >= abbrev_end) {
924				tprints("...");
925				break;
926			}
927			if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
928				tprints("?");
929				failed = 1;
930				break;
931			}
932			tprintf("%lu", (unsigned long) gid);
933		}
934		tprints("]");
935		if (failed)
936			tprintf(" %#lx", tcp->u_arg[1]);
937	}
938	return 0;
939}
940
941int
942sys_getgroups32(struct tcb *tcp)
943{
944	unsigned long len;
945
946	if (entering(tcp)) {
947		len = tcp->u_arg[0];
948		tprintf("%lu, ", len);
949	} else {
950		unsigned long size, start, cur, end, abbrev_end;
951		GETGROUPS32_T gid;
952		int failed = 0;
953
954		len = tcp->u_rval;
955		if (len == 0) {
956			tprints("[]");
957			return 0;
958		}
959		start = tcp->u_arg[1];
960		if (start == 0) {
961			tprints("NULL");
962			return 0;
963		}
964		size = len * sizeof(gid);
965		end = start + size;
966		if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
967		    size / sizeof(gid) != len || end < start) {
968			tprintf("%#lx", start);
969			return 0;
970		}
971		if (abbrev(tcp)) {
972			abbrev_end = start + max_strlen * sizeof(gid);
973			if (abbrev_end < start)
974				abbrev_end = end;
975		} else {
976			abbrev_end = end;
977		}
978		tprints("[");
979		for (cur = start; cur < end; cur += sizeof(gid)) {
980			if (cur > start)
981				tprints(", ");
982			if (cur >= abbrev_end) {
983				tprints("...");
984				break;
985			}
986			if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
987				tprints("?");
988				failed = 1;
989				break;
990			}
991			tprintf("%lu", (unsigned long) gid);
992		}
993		tprints("]");
994		if (failed)
995			tprintf(" %#lx", tcp->u_arg[1]);
996	}
997	return 0;
998}
999
1000static void
1001printargv(struct tcb *tcp, long addr)
1002{
1003	union {
1004		unsigned int p32;
1005		unsigned long p64;
1006		char data[sizeof(long)];
1007	} cp;
1008	const char *sep;
1009	int n = 0;
1010	unsigned wordsize = personality_wordsize[current_personality];
1011
1012	cp.p64 = 1;
1013	for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1014		if (umoven(tcp, addr, wordsize, cp.data) < 0) {
1015			tprintf("%#lx", addr);
1016			return;
1017		}
1018		if (wordsize == 4)
1019			cp.p64 = cp.p32;
1020		if (cp.p64 == 0)
1021			break;
1022		tprints(sep);
1023		printstr(tcp, cp.p64, -1);
1024		addr += wordsize;
1025	}
1026	if (cp.p64)
1027		tprintf("%s...", sep);
1028}
1029
1030static void
1031printargc(const char *fmt, struct tcb *tcp, long addr)
1032{
1033	int count;
1034	char *cp;
1035
1036	for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1037		addr += sizeof(char *);
1038	}
1039	tprintf(fmt, count, count == 1 ? "" : "s");
1040}
1041
1042#if defined(SPARC) || defined(SPARC64)
1043int
1044sys_execv(struct tcb *tcp)
1045{
1046	if (entering(tcp)) {
1047		printpath(tcp, tcp->u_arg[0]);
1048		if (!verbose(tcp))
1049			tprintf(", %#lx", tcp->u_arg[1]);
1050		else {
1051			tprints(", [");
1052			printargv(tcp, tcp->u_arg[1]);
1053			tprints("]");
1054		}
1055	}
1056	return 0;
1057}
1058#endif
1059
1060int
1061sys_execve(struct tcb *tcp)
1062{
1063	if (entering(tcp)) {
1064		printpath(tcp, tcp->u_arg[0]);
1065		if (!verbose(tcp))
1066			tprintf(", %#lx", tcp->u_arg[1]);
1067		else {
1068			tprints(", [");
1069			printargv(tcp, tcp->u_arg[1]);
1070			tprints("]");
1071		}
1072		if (!verbose(tcp))
1073			tprintf(", %#lx", tcp->u_arg[2]);
1074		else if (abbrev(tcp))
1075			printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1076		else {
1077			tprints(", [");
1078			printargv(tcp, tcp->u_arg[2]);
1079			tprints("]");
1080		}
1081	}
1082	return 0;
1083}
1084
1085#if defined(TCB_WAITEXECVE)
1086int
1087internal_exec(struct tcb *tcp)
1088{
1089	if (exiting(tcp) && syserror(tcp))
1090		tcp->flags &= ~TCB_WAITEXECVE;
1091	else {
1092		/* Maybe we have post-execve SIGTRAP suppressed? */
1093		if (!(ptrace_setoptions & PTRACE_O_TRACEEXEC))
1094			tcp->flags |= TCB_WAITEXECVE; /* no */
1095	}
1096	return 0;
1097}
1098#endif
1099
1100#ifndef __WNOTHREAD
1101#define __WNOTHREAD	0x20000000
1102#endif
1103#ifndef __WALL
1104#define __WALL		0x40000000
1105#endif
1106#ifndef __WCLONE
1107#define __WCLONE	0x80000000
1108#endif
1109
1110static const struct xlat wait4_options[] = {
1111	{ WNOHANG,	"WNOHANG"	},
1112#ifndef WSTOPPED
1113	{ WUNTRACED,	"WUNTRACED"	},
1114#endif
1115#ifdef WEXITED
1116	{ WEXITED,	"WEXITED"	},
1117#endif
1118#ifdef WTRAPPED
1119	{ WTRAPPED,	"WTRAPPED"	},
1120#endif
1121#ifdef WSTOPPED
1122	{ WSTOPPED,	"WSTOPPED"	},
1123#endif
1124#ifdef WCONTINUED
1125	{ WCONTINUED,	"WCONTINUED"	},
1126#endif
1127#ifdef WNOWAIT
1128	{ WNOWAIT,	"WNOWAIT"	},
1129#endif
1130#ifdef __WCLONE
1131	{ __WCLONE,	"__WCLONE"	},
1132#endif
1133#ifdef __WALL
1134	{ __WALL,	"__WALL"	},
1135#endif
1136#ifdef __WNOTHREAD
1137	{ __WNOTHREAD,	"__WNOTHREAD"	},
1138#endif
1139	{ 0,		NULL		},
1140};
1141
1142#if !defined WCOREFLAG && defined WCOREFLG
1143# define WCOREFLAG WCOREFLG
1144#endif
1145#ifndef WCOREFLAG
1146# define WCOREFLAG 0x80
1147#endif
1148#ifndef WCOREDUMP
1149# define WCOREDUMP(status) ((status) & 0200)
1150#endif
1151
1152#ifndef W_STOPCODE
1153#define W_STOPCODE(sig)		((sig) << 8 | 0x7f)
1154#endif
1155#ifndef W_EXITCODE
1156#define W_EXITCODE(ret, sig)	((ret) << 8 | (sig))
1157#endif
1158
1159static int
1160printstatus(int status)
1161{
1162	int exited = 0;
1163
1164	/*
1165	 * Here is a tricky presentation problem.  This solution
1166	 * is still not entirely satisfactory but since there
1167	 * are no wait status constructors it will have to do.
1168	 */
1169	if (WIFSTOPPED(status)) {
1170		tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1171			signame(WSTOPSIG(status)));
1172		status &= ~W_STOPCODE(WSTOPSIG(status));
1173	}
1174	else if (WIFSIGNALED(status)) {
1175		tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1176			signame(WTERMSIG(status)),
1177			WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1178		status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1179	}
1180	else if (WIFEXITED(status)) {
1181		tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1182			WEXITSTATUS(status));
1183		exited = 1;
1184		status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1185	}
1186	else {
1187		tprintf("[%#x]", status);
1188		return 0;
1189	}
1190
1191	if (status == 0)
1192		tprints("]");
1193	else
1194		tprintf(" | %#x]", status);
1195
1196	return exited;
1197}
1198
1199static int
1200printwaitn(struct tcb *tcp, int n, int bitness)
1201{
1202	int status;
1203
1204	if (entering(tcp)) {
1205		/* On Linux, kernel-side pid_t is typedef'ed to int
1206		 * on all arches. Also, glibc-2.8 truncates wait3 and wait4
1207		 * pid argument to int on 64bit arches, producing,
1208		 * for example, wait4(4294967295, ...) instead of -1
1209		 * in strace. We have to use int here, not long.
1210		 */
1211		int pid = tcp->u_arg[0];
1212		tprintf("%d, ", pid);
1213	} else {
1214		/* status */
1215		if (!tcp->u_arg[1])
1216			tprints("NULL");
1217		else if (syserror(tcp) || tcp->u_rval == 0)
1218			tprintf("%#lx", tcp->u_arg[1]);
1219		else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1220			tprints("[?]");
1221		else
1222			printstatus(status);
1223		/* options */
1224		tprints(", ");
1225		printflags(wait4_options, tcp->u_arg[2], "W???");
1226		if (n == 4) {
1227			tprints(", ");
1228			/* usage */
1229			if (!tcp->u_arg[3])
1230				tprints("NULL");
1231			else if (tcp->u_rval > 0) {
1232#ifdef ALPHA
1233				if (bitness)
1234					printrusage32(tcp, tcp->u_arg[3]);
1235				else
1236#endif
1237					printrusage(tcp, tcp->u_arg[3]);
1238			}
1239			else
1240				tprintf("%#lx", tcp->u_arg[3]);
1241		}
1242	}
1243	return 0;
1244}
1245
1246int
1247sys_waitpid(struct tcb *tcp)
1248{
1249	return printwaitn(tcp, 3, 0);
1250}
1251
1252int
1253sys_wait4(struct tcb *tcp)
1254{
1255	return printwaitn(tcp, 4, 0);
1256}
1257
1258#ifdef ALPHA
1259int
1260sys_osf_wait4(struct tcb *tcp)
1261{
1262	return printwaitn(tcp, 4, 1);
1263}
1264#endif
1265
1266static const struct xlat waitid_types[] = {
1267	{ P_PID,	"P_PID"		},
1268#ifdef P_PPID
1269	{ P_PPID,	"P_PPID"	},
1270#endif
1271	{ P_PGID,	"P_PGID"	},
1272#ifdef P_SID
1273	{ P_SID,	"P_SID"		},
1274#endif
1275#ifdef P_CID
1276	{ P_CID,	"P_CID"		},
1277#endif
1278#ifdef P_UID
1279	{ P_UID,	"P_UID"		},
1280#endif
1281#ifdef P_GID
1282	{ P_GID,	"P_GID"		},
1283#endif
1284	{ P_ALL,	"P_ALL"		},
1285#ifdef P_LWPID
1286	{ P_LWPID,	"P_LWPID"	},
1287#endif
1288	{ 0,		NULL		},
1289};
1290
1291int
1292sys_waitid(struct tcb *tcp)
1293{
1294	siginfo_t si;
1295
1296	if (entering(tcp)) {
1297		printxval(waitid_types, tcp->u_arg[0], "P_???");
1298		tprintf(", %ld, ", tcp->u_arg[1]);
1299	}
1300	else {
1301		/* siginfo */
1302		if (!tcp->u_arg[2])
1303			tprints("NULL");
1304		else if (syserror(tcp))
1305			tprintf("%#lx", tcp->u_arg[2]);
1306		else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1307			tprints("{???}");
1308		else
1309			printsiginfo(&si, verbose(tcp));
1310		/* options */
1311		tprints(", ");
1312		printflags(wait4_options, tcp->u_arg[3], "W???");
1313		if (tcp->u_nargs > 4) {
1314			/* usage */
1315			tprints(", ");
1316			if (!tcp->u_arg[4])
1317				tprints("NULL");
1318			else if (tcp->u_error)
1319				tprintf("%#lx", tcp->u_arg[4]);
1320			else
1321				printrusage(tcp, tcp->u_arg[4]);
1322		}
1323	}
1324	return 0;
1325}
1326
1327int
1328sys_uname(struct tcb *tcp)
1329{
1330	struct utsname uname;
1331
1332	if (exiting(tcp)) {
1333		if (syserror(tcp) || !verbose(tcp))
1334			tprintf("%#lx", tcp->u_arg[0]);
1335		else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1336			tprints("{...}");
1337		else if (!abbrev(tcp)) {
1338
1339			tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1340				uname.sysname, uname.nodename);
1341			tprintf("release=\"%s\", version=\"%s\", ",
1342				uname.release, uname.version);
1343			tprintf("machine=\"%s\"", uname.machine);
1344#ifndef __GLIBC__
1345			tprintf(", domainname=\"%s\"", uname.domainname);
1346#endif
1347			tprints("}");
1348		}
1349		else
1350			tprintf("{sys=\"%s\", node=\"%s\", ...}",
1351				uname.sysname, uname.nodename);
1352	}
1353	return 0;
1354}
1355
1356static const struct xlat ptrace_cmds[] = {
1357	{ PTRACE_TRACEME,	"PTRACE_TRACEME"	},
1358	{ PTRACE_PEEKTEXT,	"PTRACE_PEEKTEXT"	},
1359	{ PTRACE_PEEKDATA,	"PTRACE_PEEKDATA"	},
1360	{ PTRACE_PEEKUSER,	"PTRACE_PEEKUSER"	},
1361	{ PTRACE_POKETEXT,	"PTRACE_POKETEXT"	},
1362	{ PTRACE_POKEDATA,	"PTRACE_POKEDATA"	},
1363	{ PTRACE_POKEUSER,	"PTRACE_POKEUSER"	},
1364	{ PTRACE_CONT,		"PTRACE_CONT"		},
1365	{ PTRACE_KILL,		"PTRACE_KILL"		},
1366	{ PTRACE_SINGLESTEP,	"PTRACE_SINGLESTEP"	},
1367	{ PTRACE_ATTACH,	"PTRACE_ATTACH"		},
1368	{ PTRACE_DETACH,	"PTRACE_DETACH"		},
1369#  ifdef PTRACE_GETREGS
1370	{ PTRACE_GETREGS,	"PTRACE_GETREGS"	},
1371#  endif
1372#  ifdef PTRACE_SETREGS
1373	{ PTRACE_SETREGS,	"PTRACE_SETREGS"	},
1374#  endif
1375#  ifdef PTRACE_GETFPREGS
1376	{ PTRACE_GETFPREGS,	"PTRACE_GETFPREGS"	},
1377#  endif
1378#  ifdef PTRACE_SETFPREGS
1379	{ PTRACE_SETFPREGS,	"PTRACE_SETFPREGS"	},
1380#  endif
1381#  ifdef PTRACE_GETFPXREGS
1382	{ PTRACE_GETFPXREGS,	"PTRACE_GETFPXREGS"	},
1383#  endif
1384#  ifdef PTRACE_SETFPXREGS
1385	{ PTRACE_SETFPXREGS,	"PTRACE_SETFPXREGS"	},
1386#  endif
1387#  ifdef PTRACE_GETVRREGS
1388	{ PTRACE_GETVRREGS,	"PTRACE_GETVRREGS"	},
1389#  endif
1390#  ifdef PTRACE_SETVRREGS
1391	{ PTRACE_SETVRREGS,	"PTRACE_SETVRREGS"	},
1392#  endif
1393#  ifdef PTRACE_SETOPTIONS
1394	{ PTRACE_SETOPTIONS,	"PTRACE_SETOPTIONS"	},
1395#  endif
1396#  ifdef PTRACE_GETEVENTMSG
1397	{ PTRACE_GETEVENTMSG,	"PTRACE_GETEVENTMSG"	},
1398#  endif
1399#  ifdef PTRACE_GETSIGINFO
1400	{ PTRACE_GETSIGINFO,	"PTRACE_GETSIGINFO"	},
1401#  endif
1402#  ifdef PTRACE_SETSIGINFO
1403	{ PTRACE_SETSIGINFO,	"PTRACE_SETSIGINFO"	},
1404#  endif
1405#  ifdef PTRACE_GETREGSET
1406	{ PTRACE_GETREGSET,	"PTRACE_GETREGSET"	},
1407#  endif
1408#  ifdef PTRACE_SETREGSET
1409	{ PTRACE_SETREGSET,	"PTRACE_SETREGSET"	},
1410#  endif
1411#  ifdef PTRACE_SET_SYSCALL
1412	{ PTRACE_SET_SYSCALL,	"PTRACE_SET_SYSCALL"	},
1413#  endif
1414#  ifdef PTRACE_SEIZE
1415	{ PTRACE_SEIZE,		"PTRACE_SEIZE"		},
1416#  endif
1417#  ifdef PTRACE_INTERRUPT
1418	{ PTRACE_INTERRUPT,	"PTRACE_INTERRUPT"	},
1419#  endif
1420#  ifdef PTRACE_LISTEN
1421	{ PTRACE_LISTEN,	"PTRACE_LISTEN"		},
1422#  endif
1423	{ PTRACE_SYSCALL,	"PTRACE_SYSCALL"	},
1424
1425	{ 0,			NULL			},
1426};
1427
1428#  ifdef PTRACE_SETOPTIONS
1429static const struct xlat ptrace_setoptions_flags[] = {
1430#   ifdef PTRACE_O_TRACESYSGOOD
1431	{ PTRACE_O_TRACESYSGOOD,"PTRACE_O_TRACESYSGOOD"	},
1432#   endif
1433#   ifdef PTRACE_O_TRACEFORK
1434	{ PTRACE_O_TRACEFORK,	"PTRACE_O_TRACEFORK"	},
1435#   endif
1436#   ifdef PTRACE_O_TRACEVFORK
1437	{ PTRACE_O_TRACEVFORK,	"PTRACE_O_TRACEVFORK"	},
1438#   endif
1439#   ifdef PTRACE_O_TRACECLONE
1440	{ PTRACE_O_TRACECLONE,	"PTRACE_O_TRACECLONE"	},
1441#   endif
1442#   ifdef PTRACE_O_TRACEEXEC
1443	{ PTRACE_O_TRACEEXEC,	"PTRACE_O_TRACEEXEC"	},
1444#   endif
1445#   ifdef PTRACE_O_TRACEVFORKDONE
1446	{ PTRACE_O_TRACEVFORKDONE,"PTRACE_O_TRACEVFORKDONE"},
1447#   endif
1448#   ifdef PTRACE_O_TRACEEXIT
1449	{ PTRACE_O_TRACEEXIT,	"PTRACE_O_TRACEEXIT"	},
1450#   endif
1451	{ 0,			NULL			},
1452};
1453#  endif /* PTRACE_SETOPTIONS */
1454
1455const struct xlat struct_user_offsets[] = {
1456#   if defined(S390) || defined(S390X)
1457	{ PT_PSWMASK,		"psw_mask"				},
1458	{ PT_PSWADDR,		"psw_addr"				},
1459	{ PT_GPR0,		"gpr0"					},
1460	{ PT_GPR1,		"gpr1"					},
1461	{ PT_GPR2,		"gpr2"					},
1462	{ PT_GPR3,		"gpr3"					},
1463	{ PT_GPR4,		"gpr4"					},
1464	{ PT_GPR5,		"gpr5"					},
1465	{ PT_GPR6,		"gpr6"					},
1466	{ PT_GPR7,		"gpr7"					},
1467	{ PT_GPR8,		"gpr8"					},
1468	{ PT_GPR9,		"gpr9"					},
1469	{ PT_GPR10,		"gpr10"					},
1470	{ PT_GPR11,		"gpr11"					},
1471	{ PT_GPR12,		"gpr12"					},
1472	{ PT_GPR13,		"gpr13"					},
1473	{ PT_GPR14,		"gpr14"					},
1474	{ PT_GPR15,		"gpr15"					},
1475	{ PT_ACR0,		"acr0"					},
1476	{ PT_ACR1,		"acr1"					},
1477	{ PT_ACR2,		"acr2"					},
1478	{ PT_ACR3,		"acr3"					},
1479	{ PT_ACR4,		"acr4"					},
1480	{ PT_ACR5,		"acr5"					},
1481	{ PT_ACR6,		"acr6"					},
1482	{ PT_ACR7,		"acr7"					},
1483	{ PT_ACR8,		"acr8"					},
1484	{ PT_ACR9,		"acr9"					},
1485	{ PT_ACR10,		"acr10"					},
1486	{ PT_ACR11,		"acr11"					},
1487	{ PT_ACR12,		"acr12"					},
1488	{ PT_ACR13,		"acr13"					},
1489	{ PT_ACR14,		"acr14"					},
1490	{ PT_ACR15,		"acr15"					},
1491	{ PT_ORIGGPR2,		"orig_gpr2"				},
1492	{ PT_FPC,		"fpc"					},
1493#    if defined(S390)
1494	{ PT_FPR0_HI,		"fpr0.hi"				},
1495	{ PT_FPR0_LO,		"fpr0.lo"				},
1496	{ PT_FPR1_HI,		"fpr1.hi"				},
1497	{ PT_FPR1_LO,		"fpr1.lo"				},
1498	{ PT_FPR2_HI,		"fpr2.hi"				},
1499	{ PT_FPR2_LO,		"fpr2.lo"				},
1500	{ PT_FPR3_HI,		"fpr3.hi"				},
1501	{ PT_FPR3_LO,		"fpr3.lo"				},
1502	{ PT_FPR4_HI,		"fpr4.hi"				},
1503	{ PT_FPR4_LO,		"fpr4.lo"				},
1504	{ PT_FPR5_HI,		"fpr5.hi"				},
1505	{ PT_FPR5_LO,		"fpr5.lo"				},
1506	{ PT_FPR6_HI,		"fpr6.hi"				},
1507	{ PT_FPR6_LO,		"fpr6.lo"				},
1508	{ PT_FPR7_HI,		"fpr7.hi"				},
1509	{ PT_FPR7_LO,		"fpr7.lo"				},
1510	{ PT_FPR8_HI,		"fpr8.hi"				},
1511	{ PT_FPR8_LO,		"fpr8.lo"				},
1512	{ PT_FPR9_HI,		"fpr9.hi"				},
1513	{ PT_FPR9_LO,		"fpr9.lo"				},
1514	{ PT_FPR10_HI,		"fpr10.hi"				},
1515	{ PT_FPR10_LO,		"fpr10.lo"				},
1516	{ PT_FPR11_HI,		"fpr11.hi"				},
1517	{ PT_FPR11_LO,		"fpr11.lo"				},
1518	{ PT_FPR12_HI,		"fpr12.hi"				},
1519	{ PT_FPR12_LO,		"fpr12.lo"				},
1520	{ PT_FPR13_HI,		"fpr13.hi"				},
1521	{ PT_FPR13_LO,		"fpr13.lo"				},
1522	{ PT_FPR14_HI,		"fpr14.hi"				},
1523	{ PT_FPR14_LO,		"fpr14.lo"				},
1524	{ PT_FPR15_HI,		"fpr15.hi"				},
1525	{ PT_FPR15_LO,		"fpr15.lo"				},
1526#    endif
1527#    if defined(S390X)
1528	{ PT_FPR0,		"fpr0"					},
1529	{ PT_FPR1,		"fpr1"					},
1530	{ PT_FPR2,		"fpr2"					},
1531	{ PT_FPR3,		"fpr3"					},
1532	{ PT_FPR4,		"fpr4"					},
1533	{ PT_FPR5,		"fpr5"					},
1534	{ PT_FPR6,		"fpr6"					},
1535	{ PT_FPR7,		"fpr7"					},
1536	{ PT_FPR8,		"fpr8"					},
1537	{ PT_FPR9,		"fpr9"					},
1538	{ PT_FPR10,		"fpr10"					},
1539	{ PT_FPR11,		"fpr11"					},
1540	{ PT_FPR12,		"fpr12"					},
1541	{ PT_FPR13,		"fpr13"					},
1542	{ PT_FPR14,		"fpr14"					},
1543	{ PT_FPR15,		"fpr15"					},
1544#    endif
1545	{ PT_CR_9,		"cr9"					},
1546	{ PT_CR_10,		"cr10"					},
1547	{ PT_CR_11,		"cr11"					},
1548	{ PT_IEEE_IP,		"ieee_exception_ip"			},
1549#   elif defined(SPARC)
1550	/* XXX No support for these offsets yet. */
1551#   elif defined(HPPA)
1552	/* XXX No support for these offsets yet. */
1553#   elif defined(POWERPC)
1554#    ifndef PT_ORIG_R3
1555#     define PT_ORIG_R3 34
1556#    endif
1557#    define REGSIZE (sizeof(unsigned long))
1558	{ REGSIZE*PT_R0,		"r0"				},
1559	{ REGSIZE*PT_R1,		"r1"				},
1560	{ REGSIZE*PT_R2,		"r2"				},
1561	{ REGSIZE*PT_R3,		"r3"				},
1562	{ REGSIZE*PT_R4,		"r4"				},
1563	{ REGSIZE*PT_R5,		"r5"				},
1564	{ REGSIZE*PT_R6,		"r6"				},
1565	{ REGSIZE*PT_R7,		"r7"				},
1566	{ REGSIZE*PT_R8,		"r8"				},
1567	{ REGSIZE*PT_R9,		"r9"				},
1568	{ REGSIZE*PT_R10,		"r10"				},
1569	{ REGSIZE*PT_R11,		"r11"				},
1570	{ REGSIZE*PT_R12,		"r12"				},
1571	{ REGSIZE*PT_R13,		"r13"				},
1572	{ REGSIZE*PT_R14,		"r14"				},
1573	{ REGSIZE*PT_R15,		"r15"				},
1574	{ REGSIZE*PT_R16,		"r16"				},
1575	{ REGSIZE*PT_R17,		"r17"				},
1576	{ REGSIZE*PT_R18,		"r18"				},
1577	{ REGSIZE*PT_R19,		"r19"				},
1578	{ REGSIZE*PT_R20,		"r20"				},
1579	{ REGSIZE*PT_R21,		"r21"				},
1580	{ REGSIZE*PT_R22,		"r22"				},
1581	{ REGSIZE*PT_R23,		"r23"				},
1582	{ REGSIZE*PT_R24,		"r24"				},
1583	{ REGSIZE*PT_R25,		"r25"				},
1584	{ REGSIZE*PT_R26,		"r26"				},
1585	{ REGSIZE*PT_R27,		"r27"				},
1586	{ REGSIZE*PT_R28,		"r28"				},
1587	{ REGSIZE*PT_R29,		"r29"				},
1588	{ REGSIZE*PT_R30,		"r30"				},
1589	{ REGSIZE*PT_R31,		"r31"				},
1590	{ REGSIZE*PT_NIP,		"NIP"				},
1591	{ REGSIZE*PT_MSR,		"MSR"				},
1592	{ REGSIZE*PT_ORIG_R3,		"ORIG_R3"			},
1593	{ REGSIZE*PT_CTR,		"CTR"				},
1594	{ REGSIZE*PT_LNK,		"LNK"				},
1595	{ REGSIZE*PT_XER,		"XER"				},
1596	{ REGSIZE*PT_CCR,		"CCR"				},
1597	{ REGSIZE*PT_FPR0,		"FPR0"				},
1598#    undef REGSIZE
1599#   elif defined(ALPHA)
1600	{ 0,			"r0"					},
1601	{ 1,			"r1"					},
1602	{ 2,			"r2"					},
1603	{ 3,			"r3"					},
1604	{ 4,			"r4"					},
1605	{ 5,			"r5"					},
1606	{ 6,			"r6"					},
1607	{ 7,			"r7"					},
1608	{ 8,			"r8"					},
1609	{ 9,			"r9"					},
1610	{ 10,			"r10"					},
1611	{ 11,			"r11"					},
1612	{ 12,			"r12"					},
1613	{ 13,			"r13"					},
1614	{ 14,			"r14"					},
1615	{ 15,			"r15"					},
1616	{ 16,			"r16"					},
1617	{ 17,			"r17"					},
1618	{ 18,			"r18"					},
1619	{ 19,			"r19"					},
1620	{ 20,			"r20"					},
1621	{ 21,			"r21"					},
1622	{ 22,			"r22"					},
1623	{ 23,			"r23"					},
1624	{ 24,			"r24"					},
1625	{ 25,			"r25"					},
1626	{ 26,			"r26"					},
1627	{ 27,			"r27"					},
1628	{ 28,			"r28"					},
1629	{ 29,			"gp"					},
1630	{ 30,			"fp"					},
1631	{ 31,			"zero"					},
1632	{ 32,			"fp0"					},
1633	{ 33,			"fp"					},
1634	{ 34,			"fp2"					},
1635	{ 35,			"fp3"					},
1636	{ 36,			"fp4"					},
1637	{ 37,			"fp5"					},
1638	{ 38,			"fp6"					},
1639	{ 39,			"fp7"					},
1640	{ 40,			"fp8"					},
1641	{ 41,			"fp9"					},
1642	{ 42,			"fp10"					},
1643	{ 43,			"fp11"					},
1644	{ 44,			"fp12"					},
1645	{ 45,			"fp13"					},
1646	{ 46,			"fp14"					},
1647	{ 47,			"fp15"					},
1648	{ 48,			"fp16"					},
1649	{ 49,			"fp17"					},
1650	{ 50,			"fp18"					},
1651	{ 51,			"fp19"					},
1652	{ 52,			"fp20"					},
1653	{ 53,			"fp21"					},
1654	{ 54,			"fp22"					},
1655	{ 55,			"fp23"					},
1656	{ 56,			"fp24"					},
1657	{ 57,			"fp25"					},
1658	{ 58,			"fp26"					},
1659	{ 59,			"fp27"					},
1660	{ 60,			"fp28"					},
1661	{ 61,			"fp29"					},
1662	{ 62,			"fp30"					},
1663	{ 63,			"fp31"					},
1664	{ 64,			"pc"					},
1665#   elif defined(IA64)
1666	{ PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
1667	{ PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
1668	{ PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
1669	{ PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
1670	{ PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
1671	{ PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
1672	{ PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
1673	{ PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
1674	{ PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
1675	{ PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
1676	{ PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
1677	{ PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
1678	{ PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
1679	{ PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
1680	{ PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
1681	{ PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
1682	{ PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
1683	{ PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
1684	{ PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
1685	{ PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
1686	{ PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
1687	{ PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
1688	{ PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
1689	{ PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
1690	{ PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
1691	{ PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
1692	{ PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
1693	{ PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
1694	{ PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
1695	{ PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
1696	{ PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
1697	{ PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
1698	/* switch stack: */
1699	{ PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
1700	{ PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
1701	{ PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
1702	{ PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
1703	{ PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
1704	{ PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
1705	{ PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
1706	{ PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
1707	{ PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
1708	{ PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
1709	{ PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
1710	{ PT_B4, "b4" }, { PT_B5, "b5" },
1711	{ PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
1712	/* pt_regs */
1713	{ PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
1714	{ PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
1715	{ PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
1716	{ PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
1717	{ PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
1718	{ PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
1719	{ PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
1720	{ PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
1721	{ PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
1722	{ PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
1723	{ PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
1724	{ PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
1725	{ PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
1726	{ PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
1727	{ PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
1728	{ PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
1729	{ PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
1730#    ifdef PT_AR_CSD
1731	{ PT_AR_CSD, "ar.csd" },
1732#    endif
1733#    ifdef PT_AR_SSD
1734	{ PT_AR_SSD, "ar.ssd" },
1735#    endif
1736	{ PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
1737#   elif defined(I386)
1738	{ 4*EBX,		"4*EBX"					},
1739	{ 4*ECX,		"4*ECX"					},
1740	{ 4*EDX,		"4*EDX"					},
1741	{ 4*ESI,		"4*ESI"					},
1742	{ 4*EDI,		"4*EDI"					},
1743	{ 4*EBP,		"4*EBP"					},
1744	{ 4*EAX,		"4*EAX"					},
1745	{ 4*DS,			"4*DS"					},
1746	{ 4*ES,			"4*ES"					},
1747	{ 4*FS,			"4*FS"					},
1748	{ 4*GS,			"4*GS"					},
1749	{ 4*ORIG_EAX,		"4*ORIG_EAX"				},
1750	{ 4*EIP,		"4*EIP"					},
1751	{ 4*CS,			"4*CS"					},
1752	{ 4*EFL,		"4*EFL"					},
1753	{ 4*UESP,		"4*UESP"				},
1754	{ 4*SS,			"4*SS"					},
1755#   elif defined(X86_64)
1756	{ 8*R15,		"8*R15"					},
1757	{ 8*R14,		"8*R14"					},
1758	{ 8*R13,		"8*R13"					},
1759	{ 8*R12,		"8*R12"					},
1760	{ 8*RBP,		"8*RBP"					},
1761	{ 8*RBX,		"8*RBX"					},
1762	{ 8*R11,		"8*R11"					},
1763	{ 8*R10,		"8*R10"					},
1764	{ 8*R9,			"8*R9"					},
1765	{ 8*R8,			"8*R8"					},
1766	{ 8*RAX,		"8*RAX"					},
1767	{ 8*RCX,		"8*RCX"					},
1768	{ 8*RDX,		"8*RDX"					},
1769	{ 8*RSI,		"8*RSI"					},
1770	{ 8*RDI,		"8*RDI"					},
1771	{ 8*ORIG_RAX,		"8*ORIG_RAX"				},
1772	{ 8*RIP,		"8*RIP"					},
1773	{ 8*CS,			"8*CS"					},
1774	{ 8*EFLAGS,		"8*EFL"					},
1775	{ 8*RSP,		"8*RSP"					},
1776	{ 8*SS,			"8*SS"					},
1777#   elif defined(M68K)
1778	{ 4*PT_D1,		"4*PT_D1"				},
1779	{ 4*PT_D2,		"4*PT_D2"				},
1780	{ 4*PT_D3,		"4*PT_D3"				},
1781	{ 4*PT_D4,		"4*PT_D4"				},
1782	{ 4*PT_D5,		"4*PT_D5"				},
1783	{ 4*PT_D6,		"4*PT_D6"				},
1784	{ 4*PT_D7,		"4*PT_D7"				},
1785	{ 4*PT_A0,		"4*PT_A0"				},
1786	{ 4*PT_A1,		"4*PT_A1"				},
1787	{ 4*PT_A2,		"4*PT_A2"				},
1788	{ 4*PT_A3,		"4*PT_A3"				},
1789	{ 4*PT_A4,		"4*PT_A4"				},
1790	{ 4*PT_A5,		"4*PT_A5"				},
1791	{ 4*PT_A6,		"4*PT_A6"				},
1792	{ 4*PT_D0,		"4*PT_D0"				},
1793	{ 4*PT_USP,		"4*PT_USP"				},
1794	{ 4*PT_ORIG_D0,		"4*PT_ORIG_D0"				},
1795	{ 4*PT_SR,		"4*PT_SR"				},
1796	{ 4*PT_PC,		"4*PT_PC"				},
1797#   elif defined(SH)
1798	{ 4*REG_REG0,		"4*REG_REG0"				},
1799	{ 4*(REG_REG0+1),	"4*REG_REG1"				},
1800	{ 4*(REG_REG0+2),	"4*REG_REG2"				},
1801	{ 4*(REG_REG0+3),	"4*REG_REG3"				},
1802	{ 4*(REG_REG0+4),	"4*REG_REG4"				},
1803	{ 4*(REG_REG0+5),	"4*REG_REG5"				},
1804	{ 4*(REG_REG0+6),	"4*REG_REG6"				},
1805	{ 4*(REG_REG0+7),	"4*REG_REG7"				},
1806	{ 4*(REG_REG0+8),	"4*REG_REG8"				},
1807	{ 4*(REG_REG0+9),	"4*REG_REG9"				},
1808	{ 4*(REG_REG0+10),	"4*REG_REG10"				},
1809	{ 4*(REG_REG0+11),	"4*REG_REG11"				},
1810	{ 4*(REG_REG0+12),	"4*REG_REG12"				},
1811	{ 4*(REG_REG0+13),	"4*REG_REG13"				},
1812	{ 4*(REG_REG0+14),	"4*REG_REG14"				},
1813	{ 4*REG_REG15,		"4*REG_REG15"				},
1814	{ 4*REG_PC,		"4*REG_PC"				},
1815	{ 4*REG_PR,		"4*REG_PR"				},
1816	{ 4*REG_SR,		"4*REG_SR"				},
1817	{ 4*REG_GBR,		"4*REG_GBR"				},
1818	{ 4*REG_MACH,		"4*REG_MACH"				},
1819	{ 4*REG_MACL,		"4*REG_MACL"				},
1820	{ 4*REG_SYSCALL,	"4*REG_SYSCALL"				},
1821	{ 4*REG_FPUL,		"4*REG_FPUL"				},
1822	{ 4*REG_FPREG0,		"4*REG_FPREG0"				},
1823	{ 4*(REG_FPREG0+1),	"4*REG_FPREG1"				},
1824	{ 4*(REG_FPREG0+2),	"4*REG_FPREG2"				},
1825	{ 4*(REG_FPREG0+3),	"4*REG_FPREG3"				},
1826	{ 4*(REG_FPREG0+4),	"4*REG_FPREG4"				},
1827	{ 4*(REG_FPREG0+5),	"4*REG_FPREG5"				},
1828	{ 4*(REG_FPREG0+6),	"4*REG_FPREG6"				},
1829	{ 4*(REG_FPREG0+7),	"4*REG_FPREG7"				},
1830	{ 4*(REG_FPREG0+8),	"4*REG_FPREG8"				},
1831	{ 4*(REG_FPREG0+9),	"4*REG_FPREG9"				},
1832	{ 4*(REG_FPREG0+10),	"4*REG_FPREG10"				},
1833	{ 4*(REG_FPREG0+11),	"4*REG_FPREG11"				},
1834	{ 4*(REG_FPREG0+12),	"4*REG_FPREG12"				},
1835	{ 4*(REG_FPREG0+13),	"4*REG_FPREG13"				},
1836	{ 4*(REG_FPREG0+14),	"4*REG_FPREG14"				},
1837	{ 4*REG_FPREG15,	"4*REG_FPREG15"				},
1838#    ifdef REG_XDREG0
1839	{ 4*REG_XDREG0,		"4*REG_XDREG0"				},
1840	{ 4*(REG_XDREG0+2),	"4*REG_XDREG2"				},
1841	{ 4*(REG_XDREG0+4),	"4*REG_XDREG4"				},
1842	{ 4*(REG_XDREG0+6),	"4*REG_XDREG6"				},
1843	{ 4*(REG_XDREG0+8),	"4*REG_XDREG8"				},
1844	{ 4*(REG_XDREG0+10),	"4*REG_XDREG10"				},
1845	{ 4*(REG_XDREG0+12),	"4*REG_XDREG12"				},
1846	{ 4*REG_XDREG14,	"4*REG_XDREG14"				},
1847#    endif
1848	{ 4*REG_FPSCR,		"4*REG_FPSCR"				},
1849#   elif defined(SH64)
1850	{ 0,			"PC(L)"					},
1851	{ 4,			"PC(U)"					},
1852	{ 8,			"SR(L)"					},
1853	{ 12,			"SR(U)"					},
1854	{ 16,			"syscall no.(L)"			},
1855	{ 20,			"syscall_no.(U)"			},
1856	{ 24,			"R0(L)"					},
1857	{ 28,			"R0(U)"					},
1858	{ 32,			"R1(L)"					},
1859	{ 36,			"R1(U)"					},
1860	{ 40,			"R2(L)"					},
1861	{ 44,			"R2(U)"					},
1862	{ 48,			"R3(L)"					},
1863	{ 52,			"R3(U)"					},
1864	{ 56,			"R4(L)"					},
1865	{ 60,			"R4(U)"					},
1866	{ 64,			"R5(L)"					},
1867	{ 68,			"R5(U)"					},
1868	{ 72,			"R6(L)"					},
1869	{ 76,			"R6(U)"					},
1870	{ 80,			"R7(L)"					},
1871	{ 84,			"R7(U)"					},
1872	{ 88,			"R8(L)"					},
1873	{ 92,			"R8(U)"					},
1874	{ 96,			"R9(L)"					},
1875	{ 100,			"R9(U)"					},
1876	{ 104,			"R10(L)"				},
1877	{ 108,			"R10(U)"				},
1878	{ 112,			"R11(L)"				},
1879	{ 116,			"R11(U)"				},
1880	{ 120,			"R12(L)"				},
1881	{ 124,			"R12(U)"				},
1882	{ 128,			"R13(L)"				},
1883	{ 132,			"R13(U)"				},
1884	{ 136,			"R14(L)"				},
1885	{ 140,			"R14(U)"				},
1886	{ 144,			"R15(L)"				},
1887	{ 148,			"R15(U)"				},
1888	{ 152,			"R16(L)"				},
1889	{ 156,			"R16(U)"				},
1890	{ 160,			"R17(L)"				},
1891	{ 164,			"R17(U)"				},
1892	{ 168,			"R18(L)"				},
1893	{ 172,			"R18(U)"				},
1894	{ 176,			"R19(L)"				},
1895	{ 180,			"R19(U)"				},
1896	{ 184,			"R20(L)"				},
1897	{ 188,			"R20(U)"				},
1898	{ 192,			"R21(L)"				},
1899	{ 196,			"R21(U)"				},
1900	{ 200,			"R22(L)"				},
1901	{ 204,			"R22(U)"				},
1902	{ 208,			"R23(L)"				},
1903	{ 212,			"R23(U)"				},
1904	{ 216,			"R24(L)"				},
1905	{ 220,			"R24(U)"				},
1906	{ 224,			"R25(L)"				},
1907	{ 228,			"R25(U)"				},
1908	{ 232,			"R26(L)"				},
1909	{ 236,			"R26(U)"				},
1910	{ 240,			"R27(L)"				},
1911	{ 244,			"R27(U)"				},
1912	{ 248,			"R28(L)"				},
1913	{ 252,			"R28(U)"				},
1914	{ 256,			"R29(L)"				},
1915	{ 260,			"R29(U)"				},
1916	{ 264,			"R30(L)"				},
1917	{ 268,			"R30(U)"				},
1918	{ 272,			"R31(L)"				},
1919	{ 276,			"R31(U)"				},
1920	{ 280,			"R32(L)"				},
1921	{ 284,			"R32(U)"				},
1922	{ 288,			"R33(L)"				},
1923	{ 292,			"R33(U)"				},
1924	{ 296,			"R34(L)"				},
1925	{ 300,			"R34(U)"				},
1926	{ 304,			"R35(L)"				},
1927	{ 308,			"R35(U)"				},
1928	{ 312,			"R36(L)"				},
1929	{ 316,			"R36(U)"				},
1930	{ 320,			"R37(L)"				},
1931	{ 324,			"R37(U)"				},
1932	{ 328,			"R38(L)"				},
1933	{ 332,			"R38(U)"				},
1934	{ 336,			"R39(L)"				},
1935	{ 340,			"R39(U)"				},
1936	{ 344,			"R40(L)"				},
1937	{ 348,			"R40(U)"				},
1938	{ 352,			"R41(L)"				},
1939	{ 356,			"R41(U)"				},
1940	{ 360,			"R42(L)"				},
1941	{ 364,			"R42(U)"				},
1942	{ 368,			"R43(L)"				},
1943	{ 372,			"R43(U)"				},
1944	{ 376,			"R44(L)"				},
1945	{ 380,			"R44(U)"				},
1946	{ 384,			"R45(L)"				},
1947	{ 388,			"R45(U)"				},
1948	{ 392,			"R46(L)"				},
1949	{ 396,			"R46(U)"				},
1950	{ 400,			"R47(L)"				},
1951	{ 404,			"R47(U)"				},
1952	{ 408,			"R48(L)"				},
1953	{ 412,			"R48(U)"				},
1954	{ 416,			"R49(L)"				},
1955	{ 420,			"R49(U)"				},
1956	{ 424,			"R50(L)"				},
1957	{ 428,			"R50(U)"				},
1958	{ 432,			"R51(L)"				},
1959	{ 436,			"R51(U)"				},
1960	{ 440,			"R52(L)"				},
1961	{ 444,			"R52(U)"				},
1962	{ 448,			"R53(L)"				},
1963	{ 452,			"R53(U)"				},
1964	{ 456,			"R54(L)"				},
1965	{ 460,			"R54(U)"				},
1966	{ 464,			"R55(L)"				},
1967	{ 468,			"R55(U)"				},
1968	{ 472,			"R56(L)"				},
1969	{ 476,			"R56(U)"				},
1970	{ 480,			"R57(L)"				},
1971	{ 484,			"R57(U)"				},
1972	{ 488,			"R58(L)"				},
1973	{ 492,			"R58(U)"				},
1974	{ 496,			"R59(L)"				},
1975	{ 500,			"R59(U)"				},
1976	{ 504,			"R60(L)"				},
1977	{ 508,			"R60(U)"				},
1978	{ 512,			"R61(L)"				},
1979	{ 516,			"R61(U)"				},
1980	{ 520,			"R62(L)"				},
1981	{ 524,			"R62(U)"				},
1982	{ 528,			"TR0(L)"				},
1983	{ 532,			"TR0(U)"				},
1984	{ 536,			"TR1(L)"				},
1985	{ 540,			"TR1(U)"				},
1986	{ 544,			"TR2(L)"				},
1987	{ 548,			"TR2(U)"				},
1988	{ 552,			"TR3(L)"				},
1989	{ 556,			"TR3(U)"				},
1990	{ 560,			"TR4(L)"				},
1991	{ 564,			"TR4(U)"				},
1992	{ 568,			"TR5(L)"				},
1993	{ 572,			"TR5(U)"				},
1994	{ 576,			"TR6(L)"				},
1995	{ 580,			"TR6(U)"				},
1996	{ 584,			"TR7(L)"				},
1997	{ 588,			"TR7(U)"				},
1998	/* This entry is in case pt_regs contains dregs (depends on
1999	   the kernel build options). */
2000	{ uoff(regs),		"offsetof(struct user, regs)"		},
2001	{ uoff(fpu),		"offsetof(struct user, fpu)"		},
2002#   elif defined(ARM)
2003	{ uoff(regs.ARM_r0),	"r0"					},
2004	{ uoff(regs.ARM_r1),	"r1"					},
2005	{ uoff(regs.ARM_r2),	"r2"					},
2006	{ uoff(regs.ARM_r3),	"r3"					},
2007	{ uoff(regs.ARM_r4),	"r4"					},
2008	{ uoff(regs.ARM_r5),	"r5"					},
2009	{ uoff(regs.ARM_r6),	"r6"					},
2010	{ uoff(regs.ARM_r7),	"r7"					},
2011	{ uoff(regs.ARM_r8),	"r8"					},
2012	{ uoff(regs.ARM_r9),	"r9"					},
2013	{ uoff(regs.ARM_r10),	"r10"					},
2014	{ uoff(regs.ARM_fp),	"fp"					},
2015	{ uoff(regs.ARM_ip),	"ip"					},
2016	{ uoff(regs.ARM_sp),	"sp"					},
2017	{ uoff(regs.ARM_lr),	"lr"					},
2018	{ uoff(regs.ARM_pc),	"pc"					},
2019	{ uoff(regs.ARM_cpsr),	"cpsr"					},
2020#   elif defined(AVR32)
2021	{ uoff(regs.sr),	"sr"					},
2022	{ uoff(regs.pc),	"pc"					},
2023	{ uoff(regs.lr),	"lr"					},
2024	{ uoff(regs.sp),	"sp"					},
2025	{ uoff(regs.r12),	"r12"					},
2026	{ uoff(regs.r11),	"r11"					},
2027	{ uoff(regs.r10),	"r10"					},
2028	{ uoff(regs.r9),	"r9"					},
2029	{ uoff(regs.r8),	"r8"					},
2030	{ uoff(regs.r7),	"r7"					},
2031	{ uoff(regs.r6),	"r6"					},
2032	{ uoff(regs.r5),	"r5"					},
2033	{ uoff(regs.r4),	"r4"					},
2034	{ uoff(regs.r3),	"r3"					},
2035	{ uoff(regs.r2),	"r2"					},
2036	{ uoff(regs.r1),	"r1"					},
2037	{ uoff(regs.r0),	"r0"					},
2038	{ uoff(regs.r12_orig),	"orig_r12"				},
2039#   elif defined(MIPS)
2040	{ 0,			"r0"					},
2041	{ 1,			"r1"					},
2042	{ 2,			"r2"					},
2043	{ 3,			"r3"					},
2044	{ 4,			"r4"					},
2045	{ 5,			"r5"					},
2046	{ 6,			"r6"					},
2047	{ 7,			"r7"					},
2048	{ 8,			"r8"					},
2049	{ 9,			"r9"					},
2050	{ 10,			"r10"					},
2051	{ 11,			"r11"					},
2052	{ 12,			"r12"					},
2053	{ 13,			"r13"					},
2054	{ 14,			"r14"					},
2055	{ 15,			"r15"					},
2056	{ 16,			"r16"					},
2057	{ 17,			"r17"					},
2058	{ 18,			"r18"					},
2059	{ 19,			"r19"					},
2060	{ 20,			"r20"					},
2061	{ 21,			"r21"					},
2062	{ 22,			"r22"					},
2063	{ 23,			"r23"					},
2064	{ 24,			"r24"					},
2065	{ 25,			"r25"					},
2066	{ 26,			"r26"					},
2067	{ 27,			"r27"					},
2068	{ 28,			"r28"					},
2069	{ 29,			"r29"					},
2070	{ 30,			"r30"					},
2071	{ 31,			"r31"					},
2072	{ 32,			"f0"					},
2073	{ 33,			"f1"					},
2074	{ 34,			"f2"					},
2075	{ 35,			"f3"					},
2076	{ 36,			"f4"					},
2077	{ 37,			"f5"					},
2078	{ 38,			"f6"					},
2079	{ 39,			"f7"					},
2080	{ 40,			"f8"					},
2081	{ 41,			"f9"					},
2082	{ 42,			"f10"					},
2083	{ 43,			"f11"					},
2084	{ 44,			"f12"					},
2085	{ 45,			"f13"					},
2086	{ 46,			"f14"					},
2087	{ 47,			"f15"					},
2088	{ 48,			"f16"					},
2089	{ 49,			"f17"					},
2090	{ 50,			"f18"					},
2091	{ 51,			"f19"					},
2092	{ 52,			"f20"					},
2093	{ 53,			"f21"					},
2094	{ 54,			"f22"					},
2095	{ 55,			"f23"					},
2096	{ 56,			"f24"					},
2097	{ 57,			"f25"					},
2098	{ 58,			"f26"					},
2099	{ 59,			"f27"					},
2100	{ 60,			"f28"					},
2101	{ 61,			"f29"					},
2102	{ 62,			"f30"					},
2103	{ 63,			"f31"					},
2104	{ 64,			"pc"					},
2105	{ 65,			"cause"					},
2106	{ 66,			"badvaddr"				},
2107	{ 67,			"mmhi"					},
2108	{ 68,			"mmlo"					},
2109	{ 69,			"fpcsr"					},
2110	{ 70,			"fpeir"					},
2111#   elif defined(TILE)
2112	{ PTREGS_OFFSET_REG(0),  "r0"  },
2113	{ PTREGS_OFFSET_REG(1),  "r1"  },
2114	{ PTREGS_OFFSET_REG(2),  "r2"  },
2115	{ PTREGS_OFFSET_REG(3),  "r3"  },
2116	{ PTREGS_OFFSET_REG(4),  "r4"  },
2117	{ PTREGS_OFFSET_REG(5),  "r5"  },
2118	{ PTREGS_OFFSET_REG(6),  "r6"  },
2119	{ PTREGS_OFFSET_REG(7),  "r7"  },
2120	{ PTREGS_OFFSET_REG(8),  "r8"  },
2121	{ PTREGS_OFFSET_REG(9),  "r9"  },
2122	{ PTREGS_OFFSET_REG(10), "r10" },
2123	{ PTREGS_OFFSET_REG(11), "r11" },
2124	{ PTREGS_OFFSET_REG(12), "r12" },
2125	{ PTREGS_OFFSET_REG(13), "r13" },
2126	{ PTREGS_OFFSET_REG(14), "r14" },
2127	{ PTREGS_OFFSET_REG(15), "r15" },
2128	{ PTREGS_OFFSET_REG(16), "r16" },
2129	{ PTREGS_OFFSET_REG(17), "r17" },
2130	{ PTREGS_OFFSET_REG(18), "r18" },
2131	{ PTREGS_OFFSET_REG(19), "r19" },
2132	{ PTREGS_OFFSET_REG(20), "r20" },
2133	{ PTREGS_OFFSET_REG(21), "r21" },
2134	{ PTREGS_OFFSET_REG(22), "r22" },
2135	{ PTREGS_OFFSET_REG(23), "r23" },
2136	{ PTREGS_OFFSET_REG(24), "r24" },
2137	{ PTREGS_OFFSET_REG(25), "r25" },
2138	{ PTREGS_OFFSET_REG(26), "r26" },
2139	{ PTREGS_OFFSET_REG(27), "r27" },
2140	{ PTREGS_OFFSET_REG(28), "r28" },
2141	{ PTREGS_OFFSET_REG(29), "r29" },
2142	{ PTREGS_OFFSET_REG(30), "r30" },
2143	{ PTREGS_OFFSET_REG(31), "r31" },
2144	{ PTREGS_OFFSET_REG(32), "r32" },
2145	{ PTREGS_OFFSET_REG(33), "r33" },
2146	{ PTREGS_OFFSET_REG(34), "r34" },
2147	{ PTREGS_OFFSET_REG(35), "r35" },
2148	{ PTREGS_OFFSET_REG(36), "r36" },
2149	{ PTREGS_OFFSET_REG(37), "r37" },
2150	{ PTREGS_OFFSET_REG(38), "r38" },
2151	{ PTREGS_OFFSET_REG(39), "r39" },
2152	{ PTREGS_OFFSET_REG(40), "r40" },
2153	{ PTREGS_OFFSET_REG(41), "r41" },
2154	{ PTREGS_OFFSET_REG(42), "r42" },
2155	{ PTREGS_OFFSET_REG(43), "r43" },
2156	{ PTREGS_OFFSET_REG(44), "r44" },
2157	{ PTREGS_OFFSET_REG(45), "r45" },
2158	{ PTREGS_OFFSET_REG(46), "r46" },
2159	{ PTREGS_OFFSET_REG(47), "r47" },
2160	{ PTREGS_OFFSET_REG(48), "r48" },
2161	{ PTREGS_OFFSET_REG(49), "r49" },
2162	{ PTREGS_OFFSET_REG(50), "r50" },
2163	{ PTREGS_OFFSET_REG(51), "r51" },
2164	{ PTREGS_OFFSET_REG(52), "r52" },
2165	{ PTREGS_OFFSET_TP, "tp" },
2166	{ PTREGS_OFFSET_SP, "sp" },
2167	{ PTREGS_OFFSET_LR, "lr" },
2168	{ PTREGS_OFFSET_PC, "pc" },
2169	{ PTREGS_OFFSET_EX1, "ex1" },
2170	{ PTREGS_OFFSET_FAULTNUM, "faultnum" },
2171	{ PTREGS_OFFSET_ORIG_R0, "orig_r0" },
2172	{ PTREGS_OFFSET_FLAGS, "flags" },
2173#   endif
2174#   ifdef CRISV10
2175	{ 4*PT_FRAMETYPE, "4*PT_FRAMETYPE" },
2176	{ 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
2177	{ 4*PT_R13, "4*PT_R13" },
2178	{ 4*PT_R12, "4*PT_R12" },
2179	{ 4*PT_R11, "4*PT_R11" },
2180	{ 4*PT_R10, "4*PT_R10" },
2181	{ 4*PT_R9, "4*PT_R9" },
2182	{ 4*PT_R8, "4*PT_R8" },
2183	{ 4*PT_R7, "4*PT_R7" },
2184	{ 4*PT_R6, "4*PT_R6" },
2185	{ 4*PT_R5, "4*PT_R5" },
2186	{ 4*PT_R4, "4*PT_R4" },
2187	{ 4*PT_R3, "4*PT_R3" },
2188	{ 4*PT_R2, "4*PT_R2" },
2189	{ 4*PT_R1, "4*PT_R1" },
2190	{ 4*PT_R0, "4*PT_R0" },
2191	{ 4*PT_MOF, "4*PT_MOF" },
2192	{ 4*PT_DCCR, "4*PT_DCCR" },
2193	{ 4*PT_SRP, "4*PT_SRP" },
2194	{ 4*PT_IRP, "4*PT_IRP" },
2195	{ 4*PT_CSRINSTR, "4*PT_CSRINSTR" },
2196	{ 4*PT_CSRADDR, "4*PT_CSRADDR" },
2197	{ 4*PT_CSRDATA, "4*PT_CSRDATA" },
2198	{ 4*PT_USP, "4*PT_USP" },
2199#   endif
2200#   ifdef CRISV32
2201	{ 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
2202	{ 4*PT_R0, "4*PT_R0" },
2203	{ 4*PT_R1, "4*PT_R1" },
2204	{ 4*PT_R2, "4*PT_R2" },
2205	{ 4*PT_R3, "4*PT_R3" },
2206	{ 4*PT_R4, "4*PT_R4" },
2207	{ 4*PT_R5, "4*PT_R5" },
2208	{ 4*PT_R6, "4*PT_R6" },
2209	{ 4*PT_R7, "4*PT_R7" },
2210	{ 4*PT_R8, "4*PT_R8" },
2211	{ 4*PT_R9, "4*PT_R9" },
2212	{ 4*PT_R10, "4*PT_R10" },
2213	{ 4*PT_R11, "4*PT_R11" },
2214	{ 4*PT_R12, "4*PT_R12" },
2215	{ 4*PT_R13, "4*PT_R13" },
2216	{ 4*PT_ACR, "4*PT_ACR" },
2217	{ 4*PT_SRS, "4*PT_SRS" },
2218	{ 4*PT_MOF, "4*PT_MOF" },
2219	{ 4*PT_SPC, "4*PT_SPC" },
2220	{ 4*PT_CCS, "4*PT_CCS" },
2221	{ 4*PT_SRP, "4*PT_SRP" },
2222	{ 4*PT_ERP, "4*PT_ERP" },
2223	{ 4*PT_EXS, "4*PT_EXS" },
2224	{ 4*PT_EDA, "4*PT_EDA" },
2225	{ 4*PT_USP, "4*PT_USP" },
2226	{ 4*PT_PPC, "4*PT_PPC" },
2227	{ 4*PT_BP_CTRL, "4*PT_BP_CTRL" },
2228	{ 4*PT_BP+4, "4*PT_BP+4" },
2229	{ 4*PT_BP+8, "4*PT_BP+8" },
2230	{ 4*PT_BP+12, "4*PT_BP+12" },
2231	{ 4*PT_BP+16, "4*PT_BP+16" },
2232	{ 4*PT_BP+20, "4*PT_BP+20" },
2233	{ 4*PT_BP+24, "4*PT_BP+24" },
2234	{ 4*PT_BP+28, "4*PT_BP+28" },
2235	{ 4*PT_BP+32, "4*PT_BP+32" },
2236	{ 4*PT_BP+36, "4*PT_BP+36" },
2237	{ 4*PT_BP+40, "4*PT_BP+40" },
2238	{ 4*PT_BP+44, "4*PT_BP+44" },
2239	{ 4*PT_BP+48, "4*PT_BP+48" },
2240	{ 4*PT_BP+52, "4*PT_BP+52" },
2241	{ 4*PT_BP+56, "4*PT_BP+56" },
2242#   endif
2243#   ifdef MICROBLAZE
2244	{ PT_GPR(0),		"r0"					},
2245	{ PT_GPR(1),		"r1"					},
2246	{ PT_GPR(2),		"r2"					},
2247	{ PT_GPR(3),		"r3"					},
2248	{ PT_GPR(4),		"r4"					},
2249	{ PT_GPR(5),		"r5"					},
2250	{ PT_GPR(6),		"r6"					},
2251	{ PT_GPR(7),		"r7"					},
2252	{ PT_GPR(8),		"r8"					},
2253	{ PT_GPR(9),		"r9"					},
2254	{ PT_GPR(10),		"r10"					},
2255	{ PT_GPR(11),		"r11"					},
2256	{ PT_GPR(12),		"r12"					},
2257	{ PT_GPR(13),		"r13"					},
2258	{ PT_GPR(14),		"r14"					},
2259	{ PT_GPR(15),		"r15"					},
2260	{ PT_GPR(16),		"r16"					},
2261	{ PT_GPR(17),		"r17"					},
2262	{ PT_GPR(18),		"r18"					},
2263	{ PT_GPR(19),		"r19"					},
2264	{ PT_GPR(20),		"r20"					},
2265	{ PT_GPR(21),		"r21"					},
2266	{ PT_GPR(22),		"r22"					},
2267	{ PT_GPR(23),		"r23"					},
2268	{ PT_GPR(24),		"r24"					},
2269	{ PT_GPR(25),		"r25"					},
2270	{ PT_GPR(26),		"r26"					},
2271	{ PT_GPR(27),		"r27"					},
2272	{ PT_GPR(28),		"r28"					},
2273	{ PT_GPR(29),		"r29"					},
2274	{ PT_GPR(30),		"r30"					},
2275	{ PT_GPR(31),		"r31"					},
2276	{ PT_PC,		"rpc",					},
2277	{ PT_MSR,		"rmsr",					},
2278	{ PT_EAR,		"rear",					},
2279	{ PT_ESR,		"resr",					},
2280	{ PT_FSR,		"rfsr",					},
2281	{ PT_KERNEL_MODE,	"kernel_mode",				},
2282#   endif
2283
2284#   if !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) \
2285		&& !defined(ALPHA) && !defined(IA64) \
2286		&& !defined(CRISV10) && !defined(CRISV32) && !defined(MICROBLAZE)
2287#    if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(AVR32) && !defined(BFIN) && !defined(TILE)
2288	{ uoff(u_fpvalid),	"offsetof(struct user, u_fpvalid)"	},
2289#    endif
2290#    if defined(I386) || defined(X86_64)
2291	{ uoff(i387),		"offsetof(struct user, i387)"		},
2292#    endif
2293#    if defined(M68K)
2294	{ uoff(m68kfp),		"offsetof(struct user, m68kfp)"		},
2295#    endif
2296	{ uoff(u_tsize),	"offsetof(struct user, u_tsize)"	},
2297	{ uoff(u_dsize),	"offsetof(struct user, u_dsize)"	},
2298	{ uoff(u_ssize),	"offsetof(struct user, u_ssize)"	},
2299#    if !defined(SPARC64)
2300	{ uoff(start_code),	"offsetof(struct user, start_code)"	},
2301#    endif
2302#    if defined(AVR32) || defined(SH64)
2303	{ uoff(start_data),	"offsetof(struct user, start_data)"	},
2304#    endif
2305#    if !defined(SPARC64)
2306	{ uoff(start_stack),	"offsetof(struct user, start_stack)"	},
2307#    endif
2308	{ uoff(signal),		"offsetof(struct user, signal)"		},
2309#    if !defined(AVR32) && !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64) && !defined(TILE)
2310	{ uoff(reserved),	"offsetof(struct user, reserved)"	},
2311#    endif
2312#    if !defined(SPARC64)
2313	{ uoff(u_ar0),		"offsetof(struct user, u_ar0)"		},
2314#    endif
2315#    if !defined(ARM) && !defined(AVR32) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN) && !defined(TILE)
2316	{ uoff(u_fpstate),	"offsetof(struct user, u_fpstate)"	},
2317#    endif
2318	{ uoff(magic),		"offsetof(struct user, magic)"		},
2319	{ uoff(u_comm),		"offsetof(struct user, u_comm)"		},
2320#    if defined(I386) || defined(X86_64)
2321	{ uoff(u_debugreg),	"offsetof(struct user, u_debugreg)"	},
2322#    endif
2323#   endif /* !defined(many arches) */
2324
2325#  ifndef HPPA
2326	{ sizeof(struct user),	"sizeof(struct user)"			},
2327#  endif
2328	{ 0,			NULL					},
2329};
2330
2331int
2332sys_ptrace(struct tcb *tcp)
2333{
2334	const struct xlat *x;
2335	long addr;
2336
2337	if (entering(tcp)) {
2338		printxval(ptrace_cmds, tcp->u_arg[0],
2339			  "PTRACE_???"
2340			);
2341		tprintf(", %lu, ", tcp->u_arg[1]);
2342		addr = tcp->u_arg[2];
2343		if (tcp->u_arg[0] == PTRACE_PEEKUSER
2344			|| tcp->u_arg[0] == PTRACE_POKEUSER) {
2345			for (x = struct_user_offsets; x->str; x++) {
2346				if (x->val >= addr)
2347					break;
2348			}
2349			if (!x->str)
2350				tprintf("%#lx, ", addr);
2351			else if (x->val > addr && x != struct_user_offsets) {
2352				x--;
2353				tprintf("%s + %ld, ", x->str, addr - x->val);
2354			}
2355			else
2356				tprintf("%s, ", x->str);
2357		}
2358		else
2359			tprintf("%#lx, ", tcp->u_arg[2]);
2360		switch (tcp->u_arg[0]) {
2361#  ifndef IA64
2362		case PTRACE_PEEKDATA:
2363		case PTRACE_PEEKTEXT:
2364		case PTRACE_PEEKUSER:
2365			break;
2366#  endif
2367		case PTRACE_CONT:
2368		case PTRACE_SINGLESTEP:
2369		case PTRACE_SYSCALL:
2370		case PTRACE_DETACH:
2371			printsignal(tcp->u_arg[3]);
2372			break;
2373#  ifdef PTRACE_SETOPTIONS
2374		case PTRACE_SETOPTIONS:
2375			printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
2376			break;
2377#  endif
2378#  ifdef PTRACE_SETSIGINFO
2379		case PTRACE_SETSIGINFO: {
2380			siginfo_t si;
2381			if (!tcp->u_arg[3])
2382				tprints("NULL");
2383			else if (syserror(tcp))
2384				tprintf("%#lx", tcp->u_arg[3]);
2385			else if (umove(tcp, tcp->u_arg[3], &si) < 0)
2386				tprints("{???}");
2387			else
2388				printsiginfo(&si, verbose(tcp));
2389			break;
2390		}
2391#  endif
2392#  ifdef PTRACE_GETSIGINFO
2393		case PTRACE_GETSIGINFO:
2394			/* Don't print anything, do it at syscall return. */
2395			break;
2396#  endif
2397		default:
2398			tprintf("%#lx", tcp->u_arg[3]);
2399			break;
2400		}
2401	} else {
2402		switch (tcp->u_arg[0]) {
2403		case PTRACE_PEEKDATA:
2404		case PTRACE_PEEKTEXT:
2405		case PTRACE_PEEKUSER:
2406#  ifdef IA64
2407			return RVAL_HEX;
2408#  else
2409			printnum(tcp, tcp->u_arg[3], "%#lx");
2410			break;
2411#  endif
2412#  ifdef PTRACE_GETSIGINFO
2413		case PTRACE_GETSIGINFO: {
2414			siginfo_t si;
2415			if (!tcp->u_arg[3])
2416				tprints("NULL");
2417			else if (syserror(tcp))
2418				tprintf("%#lx", tcp->u_arg[3]);
2419			else if (umove(tcp, tcp->u_arg[3], &si) < 0)
2420				tprints("{???}");
2421			else
2422				printsiginfo(&si, verbose(tcp));
2423			break;
2424		}
2425#  endif
2426		}
2427	}
2428	return 0;
2429}
2430
2431# ifndef FUTEX_CMP_REQUEUE
2432#  define FUTEX_CMP_REQUEUE 4
2433# endif
2434# ifndef FUTEX_WAKE_OP
2435#  define FUTEX_WAKE_OP 5
2436# endif
2437# ifndef FUTEX_LOCK_PI
2438#  define FUTEX_LOCK_PI 6
2439#  define FUTEX_UNLOCK_PI 7
2440#  define FUTEX_TRYLOCK_PI 8
2441# endif
2442# ifndef FUTEX_WAIT_BITSET
2443#  define FUTEX_WAIT_BITSET 9
2444# endif
2445# ifndef FUTEX_WAKE_BITSET
2446#  define FUTEX_WAKE_BITSET 10
2447# endif
2448# ifndef FUTEX_WAIT_REQUEUE_PI
2449#  define FUTEX_WAIT_REQUEUE_PI 11
2450# endif
2451# ifndef FUTEX_CMP_REQUEUE_PI
2452#  define FUTEX_CMP_REQUEUE_PI 12
2453# endif
2454# ifndef FUTEX_PRIVATE_FLAG
2455#  define FUTEX_PRIVATE_FLAG 128
2456# endif
2457# ifndef FUTEX_CLOCK_REALTIME
2458#  define FUTEX_CLOCK_REALTIME 256
2459# endif
2460static const struct xlat futexops[] = {
2461	{ FUTEX_WAIT,					"FUTEX_WAIT" },
2462	{ FUTEX_WAKE,					"FUTEX_WAKE" },
2463	{ FUTEX_FD,					"FUTEX_FD" },
2464	{ FUTEX_REQUEUE,				"FUTEX_REQUEUE" },
2465	{ FUTEX_CMP_REQUEUE,				"FUTEX_CMP_REQUEUE" },
2466	{ FUTEX_WAKE_OP,				"FUTEX_WAKE_OP" },
2467	{ FUTEX_LOCK_PI,				"FUTEX_LOCK_PI" },
2468	{ FUTEX_UNLOCK_PI,				"FUTEX_UNLOCK_PI" },
2469	{ FUTEX_TRYLOCK_PI,				"FUTEX_TRYLOCK_PI" },
2470	{ FUTEX_WAIT_BITSET,				"FUTEX_WAIT_BITSET" },
2471	{ FUTEX_WAKE_BITSET,				"FUTEX_WAKE_BITSET" },
2472	{ FUTEX_WAIT_REQUEUE_PI,			"FUTEX_WAIT_REQUEUE_PI" },
2473	{ FUTEX_CMP_REQUEUE_PI,				"FUTEX_CMP_REQUEUE_PI" },
2474	{ FUTEX_WAIT|FUTEX_PRIVATE_FLAG,		"FUTEX_WAIT_PRIVATE" },
2475	{ FUTEX_WAKE|FUTEX_PRIVATE_FLAG,		"FUTEX_WAKE_PRIVATE" },
2476	{ FUTEX_FD|FUTEX_PRIVATE_FLAG,			"FUTEX_FD_PRIVATE" },
2477	{ FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG,		"FUTEX_REQUEUE_PRIVATE" },
2478	{ FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG,		"FUTEX_CMP_REQUEUE_PRIVATE" },
2479	{ FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG,		"FUTEX_WAKE_OP_PRIVATE" },
2480	{ FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG,		"FUTEX_LOCK_PI_PRIVATE" },
2481	{ FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG,		"FUTEX_UNLOCK_PI_PRIVATE" },
2482	{ FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG,		"FUTEX_TRYLOCK_PI_PRIVATE" },
2483	{ FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG,		"FUTEX_WAIT_BITSET_PRIVATE" },
2484	{ FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG,		"FUTEX_WAKE_BITSET_PRIVATE" },
2485	{ FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG,	"FUTEX_WAIT_REQUEUE_PI_PRIVATE" },
2486	{ FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG,	"FUTEX_CMP_REQUEUE_PI_PRIVATE" },
2487	{ FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME,	"FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME" },
2488	{ FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME,	"FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME" },
2489	{ FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME,	"FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME" },
2490	{ FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME,	"FUTEX_WAIT_REQUEUE_PI_PRIVATE|FUTEX_CLOCK_REALTIME" },
2491	{ 0,						NULL }
2492};
2493# ifndef FUTEX_OP_SET
2494#  define FUTEX_OP_SET		0
2495#  define FUTEX_OP_ADD		1
2496#  define FUTEX_OP_OR		2
2497#  define FUTEX_OP_ANDN		3
2498#  define FUTEX_OP_XOR		4
2499#  define FUTEX_OP_CMP_EQ	0
2500#  define FUTEX_OP_CMP_NE	1
2501#  define FUTEX_OP_CMP_LT	2
2502#  define FUTEX_OP_CMP_LE	3
2503#  define FUTEX_OP_CMP_GT	4
2504#  define FUTEX_OP_CMP_GE	5
2505# endif
2506static const struct xlat futexwakeops[] = {
2507	{ FUTEX_OP_SET,		"FUTEX_OP_SET" },
2508	{ FUTEX_OP_ADD,		"FUTEX_OP_ADD" },
2509	{ FUTEX_OP_OR,		"FUTEX_OP_OR" },
2510	{ FUTEX_OP_ANDN,	"FUTEX_OP_ANDN" },
2511	{ FUTEX_OP_XOR,		"FUTEX_OP_XOR" },
2512	{ 0,			NULL }
2513};
2514static const struct xlat futexwakecmps[] = {
2515	{ FUTEX_OP_CMP_EQ,	"FUTEX_OP_CMP_EQ" },
2516	{ FUTEX_OP_CMP_NE,	"FUTEX_OP_CMP_NE" },
2517	{ FUTEX_OP_CMP_LT,	"FUTEX_OP_CMP_LT" },
2518	{ FUTEX_OP_CMP_LE,	"FUTEX_OP_CMP_LE" },
2519	{ FUTEX_OP_CMP_GT,	"FUTEX_OP_CMP_GT" },
2520	{ FUTEX_OP_CMP_GE,	"FUTEX_OP_CMP_GE" },
2521	{ 0,			NULL }
2522};
2523
2524int
2525sys_futex(struct tcb *tcp)
2526{
2527	if (entering(tcp)) {
2528		long int cmd = tcp->u_arg[1] & 127;
2529		tprintf("%p, ", (void *) tcp->u_arg[0]);
2530		printxval(futexops, tcp->u_arg[1], "FUTEX_???");
2531		tprintf(", %ld", tcp->u_arg[2]);
2532		if (cmd == FUTEX_WAKE_BITSET)
2533			tprintf(", %lx", tcp->u_arg[5]);
2534		else if (cmd == FUTEX_WAIT) {
2535			tprints(", ");
2536			printtv(tcp, tcp->u_arg[3]);
2537		} else if (cmd == FUTEX_WAIT_BITSET) {
2538			tprints(", ");
2539			printtv(tcp, tcp->u_arg[3]);
2540			tprintf(", %lx", tcp->u_arg[5]);
2541		} else if (cmd == FUTEX_REQUEUE)
2542			tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
2543		else if (cmd == FUTEX_CMP_REQUEUE || cmd == FUTEX_CMP_REQUEUE_PI)
2544			tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
2545		else if (cmd == FUTEX_WAKE_OP) {
2546			tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
2547			if ((tcp->u_arg[5] >> 28) & 8)
2548				tprints("FUTEX_OP_OPARG_SHIFT|");
2549			printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
2550			tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
2551			if ((tcp->u_arg[5] >> 24) & 8)
2552				tprints("FUTEX_OP_OPARG_SHIFT|");
2553			printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
2554			tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
2555		} else if (cmd == FUTEX_WAIT_REQUEUE_PI) {
2556			tprints(", ");
2557			printtv(tcp, tcp->u_arg[3]);
2558			tprintf(", %p", (void *) tcp->u_arg[4]);
2559		}
2560	}
2561	return 0;
2562}
2563
2564static void
2565print_affinitylist(struct tcb *tcp, long list, unsigned int len)
2566{
2567	int first = 1;
2568	unsigned long w, min_len;
2569
2570	if (abbrev(tcp) && len / sizeof(w) > max_strlen)
2571		min_len = len - max_strlen * sizeof(w);
2572	else
2573		min_len = 0;
2574	for (; len >= sizeof(w) && len > min_len;
2575	     len -= sizeof(w), list += sizeof(w)) {
2576		if (umove(tcp, list, &w) < 0)
2577			break;
2578		if (first)
2579			tprints("{");
2580		else
2581			tprints(", ");
2582		first = 0;
2583		tprintf("%lx", w);
2584	}
2585	if (len) {
2586		if (first)
2587			tprintf("%#lx", list);
2588		else
2589			tprintf(", %s}", (len >= sizeof(w) && len > min_len ?
2590				"???" : "..."));
2591	} else {
2592		tprints(first ? "{}" : "}");
2593	}
2594}
2595
2596int
2597sys_sched_setaffinity(struct tcb *tcp)
2598{
2599	if (entering(tcp)) {
2600		tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2601		print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
2602	}
2603	return 0;
2604}
2605
2606int
2607sys_sched_getaffinity(struct tcb *tcp)
2608{
2609	if (entering(tcp)) {
2610		tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2611	} else {
2612		if (tcp->u_rval == -1)
2613			tprintf("%#lx", tcp->u_arg[2]);
2614		else
2615			print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
2616	}
2617	return 0;
2618}
2619
2620int
2621sys_get_robust_list(struct tcb *tcp)
2622{
2623	if (entering(tcp)) {
2624		tprintf("%ld, ", (long) (pid_t) tcp->u_arg[0]);
2625	} else {
2626		void *addr;
2627		size_t len;
2628
2629		if (syserror(tcp) ||
2630		    !tcp->u_arg[1] ||
2631		    umove(tcp, tcp->u_arg[1], &addr) < 0) {
2632			tprintf("%#lx, ", tcp->u_arg[1]);
2633		} else {
2634			tprintf("[%p], ", addr);
2635		}
2636
2637		if (syserror(tcp) ||
2638		    !tcp->u_arg[2] ||
2639		    umove(tcp, tcp->u_arg[2], &len) < 0) {
2640			tprintf("%#lx", tcp->u_arg[2]);
2641		} else {
2642			tprintf("[%lu]", (unsigned long) len);
2643		}
2644	}
2645	return 0;
2646}
2647
2648static const struct xlat schedulers[] = {
2649	{ SCHED_OTHER,	"SCHED_OTHER" },
2650	{ SCHED_RR,	"SCHED_RR" },
2651	{ SCHED_FIFO,	"SCHED_FIFO" },
2652	{ 0,		NULL }
2653};
2654
2655int
2656sys_sched_getscheduler(struct tcb *tcp)
2657{
2658	if (entering(tcp)) {
2659		tprintf("%d", (int) tcp->u_arg[0]);
2660	} else if (!syserror(tcp)) {
2661		tcp->auxstr = xlookup(schedulers, tcp->u_rval);
2662		if (tcp->auxstr != NULL)
2663			return RVAL_STR;
2664	}
2665	return 0;
2666}
2667
2668int
2669sys_sched_setscheduler(struct tcb *tcp)
2670{
2671	if (entering(tcp)) {
2672		struct sched_param p;
2673		tprintf("%d, ", (int) tcp->u_arg[0]);
2674		printxval(schedulers, tcp->u_arg[1], "SCHED_???");
2675		if (umove(tcp, tcp->u_arg[2], &p) < 0)
2676			tprintf(", %#lx", tcp->u_arg[2]);
2677		else
2678			tprintf(", { %d }", p.__sched_priority);
2679	}
2680	return 0;
2681}
2682
2683int
2684sys_sched_getparam(struct tcb *tcp)
2685{
2686	if (entering(tcp)) {
2687		tprintf("%d, ", (int) tcp->u_arg[0]);
2688	} else {
2689		struct sched_param p;
2690		if (umove(tcp, tcp->u_arg[1], &p) < 0)
2691			tprintf("%#lx", tcp->u_arg[1]);
2692		else
2693			tprintf("{ %d }", p.__sched_priority);
2694	}
2695	return 0;
2696}
2697
2698int
2699sys_sched_setparam(struct tcb *tcp)
2700{
2701	if (entering(tcp)) {
2702		struct sched_param p;
2703		if (umove(tcp, tcp->u_arg[1], &p) < 0)
2704			tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
2705		else
2706			tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
2707	}
2708	return 0;
2709}
2710
2711int
2712sys_sched_get_priority_min(struct tcb *tcp)
2713{
2714	if (entering(tcp)) {
2715		printxval(schedulers, tcp->u_arg[0], "SCHED_???");
2716	}
2717	return 0;
2718}
2719
2720int
2721sys_sched_rr_get_interval(struct tcb *tcp)
2722{
2723	if (entering(tcp)) {
2724		tprintf("%ld, ", (long) (pid_t) tcp->u_arg[0]);
2725	} else {
2726		if (syserror(tcp))
2727			tprintf("%#lx", tcp->u_arg[1]);
2728		else
2729			print_timespec(tcp, tcp->u_arg[1]);
2730	}
2731	return 0;
2732}
2733
2734# ifdef X86_64
2735# include <asm/prctl.h>
2736
2737static const struct xlat archvals[] = {
2738	{ ARCH_SET_GS,		"ARCH_SET_GS"		},
2739	{ ARCH_SET_FS,		"ARCH_SET_FS"		},
2740	{ ARCH_GET_FS,		"ARCH_GET_FS"		},
2741	{ ARCH_GET_GS,		"ARCH_GET_GS"		},
2742	{ 0,			NULL			},
2743};
2744
2745int
2746sys_arch_prctl(struct tcb *tcp)
2747{
2748	if (entering(tcp)) {
2749		printxval(archvals, tcp->u_arg[0], "ARCH_???");
2750		if (tcp->u_arg[0] == ARCH_SET_GS
2751		 || tcp->u_arg[0] == ARCH_SET_FS
2752		) {
2753			tprintf(", %#lx", tcp->u_arg[1]);
2754		}
2755	} else {
2756		if (tcp->u_arg[0] == ARCH_GET_GS
2757		 || tcp->u_arg[0] == ARCH_GET_FS
2758		) {
2759			long int v;
2760			if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
2761				tprintf(", [%#lx]", v);
2762			else
2763				tprintf(", %#lx", tcp->u_arg[1]);
2764		}
2765	}
2766	return 0;
2767}
2768# endif /* X86_64 */
2769
2770int
2771sys_getcpu(struct tcb *tcp)
2772{
2773	if (exiting(tcp)) {
2774		unsigned u;
2775		if (tcp->u_arg[0] == 0)
2776			tprints("NULL, ");
2777		else if (umove(tcp, tcp->u_arg[0], &u) < 0)
2778			tprintf("%#lx, ", tcp->u_arg[0]);
2779		else
2780			tprintf("[%u], ", u);
2781		if (tcp->u_arg[1] == 0)
2782			tprints("NULL, ");
2783		else if (umove(tcp, tcp->u_arg[1], &u) < 0)
2784			tprintf("%#lx, ", tcp->u_arg[1]);
2785		else
2786			tprintf("[%u], ", u);
2787		tprintf("%#lx", tcp->u_arg[2]);
2788	}
2789	return 0;
2790}
2791
2792int
2793sys_process_vm_readv(struct tcb *tcp)
2794{
2795	if (entering(tcp)) {
2796		/* arg 1: pid */
2797		tprintf("%ld, ", tcp->u_arg[0]);
2798	} else {
2799		/* arg 2: local iov */
2800		if (syserror(tcp)) {
2801			tprintf("%#lx", tcp->u_arg[1]);
2802		} else {
2803			tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1);
2804		}
2805		/* arg 3: local iovcnt */
2806		tprintf(", %lu, ", tcp->u_arg[2]);
2807		/* arg 4: remote iov */
2808		if (syserror(tcp)) {
2809			tprintf("%#lx", tcp->u_arg[3]);
2810		} else {
2811			tprint_iov(tcp, tcp->u_arg[4], tcp->u_arg[3], 0);
2812		}
2813		/* arg 5: remote iovcnt */
2814		/* arg 6: flags */
2815		tprintf(", %lu, %lu", tcp->u_arg[4], tcp->u_arg[5]);
2816	}
2817	return 0;
2818}
2819
2820int
2821sys_process_vm_writev(struct tcb *tcp)
2822{
2823	if (entering(tcp)) {
2824		/* arg 1: pid */
2825		tprintf("%ld, ", tcp->u_arg[0]);
2826		/* arg 2: local iov */
2827		if (syserror(tcp))
2828			tprintf("%#lx", tcp->u_arg[1]);
2829		else
2830			tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1);
2831		/* arg 3: local iovcnt */
2832		tprintf(", %lu, ", tcp->u_arg[2]);
2833		/* arg 4: remote iov */
2834		if (syserror(tcp))
2835			tprintf("%#lx", tcp->u_arg[3]);
2836		else
2837			tprint_iov(tcp, tcp->u_arg[4], tcp->u_arg[3], 0);
2838		/* arg 5: remote iovcnt */
2839		/* arg 6: flags */
2840		tprintf(", %lu, %lu", tcp->u_arg[4], tcp->u_arg[5]);
2841	}
2842	return 0;
2843}
2844