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