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