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