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