]> granicus.if.org Git - strace/blob - process.c
2005-02-05 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 static void
1579 printargv(tcp, addr)
1580 struct tcb *tcp;
1581 long addr;
1582 {
1583         char *cp;
1584         char *sep;
1585         int max = max_strlen / 2;
1586
1587         for (sep = ""; --max >= 0; sep = ", ") {
1588                 if (!abbrev(tcp))
1589                         max++;
1590                 if (umove(tcp, addr, &cp) < 0) {
1591                         tprintf("%#lx", addr);
1592                         return;
1593                 }
1594                 if (cp == 0)
1595                         break;
1596                 tprintf(sep);
1597                 printstr(tcp, (long) cp, -1);
1598                 addr += sizeof(char *);
1599         }
1600         if (cp)
1601                 tprintf(", ...");
1602 }
1603
1604 static void
1605 printargc(fmt, tcp, addr)
1606 char *fmt;
1607 struct tcb *tcp;
1608 long addr;
1609 {
1610         int count;
1611         char *cp;
1612
1613         for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1614                 addr += sizeof(char *);
1615         }
1616         tprintf(fmt, count, count == 1 ? "" : "s");
1617 }
1618
1619 int
1620 sys_execv(tcp)
1621 struct tcb *tcp;
1622 {
1623         if (entering(tcp)) {
1624                 printpath(tcp, tcp->u_arg[0]);
1625                 if (!verbose(tcp))
1626                         tprintf(", %#lx", tcp->u_arg[1]);
1627 #if 0
1628                 else if (abbrev(tcp))
1629                         printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1630 #endif
1631                 else {
1632                         tprintf(", [");
1633                         printargv(tcp, tcp->u_arg[1]);
1634                         tprintf("]");
1635                 }
1636         }
1637         return 0;
1638 }
1639
1640 int
1641 sys_execve(tcp)
1642 struct tcb *tcp;
1643 {
1644         if (entering(tcp)) {
1645                 printpath(tcp, tcp->u_arg[0]);
1646                 if (!verbose(tcp))
1647                         tprintf(", %#lx", tcp->u_arg[1]);
1648 #if 0
1649                 else if (abbrev(tcp))
1650                         printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1651 #endif
1652                 else {
1653                         tprintf(", [");
1654                         printargv(tcp, tcp->u_arg[1]);
1655                         tprintf("]");
1656                 }
1657                 if (!verbose(tcp))
1658                         tprintf(", %#lx", tcp->u_arg[2]);
1659                 else if (abbrev(tcp))
1660                         printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1661                 else {
1662                         tprintf(", [");
1663                         printargv(tcp, tcp->u_arg[2]);
1664                         tprintf("]");
1665                 }
1666         }
1667         return 0;
1668 }
1669
1670 #if UNIXWARE > 2
1671
1672 int sys_rexecve(tcp)
1673 struct tcb *tcp;
1674 {
1675         if (entering (tcp)) {
1676                 sys_execve (tcp);
1677                 tprintf (", %ld", tcp->u_arg[3]);
1678         }
1679         return 0;
1680 }
1681
1682 #endif
1683
1684 int
1685 internal_exec(tcp)
1686 struct tcb *tcp;
1687 {
1688 #ifdef SUNOS4
1689         if (exiting(tcp) && !syserror(tcp) && followfork)
1690                 fixvfork(tcp);
1691 #endif /* SUNOS4 */
1692 #if defined LINUX && defined TCB_WAITEXECVE
1693         if (exiting(tcp) && syserror(tcp))
1694                 tcp->flags &= ~TCB_WAITEXECVE;
1695         else
1696                 tcp->flags |= TCB_WAITEXECVE;
1697 #endif /* LINUX && TCB_WAITEXECVE */
1698         return 0;
1699 }
1700
1701 #ifdef LINUX
1702 #ifndef __WNOTHREAD
1703 #define __WNOTHREAD     0x20000000
1704 #endif
1705 #ifndef __WALL
1706 #define __WALL          0x40000000
1707 #endif
1708 #ifndef __WCLONE
1709 #define __WCLONE        0x80000000
1710 #endif
1711 #endif /* LINUX */
1712
1713 static const struct xlat wait4_options[] = {
1714         { WNOHANG,      "WNOHANG"       },
1715 #ifndef WSTOPPED
1716         { WUNTRACED,    "WUNTRACED"     },
1717 #endif
1718 #ifdef WEXITED
1719         { WEXITED,      "WEXITED"       },
1720 #endif
1721 #ifdef WTRAPPED
1722         { WTRAPPED,     "WTRAPPED"      },
1723 #endif
1724 #ifdef WSTOPPED
1725         { WSTOPPED,     "WSTOPPED"      },
1726 #endif
1727 #ifdef WCONTINUED
1728         { WCONTINUED,   "WCONTINUED"    },
1729 #endif
1730 #ifdef WNOWAIT
1731         { WNOWAIT,      "WNOWAIT"       },
1732 #endif
1733 #ifdef __WCLONE
1734         { __WCLONE,     "__WCLONE"      },
1735 #endif
1736 #ifdef __WALL
1737         { __WALL,       "__WALL"        },
1738 #endif
1739 #ifdef __WNOTHREAD
1740         { __WNOTHREAD,  "__WNOTHREAD"   },
1741 #endif
1742         { 0,            NULL            },
1743 };
1744
1745 #if !defined WCOREFLAG && defined WCOREFLG
1746 # define WCOREFLAG WCOREFLG
1747 #endif
1748 #ifndef WCOREFLAG
1749 #define WCOREFLAG 0x80
1750 #endif
1751
1752 #ifndef W_STOPCODE
1753 #define W_STOPCODE(sig)         ((sig) << 8 | 0x7f)
1754 #endif
1755 #ifndef W_EXITCODE
1756 #define W_EXITCODE(ret, sig)    ((ret) << 8 | (sig))
1757 #endif
1758
1759 static int
1760 printstatus(status)
1761 int status;
1762 {
1763         int exited = 0;
1764
1765         /*
1766          * Here is a tricky presentation problem.  This solution
1767          * is still not entirely satisfactory but since there
1768          * are no wait status constructors it will have to do.
1769          */
1770         if (WIFSTOPPED(status)) {
1771                 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1772                         signame(WSTOPSIG(status)));
1773                 status &= ~W_STOPCODE(WSTOPSIG(status));
1774         }
1775         else if (WIFSIGNALED(status)) {
1776                 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1777                         signame(WTERMSIG(status)),
1778                         WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1779                 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1780         }
1781         else if (WIFEXITED(status)) {
1782                 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1783                         WEXITSTATUS(status));
1784                 exited = 1;
1785                 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1786         }
1787         else {
1788                 tprintf("[%#x]", status);
1789                 return 0;
1790         }
1791
1792         if (status == 0)
1793                 tprintf("]");
1794         else
1795                 tprintf(" | %#x]", status);
1796
1797         return exited;
1798 }
1799
1800 static int
1801 printwaitn(tcp, n, bitness)
1802 struct tcb *tcp;
1803 int n;
1804 int bitness;
1805 {
1806         int status;
1807         int exited = 0;
1808
1809         if (entering(tcp)) {
1810                 tprintf("%ld, ", tcp->u_arg[0]);
1811         } else {
1812                 /* status */
1813                 if (!tcp->u_arg[1])
1814                         tprintf("NULL");
1815                 else if (syserror(tcp) || tcp->u_rval == 0)
1816                         tprintf("%#lx", tcp->u_arg[1]);
1817                 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1818                         tprintf("[?]");
1819                 else
1820                         exited = printstatus(status);
1821                 /* options */
1822                 tprintf(", ");
1823                 if (!printflags(wait4_options, tcp->u_arg[2]))
1824                         tprintf("0");
1825                 if (n == 4) {
1826                         tprintf(", ");
1827                         /* usage */
1828                         if (!tcp->u_arg[3])
1829                                 tprintf("NULL");
1830 #ifdef LINUX
1831                         else if (tcp->u_rval > 0) {
1832 #ifdef LINUX_64BIT
1833                                 if (bitness)
1834                                         printrusage32(tcp, tcp->u_arg[3]);
1835                                 else
1836 #endif
1837                                         printrusage(tcp, tcp->u_arg[3]);
1838                         }
1839 #endif /* LINUX */
1840 #ifdef SUNOS4
1841                         else if (tcp->u_rval > 0 && exited)
1842                                 printrusage(tcp, tcp->u_arg[3]);
1843 #endif /* SUNOS4 */
1844                         else
1845                                 tprintf("%#lx", tcp->u_arg[3]);
1846                 }
1847         }
1848         return 0;
1849 }
1850
1851 int
1852 internal_wait(tcp, flagarg)
1853 struct tcb *tcp;
1854 int flagarg;
1855 {
1856         int got_kids;
1857
1858 #ifdef TCB_CLONE_THREAD
1859         if (tcp->flags & TCB_CLONE_THREAD)
1860                 /* The children we wait for are our parent's children.  */
1861                 got_kids = (tcp->parent->nchildren
1862                             > tcp->parent->nclone_detached);
1863         else
1864                 got_kids = (tcp->nchildren > tcp->nclone_detached);
1865 #else
1866         got_kids = tcp->nchildren > 0;
1867 #endif
1868
1869         if (entering(tcp) && got_kids) {
1870                 /* There are children that this parent should block for.
1871                    But ptrace made us the parent of the traced children
1872                    and the real parent will get ECHILD from the wait call.
1873
1874                    XXX If we attached with strace -f -p PID, then there
1875                    may be untraced dead children the parent could be reaping
1876                    now, but we make him block.  */
1877
1878                 /* ??? WTA: fix bug with hanging children */
1879
1880                 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
1881                         /*
1882                          * There are traced children.  We'll make the parent
1883                          * block to avoid a false ECHILD error due to our
1884                          * ptrace having stolen the children.  However,
1885                          * we shouldn't block if there are zombies to reap.
1886                          * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1887                          */
1888                         struct tcb *child = NULL;
1889                         if (tcp->nzombies > 0 &&
1890                             (tcp->u_arg[0] == -1 ||
1891                              (child = pid2tcb(tcp->u_arg[0])) == NULL))
1892                                 return 0;
1893                         if (tcp->u_arg[0] > 0) {
1894                                 /*
1895                                  * If the parent waits for a specified child
1896                                  * PID, then it must get ECHILD right away
1897                                  * if that PID is not one of its children.
1898                                  * Make sure that the requested PID matches
1899                                  * one of the parent's children that we are
1900                                  * tracing, and don't suspend it otherwise.
1901                                  */
1902                                 if (child == NULL)
1903                                         child = pid2tcb(tcp->u_arg[0]);
1904                                 if (child == NULL || child->parent != (
1905 #ifdef TCB_CLONE_THREAD
1906                                             (tcp->flags & TCB_CLONE_THREAD)
1907                                             ? tcp->parent :
1908 #endif
1909                                             tcp))
1910                                         return 0;
1911                         }
1912                         tcp->flags |= TCB_SUSPENDED;
1913                         tcp->waitpid = tcp->u_arg[0];
1914 #ifdef TCB_CLONE_THREAD
1915                         if (tcp->flags & TCB_CLONE_THREAD)
1916                                 tcp->parent->nclone_waiting++;
1917 #endif
1918                 }
1919         }
1920         if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
1921                 if (tcp->u_arg[flagarg] & WNOHANG) {
1922                         /* We must force a fake result of 0 instead of
1923                            the ECHILD error.  */
1924                         extern int force_result();
1925                         return force_result(tcp, 0, 0);
1926                 }
1927         }
1928         else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
1929                  tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
1930                 /*
1931                  * We just reaped a child we don't know about,
1932                  * presumably a zombie we already droptcb'd.
1933                  */
1934                 tcp->nzombies--;
1935         }
1936         return 0;
1937 }
1938
1939 #ifdef SVR4
1940
1941 int
1942 sys_wait(tcp)
1943 struct tcb *tcp;
1944 {
1945         if (exiting(tcp)) {
1946                 /* The library wrapper stuffs this into the user variable. */
1947                 if (!syserror(tcp))
1948                         printstatus(getrval2(tcp));
1949         }
1950         return 0;
1951 }
1952
1953 #endif /* SVR4 */
1954
1955 #ifdef FREEBSD
1956 int
1957 sys_wait(tcp)
1958 struct tcb *tcp;
1959 {
1960         int status;
1961
1962         if (exiting(tcp)) {
1963                 if (!syserror(tcp)) {
1964                         if (umove(tcp, tcp->u_arg[0], &status) < 0)
1965                                 tprintf("%#lx", tcp->u_arg[0]);
1966                         else
1967                                 printstatus(status);
1968                 }
1969         }
1970         return 0;
1971 }
1972 #endif
1973
1974 int
1975 sys_waitpid(tcp)
1976 struct tcb *tcp;
1977 {
1978         return printwaitn(tcp, 3, 0);
1979 }
1980
1981 int
1982 sys_wait4(tcp)
1983 struct tcb *tcp;
1984 {
1985         return printwaitn(tcp, 4, 0);
1986 }
1987
1988 #ifdef ALPHA
1989 int
1990 sys_osf_wait4(tcp)
1991 struct tcb *tcp;
1992 {
1993         return printwaitn(tcp, 4, 1);
1994 }
1995 #endif
1996
1997 #if defined SVR4 || defined LINUX
1998
1999 static const struct xlat waitid_types[] = {
2000         { P_PID,        "P_PID"         },
2001 #ifdef P_PPID
2002         { P_PPID,       "P_PPID"        },
2003 #endif
2004         { P_PGID,       "P_PGID"        },
2005 #ifdef P_SID
2006         { P_SID,        "P_SID"         },
2007 #endif
2008 #ifdef P_CID
2009         { P_CID,        "P_CID"         },
2010 #endif
2011 #ifdef P_UID
2012         { P_UID,        "P_UID"         },
2013 #endif
2014 #ifdef P_GID
2015         { P_GID,        "P_GID"         },
2016 #endif
2017         { P_ALL,        "P_ALL"         },
2018 #ifdef P_LWPID
2019         { P_LWPID,      "P_LWPID"       },
2020 #endif
2021         { 0,            NULL            },
2022 };
2023
2024 int
2025 sys_waitid(tcp)
2026 struct tcb *tcp;
2027 {
2028         siginfo_t si;
2029         int exited;
2030
2031         if (entering(tcp)) {
2032                 printxval(waitid_types, tcp->u_arg[0], "P_???");
2033                 tprintf(", %ld, ", tcp->u_arg[1]);
2034         }
2035         else {
2036                 /* siginfo */
2037                 exited = 0;
2038                 if (!tcp->u_arg[2])
2039                         tprintf("NULL");
2040                 else if (syserror(tcp))
2041                         tprintf("%#lx", tcp->u_arg[2]);
2042                 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2043                         tprintf("{???}");
2044                 else
2045                         printsiginfo(&si, verbose (tcp));
2046                 /* options */
2047                 tprintf(", ");
2048                 if (!printflags(wait4_options, tcp->u_arg[3]))
2049                         tprintf("0");
2050                 if (tcp->u_nargs > 4) {
2051                         /* usage */
2052                         tprintf(", ");
2053                         if (!tcp->u_arg[4])
2054                                 tprintf("NULL");
2055                         else if (tcp->u_error)
2056                                 tprintf("%#lx", tcp->u_arg[4]);
2057                         else
2058                                 printrusage(tcp, tcp->u_arg[4]);
2059                 }
2060         }
2061         return 0;
2062 }
2063
2064 #endif /* SVR4 or LINUX */
2065
2066 int
2067 sys_alarm(tcp)
2068 struct tcb *tcp;
2069 {
2070         if (entering(tcp))
2071                 tprintf("%lu", tcp->u_arg[0]);
2072         return 0;
2073 }
2074
2075 int
2076 sys_uname(tcp)
2077 struct tcb *tcp;
2078 {
2079         struct utsname uname;
2080
2081         if (exiting(tcp)) {
2082                 if (syserror(tcp) || !verbose(tcp))
2083                         tprintf("%#lx", tcp->u_arg[0]);
2084                 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2085                         tprintf("{...}");
2086                 else if (!abbrev(tcp)) {
2087
2088                         tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2089                                 uname.sysname, uname.nodename);
2090                         tprintf("release=\"%s\", version=\"%s\", ",
2091                                 uname.release, uname.version);
2092                         tprintf("machine=\"%s\"", uname.machine);
2093 #ifdef LINUX
2094 #ifndef __GLIBC__
2095                         tprintf(", domainname=\"%s\"", uname.domainname);
2096 #endif /* __GLIBC__ */
2097 #endif /* LINUX */
2098                         tprintf("}");
2099                 }
2100                 else
2101                         tprintf("{sys=\"%s\", node=\"%s\", ...}",
2102                                 uname.sysname, uname.nodename);
2103         }
2104         return 0;
2105 }
2106
2107 #ifndef SVR4
2108
2109 static const struct xlat ptrace_cmds[] = {
2110 #ifndef FREEBSD
2111         { PTRACE_TRACEME,       "PTRACE_TRACEME"        },
2112         { PTRACE_PEEKTEXT,      "PTRACE_PEEKTEXT",      },
2113         { PTRACE_PEEKDATA,      "PTRACE_PEEKDATA",      },
2114         { PTRACE_PEEKUSER,      "PTRACE_PEEKUSER",      },
2115         { PTRACE_POKETEXT,      "PTRACE_POKETEXT",      },
2116         { PTRACE_POKEDATA,      "PTRACE_POKEDATA",      },
2117         { PTRACE_POKEUSER,      "PTRACE_POKEUSER",      },
2118         { PTRACE_CONT,          "PTRACE_CONT"           },
2119         { PTRACE_KILL,          "PTRACE_KILL"           },
2120         { PTRACE_SINGLESTEP,    "PTRACE_SINGLESTEP"     },
2121         { PTRACE_ATTACH,        "PTRACE_ATTACH"         },
2122         { PTRACE_DETACH,        "PTRACE_DETACH"         },
2123 #ifdef PTRACE_GETREGS
2124         { PTRACE_GETREGS,       "PTRACE_GETREGS"        },
2125 #endif
2126 #ifdef PTRACE_SETREGS
2127         { PTRACE_SETREGS,       "PTRACE_SETREGS"        },
2128 #endif
2129 #ifdef PTRACE_GETFPREGS
2130         { PTRACE_GETFPREGS,     "PTRACE_GETFPREGS",     },
2131 #endif
2132 #ifdef PTRACE_SETFPREGS
2133         { PTRACE_SETFPREGS,     "PTRACE_SETFPREGS",     },
2134 #endif
2135 #ifdef PTRACE_GETFPXREGS
2136         { PTRACE_GETFPXREGS,    "PTRACE_GETFPXREGS",    },
2137 #endif
2138 #ifdef PTRACE_SETFPXREGS
2139         { PTRACE_SETFPXREGS,    "PTRACE_SETFPXREGS",    },
2140 #endif
2141 #ifdef SUNOS4
2142         { PTRACE_READDATA,      "PTRACE_READDATA"       },
2143         { PTRACE_WRITEDATA,     "PTRACE_WRITEDATA"      },
2144         { PTRACE_READTEXT,      "PTRACE_READTEXT"       },
2145         { PTRACE_WRITETEXT,     "PTRACE_WRITETEXT"      },
2146         { PTRACE_GETFPAREGS,    "PTRACE_GETFPAREGS"     },
2147         { PTRACE_SETFPAREGS,    "PTRACE_SETFPAREGS"     },
2148 #ifdef SPARC
2149         { PTRACE_GETWINDOW,     "PTRACE_GETWINDOW"      },
2150         { PTRACE_SETWINDOW,     "PTRACE_SETWINDOW"      },
2151 #else /* !SPARC */
2152         { PTRACE_22,            "PTRACE_PTRACE_22"      },
2153         { PTRACE_23,            "PTRACE_PTRACE_23"      },
2154 #endif /* !SPARC */
2155 #endif /* SUNOS4 */
2156         { PTRACE_SYSCALL,       "PTRACE_SYSCALL"        },
2157 #ifdef SUNOS4
2158         { PTRACE_DUMPCORE,      "PTRACE_DUMPCORE"       },
2159 #ifdef I386
2160         { PTRACE_SETWRBKPT,     "PTRACE_SETWRBKPT"      },
2161         { PTRACE_SETACBKPT,     "PTRACE_SETACBKPT"      },
2162         { PTRACE_CLRDR7,        "PTRACE_CLRDR7"         },
2163 #else /* !I386 */
2164         { PTRACE_26,            "PTRACE_26"             },
2165         { PTRACE_27,            "PTRACE_27"             },
2166         { PTRACE_28,            "PTRACE_28"             },
2167 #endif /* !I386 */
2168         { PTRACE_GETUCODE,      "PTRACE_GETUCODE"       },
2169 #endif /* SUNOS4 */
2170 #else /* FREEBSD */
2171         { PT_TRACE_ME,          "PT_TRACE_ME"           },
2172         { PT_READ_I,            "PT_READ_I"             },
2173         { PT_READ_D,            "PT_READ_D"             },
2174         { PT_WRITE_I,           "PT_WRITE_I"            },
2175         { PT_WRITE_D,           "PT_WRITE_D"            },
2176 #ifdef PT_READ_U
2177         { PT_READ_U,            "PT_READ_U"             },
2178 #endif
2179         { PT_CONTINUE,          "PT_CONTINUE"           },
2180         { PT_KILL,              "PT_KILL"               },
2181         { PT_STEP,              "PT_STEP"               },
2182         { PT_ATTACH,            "PT_ATTACH"             },
2183         { PT_DETACH,            "PT_DETACH"             },
2184         { PT_GETREGS,           "PT_GETREGS"            },
2185         { PT_SETREGS,           "PT_SETREGS"            },
2186         { PT_GETFPREGS,         "PT_GETFPREGS"          },
2187         { PT_SETFPREGS,         "PT_SETFPREGS"          },
2188         { PT_GETDBREGS,         "PT_GETDBREGS"          },
2189         { PT_SETDBREGS,         "PT_SETDBREGS"          },
2190 #endif /* FREEBSD */
2191         { 0,                    NULL                    },
2192 };
2193
2194 #ifndef FREEBSD
2195 #ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2196 static
2197 #endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2198 const struct xlat struct_user_offsets[] = {
2199 #ifdef LINUX
2200 #if defined(S390) || defined(S390X)
2201         { PT_PSWMASK,           "psw_mask"                              },
2202         { PT_PSWADDR,           "psw_addr"                              },
2203         { PT_GPR0,              "gpr0"                                  },
2204         { PT_GPR1,              "gpr1"                                  },
2205         { PT_GPR2,              "gpr2"                                  },
2206         { PT_GPR3,              "gpr3"                                  },
2207         { PT_GPR4,              "gpr4"                                  },
2208         { PT_GPR5,              "gpr5"                                  },
2209         { PT_GPR6,              "gpr6"                                  },
2210         { PT_GPR7,              "gpr7"                                  },
2211         { PT_GPR8,              "gpr8"                                  },
2212         { PT_GPR9,              "gpr9"                                  },
2213         { PT_GPR10,             "gpr10"                                 },
2214         { PT_GPR11,             "gpr11"                                 },
2215         { PT_GPR12,             "gpr12"                                 },
2216         { PT_GPR13,             "gpr13"                                 },
2217         { PT_GPR14,             "gpr14"                                 },
2218         { PT_GPR15,             "gpr15"                                 },
2219         { PT_ACR0,              "acr0"                                  },
2220         { PT_ACR1,              "acr1"                                  },
2221         { PT_ACR2,              "acr2"                                  },
2222         { PT_ACR3,              "acr3"                                  },
2223         { PT_ACR4,              "acr4"                                  },
2224         { PT_ACR5,              "acr5"                                  },
2225         { PT_ACR6,              "acr6"                                  },
2226         { PT_ACR7,              "acr7"                                  },
2227         { PT_ACR8,              "acr8"                                  },
2228         { PT_ACR9,              "acr9"                                  },
2229         { PT_ACR10,             "acr10"                                 },
2230         { PT_ACR11,             "acr11"                                 },
2231         { PT_ACR12,             "acr12"                                 },
2232         { PT_ACR13,             "acr13"                                 },
2233         { PT_ACR14,             "acr14"                                 },
2234         { PT_ACR15,             "acr15"                                 },
2235         { PT_ORIGGPR2,          "orig_gpr2"                             },
2236         { PT_FPC,               "fpc"                                   },
2237 #if defined(S390)
2238         { PT_FPR0_HI,           "fpr0.hi"                               },
2239         { PT_FPR0_LO,           "fpr0.lo"                               },
2240         { PT_FPR1_HI,           "fpr1.hi"                               },
2241         { PT_FPR1_LO,           "fpr1.lo"                               },
2242         { PT_FPR2_HI,           "fpr2.hi"                               },
2243         { PT_FPR2_LO,           "fpr2.lo"                               },
2244         { PT_FPR3_HI,           "fpr3.hi"                               },
2245         { PT_FPR3_LO,           "fpr3.lo"                               },
2246         { PT_FPR4_HI,           "fpr4.hi"                               },
2247         { PT_FPR4_LO,           "fpr4.lo"                               },
2248         { PT_FPR5_HI,           "fpr5.hi"                               },
2249         { PT_FPR5_LO,           "fpr5.lo"                               },
2250         { PT_FPR6_HI,           "fpr6.hi"                               },
2251         { PT_FPR6_LO,           "fpr6.lo"                               },
2252         { PT_FPR7_HI,           "fpr7.hi"                               },
2253         { PT_FPR7_LO,           "fpr7.lo"                               },
2254         { PT_FPR8_HI,           "fpr8.hi"                               },
2255         { PT_FPR8_LO,           "fpr8.lo"                               },
2256         { PT_FPR9_HI,           "fpr9.hi"                               },
2257         { PT_FPR9_LO,           "fpr9.lo"                               },
2258         { PT_FPR10_HI,          "fpr10.hi"                              },
2259         { PT_FPR10_LO,          "fpr10.lo"                              },
2260         { PT_FPR11_HI,          "fpr11.hi"                              },
2261         { PT_FPR11_LO,          "fpr11.lo"                              },
2262         { PT_FPR12_HI,          "fpr12.hi"                              },
2263         { PT_FPR12_LO,          "fpr12.lo"                              },
2264         { PT_FPR13_HI,          "fpr13.hi"                              },
2265         { PT_FPR13_LO,          "fpr13.lo"                              },
2266         { PT_FPR14_HI,          "fpr14.hi"                              },
2267         { PT_FPR14_LO,          "fpr14.lo"                              },
2268         { PT_FPR15_HI,          "fpr15.hi"                              },
2269         { PT_FPR15_LO,          "fpr15.lo"                              },
2270 #endif
2271 #if defined(S390X)
2272         { PT_FPR0,              "fpr0"                                  },
2273         { PT_FPR1,              "fpr1"                                  },
2274         { PT_FPR2,              "fpr2"                                  },
2275         { PT_FPR3,              "fpr3"                                  },
2276         { PT_FPR4,              "fpr4"                                  },
2277         { PT_FPR5,              "fpr5"                                  },
2278         { PT_FPR6,              "fpr6"                                  },
2279         { PT_FPR7,              "fpr7"                                  },
2280         { PT_FPR8,              "fpr8"                                  },
2281         { PT_FPR9,              "fpr9"                                  },
2282         { PT_FPR10,             "fpr10"                                 },
2283         { PT_FPR11,             "fpr11"                                 },
2284         { PT_FPR12,             "fpr12"                                 },
2285         { PT_FPR13,             "fpr13"                                 },
2286         { PT_FPR14,             "fpr14"                                 },
2287         { PT_FPR15,             "fpr15"                                 },
2288 #endif
2289         { PT_CR_9,              "cr9"                                   },
2290         { PT_CR_10,             "cr10"                                  },
2291         { PT_CR_11,             "cr11"                                  },
2292         { PT_IEEE_IP,           "ieee_exception_ip"                     },
2293 #endif
2294 #if defined(SPARC)
2295         /* XXX No support for these offsets yet. */
2296 #elif defined(HPPA)
2297         /* XXX No support for these offsets yet. */
2298 #elif defined(POWERPC)
2299 #ifndef PT_ORIG_R3
2300 #define PT_ORIG_R3 34
2301 #endif
2302 #define REGSIZE (sizeof(unsigned long))
2303         { REGSIZE*PT_R0,                "r0"                            },
2304         { REGSIZE*PT_R1,                "r1"                            },
2305         { REGSIZE*PT_R2,                "r2"                            },
2306         { REGSIZE*PT_R3,                "r3"                            },
2307         { REGSIZE*PT_R4,                "r4"                            },
2308         { REGSIZE*PT_R5,                "r5"                            },
2309         { REGSIZE*PT_R6,                "r6"                            },
2310         { REGSIZE*PT_R7,                "r7"                            },
2311         { REGSIZE*PT_R8,                "r8"                            },
2312         { REGSIZE*PT_R9,                "r9"                            },
2313         { REGSIZE*PT_R10,               "r10"                           },
2314         { REGSIZE*PT_R11,               "r11"                           },
2315         { REGSIZE*PT_R12,               "r12"                           },
2316         { REGSIZE*PT_R13,               "r13"                           },
2317         { REGSIZE*PT_R14,               "r14"                           },
2318         { REGSIZE*PT_R15,               "r15"                           },
2319         { REGSIZE*PT_R16,               "r16"                           },
2320         { REGSIZE*PT_R17,               "r17"                           },
2321         { REGSIZE*PT_R18,               "r18"                           },
2322         { REGSIZE*PT_R19,               "r19"                           },
2323         { REGSIZE*PT_R20,               "r20"                           },
2324         { REGSIZE*PT_R21,               "r21"                           },
2325         { REGSIZE*PT_R22,               "r22"                           },
2326         { REGSIZE*PT_R23,               "r23"                           },
2327         { REGSIZE*PT_R24,               "r24"                           },
2328         { REGSIZE*PT_R25,               "r25"                           },
2329         { REGSIZE*PT_R26,               "r26"                           },
2330         { REGSIZE*PT_R27,               "r27"                           },
2331         { REGSIZE*PT_R28,               "r28"                           },
2332         { REGSIZE*PT_R29,               "r29"                           },
2333         { REGSIZE*PT_R30,               "r30"                           },
2334         { REGSIZE*PT_R31,               "r31"                           },
2335         { REGSIZE*PT_NIP,               "NIP"                           },
2336         { REGSIZE*PT_MSR,               "MSR"                           },
2337         { REGSIZE*PT_ORIG_R3,           "ORIG_R3"                       },
2338         { REGSIZE*PT_CTR,               "CTR"                           },
2339         { REGSIZE*PT_LNK,               "LNK"                           },
2340         { REGSIZE*PT_XER,               "XER"                           },
2341         { REGSIZE*PT_CCR,               "CCR"                           },
2342         { REGSIZE*PT_FPR0,              "FPR0"                          },
2343 #undef REGSIZE
2344 #else
2345 #ifdef ALPHA
2346         { 0,                    "r0"                                    },
2347         { 1,                    "r1"                                    },
2348         { 2,                    "r2"                                    },
2349         { 3,                    "r3"                                    },
2350         { 4,                    "r4"                                    },
2351         { 5,                    "r5"                                    },
2352         { 6,                    "r6"                                    },
2353         { 7,                    "r7"                                    },
2354         { 8,                    "r8"                                    },
2355         { 9,                    "r9"                                    },
2356         { 10,                   "r10"                                   },
2357         { 11,                   "r11"                                   },
2358         { 12,                   "r12"                                   },
2359         { 13,                   "r13"                                   },
2360         { 14,                   "r14"                                   },
2361         { 15,                   "r15"                                   },
2362         { 16,                   "r16"                                   },
2363         { 17,                   "r17"                                   },
2364         { 18,                   "r18"                                   },
2365         { 19,                   "r19"                                   },
2366         { 20,                   "r20"                                   },
2367         { 21,                   "r21"                                   },
2368         { 22,                   "r22"                                   },
2369         { 23,                   "r23"                                   },
2370         { 24,                   "r24"                                   },
2371         { 25,                   "r25"                                   },
2372         { 26,                   "r26"                                   },
2373         { 27,                   "r27"                                   },
2374         { 28,                   "r28"                                   },
2375         { 29,                   "gp"                                    },
2376         { 30,                   "fp"                                    },
2377         { 31,                   "zero"                                  },
2378         { 32,                   "fp0"                                   },
2379         { 33,                   "fp"                                    },
2380         { 34,                   "fp2"                                   },
2381         { 35,                   "fp3"                                   },
2382         { 36,                   "fp4"                                   },
2383         { 37,                   "fp5"                                   },
2384         { 38,                   "fp6"                                   },
2385         { 39,                   "fp7"                                   },
2386         { 40,                   "fp8"                                   },
2387         { 41,                   "fp9"                                   },
2388         { 42,                   "fp10"                                  },
2389         { 43,                   "fp11"                                  },
2390         { 44,                   "fp12"                                  },
2391         { 45,                   "fp13"                                  },
2392         { 46,                   "fp14"                                  },
2393         { 47,                   "fp15"                                  },
2394         { 48,                   "fp16"                                  },
2395         { 49,                   "fp17"                                  },
2396         { 50,                   "fp18"                                  },
2397         { 51,                   "fp19"                                  },
2398         { 52,                   "fp20"                                  },
2399         { 53,                   "fp21"                                  },
2400         { 54,                   "fp22"                                  },
2401         { 55,                   "fp23"                                  },
2402         { 56,                   "fp24"                                  },
2403         { 57,                   "fp25"                                  },
2404         { 58,                   "fp26"                                  },
2405         { 59,                   "fp27"                                  },
2406         { 60,                   "fp28"                                  },
2407         { 61,                   "fp29"                                  },
2408         { 62,                   "fp30"                                  },
2409         { 63,                   "fp31"                                  },
2410         { 64,                   "pc"                                    },
2411 #else /* !ALPHA */
2412 #ifdef IA64
2413         { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2414         { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2415         { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2416         { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2417         { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2418         { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2419         { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2420         { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2421         { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2422         { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2423         { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2424         { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2425         { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2426         { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2427         { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2428         { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2429         { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2430         { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2431         { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2432         { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2433         { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2434         { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2435         { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2436         { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2437         { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2438         { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2439         { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2440         { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2441         { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2442         { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2443         { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2444         { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2445         /* switch stack: */
2446         { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2447         { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2448         { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2449         { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2450         { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2451         { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2452         { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2453         { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2454         { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2455         { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2456         { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2457         { PT_B4, "b4" }, { PT_B5, "b5" },
2458         { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2459         /* pt_regs */
2460         { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2461         { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2462         { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2463         { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2464         { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2465         { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2466         { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2467         { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2468         { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2469         { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2470         { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2471         { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2472         { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2473         { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2474         { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2475         { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2476         { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2477 # ifdef PT_AR_CSD
2478         { PT_AR_CSD, "ar.csd" },
2479 # endif
2480 # ifdef PT_AR_SSD
2481         { PT_AR_SSD, "ar.ssd" },
2482 # endif
2483         { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2484 #else /* !IA64 */
2485 #ifdef I386
2486         { 4*EBX,                "4*EBX"                                 },
2487         { 4*ECX,                "4*ECX"                                 },
2488         { 4*EDX,                "4*EDX"                                 },
2489         { 4*ESI,                "4*ESI"                                 },
2490         { 4*EDI,                "4*EDI"                                 },
2491         { 4*EBP,                "4*EBP"                                 },
2492         { 4*EAX,                "4*EAX"                                 },
2493         { 4*DS,                 "4*DS"                                  },
2494         { 4*ES,                 "4*ES"                                  },
2495         { 4*FS,                 "4*FS"                                  },
2496         { 4*GS,                 "4*GS"                                  },
2497         { 4*ORIG_EAX,           "4*ORIG_EAX"                            },
2498         { 4*EIP,                "4*EIP"                                 },
2499         { 4*CS,                 "4*CS"                                  },
2500         { 4*EFL,                "4*EFL"                                 },
2501         { 4*UESP,               "4*UESP"                                },
2502         { 4*SS,                 "4*SS"                                  },
2503 #else /* !I386 */
2504 #ifdef X86_64
2505         { 8*RDI,                "8*RDI"                                 },
2506         { 8*RSI,                "8*RSI"                                 },
2507         { 8*RDX,                "8*RDX"                                 },
2508         { 8*R10,                "8*R10" },
2509         { 8*R8,                 "8*R8" },
2510         { 8*R9,                 "8*R9" },
2511         { 8*RBX,                "8*RBX"                                 },
2512         { 8*RCX,                "8*RCX"                                 },
2513         { 8*RBP,                "8*RBP"                                 },
2514         { 8*RAX,                "8*RAX"                                 },
2515 #if 0
2516         { 8*DS,                 "8*DS"                                  },
2517         { 8*ES,                 "8*ES"                                  },
2518         { 8*FS,                 "8*FS"                                  },
2519         { 8*GS,                 "8*GS"                                  },
2520 #endif
2521         { 8*ORIG_RAX,           "8*ORIG_EAX"                            },
2522         { 8*RIP,                "8*RIP"                                 },
2523         { 8*CS,                 "8*CS"                                  },
2524         { 8*EFLAGS,             "8*EFL"                                 },
2525         { 8*RSP,                "8*RSP"                         },
2526         { 8*SS,                 "8*SS"                                  },
2527         { 8*R11,                "8*R11" },
2528         { 8*R12,                "8*R12" },
2529         { 8*R13,                "8*R13" },
2530         { 8*R14,                "8*R14" },
2531         { 8*R15,                "8*R15" },
2532 #endif
2533 #ifdef M68K
2534         { 4*PT_D1,              "4*PT_D1"                               },
2535         { 4*PT_D2,              "4*PT_D2"                               },
2536         { 4*PT_D3,              "4*PT_D3"                               },
2537         { 4*PT_D4,              "4*PT_D4"                               },
2538         { 4*PT_D5,              "4*PT_D5"                               },
2539         { 4*PT_D6,              "4*PT_D6"                               },
2540         { 4*PT_D7,              "4*PT_D7"                               },
2541         { 4*PT_A0,              "4*PT_A0"                               },
2542         { 4*PT_A1,              "4*PT_A1"                               },
2543         { 4*PT_A2,              "4*PT_A2"                               },
2544         { 4*PT_A3,              "4*PT_A3"                               },
2545         { 4*PT_A4,              "4*PT_A4"                               },
2546         { 4*PT_A5,              "4*PT_A5"                               },
2547         { 4*PT_A6,              "4*PT_A6"                               },
2548         { 4*PT_D0,              "4*PT_D0"                               },
2549         { 4*PT_USP,             "4*PT_USP"                              },
2550         { 4*PT_ORIG_D0,         "4*PT_ORIG_D0"                          },
2551         { 4*PT_SR,              "4*PT_SR"                               },
2552         { 4*PT_PC,              "4*PT_PC"                               },
2553 #endif /* M68K */
2554 #endif /* !I386 */
2555 #ifdef SH
2556        { 4*REG_REG0,           "4*REG_REG0"                            },
2557        { 4*(REG_REG0+1),       "4*REG_REG1"                            },
2558        { 4*(REG_REG0+2),       "4*REG_REG2"                            },
2559        { 4*(REG_REG0+3),       "4*REG_REG3"                            },
2560        { 4*(REG_REG0+4),       "4*REG_REG4"                            },
2561        { 4*(REG_REG0+5),       "4*REG_REG5"                            },
2562        { 4*(REG_REG0+6),       "4*REG_REG6"                            },
2563        { 4*(REG_REG0+7),       "4*REG_REG7"                            },
2564        { 4*(REG_REG0+8),       "4*REG_REG8"                            },
2565        { 4*(REG_REG0+9),       "4*REG_REG9"                            },
2566        { 4*(REG_REG0+10),      "4*REG_REG10"                           },
2567        { 4*(REG_REG0+11),      "4*REG_REG11"                           },
2568        { 4*(REG_REG0+12),      "4*REG_REG12"                           },
2569        { 4*(REG_REG0+13),      "4*REG_REG13"                           },
2570        { 4*(REG_REG0+14),      "4*REG_REG14"                           },
2571        { 4*REG_REG15,          "4*REG_REG15"                           },
2572        { 4*REG_PC,             "4*REG_PC"                              },
2573        { 4*REG_PR,             "4*REG_PR"                              },
2574        { 4*REG_SR,             "4*REG_SR"                              },
2575        { 4*REG_GBR,            "4*REG_GBR"                             },
2576        { 4*REG_MACH,           "4*REG_MACH"                            },
2577        { 4*REG_MACL,           "4*REG_MACL"                            },
2578        { 4*REG_SYSCALL,        "4*REG_SYSCALL"                         },
2579        { 4*REG_FPUL,           "4*REG_FPUL"                            },
2580        { 4*REG_FPREG0,         "4*REG_FPREG0"                          },
2581        { 4*(REG_FPREG0+1),     "4*REG_FPREG1"                          },
2582        { 4*(REG_FPREG0+2),     "4*REG_FPREG2"                          },
2583        { 4*(REG_FPREG0+3),     "4*REG_FPREG3"                          },
2584        { 4*(REG_FPREG0+4),     "4*REG_FPREG4"                          },
2585        { 4*(REG_FPREG0+5),     "4*REG_FPREG5"                          },
2586        { 4*(REG_FPREG0+6),     "4*REG_FPREG6"                          },
2587        { 4*(REG_FPREG0+7),     "4*REG_FPREG7"                          },
2588        { 4*(REG_FPREG0+8),     "4*REG_FPREG8"                          },
2589        { 4*(REG_FPREG0+9),     "4*REG_FPREG9"                          },
2590        { 4*(REG_FPREG0+10),    "4*REG_FPREG10"                         },
2591        { 4*(REG_FPREG0+11),    "4*REG_FPREG11"                         },
2592        { 4*(REG_FPREG0+12),    "4*REG_FPREG12"                         },
2593        { 4*(REG_FPREG0+13),    "4*REG_FPREG13"                         },
2594        { 4*(REG_FPREG0+14),    "4*REG_FPREG14"                         },
2595        { 4*REG_FPREG15,        "4*REG_FPREG15"                         },
2596 #ifdef REG_XDREG0
2597        { 4*REG_XDREG0,         "4*REG_XDREG0"                          },
2598        { 4*(REG_XDREG0+2),     "4*REG_XDREG2"                          },
2599        { 4*(REG_XDREG0+4),     "4*REG_XDREG4"                          },
2600        { 4*(REG_XDREG0+6),     "4*REG_XDREG6"                          },
2601        { 4*(REG_XDREG0+8),     "4*REG_XDREG8"                          },
2602        { 4*(REG_XDREG0+10),    "4*REG_XDREG10"                         },
2603        { 4*(REG_XDREG0+12),    "4*REG_XDREG12"                         },
2604        { 4*REG_XDREG14,        "4*REG_XDREG14"                         },
2605 #endif
2606        { 4*REG_FPSCR,          "4*REG_FPSCR"                           },
2607 #endif /* SH */
2608 #ifdef SH64
2609         { 0,                    "PC(L)"                                 },
2610         { 4,                    "PC(U)"                                 },
2611         { 8,                    "SR(L)"                                 },
2612         { 12,                   "SR(U)"                                 },
2613         { 16,                   "syscall no.(L)"                        },
2614         { 20,                   "syscall_no.(U)"                        },
2615         { 24,                   "R0(L)"                                 },
2616         { 28,                   "R0(U)"                                 },
2617         { 32,                   "R1(L)"                                 },
2618         { 36,                   "R1(U)"                                 },
2619         { 40,                   "R2(L)"                                 },
2620         { 44,                   "R2(U)"                                 },
2621         { 48,                   "R3(L)"                                 },
2622         { 52,                   "R3(U)"                                 },
2623         { 56,                   "R4(L)"                                 },
2624         { 60,                   "R4(U)"                                 },
2625         { 64,                   "R5(L)"                                 },
2626         { 68,                   "R5(U)"                                 },
2627         { 72,                   "R6(L)"                                 },
2628         { 76,                   "R6(U)"                                 },
2629         { 80,                   "R7(L)"                                 },
2630         { 84,                   "R7(U)"                                 },
2631         { 88,                   "R8(L)"                                 },
2632         { 92,                   "R8(U)"                                 },
2633         { 96,                   "R9(L)"                                 },
2634         { 100,                  "R9(U)"                                 },
2635         { 104,                  "R10(L)"                                },
2636         { 108,                  "R10(U)"                                },
2637         { 112,                  "R11(L)"                                },
2638         { 116,                  "R11(U)"                                },
2639         { 120,                  "R12(L)"                                },
2640         { 124,                  "R12(U)"                                },
2641         { 128,                  "R13(L)"                                },
2642         { 132,                  "R13(U)"                                },
2643         { 136,                  "R14(L)"                                },
2644         { 140,                  "R14(U)"                                },
2645         { 144,                  "R15(L)"                                },
2646         { 148,                  "R15(U)"                                },
2647         { 152,                  "R16(L)"                                },
2648         { 156,                  "R16(U)"                                },
2649         { 160,                  "R17(L)"                                },
2650         { 164,                  "R17(U)"                                },
2651         { 168,                  "R18(L)"                                },
2652         { 172,                  "R18(U)"                                },
2653         { 176,                  "R19(L)"                                },
2654         { 180,                  "R19(U)"                                },
2655         { 184,                  "R20(L)"                                },
2656         { 188,                  "R20(U)"                                },
2657         { 192,                  "R21(L)"                                },
2658         { 196,                  "R21(U)"                                },
2659         { 200,                  "R22(L)"                                },
2660         { 204,                  "R22(U)"                                },
2661         { 208,                  "R23(L)"                                },
2662         { 212,                  "R23(U)"                                },
2663         { 216,                  "R24(L)"                                },
2664         { 220,                  "R24(U)"                                },
2665         { 224,                  "R25(L)"                                },
2666         { 228,                  "R25(U)"                                },
2667         { 232,                  "R26(L)"                                },
2668         { 236,                  "R26(U)"                                },
2669         { 240,                  "R27(L)"                                },
2670         { 244,                  "R27(U)"                                },
2671         { 248,                  "R28(L)"                                },
2672         { 252,                  "R28(U)"                                },
2673         { 256,                  "R29(L)"                                },
2674         { 260,                  "R29(U)"                                },
2675         { 264,                  "R30(L)"                                },
2676         { 268,                  "R30(U)"                                },
2677         { 272,                  "R31(L)"                                },
2678         { 276,                  "R31(U)"                                },
2679         { 280,                  "R32(L)"                                },
2680         { 284,                  "R32(U)"                                },
2681         { 288,                  "R33(L)"                                },
2682         { 292,                  "R33(U)"                                },
2683         { 296,                  "R34(L)"                                },
2684         { 300,                  "R34(U)"                                },
2685         { 304,                  "R35(L)"                                },
2686         { 308,                  "R35(U)"                                },
2687         { 312,                  "R36(L)"                                },
2688         { 316,                  "R36(U)"                                },
2689         { 320,                  "R37(L)"                                },
2690         { 324,                  "R37(U)"                                },
2691         { 328,                  "R38(L)"                                },
2692         { 332,                  "R38(U)"                                },
2693         { 336,                  "R39(L)"                                },
2694         { 340,                  "R39(U)"                                },
2695         { 344,                  "R40(L)"                                },
2696         { 348,                  "R40(U)"                                },
2697         { 352,                  "R41(L)"                                },
2698         { 356,                  "R41(U)"                                },
2699         { 360,                  "R42(L)"                                },
2700         { 364,                  "R42(U)"                                },
2701         { 368,                  "R43(L)"                                },
2702         { 372,                  "R43(U)"                                },
2703         { 376,                  "R44(L)"                                },
2704         { 380,                  "R44(U)"                                },
2705         { 384,                  "R45(L)"                                },
2706         { 388,                  "R45(U)"                                },
2707         { 392,                  "R46(L)"                                },
2708         { 396,                  "R46(U)"                                },
2709         { 400,                  "R47(L)"                                },
2710         { 404,                  "R47(U)"                                },
2711         { 408,                  "R48(L)"                                },
2712         { 412,                  "R48(U)"                                },
2713         { 416,                  "R49(L)"                                },
2714         { 420,                  "R49(U)"                                },
2715         { 424,                  "R50(L)"                                },
2716         { 428,                  "R50(U)"                                },
2717         { 432,                  "R51(L)"                                },
2718         { 436,                  "R51(U)"                                },
2719         { 440,                  "R52(L)"                                },
2720         { 444,                  "R52(U)"                                },
2721         { 448,                  "R53(L)"                                },
2722         { 452,                  "R53(U)"                                },
2723         { 456,                  "R54(L)"                                },
2724         { 460,                  "R54(U)"                                },
2725         { 464,                  "R55(L)"                                },
2726         { 468,                  "R55(U)"                                },
2727         { 472,                  "R56(L)"                                },
2728         { 476,                  "R56(U)"                                },
2729         { 480,                  "R57(L)"                                },
2730         { 484,                  "R57(U)"                                },
2731         { 488,                  "R58(L)"                                },
2732         { 492,                  "R58(U)"                                },
2733         { 496,                  "R59(L)"                                },
2734         { 500,                  "R59(U)"                                },
2735         { 504,                  "R60(L)"                                },
2736         { 508,                  "R60(U)"                                },
2737         { 512,                  "R61(L)"                                },
2738         { 516,                  "R61(U)"                                },
2739         { 520,                  "R62(L)"                                },
2740         { 524,                  "R62(U)"                                },
2741         { 528,                  "TR0(L)"                                },
2742         { 532,                  "TR0(U)"                                },
2743         { 536,                  "TR1(L)"                                },
2744         { 540,                  "TR1(U)"                                },
2745         { 544,                  "TR2(L)"                                },
2746         { 548,                  "TR2(U)"                                },
2747         { 552,                  "TR3(L)"                                },
2748         { 556,                  "TR3(U)"                                },
2749         { 560,                  "TR4(L)"                                },
2750         { 564,                  "TR4(U)"                                },
2751         { 568,                  "TR5(L)"                                },
2752         { 572,                  "TR5(U)"                                },
2753         { 576,                  "TR6(L)"                                },
2754         { 580,                  "TR6(U)"                                },
2755         { 584,                  "TR7(L)"                                },
2756         { 588,                  "TR7(U)"                                },
2757         /* This entry is in case pt_regs contains dregs (depends on
2758            the kernel build options). */
2759         { uoff(regs),           "offsetof(struct user, regs)"           },
2760         { uoff(fpu),            "offsetof(struct user, fpu)"            },
2761 #endif
2762 #ifdef ARM
2763         { uoff(regs.ARM_r0),    "r0"                                    },
2764         { uoff(regs.ARM_r1),    "r1"                                    },
2765         { uoff(regs.ARM_r2),    "r2"                                    },
2766         { uoff(regs.ARM_r3),    "r3"                                    },
2767         { uoff(regs.ARM_r4),    "r4"                                    },
2768         { uoff(regs.ARM_r5),    "r5"                                    },
2769         { uoff(regs.ARM_r6),    "r6"                                    },
2770         { uoff(regs.ARM_r7),    "r7"                                    },
2771         { uoff(regs.ARM_r8),    "r8"                                    },
2772         { uoff(regs.ARM_r9),    "r9"                                    },
2773         { uoff(regs.ARM_r10),   "r10"                                   },
2774         { uoff(regs.ARM_fp),    "fp"                                    },
2775         { uoff(regs.ARM_ip),    "ip"                                    },
2776         { uoff(regs.ARM_sp),    "sp"                                    },
2777         { uoff(regs.ARM_lr),    "lr"                                    },
2778         { uoff(regs.ARM_pc),    "pc"                                    },
2779         { uoff(regs.ARM_cpsr),  "cpsr"                                  },
2780 #endif
2781
2782 #if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64)
2783         { uoff(u_fpvalid),      "offsetof(struct user, u_fpvalid)"      },
2784 #endif
2785 #if  defined(I386) || defined(X86_64)
2786         { uoff(i387),           "offsetof(struct user, i387)"           },
2787 #else /* !I386 */
2788 #ifdef M68K
2789         { uoff(m68kfp),         "offsetof(struct user, m68kfp)"         },
2790 #endif /* M68K */
2791 #endif /* !I386 */
2792         { uoff(u_tsize),        "offsetof(struct user, u_tsize)"        },
2793         { uoff(u_dsize),        "offsetof(struct user, u_dsize)"        },
2794         { uoff(u_ssize),        "offsetof(struct user, u_ssize)"        },
2795 #if !defined(SPARC64)
2796         { uoff(start_code),     "offsetof(struct user, start_code)"     },
2797 #endif
2798 #ifdef SH64
2799         { uoff(start_data),     "offsetof(struct user, start_data)"     },
2800 #endif
2801 #if !defined(SPARC64)
2802         { uoff(start_stack),    "offsetof(struct user, start_stack)"    },
2803 #endif
2804         { uoff(signal),         "offsetof(struct user, signal)"         },
2805 #if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
2806         { uoff(reserved),       "offsetof(struct user, reserved)"       },
2807 #endif
2808 #if !defined(SPARC64)
2809         { uoff(u_ar0),          "offsetof(struct user, u_ar0)"          },
2810 #endif
2811 #if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64)
2812         { uoff(u_fpstate),      "offsetof(struct user, u_fpstate)"      },
2813 #endif
2814         { uoff(magic),          "offsetof(struct user, magic)"          },
2815         { uoff(u_comm),         "offsetof(struct user, u_comm)"         },
2816 #if defined(I386) || defined(X86_64)
2817         { uoff(u_debugreg),     "offsetof(struct user, u_debugreg)"     },
2818 #endif /* I386 */
2819 #endif /* !IA64 */
2820 #endif /* !ALPHA */
2821 #endif /* !POWERPC/!SPARC */
2822 #endif /* LINUX */
2823 #ifdef SUNOS4
2824         { uoff(u_pcb),          "offsetof(struct user, u_pcb)"          },
2825         { uoff(u_procp),        "offsetof(struct user, u_procp)"        },
2826         { uoff(u_ar0),          "offsetof(struct user, u_ar0)"          },
2827         { uoff(u_comm[0]),      "offsetof(struct user, u_comm[0])"      },
2828         { uoff(u_arg[0]),       "offsetof(struct user, u_arg[0])"       },
2829         { uoff(u_ap),           "offsetof(struct user, u_ap)"           },
2830         { uoff(u_qsave),        "offsetof(struct user, u_qsave)"        },
2831         { uoff(u_rval1),        "offsetof(struct user, u_rval1)"        },
2832         { uoff(u_rval2),        "offsetof(struct user, u_rval2)"        },
2833         { uoff(u_error),        "offsetof(struct user, u_error)"        },
2834         { uoff(u_eosys),        "offsetof(struct user, u_eosys)"        },
2835         { uoff(u_ssave),        "offsetof(struct user, u_ssave)"        },
2836         { uoff(u_signal[0]),    "offsetof(struct user, u_signal)"       },
2837         { uoff(u_sigmask[0]),   "offsetof(struct user, u_sigmask)"      },
2838         { uoff(u_sigonstack),   "offsetof(struct user, u_sigonstack)"   },
2839         { uoff(u_sigintr),      "offsetof(struct user, u_sigintr)"      },
2840         { uoff(u_sigreset),     "offsetof(struct user, u_sigreset)"     },
2841         { uoff(u_oldmask),      "offsetof(struct user, u_oldmask)"      },
2842         { uoff(u_code),         "offsetof(struct user, u_code)"         },
2843         { uoff(u_addr),         "offsetof(struct user, u_addr)"         },
2844         { uoff(u_sigstack),     "offsetof(struct user, u_sigstack)"     },
2845         { uoff(u_ofile),        "offsetof(struct user, u_ofile)"        },
2846         { uoff(u_pofile),       "offsetof(struct user, u_pofile)"       },
2847         { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2848         { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2849         { uoff(u_lastfile),     "offsetof(struct user, u_lastfile)"     },
2850         { uoff(u_cwd),          "offsetof(struct user, u_cwd)"          },
2851         { uoff(u_cdir),         "offsetof(struct user, u_cdir)"         },
2852         { uoff(u_rdir),         "offsetof(struct user, u_rdir)"         },
2853         { uoff(u_cmask),        "offsetof(struct user, u_cmask)"        },
2854         { uoff(u_ru),           "offsetof(struct user, u_ru)"           },
2855         { uoff(u_cru),          "offsetof(struct user, u_cru)"          },
2856         { uoff(u_timer[0]),     "offsetof(struct user, u_timer[0])"     },
2857         { uoff(u_XXX[0]),       "offsetof(struct user, u_XXX[0])"       },
2858         { uoff(u_ioch),         "offsetof(struct user, u_ioch)"         },
2859         { uoff(u_start),        "offsetof(struct user, u_start)"        },
2860         { uoff(u_acflag),       "offsetof(struct user, u_acflag)"       },
2861         { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2862         { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2863         { uoff(u_prof.pr_off),  "offsetof(struct user, u_prof.pr_off)"  },
2864         { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2865         { uoff(u_rlimit[0]),    "offsetof(struct user, u_rlimit)"       },
2866         { uoff(u_exdata.Ux_A),  "offsetof(struct user, u_exdata.Ux_A)"  },
2867         { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2868         { uoff(u_lofault),      "offsetof(struct user, u_lofault)"      },
2869 #endif /* SUNOS4 */
2870 #ifndef HPPA
2871         { sizeof(struct user),  "sizeof(struct user)"                   },
2872 #endif
2873         { 0,                    NULL                                    },
2874 };
2875 #endif
2876
2877 int
2878 sys_ptrace(tcp)
2879 struct tcb *tcp;
2880 {
2881         const struct xlat *x;
2882         long addr;
2883
2884         if (entering(tcp)) {
2885                 printxval(ptrace_cmds, tcp->u_arg[0],
2886 #ifndef FREEBSD
2887                           "PTRACE_???"
2888 #else
2889                           "PT_???"
2890 #endif
2891                         );
2892                 tprintf(", %lu, ", tcp->u_arg[1]);
2893                 addr = tcp->u_arg[2];
2894 #ifndef FREEBSD
2895                 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2896                         || tcp->u_arg[0] == PTRACE_POKEUSER) {
2897                         for (x = struct_user_offsets; x->str; x++) {
2898                                 if (x->val >= addr)
2899                                         break;
2900                         }
2901                         if (!x->str)
2902                                 tprintf("%#lx, ", addr);
2903                         else if (x->val > addr && x != struct_user_offsets) {
2904                                 x--;
2905                                 tprintf("%s + %ld, ", x->str, addr - x->val);
2906                         }
2907                         else
2908                                 tprintf("%s, ", x->str);
2909                 }
2910                 else
2911 #endif
2912                         tprintf("%#lx, ", tcp->u_arg[2]);
2913 #ifdef LINUX
2914                 switch (tcp->u_arg[0]) {
2915                 case PTRACE_PEEKDATA:
2916                 case PTRACE_PEEKTEXT:
2917                 case PTRACE_PEEKUSER:
2918                         break;
2919                 case PTRACE_CONT:
2920                 case PTRACE_SINGLESTEP:
2921                 case PTRACE_SYSCALL:
2922                 case PTRACE_DETACH:
2923                         printsignal(tcp->u_arg[3]);
2924                         break;
2925                 default:
2926                         tprintf("%#lx", tcp->u_arg[3]);
2927                         break;
2928                 }
2929         } else {
2930                 switch (tcp->u_arg[0]) {
2931                 case PTRACE_PEEKDATA:
2932                 case PTRACE_PEEKTEXT:
2933                 case PTRACE_PEEKUSER:
2934                         printnum(tcp, tcp->u_arg[3], "%#lx");
2935                         break;
2936                 }
2937         }
2938 #endif /* LINUX */
2939 #ifdef SUNOS4
2940                 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2941                         tcp->u_arg[0] == PTRACE_WRITETEXT) {
2942                         tprintf("%lu, ", tcp->u_arg[3]);
2943                         printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2944                 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2945                                 tcp->u_arg[0] != PTRACE_READTEXT) {
2946                         tprintf("%#lx", tcp->u_arg[3]);
2947                 }
2948         } else {
2949                 if (tcp->u_arg[0] == PTRACE_READDATA ||
2950                         tcp->u_arg[0] == PTRACE_READTEXT) {
2951                         tprintf("%lu, ", tcp->u_arg[3]);
2952                         printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2953                 }
2954         }
2955 #endif /* SUNOS4 */
2956 #ifdef FREEBSD
2957                 tprintf("%lu", tcp->u_arg[3]);
2958         }
2959 #endif /* FREEBSD */
2960         return 0;
2961 }
2962
2963 #endif /* !SVR4 */
2964
2965 #ifdef LINUX
2966 static const struct xlat futexops[] = {
2967         { FUTEX_WAIT,   "FUTEX_WAIT" },
2968         { FUTEX_WAKE,   "FUTEX_WAKE" },
2969         { FUTEX_FD,     "FUTEX_FD" },
2970         { FUTEX_REQUEUE,"FUTEX_REQUEUE" },
2971         { 0,            NULL }
2972 };
2973
2974 int
2975 sys_futex(tcp)
2976 struct tcb *tcp;
2977 {
2978     if (entering(tcp)) {
2979         tprintf("%p, ", (void *) tcp->u_arg[0]);
2980         printxval(futexops, tcp->u_arg[1], "FUTEX_???");
2981         tprintf(", %ld", tcp->u_arg[2]);
2982         if (tcp->u_arg[1] == FUTEX_WAIT) {
2983                 tprintf(", ");
2984                 printtv(tcp, tcp->u_arg[3]);
2985         } else if (tcp->u_arg[1] == FUTEX_REQUEUE)
2986                 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
2987     }
2988     return 0;
2989 }
2990
2991 static void
2992 print_affinitylist(tcp, list, len)
2993 struct tcb *tcp;
2994 long list;
2995 unsigned int len;
2996 {
2997     int first = 1;
2998     tprintf(" {");
2999     while (len >= sizeof (unsigned long)) {
3000         unsigned long w;
3001         umove(tcp, list, &w);
3002         tprintf("%s %lx", first ? "" : ",", w);
3003         first = 0;
3004         len -= sizeof (unsigned long);
3005         list += sizeof(unsigned long);
3006     }
3007     tprintf(" }");
3008 }
3009
3010 int
3011 sys_sched_setaffinity(tcp)
3012 struct tcb *tcp;
3013 {
3014     if (entering(tcp)) {
3015         tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3016         print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3017     }
3018     return 0;
3019 }
3020
3021 int
3022 sys_sched_getaffinity(tcp)
3023 struct tcb *tcp;
3024 {
3025     if (entering(tcp)) {
3026         tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3027     } else {
3028         if (tcp->u_rval == -1)
3029             tprintf("%#lx", tcp->u_arg[2]);
3030         else
3031             print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3032     }
3033     return 0;
3034 }
3035
3036 static const struct xlat schedulers[] = {
3037         { SCHED_OTHER,  "SCHED_OTHER" },
3038         { SCHED_RR,     "SCHED_RR" },
3039         { SCHED_FIFO,   "SCHED_FIFO" },
3040         { 0,            NULL }
3041 };
3042
3043 int
3044 sys_sched_getscheduler(tcp)
3045 struct tcb *tcp;
3046 {
3047     if (entering(tcp)) {
3048         tprintf("%d", (int) tcp->u_arg[0]);
3049     } else if (! syserror(tcp)) {
3050         tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3051         if (tcp->auxstr != NULL)
3052             return RVAL_STR;
3053     }
3054     return 0;
3055 }
3056
3057 int
3058 sys_sched_setscheduler(tcp)
3059 struct tcb *tcp;
3060 {
3061     if (entering(tcp)) {
3062         struct sched_param p;
3063         tprintf("%d, ", (int) tcp->u_arg[0]);
3064         printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3065         if (umove(tcp, tcp->u_arg[2], &p) < 0)
3066             tprintf(", %#lx", tcp->u_arg[2]);
3067         else
3068             tprintf(", { %d }", p.__sched_priority);
3069     }
3070     return 0;
3071 }
3072
3073 int
3074 sys_sched_getparam(tcp)
3075 struct tcb *tcp;
3076 {
3077     if (entering(tcp)) {
3078             tprintf("%d, ", (int) tcp->u_arg[0]);
3079     } else {
3080         struct sched_param p;
3081         if (umove(tcp, tcp->u_arg[1], &p) < 0)
3082             tprintf("%#lx", tcp->u_arg[1]);
3083         else
3084             tprintf("{ %d }", p.__sched_priority);
3085     }
3086     return 0;
3087 }
3088
3089 int
3090 sys_sched_setparam(tcp)
3091 struct tcb *tcp;
3092 {
3093     if (entering(tcp)) {
3094         struct sched_param p;
3095         if (umove(tcp, tcp->u_arg[1], &p) < 0)
3096             tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3097         else
3098             tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3099     }
3100     return 0;
3101 }
3102
3103 int
3104 sys_sched_get_priority_min(tcp)
3105 struct tcb *tcp;
3106 {
3107     if (entering(tcp)) {
3108         printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3109     }
3110     return 0;
3111 }
3112
3113 #ifdef X86_64
3114 #include <asm/prctl.h>
3115
3116 static const struct xlat archvals[] = {
3117         { ARCH_SET_GS,          "ARCH_SET_GS"           },
3118         { ARCH_SET_FS,          "ARCH_SET_FS"           },
3119         { ARCH_GET_FS,          "ARCH_GET_FS"           },
3120         { ARCH_GET_GS,          "ARCH_GET_GS"           },
3121         { 0,                    NULL                    },
3122 };
3123
3124 int
3125 sys_arch_prctl(tcp)
3126 struct tcb *tcp;
3127 {
3128     if (entering(tcp)) {
3129         printxval(archvals, tcp->u_arg[0], "ARCH_???");
3130         if (tcp->u_arg[0] == ARCH_SET_GS
3131             || tcp->u_arg[0] == ARCH_SET_FS)
3132             tprintf(", %#lx", tcp->u_arg[1]);
3133     } else {
3134         if (tcp->u_arg[0] == ARCH_GET_GS
3135             || tcp->u_arg[0] == ARCH_GET_FS) {
3136             long int v;
3137             if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3138                 tprintf(", [%#lx]", v);
3139             else
3140                 tprintf(", %#lx", tcp->u_arg[1]);
3141         }
3142     }
3143     return 0;
3144 }
3145 #endif
3146
3147 #endif