]> granicus.if.org Git - strace/blob - process.c
c24bfc665d1013b8c9e09583278805c22fbdff58
[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 #ifdef SPARC
61 #  define fpq kernel_fpq
62 #  define fq kernel_fq
63 #  define fpu kernel_fpu
64 #endif
65 #include <asm/reg.h>
66 #ifdef SPARC
67 #  undef fpq
68 #  undef fq
69 #  undef fpu
70 #endif
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 #include <linux/ptrace.h>
86 #endif
87
88 #ifdef HAVE_LINUX_FUTEX_H
89 #include <linux/futex.h>
90 #endif
91 #if defined LINUX
92 # ifndef FUTEX_WAIT
93 #  define FUTEX_WAIT 0
94 # endif
95 # ifndef FUTEX_WAKE
96 #  define FUTEX_WAKE 1
97 # endif
98 # ifndef FUTEX_FD
99 #  define FUTEX_FD 2
100 # endif
101 #endif
102
103 #ifdef LINUX
104 #include <asm/posix_types.h>
105 #undef GETGROUPS_T
106 #define GETGROUPS_T __kernel_gid_t
107 #endif /* LINUX */
108
109 #if defined(LINUX) && defined(IA64)
110 # include <asm/ptrace_offsets.h>
111 # include <asm/rse.h>
112 #endif
113
114 #ifdef HAVE_PRCTL
115 #include <sys/prctl.h>
116 #endif
117
118 #ifndef WCOREDUMP
119 #define WCOREDUMP(status) ((status) & 0200)
120 #endif
121
122 /* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
123 #if defined(HAVE_PRCTL)
124 static struct xlat prctl_options[] = {
125 #ifdef PR_MAXPROCS
126         { PR_MAXPROCS,          "PR_MAXPROCS"           },
127 #endif
128 #ifdef PR_ISBLOCKED
129         { PR_ISBLOCKED,         "PR_ISBLOCKED"          },
130 #endif
131 #ifdef PR_SETSTACKSIZE
132         { PR_SETSTACKSIZE,      "PR_SETSTACKSIZE"       },
133 #endif
134 #ifdef PR_GETSTACKSIZE
135         { PR_GETSTACKSIZE,      "PR_GETSTACKSIZE"       },
136 #endif
137 #ifdef PR_MAXPPROCS
138         { PR_MAXPPROCS,         "PR_MAXPPROCS"          },
139 #endif
140 #ifdef PR_UNBLKONEXEC
141         { PR_UNBLKONEXEC,       "PR_UNBLKONEXEC"        },
142 #endif
143 #ifdef PR_ATOMICSIM
144         { PR_ATOMICSIM,         "PR_ATOMICSIM"          },
145 #endif
146 #ifdef PR_SETEXITSIG
147         { PR_SETEXITSIG,        "PR_SETEXITSIG"         },
148 #endif
149 #ifdef PR_RESIDENT
150         { PR_RESIDENT,          "PR_RESIDENT"           },
151 #endif
152 #ifdef PR_ATTACHADDR
153         { PR_ATTACHADDR,        "PR_ATTACHADDR"         },
154 #endif
155 #ifdef PR_DETACHADDR
156         { PR_DETACHADDR,        "PR_DETACHADDR"         },
157 #endif
158 #ifdef PR_TERMCHILD
159         { PR_TERMCHILD,         "PR_TERMCHILD"          },
160 #endif
161 #ifdef PR_GETSHMASK
162         { PR_GETSHMASK,         "PR_GETSHMASK"          },
163 #endif
164 #ifdef PR_GETNSHARE
165         { PR_GETNSHARE,         "PR_GETNSHARE"          },
166 #endif
167 #if defined(PR_SET_PDEATHSIG)
168         { PR_SET_PDEATHSIG,     "PR_SET_PDEATHSIG"      },
169 #endif
170 #ifdef PR_COREPID
171         { PR_COREPID,           "PR_COREPID"            },
172 #endif
173 #ifdef PR_ATTACHADDRPERM
174         { PR_ATTACHADDRPERM,    "PR_ATTACHADDRPERM"     },
175 #endif
176 #ifdef PR_PTHREADEXIT
177         { PR_PTHREADEXIT,       "PR_PTHREADEXIT"        },
178 #endif
179 #ifdef PR_SET_PDEATHSIG
180         { PR_SET_PDEATHSIG,     "PR_SET_PDEATHSIG"      },
181 #endif
182 #ifdef PR_GET_PDEATHSIG
183         { PR_GET_PDEATHSIG,     "PR_GET_PDEATHSIG"      },
184 #endif
185 #ifdef PR_GET_UNALIGN
186         { PR_GET_UNALIGN,       "PR_GET_UNALIGN"        },
187 #endif
188 #ifdef PR_SET_UNALIGN
189         { PR_SET_UNALIGN,       "PR_SET_UNALIGN"        },
190 #endif
191 #ifdef PR_GET_KEEPCAPS
192         { PR_GET_KEEPCAPS,      "PR_GET_KEEP_CAPS"      },
193 #endif
194 #ifdef PR_SET_KEEPCAPS
195         { PR_SET_KEEPCAPS,      "PR_SET_KEEP_CAPS"      },
196 #endif
197         { 0,                    NULL                    },
198 };
199
200
201 const char *
202 unalignctl_string (unsigned int ctl)
203 {
204         static char buf[16];
205
206         switch (ctl) {
207 #ifdef PR_UNALIGN_NOPRINT
208               case PR_UNALIGN_NOPRINT:
209                 return "NOPRINT";
210 #endif
211 #ifdef PR_UNALIGN_SIGBUS
212               case PR_UNALIGN_SIGBUS:
213                 return "SIGBUS";
214 #endif
215               default:
216                 break;
217         }
218         sprintf(buf, "%x", ctl);
219         return buf;
220 }
221
222
223 int
224 sys_prctl(tcp)
225 struct tcb *tcp;
226 {
227         int i;
228
229         if (entering(tcp)) {
230                 printxval(prctl_options, tcp->u_arg[0], "PR_???");
231                 switch (tcp->u_arg[0]) {
232 #ifdef PR_GETNSHARE
233                 case PR_GETNSHARE:
234                         break;
235 #endif
236 #ifdef PR_SET_DEATHSIG
237                 case PR_GET_PDEATHSIG:
238                         break;
239 #endif
240 #ifdef PR_SET_UNALIGN
241                 case PR_SET_UNALIGN:
242                         tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
243                         break;
244 #endif
245 #ifdef PR_GET_UNALIGN
246                 case PR_GET_UNALIGN:
247                         tprintf(", %#lx", tcp->u_arg[1]);
248                         break;
249 #endif
250                 default:
251                         for (i = 1; i < tcp->u_nargs; i++)
252                                 tprintf(", %#lx", tcp->u_arg[i]);
253                         break;
254                 }
255         } else {
256                 switch (tcp->u_arg[0]) {
257 #ifdef PR_GET_PDEATHSIG
258                 case PR_GET_PDEATHSIG:
259                         for (i=1; i<tcp->u_nargs; i++)
260                                 tprintf(", %#lx", tcp->u_arg[i]);
261                         break;
262 #endif
263 #ifdef PR_SET_UNALIGN
264                 case PR_SET_UNALIGN:
265                         break;
266 #endif
267 #ifdef PR_GET_UNALIGN
268                 case PR_GET_UNALIGN:
269                 {
270                         int ctl;
271
272                         umove(tcp, tcp->u_arg[1], &ctl);
273                         tcp->auxstr = unalignctl_string(ctl);
274                         return RVAL_STR;
275                 }
276 #endif
277                 default:
278                         break;
279                 }
280         }
281         return 0;
282 }
283
284 #endif /* HAVE_PRCTL */
285
286 int
287 sys_gethostid(tcp)
288 struct tcb *tcp;
289 {
290         if (exiting(tcp))
291                 return RVAL_HEX;
292         return 0;
293 }
294
295 int
296 sys_sethostname(tcp)
297 struct tcb *tcp;
298 {
299         if (entering(tcp)) {
300                 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
301                 tprintf(", %lu", tcp->u_arg[1]);
302         }
303         return 0;
304 }
305
306 int
307 sys_gethostname(tcp)
308 struct tcb *tcp;
309 {
310         if (exiting(tcp)) {
311                 if (syserror(tcp))
312                         tprintf("%#lx", tcp->u_arg[0]);
313                 else
314                         printpath(tcp, tcp->u_arg[0]);
315                 tprintf(", %lu", tcp->u_arg[1]);
316         }
317         return 0;
318 }
319
320 int
321 sys_setdomainname(tcp)
322 struct tcb *tcp;
323 {
324         if (entering(tcp)) {
325                 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
326                 tprintf(", %lu", tcp->u_arg[1]);
327         }
328         return 0;
329 }
330
331 #if !defined(LINUX)
332
333 int
334 sys_getdomainname(tcp)
335 struct tcb *tcp;
336 {
337         if (exiting(tcp)) {
338                 if (syserror(tcp))
339                         tprintf("%#lx", tcp->u_arg[0]);
340                 else
341                         printpath(tcp, tcp->u_arg[0]);
342                 tprintf(", %lu", tcp->u_arg[1]);
343         }
344         return 0;
345 }
346 #endif /* !LINUX */
347
348 int
349 sys_exit(tcp)
350 struct tcb *tcp;
351 {
352         if (exiting(tcp)) {
353                 fprintf(stderr, "_exit returned!\n");
354                 return -1;
355         }
356         /* special case: we stop tracing this process, finish line now */
357         tprintf("%ld) ", tcp->u_arg[0]);
358         tabto(acolumn);
359         tprintf("= ?");
360         printtrailer(tcp);
361         return 0;
362 }
363
364 int
365 internal_exit(tcp)
366 struct tcb *tcp;
367 {
368         if (entering(tcp)) {
369                 tcp->flags |= TCB_EXITING;
370 #ifdef __NR_exit_group
371                 if (tcp->scno == __NR_exit_group)
372                         tcp->flags |= TCB_GROUP_EXITING;
373 #endif
374         }
375         return 0;
376 }
377
378 /* TCP is creating a child we want to follow.
379    If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
380    If not, clear TCB_FOLLOWFORK, print an error, and return 1.  */
381 static int
382 fork_tcb(struct tcb *tcp)
383 {
384         if (nprocs == tcbtabsize) {
385                 /* Allocate some more TCBs and expand the table.
386                    We don't want to relocate the TCBs because our
387                    callers have pointers and it would be a pain.
388                    So tcbtab is a table of pointers.  Since we never
389                    free the TCBs, we allocate a single chunk of many.  */
390                 struct tcb **newtab = (struct tcb **)
391                         realloc(tcbtab, 2 * tcbtabsize * sizeof tcbtab[0]);
392                 struct tcb *newtcbs = (struct tcb *) calloc(tcbtabsize,
393                                                             sizeof *newtcbs);
394                 int i;
395                 if (newtab == NULL || newtcbs == NULL) {
396                         if (newtab != NULL)
397                                 free(newtab);
398                         tcp->flags &= ~TCB_FOLLOWFORK;
399                         fprintf(stderr, "sys_fork: tcb table full\n");
400                         return 1;
401                 }
402                 for (i = tcbtabsize; i < 2 * tcbtabsize; ++i)
403                         newtab[i] = &newtcbs[i - tcbtabsize];
404                 tcbtabsize *= 2;
405                 tcbtab = newtab;
406         }
407
408         tcp->flags |= TCB_FOLLOWFORK;
409         return 0;
410 }
411
412 #ifdef USE_PROCFS
413
414 int
415 sys_fork(tcp)
416 struct tcb *tcp;
417 {
418         if (exiting(tcp)) {
419                 if (getrval2(tcp)) {
420                         tcp->auxstr = "child process";
421                         return RVAL_UDECIMAL | RVAL_STR;
422                 }
423         }
424         return 0;
425 }
426
427 #if UNIXWARE > 2
428
429 int
430 sys_rfork(tcp)
431 struct tcb *tcp;
432 {
433         if (entering(tcp)) {
434                 tprintf ("%ld", tcp->u_arg[0]);
435         }
436         else {
437                 if (getrval2(tcp)) {
438                         tcp->auxstr = "child process";
439                         return RVAL_UDECIMAL | RVAL_STR;
440                 }
441         }
442         return 0;
443 }
444
445 #endif
446
447 int
448 internal_fork(tcp)
449 struct tcb *tcp;
450 {
451         struct tcb *tcpchild;
452
453         if (exiting(tcp)) {
454                 if (getrval2(tcp))
455                         return 0;
456                 if (!followfork)
457                         return 0;
458                 if (fork_tcb(tcp))
459                         return 0;
460                 if (syserror(tcp))
461                         return 0;
462                 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
463                         fprintf(stderr, "sys_fork: tcb table full\n");
464                         return 0;
465                 }
466                 if (proc_open(tcpchild, 2) < 0)
467                         droptcb(tcpchild);
468         }
469         return 0;
470 }
471
472 #else /* !USE_PROCFS */
473
474 #ifdef LINUX
475
476 /* defines copied from linux/sched.h since we can't include that
477  * ourselves (it conflicts with *lots* of libc includes)
478  */
479 #define CSIGNAL         0x000000ff      /* signal mask to be sent at exit */
480 #define CLONE_VM        0x00000100      /* set if VM shared between processes */
481 #define CLONE_FS        0x00000200      /* set if fs info shared between processes */
482 #define CLONE_FILES     0x00000400      /* set if open files shared between processes */
483 #define CLONE_SIGHAND   0x00000800      /* set if signal handlers shared */
484 #define CLONE_IDLETASK  0x00001000      /* kernel-only flag */
485 #define CLONE_PTRACE    0x00002000      /* set if we want to let tracing continue on the child too */
486 #define CLONE_VFORK     0x00004000      /* set if the parent wants the child to wake it up on mm_release */
487 #define CLONE_PARENT    0x00008000      /* set if we want to have the same parent as the cloner */
488 #define CLONE_THREAD    0x00010000      /* Same thread group? */
489 #define CLONE_NEWNS     0x00020000      /* New namespace group? */
490 #define CLONE_SYSVSEM   0x00040000      /* share system V SEM_UNDO semantics */
491 #define CLONE_SETTLS    0x00080000      /* create a new TLS for the child */
492 #define CLONE_PARENT_SETTID     0x00100000      /* set the TID in the parent */
493 #define CLONE_CHILD_CLEARTID    0x00200000      /* clear the TID in the child */
494 #define CLONE_DETACHED          0x00400000      /* parent wants no child-exit signal */
495 #define CLONE_UNTRACED          0x00800000      /* set if the tracing process can't force CLONE_PTRACE on this clone */
496 #define CLONE_CHILD_SETTID      0x01000000      /* set the TID in the child */
497
498 static struct xlat clone_flags[] = {
499     { CLONE_VM,         "CLONE_VM"      },
500     { CLONE_FS,         "CLONE_FS"      },
501     { CLONE_FILES,      "CLONE_FILES"   },
502     { CLONE_SIGHAND,    "CLONE_SIGHAND" },
503     { CLONE_IDLETASK,   "CLONE_IDLETASK"},
504     { CLONE_PTRACE,     "CLONE_PTRACE"  },
505     { CLONE_VFORK,      "CLONE_VFORK"   },
506     { CLONE_PARENT,     "CLONE_PARENT"  },
507     { CLONE_THREAD,     "CLONE_THREAD" },
508     { CLONE_NEWNS,      "CLONE_NEWNS" },
509     { CLONE_SYSVSEM,    "CLONE_SYSVSEM" },
510     { CLONE_SETTLS,     "CLONE_SETTLS" },
511     { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
512     { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
513     { CLONE_DETACHED,   "CLONE_DETACHED" },
514     { CLONE_UNTRACED,   "CLONE_UNTRACED" },
515     { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
516     { 0,                NULL            },
517 };
518
519 # ifdef I386
520 #  include <asm/ldt.h>
521 extern void print_ldt_entry();
522 # endif
523
524 int
525 sys_clone(tcp)
526 struct tcb *tcp;
527 {
528         if (exiting(tcp)) {
529                 long flags, stack;
530 # if defined S390 || defined S390X
531                 /* For some reason, S390 has the stack argument first.  */
532                 stack = tcp->u_arg[0];
533                 flags = tcp->u_arg[1];
534 # else
535                 flags = tcp->u_arg[0];
536                 stack = tcp->u_arg[1];
537 # endif
538                 tprintf("child_stack=%#lx, flags=", stack);
539                 if (printflags(clone_flags, flags) == 0)
540                         tprintf("0");
541                 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
542                                       |CLONE_SETTLS)) == 0)
543                         return 0;
544                 if (flags & CLONE_PARENT_SETTID) {
545                         int pid;
546                         if (umove(tcp, tcp->u_arg[2], &pid) == 0)
547                                 tprintf(", [%d]", pid);
548                         else
549                                 tprintf(", %#lx", tcp->u_arg[2]);
550                 }
551                 else
552                         tprintf(", <ignored>");
553 #ifdef I386
554                 if (flags & CLONE_SETTLS) {
555                         struct modify_ldt_ldt_s copy;
556                         if (umove(tcp, tcp->u_arg[3], &copy) != -1) {
557                                 tprintf(", {entry_number:%d, ",
558                                         copy.entry_number);
559                                 if (!verbose(tcp))
560                                         tprintf("...}");
561                                 else
562                                         print_ldt_entry(&copy);
563                         }
564                         else
565                                 tprintf(", %#lx", tcp->u_arg[3]);
566                 }
567                 else
568                         tprintf(", <ignored>");
569 # define TIDARG 4
570 #else
571 # define TIDARG 3
572 #endif
573                 if (flags & CLONE_CHILD_SETTID)
574                         tprintf(", %#lx", tcp->u_arg[TIDARG]);
575 #undef TIDARG
576         }
577         return 0;
578 }
579
580 int
581 sys_clone2(tcp)
582 struct tcb *tcp;
583 {
584        if (exiting(tcp)) {
585                tprintf("child_stack=%#lx, stack_size=%#lx, flags=",
586                        tcp->u_arg[1], tcp->u_arg[2]);
587                if (printflags(clone_flags, tcp->u_arg[0]) == 0)
588                        tprintf("0");
589        }
590        return 0;
591 }
592
593 #endif
594
595 int
596 sys_fork(tcp)
597 struct tcb *tcp;
598 {
599         if (exiting(tcp))
600                 return RVAL_UDECIMAL;
601         return 0;
602 }
603
604 int
605 change_syscall(tcp, new)
606 struct tcb *tcp;
607 int new;
608 {
609 #if defined(LINUX)
610 #if defined(I386)
611         /* Attempt to make vfork into fork, which we can follow. */
612         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
613                 return -1;
614         return 0;
615 #elif defined(X86_64)
616         /* Attempt to make vfork into fork, which we can follow. */
617         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
618                 return -1;
619         return 0;
620 #elif defined(POWERPC)
621         if (ptrace(PTRACE_POKEUSER, tcp->pid,
622                    (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
623                 return -1;
624        return 0;
625 #elif defined(S390) || defined(S390X)
626         /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
627         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
628                 return -1;
629         return 0;
630 #elif defined(M68K)
631         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
632                 return -1;
633         return 0;
634 #elif defined(SPARC)
635         struct regs regs;
636         if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
637                 return -1;
638         regs.r_g1=new;
639         if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
640                 return -1;
641         return 0;
642 #elif defined(MIPS)
643         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
644                 return -1;
645         return 0;
646 #elif defined(ALPHA)
647         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
648                 return -1;
649         return 0;
650 #elif defined(IA64)
651         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
652                 return -1;
653         return 0;
654 #elif defined(HPPA)
655         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
656                 return -1;
657         return 0;
658 #elif defined(SH)
659        if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), new)<0)
660                return -1;
661        return 0;
662 #else
663 #warning Do not know how to handle change_syscall for this architecture
664 #endif /* architecture */
665 #endif /* LINUX */
666         return -1;
667 }
668
669 int
670 setarg(tcp, argnum)
671         struct tcb *tcp;
672         int argnum;
673 {
674 #if defined (IA64)
675         {
676                 unsigned long *bsp, *ap;
677
678                 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
679                         return -1;
680
681                 ap = ia64_rse_skip_regs(bsp, argnum);
682                 errno = 0;
683                 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
684                 if (errno)
685                         return -1;
686
687         }
688 #elif defined(I386)
689         {
690                 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
691                 if (errno)
692                         return -1;
693         }
694 #elif defined(X86_64)
695         {
696                 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
697                 if (errno)
698                         return -1;
699         }
700 #elif defined(POWERPC)
701 #ifndef PT_ORIG_R3
702 #define PT_ORIG_R3 34
703 #endif
704         {
705                 ptrace(PTRACE_POKEUSER, tcp->pid,
706                        (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
707                        tcp->u_arg[argnum]);
708                 if (errno)
709                         return -1;
710         }
711 #elif defined(MIPS)
712         {
713                 errno = 0;
714                 if (argnum < 4)
715                         ptrace(PTRACE_POKEUSER, tcp->pid,
716                                (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
717                 else {
718                         unsigned long *sp;
719
720                         if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
721                                 return -1;
722
723                         ptrace(PTRACE_POKEDATA, tcp->pid,
724                                (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
725                 }
726                 if (errno)
727                         return -1;
728         }
729 #elif defined(S390) || defined(S390X)
730         {
731                 if(argnum <= 5)
732                         ptrace(PTRACE_POKEUSER, tcp->pid,
733                                (char *) (argnum==0 ? PT_ORIGGPR2 :
734                                PT_GPR2 + argnum*sizeof(long)),
735                                tcp->u_arg[argnum]);
736                 else
737                         return -E2BIG;
738                 if (errno)
739                         return -1;
740         }
741 #else
742 # warning Sorry, setargs not implemented for this architecture.
743 #endif
744         return 0;
745 }
746
747 #if defined SYS_clone || defined SYS_clone2
748 int
749 internal_clone(tcp)
750 struct tcb *tcp;
751 {
752         struct tcb *tcpchild;
753         int pid;
754         if (entering(tcp)) {
755                 if (!followfork)
756                         return 0;
757                 if (fork_tcb(tcp))
758                         return 0;
759                 if (setbpt(tcp) < 0)
760                         return 0;
761         } else {
762                 int bpt = tcp->flags & TCB_BPTSET;
763
764                 if (!(tcp->flags & TCB_FOLLOWFORK))
765                         return 0;
766
767                 if (syserror(tcp)) {
768                         if (bpt)
769                                 clearbpt(tcp);
770                         return 0;
771                 }
772
773                 pid = tcp->u_rval;
774
775 #ifdef CLONE_PTRACE             /* See new setbpt code.  */
776                 tcpchild = pid2tcb(pid);
777                 if (tcpchild != NULL) {
778                         /* The child already reported its startup trap
779                            before the parent reported its syscall return.  */
780                         if ((tcpchild->flags
781                              & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
782                             != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
783                                 fprintf(stderr, "\
784 [preattached child %d of %d in weird state!]\n",
785                                         pid, tcp->pid);
786                 }
787                 else
788 #endif
789                 if ((tcpchild = alloctcb(pid)) == NULL) {
790                         if (bpt)
791                                 clearbpt(tcp);
792                         fprintf(stderr, " [tcb table full]\n");
793                         kill(pid, SIGKILL); /* XXX */
794                         return 0;
795                 }
796
797 #ifndef CLONE_PTRACE
798                 /* Attach to the new child */
799                 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
800                         if (bpt)
801                                 clearbpt(tcp);
802                         perror("PTRACE_ATTACH");
803                         fprintf(stderr, "Too late?\n");
804                         droptcb(tcpchild);
805                         return 0;
806                 }
807 #endif
808
809                 if (bpt)
810                         clearbpt(tcp);
811
812                 tcpchild->flags |= TCB_ATTACHED;
813                 /* Child has BPT too, must be removed on first occasion.  */
814                 if (bpt) {
815                         tcpchild->flags |= TCB_BPTSET;
816                         tcpchild->baddr = tcp->baddr;
817                         memcpy(tcpchild->inst, tcp->inst,
818                                 sizeof tcpchild->inst);
819                 }
820                 tcpchild->parent = tcp;
821                 tcp->nchildren++;
822                 if (tcpchild->flags & TCB_SUSPENDED) {
823                         /* The child was born suspended, due to our having
824                            forced CLONE_PTRACE.  */
825                         if (bpt)
826                                 clearbpt(tcpchild);
827
828                         tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
829                         if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
830                                 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
831                                 return -1;
832                         }
833
834                         if (!qflag)
835                                 fprintf(stderr, "\
836 Process %u resumed (parent %d ready)\n",
837                                         pid, tcp->pid);
838                 }
839                 else {
840                         newoutf(tcpchild);
841                         if (!qflag)
842                                 fprintf(stderr, "Process %d attached\n", pid);
843                 }
844
845 #ifdef TCB_CLONE_THREAD
846                 if ((tcp->flags & TCB_CLONE_THREAD) && tcp->parent != NULL) {
847                         /* The parent in this clone is itself a thread
848                            belonging to another process.  There is no
849                            meaning to the parentage relationship of the new
850                            child with the thread, only with the process.
851                            We associate the new thread with our parent.
852                            Since this is done for every new thread, there
853                            will never be a TCB_CLONE_THREAD process that
854                            has children.  */
855                         --tcp->nchildren;
856                         tcp->u_arg[0] = tcp->parent->u_arg[0];
857                         tcp = tcp->parent;
858                         tcpchild->parent = tcp;
859                         ++tcp->nchildren;
860                 }
861
862                 if (tcp->u_arg[0] & CLONE_THREAD) {
863                         tcpchild->flags |= TCB_CLONE_THREAD;
864                         ++tcp->nclone_threads;
865                 }
866                 if (tcp->u_arg[0] & CLONE_DETACHED) {
867                         tcpchild->flags |= TCB_CLONE_DETACHED;
868                         ++tcp->nclone_detached;
869                 }
870 #endif
871
872         }
873         return 0;
874 }
875 #endif
876
877 int
878 internal_fork(tcp)
879 struct tcb *tcp;
880 {
881 #ifdef LINUX
882         /* We do special magic with clone for any clone or fork.  */
883         return internal_clone(tcp);
884 #else
885
886         struct tcb *tcpchild;
887         int pid;
888         int dont_follow = 0;
889
890 #ifdef SYS_vfork
891         if (tcp->scno == SYS_vfork) {
892                 /* Attempt to make vfork into fork, which we can follow. */
893                 if (!followvfork ||
894                     change_syscall(tcp, SYS_fork) < 0)
895                         dont_follow = 1;
896         }
897 #endif
898         if (entering(tcp)) {
899                 if (!followfork || dont_follow)
900                         return 0;
901                 if (fork_tcb(tcp))
902                         return 0;
903                 if (setbpt(tcp) < 0)
904                         return 0;
905         }
906         else {
907                 int bpt = tcp->flags & TCB_BPTSET;
908
909                 if (!(tcp->flags & TCB_FOLLOWFORK))
910                         return 0;
911                 if (bpt)
912                         clearbpt(tcp);
913
914                 if (syserror(tcp))
915                         return 0;
916
917                 pid = tcp->u_rval;
918                 if ((tcpchild = alloctcb(pid)) == NULL) {
919                         fprintf(stderr, " [tcb table full]\n");
920                         kill(pid, SIGKILL); /* XXX */
921                         return 0;
922                 }
923 #ifdef LINUX
924 #ifdef HPPA
925                 /* The child must have run before it can be attached. */
926                 /* This must be a bug in the parisc kernel, but I havn't
927                  * identified it yet.  Seems to be an issue associated
928                  * with attaching to a process (which sends it a signal)
929                  * before that process has ever been scheduled.  When
930                  * debugging, I started seeing crashes in
931                  * arch/parisc/kernel/signal.c:do_signal(), apparently
932                  * caused by r8 getting corrupt over the dequeue_signal()
933                  * call.  Didn't make much sense though...
934                  */
935                 {
936                         struct timeval tv;
937                         tv.tv_sec = 0;
938                         tv.tv_usec = 10000;
939                         select(0, NULL, NULL, NULL, &tv);
940                 }
941 #endif
942                 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
943                         perror("PTRACE_ATTACH");
944                         fprintf(stderr, "Too late?\n");
945                         droptcb(tcpchild);
946                         return 0;
947                 }
948 #endif /* LINUX */
949 #ifdef SUNOS4
950 #ifdef oldway
951                 /* The child must have run before it can be attached. */
952                 {
953                         struct timeval tv;
954                         tv.tv_sec = 0;
955                         tv.tv_usec = 10000;
956                         select(0, NULL, NULL, NULL, &tv);
957                 }
958                 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
959                         perror("PTRACE_ATTACH");
960                         fprintf(stderr, "Too late?\n");
961                         droptcb(tcpchild);
962                         return 0;
963                 }
964 #else /* !oldway */
965                 /* Try to catch the new process as soon as possible. */
966                 {
967                         int i;
968                         for (i = 0; i < 1024; i++)
969                                 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
970                                         break;
971                         if (i == 1024) {
972                                 perror("PTRACE_ATTACH");
973                                 fprintf(stderr, "Too late?\n");
974                                 droptcb(tcpchild);
975                                 return 0;
976                         }
977                 }
978 #endif /* !oldway */
979 #endif /* SUNOS4 */
980                 tcpchild->flags |= TCB_ATTACHED;
981                 /* Child has BPT too, must be removed on first occasion */
982                 if (bpt) {
983                         tcpchild->flags |= TCB_BPTSET;
984                         tcpchild->baddr = tcp->baddr;
985                         memcpy(tcpchild->inst, tcp->inst,
986                                 sizeof tcpchild->inst);
987                 }
988                 newoutf(tcpchild);
989                 tcpchild->parent = tcp;
990                 tcp->nchildren++;
991                 if (!qflag)
992                         fprintf(stderr, "Process %d attached\n", pid);
993         }
994         return 0;
995 #endif
996 }
997
998 #endif /* !USE_PROCFS */
999
1000 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1001
1002 int
1003 sys_vfork(tcp)
1004 struct tcb *tcp;
1005 {
1006         if (exiting(tcp))
1007                 return RVAL_UDECIMAL;
1008         return 0;
1009 }
1010
1011 #endif /* SUNOS4 || LINUX || FREEBSD */
1012
1013 #ifndef LINUX
1014
1015 static char idstr[16];
1016
1017 int
1018 sys_getpid(tcp)
1019 struct tcb *tcp;
1020 {
1021         if (exiting(tcp)) {
1022                 sprintf(idstr, "ppid %lu", getrval2(tcp));
1023                 tcp->auxstr = idstr;
1024                 return RVAL_STR;
1025         }
1026         return 0;
1027 }
1028
1029 int
1030 sys_getuid(tcp)
1031 struct tcb *tcp;
1032 {
1033         if (exiting(tcp)) {
1034                 sprintf(idstr, "euid %lu", getrval2(tcp));
1035                 tcp->auxstr = idstr;
1036                 return RVAL_STR;
1037         }
1038         return 0;
1039 }
1040
1041 int
1042 sys_getgid(tcp)
1043 struct tcb *tcp;
1044 {
1045         if (exiting(tcp)) {
1046                 sprintf(idstr, "egid %lu", getrval2(tcp));
1047                 tcp->auxstr = idstr;
1048                 return RVAL_STR;
1049         }
1050         return 0;
1051 }
1052
1053 #endif /* !LINUX */
1054
1055 #ifdef LINUX
1056
1057 int
1058 sys_setuid(tcp)
1059 struct tcb *tcp;
1060 {
1061         if (entering(tcp)) {
1062                 tprintf("%u", (uid_t) tcp->u_arg[0]);
1063         }
1064         return 0;
1065 }
1066
1067 int
1068 sys_setgid(tcp)
1069 struct tcb *tcp;
1070 {
1071         if (entering(tcp)) {
1072                 tprintf("%u", (gid_t) tcp->u_arg[0]);
1073         }
1074         return 0;
1075 }
1076
1077 int
1078 sys_getresuid(tcp)
1079     struct tcb *tcp;
1080 {
1081         if (exiting(tcp)) {
1082                 __kernel_uid_t uid;
1083                 if (syserror(tcp))
1084                         tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1085                                 tcp->u_arg[1], tcp->u_arg[2]);
1086                 else {
1087                         if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1088                                 tprintf("%#lx, ", tcp->u_arg[0]);
1089                         else
1090                                 tprintf("ruid %lu, ", (unsigned long) uid);
1091                         if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1092                                 tprintf("%#lx, ", tcp->u_arg[0]);
1093                         else
1094                                 tprintf("euid %lu, ", (unsigned long) uid);
1095                         if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1096                                 tprintf("%#lx", tcp->u_arg[0]);
1097                         else
1098                                 tprintf("suid %lu", (unsigned long) uid);
1099                 }
1100         }
1101         return 0;
1102 }
1103
1104 int
1105 sys_getresgid(tcp)
1106 struct tcb *tcp;
1107 {
1108         if (exiting(tcp)) {
1109                 __kernel_gid_t gid;
1110                 if (syserror(tcp))
1111                         tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1112                                 tcp->u_arg[1], tcp->u_arg[2]);
1113                 else {
1114                         if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1115                                 tprintf("%#lx, ", tcp->u_arg[0]);
1116                         else
1117                                 tprintf("rgid %lu, ", (unsigned long) gid);
1118                         if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1119                                 tprintf("%#lx, ", tcp->u_arg[0]);
1120                         else
1121                                 tprintf("egid %lu, ", (unsigned long) gid);
1122                         if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1123                                 tprintf("%#lx", tcp->u_arg[0]);
1124                         else
1125                                 tprintf("sgid %lu", (unsigned long) gid);
1126                 }
1127         }
1128         return 0;
1129 }
1130
1131 #endif /* LINUX */
1132
1133 int
1134 sys_setreuid(tcp)
1135 struct tcb *tcp;
1136 {
1137         if (entering(tcp)) {
1138                 tprintf("%lu, %lu",
1139                         (unsigned long) (uid_t) tcp->u_arg[0],
1140                         (unsigned long) (uid_t) tcp->u_arg[1]);
1141         }
1142         return 0;
1143 }
1144
1145 int
1146 sys_setregid(tcp)
1147 struct tcb *tcp;
1148 {
1149         if (entering(tcp)) {
1150                 tprintf("%lu, %lu",
1151                         (unsigned long) (gid_t) tcp->u_arg[0],
1152                         (unsigned long) (gid_t) tcp->u_arg[1]);
1153         }
1154         return 0;
1155 }
1156
1157 #if defined(LINUX) || defined(FREEBSD)
1158 int
1159 sys_setresuid(tcp)
1160      struct tcb *tcp;
1161 {
1162         if (entering(tcp)) {
1163                 tprintf("ruid %u, euid %u, suid %u",
1164                                 (uid_t) tcp->u_arg[0],
1165                                 (uid_t) tcp->u_arg[1],
1166                                 (uid_t) tcp->u_arg[2]);
1167         }
1168         return 0;
1169 }
1170 int
1171 sys_setresgid(tcp)
1172      struct tcb *tcp;
1173 {
1174         if (entering(tcp)) {
1175                 tprintf("rgid %u, egid %u, sgid %u",
1176                                 (uid_t) tcp->u_arg[0],
1177                                 (uid_t) tcp->u_arg[1],
1178                                 (uid_t) tcp->u_arg[2]);
1179         }
1180         return 0;
1181 }
1182
1183 #endif /* LINUX || FREEBSD */
1184
1185 int
1186 sys_setgroups(tcp)
1187 struct tcb *tcp;
1188 {
1189         int i, len;
1190         GETGROUPS_T *gidset;
1191
1192         if (entering(tcp)) {
1193                 len = tcp->u_arg[0];
1194                 tprintf("%u, ", len);
1195                 if (len <= 0) {
1196                         tprintf("[]");
1197                         return 0;
1198                 }
1199                 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1200                 if (gidset == NULL) {
1201                         fprintf(stderr, "sys_setgroups: out of memory\n");
1202                         return -1;
1203                 }
1204                 if (!verbose(tcp))
1205                         tprintf("%#lx", tcp->u_arg[1]);
1206                 else if (umoven(tcp, tcp->u_arg[1],
1207                     len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1208                         tprintf("[?]");
1209                 else {
1210                         tprintf("[");
1211                         for (i = 0; i < len; i++)
1212                                 tprintf("%s%lu", i ? ", " : "",
1213                                         (unsigned long) gidset[i]);
1214                         tprintf("]");
1215                 }
1216                 free((char *) gidset);
1217         }
1218         return 0;
1219 }
1220
1221 int
1222 sys_getgroups(tcp)
1223 struct tcb *tcp;
1224 {
1225         int i, len;
1226         GETGROUPS_T *gidset;
1227
1228         if (entering(tcp)) {
1229                 len = tcp->u_arg[0];
1230                 tprintf("%u, ", len);
1231         } else {
1232                 len = tcp->u_rval;
1233                 if (len <= 0) {
1234                         tprintf("[]");
1235                         return 0;
1236                 }
1237                 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1238                 if (gidset == NULL) {
1239                         fprintf(stderr, "sys_getgroups: out of memory\n");
1240                         return -1;
1241                 }
1242                 if (!tcp->u_arg[1])
1243                         tprintf("NULL");
1244                 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1245                         tprintf("%#lx", tcp->u_arg[1]);
1246                 else if (umoven(tcp, tcp->u_arg[1],
1247                     len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1248                         tprintf("[?]");
1249                 else {
1250                         tprintf("[");
1251                         for (i = 0; i < len; i++)
1252                                 tprintf("%s%lu", i ? ", " : "",
1253                                         (unsigned long) gidset[i]);
1254                         tprintf("]");
1255                 }
1256                 free((char *)gidset);
1257         }
1258         return 0;
1259 }
1260
1261 int
1262 sys_setpgrp(tcp)
1263 struct tcb *tcp;
1264 {
1265         if (entering(tcp)) {
1266 #ifndef SVR4
1267                 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1268 #endif /* !SVR4 */
1269         }
1270         return 0;
1271 }
1272
1273 int
1274 sys_getpgrp(tcp)
1275 struct tcb *tcp;
1276 {
1277         if (entering(tcp)) {
1278 #ifndef SVR4
1279                 tprintf("%lu", tcp->u_arg[0]);
1280 #endif /* !SVR4 */
1281         }
1282         return 0;
1283 }
1284
1285 int
1286 sys_getsid(tcp)
1287 struct tcb *tcp;
1288 {
1289         if (entering(tcp)) {
1290                 tprintf("%lu", tcp->u_arg[0]);
1291         }
1292         return 0;
1293 }
1294
1295 int
1296 sys_setsid(tcp)
1297 struct tcb *tcp;
1298 {
1299         return 0;
1300 }
1301
1302 int
1303 sys_getpgid(tcp)
1304 struct tcb *tcp;
1305 {
1306         if (entering(tcp)) {
1307                 tprintf("%lu", tcp->u_arg[0]);
1308         }
1309         return 0;
1310 }
1311
1312 int
1313 sys_setpgid(tcp)
1314 struct tcb *tcp;
1315 {
1316         if (entering(tcp)) {
1317                 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1318         }
1319         return 0;
1320 }
1321
1322 #if UNIXWARE >= 2
1323
1324 #include <sys/privilege.h>
1325
1326
1327 static struct xlat procpriv_cmds [] = {
1328         { SETPRV,       "SETPRV"        },
1329         { CLRPRV,       "CLRPRV"        },
1330         { PUTPRV,       "PUTPRV"        },
1331         { GETPRV,       "GETPRV"        },
1332         { CNTPRV,       "CNTPRV"        },
1333         { 0,            NULL            },
1334 };
1335
1336
1337 static struct xlat procpriv_priv [] = {
1338         { P_OWNER,      "P_OWNER"       },
1339         { P_AUDIT,      "P_AUDIT"       },
1340         { P_COMPAT,     "P_COMPAT"      },
1341         { P_DACREAD,    "P_DACREAD"     },
1342         { P_DACWRITE,   "P_DACWRITE"    },
1343         { P_DEV,        "P_DEV"         },
1344         { P_FILESYS,    "P_FILESYS"     },
1345         { P_MACREAD,    "P_MACREAD"     },
1346         { P_MACWRITE,   "P_MACWRITE"    },
1347         { P_MOUNT,      "P_MOUNT"       },
1348         { P_MULTIDIR,   "P_MULTIDIR"    },
1349         { P_SETPLEVEL,  "P_SETPLEVEL"   },
1350         { P_SETSPRIV,   "P_SETSPRIV"    },
1351         { P_SETUID,     "P_SETUID"      },
1352         { P_SYSOPS,     "P_SYSOPS"      },
1353         { P_SETUPRIV,   "P_SETUPRIV"    },
1354         { P_DRIVER,     "P_DRIVER"      },
1355         { P_RTIME,      "P_RTIME"       },
1356         { P_MACUPGRADE, "P_MACUPGRADE"  },
1357         { P_FSYSRANGE,  "P_FSYSRANGE"   },
1358         { P_SETFLEVEL,  "P_SETFLEVEL"   },
1359         { P_AUDITWR,    "P_AUDITWR"     },
1360         { P_TSHAR,      "P_TSHAR"       },
1361         { P_PLOCK,      "P_PLOCK"       },
1362         { P_CORE,       "P_CORE"        },
1363         { P_LOADMOD,    "P_LOADMOD"     },
1364         { P_BIND,       "P_BIND"        },
1365         { P_ALLPRIVS,   "P_ALLPRIVS"    },
1366         { 0,            NULL            },
1367 };
1368
1369
1370 static struct xlat procpriv_type [] = {
1371         { PS_FIX,       "PS_FIX"        },
1372         { PS_INH,       "PS_INH"        },
1373         { PS_MAX,       "PS_MAX"        },
1374         { PS_WKG,       "PS_WKG"        },
1375         { 0,            NULL            },
1376 };
1377
1378
1379 static void
1380 printpriv(tcp, addr, len, opt)
1381 struct tcb *tcp;
1382 long addr;
1383 int len;
1384 struct xlat *opt;
1385 {
1386         priv_t buf [128];
1387         int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1388         int dots = len > max;
1389         int i;
1390
1391         if (len > max) len = max;
1392
1393         if (len <= 0 ||
1394             umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1395         {
1396                 tprintf ("%#lx", addr);
1397                 return;
1398         }
1399
1400         tprintf ("[");
1401
1402         for (i = 0; i < len; ++i) {
1403                 char *t, *p;
1404
1405                 if (i) tprintf (", ");
1406
1407                 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1408                     (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1409                 {
1410                         tprintf ("%s|%s", t, p);
1411                 }
1412                 else {
1413                         tprintf ("%#lx", buf [i]);
1414                 }
1415         }
1416
1417         if (dots) tprintf (" ...");
1418
1419         tprintf ("]");
1420 }
1421
1422
1423 int
1424 sys_procpriv(tcp)
1425 struct tcb *tcp;
1426 {
1427         if (entering(tcp)) {
1428                 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1429                 switch (tcp->u_arg[0]) {
1430                     case CNTPRV:
1431                         tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1432                         break;
1433
1434                     case GETPRV:
1435                         break;
1436
1437                     default:
1438                         tprintf (", ");
1439                         printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1440                         tprintf (", %ld", tcp->u_arg[2]);
1441                 }
1442         }
1443         else if (tcp->u_arg[0] == GETPRV) {
1444                 if (syserror (tcp)) {
1445                         tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1446                 }
1447                 else {
1448                         tprintf (", ");
1449                         printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1450                         tprintf (", %ld", tcp->u_arg[2]);
1451                 }
1452         }
1453
1454         return 0;
1455 }
1456
1457 #endif
1458
1459
1460 void
1461 fake_execve(tcp, program, argv, envp)
1462 struct tcb *tcp;
1463 char *program;
1464 char *argv[];
1465 char *envp[];
1466 {
1467         int i;
1468
1469 #ifdef ARM
1470         if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1471                 return;
1472 #else
1473         if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1474                 return;
1475 #endif /* !ARM */
1476         printleader(tcp);
1477         tprintf("execve(");
1478         string_quote(program);
1479         tprintf(", [");
1480         for (i = 0; argv[i] != NULL; i++) {
1481                 if (i != 0)
1482                         tprintf(", ");
1483                 string_quote(argv[i]);
1484         }
1485         for (i = 0; envp[i] != NULL; i++)
1486                 ;
1487         tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1488         tabto(acolumn);
1489         tprintf("= 0");
1490         printtrailer(tcp);
1491 }
1492
1493 static void
1494 printargv(tcp, addr)
1495 struct tcb *tcp;
1496 long addr;
1497 {
1498         char *cp;
1499         char *sep;
1500         int max = max_strlen / 2;
1501
1502         for (sep = ""; --max >= 0; sep = ", ") {
1503                 if (!abbrev(tcp))
1504                         max++;
1505                 if (umove(tcp, addr, &cp) < 0) {
1506                         tprintf("%#lx", addr);
1507                         return;
1508                 }
1509                 if (cp == 0)
1510                         break;
1511                 tprintf(sep);
1512                 printstr(tcp, (long) cp, -1);
1513                 addr += sizeof(char *);
1514         }
1515         if (cp)
1516                 tprintf(", ...");
1517 }
1518
1519 static void
1520 printargc(fmt, tcp, addr)
1521 char *fmt;
1522 struct tcb *tcp;
1523 long addr;
1524 {
1525         int count;
1526         char *cp;
1527
1528         for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1529                 addr += sizeof(char *);
1530         }
1531         tprintf(fmt, count, count == 1 ? "" : "s");
1532 }
1533
1534 int
1535 sys_execv(tcp)
1536 struct tcb *tcp;
1537 {
1538         if (entering(tcp)) {
1539                 printpath(tcp, tcp->u_arg[0]);
1540                 if (!verbose(tcp))
1541                         tprintf(", %#lx", tcp->u_arg[1]);
1542 #if 0
1543                 else if (abbrev(tcp))
1544                         printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1545 #endif
1546                 else {
1547                         tprintf(", [");
1548                         printargv(tcp, tcp->u_arg[1]);
1549                         tprintf("]");
1550                 }
1551         }
1552         return 0;
1553 }
1554
1555 int
1556 sys_execve(tcp)
1557 struct tcb *tcp;
1558 {
1559         if (entering(tcp)) {
1560                 printpath(tcp, tcp->u_arg[0]);
1561                 if (!verbose(tcp))
1562                         tprintf(", %#lx", tcp->u_arg[1]);
1563 #if 0
1564                 else if (abbrev(tcp))
1565                         printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1566 #endif
1567                 else {
1568                         tprintf(", [");
1569                         printargv(tcp, tcp->u_arg[1]);
1570                         tprintf("]");
1571                 }
1572                 if (!verbose(tcp))
1573                         tprintf(", %#lx", tcp->u_arg[2]);
1574                 else if (abbrev(tcp))
1575                         printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1576                 else {
1577                         tprintf(", [");
1578                         printargv(tcp, tcp->u_arg[2]);
1579                         tprintf("]");
1580                 }
1581         }
1582 #if defined LINUX && defined TCB_WAITEXECVE
1583         tcp->flags |= TCB_WAITEXECVE;
1584 #endif /* LINUX && TCB_WAITEXECVE */
1585         return 0;
1586 }
1587
1588 #if UNIXWARE > 2
1589
1590 int sys_rexecve(tcp)
1591 struct tcb *tcp;
1592 {
1593         if (entering (tcp)) {
1594                 sys_execve (tcp);
1595                 tprintf (", %ld", tcp->u_arg[3]);
1596         }
1597         return 0;
1598 }
1599
1600 #endif
1601
1602 int
1603 internal_exec(tcp)
1604 struct tcb *tcp;
1605 {
1606 #ifdef SUNOS4
1607         if (exiting(tcp) && !syserror(tcp) && followfork)
1608                 fixvfork(tcp);
1609 #endif /* SUNOS4 */
1610         return 0;
1611 }
1612
1613 #ifdef LINUX
1614 #ifndef __WNOTHREAD
1615 #define __WNOTHREAD     0x20000000
1616 #endif
1617 #ifndef __WALL
1618 #define __WALL          0x40000000
1619 #endif
1620 #ifndef __WCLONE
1621 #define __WCLONE        0x80000000
1622 #endif
1623 #endif /* LINUX */
1624
1625 static struct xlat wait4_options[] = {
1626         { WNOHANG,      "WNOHANG"       },
1627 #ifndef WSTOPPED
1628         { WUNTRACED,    "WUNTRACED"     },
1629 #endif
1630 #ifdef WEXITED
1631         { WEXITED,      "WEXITED"       },
1632 #endif
1633 #ifdef WTRAPPED
1634         { WTRAPPED,     "WTRAPPED"      },
1635 #endif
1636 #ifdef WSTOPPED
1637         { WSTOPPED,     "WSTOPPED"      },
1638 #endif
1639 #ifdef WCONTINUED
1640         { WCONTINUED,   "WCONTINUED"    },
1641 #endif
1642 #ifdef WNOWAIT
1643         { WNOWAIT,      "WNOWAIT"       },
1644 #endif
1645 #ifdef __WCLONE
1646         { __WCLONE,     "__WCLONE"      },
1647 #endif
1648 #ifdef __WALL
1649         { __WALL,       "__WALL"        },
1650 #endif
1651 #ifdef __WNOTHREAD
1652         { __WNOTHREAD,  "__WNOTHREAD"   },
1653 #endif
1654         { 0,            NULL            },
1655 };
1656
1657 static int
1658 printstatus(status)
1659 int status;
1660 {
1661         int exited = 0;
1662
1663         /*
1664          * Here is a tricky presentation problem.  This solution
1665          * is still not entirely satisfactory but since there
1666          * are no wait status constructors it will have to do.
1667          */
1668         if (WIFSTOPPED(status))
1669                 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
1670                         signame(WSTOPSIG(status)));
1671         else if WIFSIGNALED(status)
1672                 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
1673                         signame(WTERMSIG(status)),
1674                         WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1675         else if WIFEXITED(status) {
1676                 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1677                         WEXITSTATUS(status));
1678                 exited = 1;
1679         }
1680         else
1681                 tprintf("[%#x]", status);
1682         return exited;
1683 }
1684
1685 static int
1686 printwaitn(tcp, n, bitness)
1687 struct tcb *tcp;
1688 int n;
1689 int bitness;
1690 {
1691         int status;
1692         int exited = 0;
1693
1694         if (entering(tcp)) {
1695                 tprintf("%ld, ", tcp->u_arg[0]);
1696         } else {
1697                 /* status */
1698                 if (!tcp->u_arg[1])
1699                         tprintf("NULL");
1700                 else if (syserror(tcp) || tcp->u_rval == 0)
1701                         tprintf("%#lx", tcp->u_arg[1]);
1702                 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1703                         tprintf("[?]");
1704                 else
1705                         exited = printstatus(status);
1706                 /* options */
1707                 tprintf(", ");
1708                 if (!printflags(wait4_options, tcp->u_arg[2]))
1709                         tprintf("0");
1710                 if (n == 4) {
1711                         tprintf(", ");
1712                         /* usage */
1713                         if (!tcp->u_arg[3])
1714                                 tprintf("NULL");
1715 #ifdef LINUX
1716                         else if (tcp->u_rval > 0) {
1717 #ifdef LINUX_64BIT
1718                                 if (bitness)
1719                                         printrusage32(tcp, tcp->u_arg[3]);
1720                                 else
1721 #endif
1722                                         printrusage(tcp, tcp->u_arg[3]);
1723                         }
1724 #endif /* LINUX */
1725 #ifdef SUNOS4
1726                         else if (tcp->u_rval > 0 && exited)
1727                                 printrusage(tcp, tcp->u_arg[3]);
1728 #endif /* SUNOS4 */
1729                         else
1730                                 tprintf("%#lx", tcp->u_arg[3]);
1731                 }
1732         }
1733         return 0;
1734 }
1735
1736 int
1737 internal_wait(tcp)
1738 struct tcb *tcp;
1739 {
1740         int got_kids;
1741
1742 #ifdef TCB_CLONE_THREAD
1743         if (tcp->flags & TCB_CLONE_THREAD)
1744                 /* The children we wait for are our parent's children.  */
1745                 got_kids = (tcp->parent->nchildren
1746                             > tcp->parent->nclone_detached);
1747         else
1748                 got_kids = (tcp->nchildren > tcp->nclone_detached);
1749 #else
1750         got_kids = tcp->nchildren > 0;
1751 #endif
1752
1753         if (entering(tcp) && got_kids) {
1754                 /* There are children that this parent should block for.
1755                    But ptrace made us the parent of the traced children
1756                    and the real parent will get ECHILD from the wait call.
1757
1758                    XXX If we attached with strace -f -p PID, then there
1759                    may be untraced dead children the parent could be reaping
1760                    now, but we make him block.  */
1761
1762                 /* ??? WTA: fix bug with hanging children */
1763
1764                 if (!(tcp->u_arg[2] & WNOHANG)) {
1765                         /* There are traced children */
1766                         tcp->flags |= TCB_SUSPENDED;
1767                         tcp->waitpid = tcp->u_arg[0];
1768 #ifdef TCB_CLONE_THREAD
1769                         if (tcp->flags & TCB_CLONE_THREAD)
1770                                 tcp->parent->nclone_waiting++;
1771 #endif
1772                 }
1773         }
1774         if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
1775                 if (tcp->u_arg[2] & WNOHANG) {
1776                         /* We must force a fake result of 0 instead of
1777                            the ECHILD error.  */
1778                         extern int force_result();
1779                         return force_result(tcp, 0, 0);
1780                 }
1781                 else
1782                         fprintf(stderr,
1783                                 "internal_wait: should not have resumed %d\n",
1784                                 tcp->pid);
1785         }
1786         return 0;
1787 }
1788
1789 #ifdef SVR4
1790
1791 int
1792 sys_wait(tcp)
1793 struct tcb *tcp;
1794 {
1795         if (exiting(tcp)) {
1796                 /* The library wrapper stuffs this into the user variable. */
1797                 if (!syserror(tcp))
1798                         printstatus(getrval2(tcp));
1799         }
1800         return 0;
1801 }
1802
1803 #endif /* SVR4 */
1804
1805 #ifdef FREEBSD
1806 int
1807 sys_wait(tcp)
1808 struct tcb *tcp;
1809 {
1810         int status;
1811
1812         if (exiting(tcp)) {
1813                 if (!syserror(tcp)) {
1814                         if (umove(tcp, tcp->u_arg[0], &status) < 0)
1815                                 tprintf("%#lx", tcp->u_arg[0]);
1816                         else
1817                                 printstatus(status);
1818                 }
1819         }
1820         return 0;
1821 }
1822 #endif
1823
1824 int
1825 sys_waitpid(tcp)
1826 struct tcb *tcp;
1827 {
1828         return printwaitn(tcp, 3, 0);
1829 }
1830
1831 int
1832 sys_wait4(tcp)
1833 struct tcb *tcp;
1834 {
1835         return printwaitn(tcp, 4, 0);
1836 }
1837
1838 #ifdef ALPHA
1839 int
1840 sys_osf_wait4(tcp)
1841 struct tcb *tcp;
1842 {
1843         return printwaitn(tcp, 4, 1);
1844 }
1845 #endif
1846
1847 #ifdef SVR4
1848
1849 static struct xlat waitid_types[] = {
1850         { P_PID,        "P_PID"         },
1851         { P_PPID,       "P_PPID"        },
1852         { P_PGID,       "P_PGID"        },
1853         { P_SID,        "P_SID"         },
1854         { P_CID,        "P_CID"         },
1855         { P_UID,        "P_UID"         },
1856         { P_GID,        "P_GID"         },
1857         { P_ALL,        "P_ALL"         },
1858 #ifdef P_LWPID
1859         { P_LWPID,      "P_LWPID"       },
1860 #endif
1861         { 0,            NULL            },
1862 };
1863
1864 int
1865 sys_waitid(tcp)
1866 struct tcb *tcp;
1867 {
1868         siginfo_t si;
1869         int exited;
1870
1871         if (entering(tcp)) {
1872                 printxval(waitid_types, tcp->u_arg[0], "P_???");
1873                 tprintf(", %ld, ", tcp->u_arg[1]);
1874                 if (tcp->nchildren > 0) {
1875                         /* There are traced children */
1876                         tcp->flags |= TCB_SUSPENDED;
1877                         tcp->waitpid = tcp->u_arg[0];
1878                 }
1879         }
1880         else {
1881                 /* siginfo */
1882                 exited = 0;
1883                 if (!tcp->u_arg[2])
1884                         tprintf("NULL");
1885                 else if (syserror(tcp))
1886                         tprintf("%#lx", tcp->u_arg[2]);
1887                 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1888                         tprintf("{???}");
1889                 else
1890                         printsiginfo(&si, verbose (tcp));
1891                 /* options */
1892                 tprintf(", ");
1893                 if (!printflags(wait4_options, tcp->u_arg[3]))
1894                         tprintf("0");
1895         }
1896         return 0;
1897 }
1898
1899 #endif /* SVR4 */
1900
1901 int
1902 sys_alarm(tcp)
1903 struct tcb *tcp;
1904 {
1905         if (entering(tcp))
1906                 tprintf("%lu", tcp->u_arg[0]);
1907         return 0;
1908 }
1909
1910 int
1911 sys_uname(tcp)
1912 struct tcb *tcp;
1913 {
1914         struct utsname uname;
1915
1916         if (exiting(tcp)) {
1917                 if (syserror(tcp) || !verbose(tcp))
1918                         tprintf("%#lx", tcp->u_arg[0]);
1919                 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1920                         tprintf("{...}");
1921                 else if (!abbrev(tcp)) {
1922
1923                         tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1924                                 uname.sysname, uname.nodename);
1925                         tprintf("release=\"%s\", version=\"%s\", ",
1926                                 uname.release, uname.version);
1927                         tprintf("machine=\"%s\"", uname.machine);
1928 #ifdef LINUX
1929 #ifndef __GLIBC__
1930                         tprintf(", domainname=\"%s\"", uname.domainname);
1931 #endif /* __GLIBC__ */
1932 #endif /* LINUX */
1933                         tprintf("}");
1934                 }
1935                 else
1936                         tprintf("{sys=\"%s\", node=\"%s\", ...}",
1937                                 uname.sysname, uname.nodename);
1938         }
1939         return 0;
1940 }
1941
1942 #ifndef SVR4
1943
1944 static struct xlat ptrace_cmds[] = {
1945 #ifndef FREEBSD
1946         { PTRACE_TRACEME,       "PTRACE_TRACEME"        },
1947         { PTRACE_PEEKTEXT,      "PTRACE_PEEKTEXT",      },
1948         { PTRACE_PEEKDATA,      "PTRACE_PEEKDATA",      },
1949         { PTRACE_PEEKUSER,      "PTRACE_PEEKUSER",      },
1950         { PTRACE_POKETEXT,      "PTRACE_POKETEXT",      },
1951         { PTRACE_POKEDATA,      "PTRACE_POKEDATA",      },
1952         { PTRACE_POKEUSER,      "PTRACE_POKEUSER",      },
1953         { PTRACE_CONT,          "PTRACE_CONT"           },
1954         { PTRACE_KILL,          "PTRACE_KILL"           },
1955         { PTRACE_SINGLESTEP,    "PTRACE_SINGLESTEP"     },
1956         { PTRACE_ATTACH,        "PTRACE_ATTACH"         },
1957         { PTRACE_DETACH,        "PTRACE_DETACH"         },
1958 #ifdef PTRACE_GETREGS
1959         { PTRACE_GETREGS,       "PTRACE_GETREGS"        },
1960 #endif
1961 #ifdef PTRACE_SETREGS
1962         { PTRACE_SETREGS,       "PTRACE_SETREGS"        },
1963 #endif
1964 #ifdef PTRACE_GETFPREGS
1965         { PTRACE_GETFPREGS,     "PTRACE_GETFPREGS",     },
1966 #endif
1967 #ifdef PTRACE_SETFPREGS
1968         { PTRACE_SETFPREGS,     "PTRACE_SETFPREGS",     },
1969 #endif
1970 #ifdef PTRACE_GETFPXREGS
1971         { PTRACE_GETFPXREGS,    "PTRACE_GETFPXREGS",    },
1972 #endif
1973 #ifdef PTRACE_SETFPXREGS
1974         { PTRACE_SETFPXREGS,    "PTRACE_SETFPXREGS",    },
1975 #endif
1976 #ifdef SUNOS4
1977         { PTRACE_READDATA,      "PTRACE_READDATA"       },
1978         { PTRACE_WRITEDATA,     "PTRACE_WRITEDATA"      },
1979         { PTRACE_READTEXT,      "PTRACE_READTEXT"       },
1980         { PTRACE_WRITETEXT,     "PTRACE_WRITETEXT"      },
1981         { PTRACE_GETFPAREGS,    "PTRACE_GETFPAREGS"     },
1982         { PTRACE_SETFPAREGS,    "PTRACE_SETFPAREGS"     },
1983 #ifdef SPARC
1984         { PTRACE_GETWINDOW,     "PTRACE_GETWINDOW"      },
1985         { PTRACE_SETWINDOW,     "PTRACE_SETWINDOW"      },
1986 #else /* !SPARC */
1987         { PTRACE_22,            "PTRACE_PTRACE_22"      },
1988         { PTRACE_23,            "PTRACE_PTRACE_23"      },
1989 #endif /* !SPARC */
1990 #endif /* SUNOS4 */
1991         { PTRACE_SYSCALL,       "PTRACE_SYSCALL"        },
1992 #ifdef SUNOS4
1993         { PTRACE_DUMPCORE,      "PTRACE_DUMPCORE"       },
1994 #ifdef I386
1995         { PTRACE_SETWRBKPT,     "PTRACE_SETWRBKPT"      },
1996         { PTRACE_SETACBKPT,     "PTRACE_SETACBKPT"      },
1997         { PTRACE_CLRDR7,        "PTRACE_CLRDR7"         },
1998 #else /* !I386 */
1999         { PTRACE_26,            "PTRACE_26"             },
2000         { PTRACE_27,            "PTRACE_27"             },
2001         { PTRACE_28,            "PTRACE_28"             },
2002 #endif /* !I386 */
2003         { PTRACE_GETUCODE,      "PTRACE_GETUCODE"       },
2004 #endif /* SUNOS4 */
2005 #else /* FREEBSD */
2006         { PT_TRACE_ME,          "PT_TRACE_ME"           },
2007         { PT_READ_I,            "PT_READ_I"             },
2008         { PT_READ_D,            "PT_READ_D"             },
2009         { PT_WRITE_I,           "PT_WRITE_I"            },
2010         { PT_WRITE_D,           "PT_WRITE_D"            },
2011 #ifdef PT_READ_U
2012         { PT_READ_U,            "PT_READ_U"             },
2013 #endif
2014         { PT_CONTINUE,          "PT_CONTINUE"           },
2015         { PT_KILL,              "PT_KILL"               },
2016         { PT_STEP,              "PT_STEP"               },
2017         { PT_ATTACH,            "PT_ATTACH"             },
2018         { PT_DETACH,            "PT_DETACH"             },
2019         { PT_GETREGS,           "PT_GETREGS"            },
2020         { PT_SETREGS,           "PT_SETREGS"            },
2021         { PT_GETFPREGS,         "PT_GETFPREGS"          },
2022         { PT_SETFPREGS,         "PT_SETFPREGS"          },
2023         { PT_GETDBREGS,         "PT_GETDBREGS"          },
2024         { PT_SETDBREGS,         "PT_SETDBREGS"          },
2025 #endif /* FREEBSD */
2026         { 0,                    NULL                    },
2027 };
2028
2029 #ifndef FREEBSD
2030 #ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2031 static
2032 #endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2033 struct xlat struct_user_offsets[] = {
2034 #ifdef LINUX
2035 #if defined(S390) || defined(S390X)
2036         { PT_PSWMASK,           "psw_mask"                              },
2037         { PT_PSWADDR,           "psw_addr"                              },
2038         { PT_GPR0,              "gpr0"                                  },
2039         { PT_GPR1,              "gpr1"                                  },
2040         { PT_GPR2,              "gpr2"                                  },
2041         { PT_GPR3,              "gpr3"                                  },
2042         { PT_GPR4,              "gpr4"                                  },
2043         { PT_GPR5,              "gpr5"                                  },
2044         { PT_GPR6,              "gpr6"                                  },
2045         { PT_GPR7,              "gpr7"                                  },
2046         { PT_GPR8,              "gpr8"                                  },
2047         { PT_GPR9,              "gpr9"                                  },
2048         { PT_GPR10,             "gpr10"                                 },
2049         { PT_GPR11,             "gpr11"                                 },
2050         { PT_GPR12,             "gpr12"                                 },
2051         { PT_GPR13,             "gpr13"                                 },
2052         { PT_GPR14,             "gpr14"                                 },
2053         { PT_GPR15,             "gpr15"                                 },
2054         { PT_ACR0,              "acr0"                                  },
2055         { PT_ACR1,              "acr1"                                  },
2056         { PT_ACR2,              "acr2"                                  },
2057         { PT_ACR3,              "acr3"                                  },
2058         { PT_ACR4,              "acr4"                                  },
2059         { PT_ACR5,              "acr5"                                  },
2060         { PT_ACR6,              "acr6"                                  },
2061         { PT_ACR7,              "acr7"                                  },
2062         { PT_ACR8,              "acr8"                                  },
2063         { PT_ACR9,              "acr9"                                  },
2064         { PT_ACR10,             "acr10"                                 },
2065         { PT_ACR11,             "acr11"                                 },
2066         { PT_ACR12,             "acr12"                                 },
2067         { PT_ACR13,             "acr13"                                 },
2068         { PT_ACR14,             "acr14"                                 },
2069         { PT_ACR15,             "acr15"                                 },
2070         { PT_ORIGGPR2,          "orig_gpr2"                             },
2071         { PT_FPC,               "fpc"                                   },
2072 #if defined(S390)
2073         { PT_FPR0_HI,           "fpr0.hi"                               },
2074         { PT_FPR0_LO,           "fpr0.lo"                               },
2075         { PT_FPR1_HI,           "fpr1.hi"                               },
2076         { PT_FPR1_LO,           "fpr1.lo"                               },
2077         { PT_FPR2_HI,           "fpr2.hi"                               },
2078         { PT_FPR2_LO,           "fpr2.lo"                               },
2079         { PT_FPR3_HI,           "fpr3.hi"                               },
2080         { PT_FPR3_LO,           "fpr3.lo"                               },
2081         { PT_FPR4_HI,           "fpr4.hi"                               },
2082         { PT_FPR4_LO,           "fpr4.lo"                               },
2083         { PT_FPR5_HI,           "fpr5.hi"                               },
2084         { PT_FPR5_LO,           "fpr5.lo"                               },
2085         { PT_FPR6_HI,           "fpr6.hi"                               },
2086         { PT_FPR6_LO,           "fpr6.lo"                               },
2087         { PT_FPR7_HI,           "fpr7.hi"                               },
2088         { PT_FPR7_LO,           "fpr7.lo"                               },
2089         { PT_FPR8_HI,           "fpr8.hi"                               },
2090         { PT_FPR8_LO,           "fpr8.lo"                               },
2091         { PT_FPR9_HI,           "fpr9.hi"                               },
2092         { PT_FPR9_LO,           "fpr9.lo"                               },
2093         { PT_FPR10_HI,          "fpr10.hi"                              },
2094         { PT_FPR10_LO,          "fpr10.lo"                              },
2095         { PT_FPR11_HI,          "fpr11.hi"                              },
2096         { PT_FPR11_LO,          "fpr11.lo"                              },
2097         { PT_FPR12_HI,          "fpr12.hi"                              },
2098         { PT_FPR12_LO,          "fpr12.lo"                              },
2099         { PT_FPR13_HI,          "fpr13.hi"                              },
2100         { PT_FPR13_LO,          "fpr13.lo"                              },
2101         { PT_FPR14_HI,          "fpr14.hi"                              },
2102         { PT_FPR14_LO,          "fpr14.lo"                              },
2103         { PT_FPR15_HI,          "fpr15.hi"                              },
2104         { PT_FPR15_LO,          "fpr15.lo"                              },
2105 #endif
2106 #if defined(S390X)
2107         { PT_FPR0,              "fpr0"                                  },
2108         { PT_FPR1,              "fpr1"                                  },
2109         { PT_FPR2,              "fpr2"                                  },
2110         { PT_FPR3,              "fpr3"                                  },
2111         { PT_FPR4,              "fpr4"                                  },
2112         { PT_FPR5,              "fpr5"                                  },
2113         { PT_FPR6,              "fpr6"                                  },
2114         { PT_FPR7,              "fpr7"                                  },
2115         { PT_FPR8,              "fpr8"                                  },
2116         { PT_FPR9,              "fpr9"                                  },
2117         { PT_FPR10,             "fpr10"                                 },
2118         { PT_FPR11,             "fpr11"                                 },
2119         { PT_FPR12,             "fpr12"                                 },
2120         { PT_FPR13,             "fpr13"                                 },
2121         { PT_FPR14,             "fpr14"                                 },
2122         { PT_FPR15,             "fpr15"                                 },
2123 #endif
2124         { PT_CR_9,              "cr9"                                   },
2125         { PT_CR_10,             "cr10"                                  },
2126         { PT_CR_11,             "cr11"                                  },
2127         { PT_IEEE_IP,           "ieee_exception_ip"                     },
2128 #endif
2129 #if defined(SPARC)
2130         /* XXX No support for these offsets yet. */
2131 #elif defined(HPPA)
2132         /* XXX No support for these offsets yet. */
2133 #elif defined(POWERPC)
2134 #ifndef PT_ORIG_R3
2135 #define PT_ORIG_R3 34
2136 #endif
2137 #define REGSIZE (sizeof(unsigned long))
2138         { REGSIZE*PT_R0,                "r0"                            },
2139         { REGSIZE*PT_R1,                "r1"                            },
2140         { REGSIZE*PT_R2,                "r2"                            },
2141         { REGSIZE*PT_R3,                "r3"                            },
2142         { REGSIZE*PT_R4,                "r4"                            },
2143         { REGSIZE*PT_R5,                "r5"                            },
2144         { REGSIZE*PT_R6,                "r6"                            },
2145         { REGSIZE*PT_R7,                "r7"                            },
2146         { REGSIZE*PT_R8,                "r8"                            },
2147         { REGSIZE*PT_R9,                "r9"                            },
2148         { REGSIZE*PT_R10,               "r10"                           },
2149         { REGSIZE*PT_R11,               "r11"                           },
2150         { REGSIZE*PT_R12,               "r12"                           },
2151         { REGSIZE*PT_R13,               "r13"                           },
2152         { REGSIZE*PT_R14,               "r14"                           },
2153         { REGSIZE*PT_R15,               "r15"                           },
2154         { REGSIZE*PT_R16,               "r16"                           },
2155         { REGSIZE*PT_R17,               "r17"                           },
2156         { REGSIZE*PT_R18,               "r18"                           },
2157         { REGSIZE*PT_R19,               "r19"                           },
2158         { REGSIZE*PT_R20,               "r20"                           },
2159         { REGSIZE*PT_R21,               "r21"                           },
2160         { REGSIZE*PT_R22,               "r22"                           },
2161         { REGSIZE*PT_R23,               "r23"                           },
2162         { REGSIZE*PT_R24,               "r24"                           },
2163         { REGSIZE*PT_R25,               "r25"                           },
2164         { REGSIZE*PT_R26,               "r26"                           },
2165         { REGSIZE*PT_R27,               "r27"                           },
2166         { REGSIZE*PT_R28,               "r28"                           },
2167         { REGSIZE*PT_R29,               "r29"                           },
2168         { REGSIZE*PT_R30,               "r30"                           },
2169         { REGSIZE*PT_R31,               "r31"                           },
2170         { REGSIZE*PT_NIP,               "NIP"                           },
2171         { REGSIZE*PT_MSR,               "MSR"                           },
2172         { REGSIZE*PT_ORIG_R3,           "ORIG_R3"                       },
2173         { REGSIZE*PT_CTR,               "CTR"                           },
2174         { REGSIZE*PT_LNK,               "LNK"                           },
2175         { REGSIZE*PT_XER,               "XER"                           },
2176         { REGSIZE*PT_CCR,               "CCR"                           },
2177         { REGSIZE*PT_FPR0,              "FPR0"                          },
2178 #undef REGSIZE
2179 #else
2180 #ifdef ALPHA
2181         { 0,                    "r0"                                    },
2182         { 1,                    "r1"                                    },
2183         { 2,                    "r2"                                    },
2184         { 3,                    "r3"                                    },
2185         { 4,                    "r4"                                    },
2186         { 5,                    "r5"                                    },
2187         { 6,                    "r6"                                    },
2188         { 7,                    "r7"                                    },
2189         { 8,                    "r8"                                    },
2190         { 9,                    "r9"                                    },
2191         { 10,                   "r10"                                   },
2192         { 11,                   "r11"                                   },
2193         { 12,                   "r12"                                   },
2194         { 13,                   "r13"                                   },
2195         { 14,                   "r14"                                   },
2196         { 15,                   "r15"                                   },
2197         { 16,                   "r16"                                   },
2198         { 17,                   "r17"                                   },
2199         { 18,                   "r18"                                   },
2200         { 19,                   "r19"                                   },
2201         { 20,                   "r20"                                   },
2202         { 21,                   "r21"                                   },
2203         { 22,                   "r22"                                   },
2204         { 23,                   "r23"                                   },
2205         { 24,                   "r24"                                   },
2206         { 25,                   "r25"                                   },
2207         { 26,                   "r26"                                   },
2208         { 27,                   "r27"                                   },
2209         { 28,                   "r28"                                   },
2210         { 29,                   "gp"                                    },
2211         { 30,                   "fp"                                    },
2212         { 31,                   "zero"                                  },
2213         { 32,                   "fp0"                                   },
2214         { 33,                   "fp"                                    },
2215         { 34,                   "fp2"                                   },
2216         { 35,                   "fp3"                                   },
2217         { 36,                   "fp4"                                   },
2218         { 37,                   "fp5"                                   },
2219         { 38,                   "fp6"                                   },
2220         { 39,                   "fp7"                                   },
2221         { 40,                   "fp8"                                   },
2222         { 41,                   "fp9"                                   },
2223         { 42,                   "fp10"                                  },
2224         { 43,                   "fp11"                                  },
2225         { 44,                   "fp12"                                  },
2226         { 45,                   "fp13"                                  },
2227         { 46,                   "fp14"                                  },
2228         { 47,                   "fp15"                                  },
2229         { 48,                   "fp16"                                  },
2230         { 49,                   "fp17"                                  },
2231         { 50,                   "fp18"                                  },
2232         { 51,                   "fp19"                                  },
2233         { 52,                   "fp20"                                  },
2234         { 53,                   "fp21"                                  },
2235         { 54,                   "fp22"                                  },
2236         { 55,                   "fp23"                                  },
2237         { 56,                   "fp24"                                  },
2238         { 57,                   "fp25"                                  },
2239         { 58,                   "fp26"                                  },
2240         { 59,                   "fp27"                                  },
2241         { 60,                   "fp28"                                  },
2242         { 61,                   "fp29"                                  },
2243         { 62,                   "fp30"                                  },
2244         { 63,                   "fp31"                                  },
2245         { 64,                   "pc"                                    },
2246 #else /* !ALPHA */
2247 #ifdef IA64
2248         { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2249         { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2250         { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2251         { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2252         { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2253         { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2254         { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2255         { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2256         { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2257         { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2258         { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2259         { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2260         { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2261         { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2262         { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2263         { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2264         { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2265         { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2266         { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2267         { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2268         { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2269         { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2270         { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2271         { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2272         { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2273         { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2274         { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2275         { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2276         { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2277         { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2278         { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2279         { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2280         /* switch stack: */
2281         { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2282         { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2283         { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2284         { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2285         { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2286         { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2287         { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2288         { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2289         { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2290         { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2291         { PT_B0, "kb0" },
2292         { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2293         { PT_B4, "b4" }, { PT_B5, "b5" },
2294         { PT_AR_PFS, "kar.pfs" },
2295         { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" },
2296         { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" },
2297         { PT_PR, "k.pr" },
2298         /* pt_regs */
2299         { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
2300         /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" },
2301         { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2302         { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2303         { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2304         { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2305         { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2306         { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2307         { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2308         { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2309         { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2310         { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2311         { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2312         { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2313         { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2314         { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2315         { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2316 #else /* !IA64 */
2317 #ifdef I386
2318         { 4*EBX,                "4*EBX"                                 },
2319         { 4*ECX,                "4*ECX"                                 },
2320         { 4*EDX,                "4*EDX"                                 },
2321         { 4*ESI,                "4*ESI"                                 },
2322         { 4*EDI,                "4*EDI"                                 },
2323         { 4*EBP,                "4*EBP"                                 },
2324         { 4*EAX,                "4*EAX"                                 },
2325         { 4*DS,                 "4*DS"                                  },
2326         { 4*ES,                 "4*ES"                                  },
2327         { 4*FS,                 "4*FS"                                  },
2328         { 4*GS,                 "4*GS"                                  },
2329         { 4*ORIG_EAX,           "4*ORIG_EAX"                            },
2330         { 4*EIP,                "4*EIP"                                 },
2331         { 4*CS,                 "4*CS"                                  },
2332         { 4*EFL,                "4*EFL"                                 },
2333         { 4*UESP,               "4*UESP"                                },
2334         { 4*SS,                 "4*SS"                                  },
2335 #else /* !I386 */
2336 #ifdef X86_64
2337         { 8*RDI,                "8*RDI"                                 },
2338         { 8*RSI,                "8*RSI"                                 },
2339         { 8*RDX,                "8*RDX"                                 },
2340         { 8*R10,                "8*R10" },
2341         { 8*R8,                 "8*R8" },
2342         { 8*R9,                 "8*R9" },
2343         { 8*RBX,                "8*RBX"                                 },
2344         { 8*RCX,                "8*RCX"                                 },
2345         { 8*RBP,                "8*RBP"                                 },
2346         { 8*RAX,                "8*RAX"                                 },
2347 #if 0
2348         { 8*DS,                 "8*DS"                                  },
2349         { 8*ES,                 "8*ES"                                  },
2350         { 8*FS,                 "8*FS"                                  },
2351         { 8*GS,                 "8*GS"                                  },
2352 #endif
2353         { 8*ORIG_RAX,           "8*ORIG_EAX"                            },
2354         { 8*RIP,                "8*RIP"                                 },
2355         { 8*CS,                 "8*CS"                                  },
2356         { 8*EFLAGS,             "8*EFL"                                 },
2357         { 8*RSP,                "8*RSP"                         },
2358         { 8*SS,                 "8*SS"                                  },
2359         { 8*R11,                "8*R11" },
2360         { 8*R12,                "8*R12" },
2361         { 8*R13,                "8*R13" },
2362         { 8*R14,                "8*R14" },
2363         { 8*R15,                "8*R15" },
2364 #endif
2365 #ifdef M68K
2366         { 4*PT_D1,              "4*PT_D1"                               },
2367         { 4*PT_D2,              "4*PT_D2"                               },
2368         { 4*PT_D3,              "4*PT_D3"                               },
2369         { 4*PT_D4,              "4*PT_D4"                               },
2370         { 4*PT_D5,              "4*PT_D5"                               },
2371         { 4*PT_D6,              "4*PT_D6"                               },
2372         { 4*PT_D7,              "4*PT_D7"                               },
2373         { 4*PT_A0,              "4*PT_A0"                               },
2374         { 4*PT_A1,              "4*PT_A1"                               },
2375         { 4*PT_A2,              "4*PT_A2"                               },
2376         { 4*PT_A3,              "4*PT_A3"                               },
2377         { 4*PT_A4,              "4*PT_A4"                               },
2378         { 4*PT_A5,              "4*PT_A5"                               },
2379         { 4*PT_A6,              "4*PT_A6"                               },
2380         { 4*PT_D0,              "4*PT_D0"                               },
2381         { 4*PT_USP,             "4*PT_USP"                              },
2382         { 4*PT_ORIG_D0,         "4*PT_ORIG_D0"                          },
2383         { 4*PT_SR,              "4*PT_SR"                               },
2384         { 4*PT_PC,              "4*PT_PC"                               },
2385 #endif /* M68K */
2386 #endif /* !I386 */
2387 #ifdef SH
2388        { 4*REG_REG0,           "4*REG_REG0"                            },
2389        { 4*(REG_REG0+1),       "4*REG_REG1"                            },
2390        { 4*(REG_REG0+2),       "4*REG_REG2"                            },
2391        { 4*(REG_REG0+3),       "4*REG_REG3"                            },
2392        { 4*(REG_REG0+4),       "4*REG_REG4"                            },
2393        { 4*(REG_REG0+5),       "4*REG_REG5"                            },
2394        { 4*(REG_REG0+6),       "4*REG_REG6"                            },
2395        { 4*(REG_REG0+7),       "4*REG_REG7"                            },
2396        { 4*(REG_REG0+8),       "4*REG_REG8"                            },
2397        { 4*(REG_REG0+9),       "4*REG_REG9"                            },
2398        { 4*(REG_REG0+10),      "4*REG_REG10"                           },
2399        { 4*(REG_REG0+11),      "4*REG_REG11"                           },
2400        { 4*(REG_REG0+12),      "4*REG_REG12"                           },
2401        { 4*(REG_REG0+13),      "4*REG_REG13"                           },
2402        { 4*(REG_REG0+14),      "4*REG_REG14"                           },
2403        { 4*REG_REG15,          "4*REG_REG15"                           },
2404        { 4*REG_PC,             "4*REG_PC"                              },
2405        { 4*REG_PR,             "4*REG_PR"                              },
2406        { 4*REG_SR,             "4*REG_SR"                              },
2407        { 4*REG_GBR,            "4*REG_GBR"                             },
2408        { 4*REG_MACH,           "4*REG_MACH"                            },
2409        { 4*REG_MACL,           "4*REG_MACL"                            },
2410        { 4*REG_SYSCALL,        "4*REG_SYSCALL"                         },
2411        { 4*REG_FPUL,           "4*REG_FPUL"                            },
2412        { 4*REG_FPREG0,         "4*REG_FPREG0"                          },
2413        { 4*(REG_FPREG0+1),     "4*REG_FPREG1"                          },
2414        { 4*(REG_FPREG0+2),     "4*REG_FPREG2"                          },
2415        { 4*(REG_FPREG0+3),     "4*REG_FPREG3"                          },
2416        { 4*(REG_FPREG0+4),     "4*REG_FPREG4"                          },
2417        { 4*(REG_FPREG0+5),     "4*REG_FPREG5"                          },
2418        { 4*(REG_FPREG0+6),     "4*REG_FPREG6"                          },
2419        { 4*(REG_FPREG0+7),     "4*REG_FPREG7"                          },
2420        { 4*(REG_FPREG0+8),     "4*REG_FPREG8"                          },
2421        { 4*(REG_FPREG0+9),     "4*REG_FPREG9"                          },
2422        { 4*(REG_FPREG0+10),    "4*REG_FPREG10"                         },
2423        { 4*(REG_FPREG0+11),    "4*REG_FPREG11"                         },
2424        { 4*(REG_FPREG0+12),    "4*REG_FPREG12"                         },
2425        { 4*(REG_FPREG0+13),    "4*REG_FPREG13"                         },
2426        { 4*(REG_FPREG0+14),    "4*REG_FPREG14"                         },
2427        { 4*REG_FPREG15,        "4*REG_FPREG15"                         },
2428        { 4*REG_XDREG0,         "4*REG_XDREG0"                          },
2429        { 4*(REG_XDREG0+2),     "4*REG_XDREG2"                          },
2430        { 4*(REG_XDREG0+4),     "4*REG_XDREG4"                          },
2431        { 4*(REG_XDREG0+6),     "4*REG_XDREG6"                          },
2432        { 4*(REG_XDREG0+8),     "4*REG_XDREG8"                          },
2433        { 4*(REG_XDREG0+10),    "4*REG_XDREG10"                         },
2434        { 4*(REG_XDREG0+12),    "4*REG_XDREG12"                         },
2435        { 4*REG_XDREG14,        "4*REG_XDREG14"                         },
2436        { 4*REG_FPSCR,          "4*REG_FPSCR"                           },
2437 #endif /* SH */
2438
2439 #if !defined(S390) && !defined(S390X) && !defined(MIPS)
2440         { uoff(u_fpvalid),      "offsetof(struct user, u_fpvalid)"      },
2441 #endif
2442 #if  defined(I386) || defined(X86_64)
2443         { uoff(i387),           "offsetof(struct user, i387)"           },
2444 #else /* !I386 */
2445 #ifdef M68K
2446         { uoff(m68kfp),         "offsetof(struct user, m68kfp)"         },
2447 #endif /* M68K */
2448 #endif /* !I386 */
2449         { uoff(u_tsize),        "offsetof(struct user, u_tsize)"        },
2450         { uoff(u_dsize),        "offsetof(struct user, u_dsize)"        },
2451         { uoff(u_ssize),        "offsetof(struct user, u_ssize)"        },
2452         { uoff(start_code),     "offsetof(struct user, start_code)"     },
2453         { uoff(start_stack),    "offsetof(struct user, start_stack)"    },
2454         { uoff(signal),         "offsetof(struct user, signal)"         },
2455 #if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH)
2456         { uoff(reserved),       "offsetof(struct user, reserved)"       },
2457 #endif
2458         { uoff(u_ar0),          "offsetof(struct user, u_ar0)"          },
2459 #if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
2460         { uoff(u_fpstate),      "offsetof(struct user, u_fpstate)"      },
2461 #endif
2462         { uoff(magic),          "offsetof(struct user, magic)"          },
2463         { uoff(u_comm),         "offsetof(struct user, u_comm)"         },
2464 #if defined(I386) || defined(X86_64)
2465         { uoff(u_debugreg),     "offsetof(struct user, u_debugreg)"     },
2466 #endif /* I386 */
2467 #endif /* !IA64 */
2468 #endif /* !ALPHA */
2469 #endif /* !POWERPC/!SPARC */
2470 #endif /* LINUX */
2471 #ifdef SUNOS4
2472         { uoff(u_pcb),          "offsetof(struct user, u_pcb)"          },
2473         { uoff(u_procp),        "offsetof(struct user, u_procp)"        },
2474         { uoff(u_ar0),          "offsetof(struct user, u_ar0)"          },
2475         { uoff(u_comm[0]),      "offsetof(struct user, u_comm[0])"      },
2476         { uoff(u_arg[0]),       "offsetof(struct user, u_arg[0])"       },
2477         { uoff(u_ap),           "offsetof(struct user, u_ap)"           },
2478         { uoff(u_qsave),        "offsetof(struct user, u_qsave)"        },
2479         { uoff(u_rval1),        "offsetof(struct user, u_rval1)"        },
2480         { uoff(u_rval2),        "offsetof(struct user, u_rval2)"        },
2481         { uoff(u_error),        "offsetof(struct user, u_error)"        },
2482         { uoff(u_eosys),        "offsetof(struct user, u_eosys)"        },
2483         { uoff(u_ssave),        "offsetof(struct user, u_ssave)"        },
2484         { uoff(u_signal[0]),    "offsetof(struct user, u_signal)"       },
2485         { uoff(u_sigmask[0]),   "offsetof(struct user, u_sigmask)"      },
2486         { uoff(u_sigonstack),   "offsetof(struct user, u_sigonstack)"   },
2487         { uoff(u_sigintr),      "offsetof(struct user, u_sigintr)"      },
2488         { uoff(u_sigreset),     "offsetof(struct user, u_sigreset)"     },
2489         { uoff(u_oldmask),      "offsetof(struct user, u_oldmask)"      },
2490         { uoff(u_code),         "offsetof(struct user, u_code)"         },
2491         { uoff(u_addr),         "offsetof(struct user, u_addr)"         },
2492         { uoff(u_sigstack),     "offsetof(struct user, u_sigstack)"     },
2493         { uoff(u_ofile),        "offsetof(struct user, u_ofile)"        },
2494         { uoff(u_pofile),       "offsetof(struct user, u_pofile)"       },
2495         { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2496         { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2497         { uoff(u_lastfile),     "offsetof(struct user, u_lastfile)"     },
2498         { uoff(u_cwd),          "offsetof(struct user, u_cwd)"          },
2499         { uoff(u_cdir),         "offsetof(struct user, u_cdir)"         },
2500         { uoff(u_rdir),         "offsetof(struct user, u_rdir)"         },
2501         { uoff(u_cmask),        "offsetof(struct user, u_cmask)"        },
2502         { uoff(u_ru),           "offsetof(struct user, u_ru)"           },
2503         { uoff(u_cru),          "offsetof(struct user, u_cru)"          },
2504         { uoff(u_timer[0]),     "offsetof(struct user, u_timer[0])"     },
2505         { uoff(u_XXX[0]),       "offsetof(struct user, u_XXX[0])"       },
2506         { uoff(u_ioch),         "offsetof(struct user, u_ioch)"         },
2507         { uoff(u_start),        "offsetof(struct user, u_start)"        },
2508         { uoff(u_acflag),       "offsetof(struct user, u_acflag)"       },
2509         { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2510         { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2511         { uoff(u_prof.pr_off),  "offsetof(struct user, u_prof.pr_off)"  },
2512         { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2513         { uoff(u_rlimit[0]),    "offsetof(struct user, u_rlimit)"       },
2514         { uoff(u_exdata.Ux_A),  "offsetof(struct user, u_exdata.Ux_A)"  },
2515         { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2516         { uoff(u_lofault),      "offsetof(struct user, u_lofault)"      },
2517 #endif /* SUNOS4 */
2518 #ifndef HPPA
2519         { sizeof(struct user),  "sizeof(struct user)"                   },
2520 #endif
2521         { 0,                    NULL                                    },
2522 };
2523 #endif
2524
2525 int
2526 sys_ptrace(tcp)
2527 struct tcb *tcp;
2528 {
2529         struct xlat *x;
2530         long addr;
2531
2532         if (entering(tcp)) {
2533                 printxval(ptrace_cmds, tcp->u_arg[0],
2534 #ifndef FREEBSD
2535                           "PTRACE_???"
2536 #else
2537                           "PT_???"
2538 #endif
2539                         );
2540                 tprintf(", %lu, ", tcp->u_arg[1]);
2541                 addr = tcp->u_arg[2];
2542 #ifndef FREEBSD
2543                 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2544                         || tcp->u_arg[0] == PTRACE_POKEUSER) {
2545                         for (x = struct_user_offsets; x->str; x++) {
2546                                 if (x->val >= addr)
2547                                         break;
2548                         }
2549                         if (!x->str)
2550                                 tprintf("%#lx, ", addr);
2551                         else if (x->val > addr && x != struct_user_offsets) {
2552                                 x--;
2553                                 tprintf("%s + %ld, ", x->str, addr - x->val);
2554                         }
2555                         else
2556                                 tprintf("%s, ", x->str);
2557                 }
2558                 else
2559 #endif
2560                         tprintf("%#lx, ", tcp->u_arg[2]);
2561 #ifdef LINUX
2562                 switch (tcp->u_arg[0]) {
2563                 case PTRACE_PEEKDATA:
2564                 case PTRACE_PEEKTEXT:
2565                 case PTRACE_PEEKUSER:
2566                         break;
2567                 case PTRACE_CONT:
2568                 case PTRACE_SINGLESTEP:
2569                 case PTRACE_SYSCALL:
2570                 case PTRACE_DETACH:
2571                         printsignal(tcp->u_arg[3]);
2572                         break;
2573                 default:
2574                         tprintf("%#lx", tcp->u_arg[3]);
2575                         break;
2576                 }
2577         } else {
2578                 switch (tcp->u_arg[0]) {
2579                 case PTRACE_PEEKDATA:
2580                 case PTRACE_PEEKTEXT:
2581                 case PTRACE_PEEKUSER:
2582                         printnum(tcp, tcp->u_arg[3], "%#lx");
2583                         break;
2584                 }
2585         }
2586 #endif /* LINUX */
2587 #ifdef SUNOS4
2588                 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2589                         tcp->u_arg[0] == PTRACE_WRITETEXT) {
2590                         tprintf("%lu, ", tcp->u_arg[3]);
2591                         printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2592                 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2593                                 tcp->u_arg[0] != PTRACE_READTEXT) {
2594                         tprintf("%#lx", tcp->u_arg[3]);
2595                 }
2596         } else {
2597                 if (tcp->u_arg[0] == PTRACE_READDATA ||
2598                         tcp->u_arg[0] == PTRACE_READTEXT) {
2599                         tprintf("%lu, ", tcp->u_arg[3]);
2600                         printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2601                 }
2602         }
2603 #endif /* SUNOS4 */
2604 #ifdef FREEBSD
2605                 tprintf("%lu", tcp->u_arg[3]);
2606         }
2607 #endif /* FREEBSD */
2608         return 0;
2609 }
2610
2611 #endif /* !SVR4 */
2612
2613 #ifdef LINUX
2614 static struct xlat futexops[] = {
2615         { FUTEX_WAIT,   "FUTEX_WAIT" },
2616         { FUTEX_WAKE,   "FUTEX_WAKE" },
2617         { FUTEX_FD,     "FUTEX_FD" },
2618         { 0,            NULL }
2619 };
2620
2621 int
2622 sys_futex(tcp)
2623 struct tcb *tcp;
2624 {
2625     if (entering(tcp)) {
2626         tprintf("%p, ", (void *) tcp->u_arg[0]);
2627         printflags(futexops, tcp->u_arg[1]);
2628         tprintf(", %ld, ", tcp->u_arg[2]);
2629         printtv(tcp, tcp->u_arg[3]);
2630     }
2631     return 0;
2632 }
2633
2634 static void
2635 print_affinitylist(list, len)
2636 unsigned long *list;
2637 unsigned int len;
2638 {
2639     int first = 1;
2640     tprintf(" {");
2641     while (len > sizeof (unsigned long)) {
2642         tprintf("%s %lx", first ? "" : ",", *list++);
2643         first = 0;
2644         len -= sizeof (unsigned long);
2645     }
2646     tprintf(" }");
2647 }
2648
2649 int
2650 sys_sched_setaffinity(tcp)
2651 struct tcb *tcp;
2652 {
2653     if (entering(tcp)) {
2654         tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2655         print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2656     }
2657     return 0;
2658 }
2659
2660 int
2661 sys_sched_getaffinity(tcp)
2662 struct tcb *tcp;
2663 {
2664     if (entering(tcp)) {
2665         tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2666     } else {
2667         print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);
2668     }
2669     return 0;
2670 }
2671 #endif