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