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