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