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