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