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