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