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