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