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