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