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