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