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