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