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