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