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