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