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