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