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