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