]> granicus.if.org Git - strace/blob - process.c
Merge Harald Böhme's solaris patches
[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  *
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  *      $Id$
35  */
36
37 #include "defs.h"
38
39 #include <fcntl.h>
40 #include <sys/stat.h>
41 #include <sys/time.h>
42 #include <sys/wait.h>
43 #include <sys/resource.h>
44 #include <sys/utsname.h>
45 #include <sys/user.h>
46 #include <sys/syscall.h>
47 #include <signal.h>
48 #ifdef SUNOS4
49 #include <machine/reg.h>
50 #endif /* SUNOS4 */
51
52 #ifdef FREEBSD
53 #include <sys/ptrace.h>
54 #endif
55
56 #ifdef HAVE_SYS_REG_H
57 # include <sys/reg.h>
58 #ifndef PTRACE_PEEKUSR
59 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
60 #endif
61 #ifndef PTRACE_POKEUSR
62 # define PTRACE_POKEUSR PTRACE_POKEUSER
63 #endif
64 #elif defined(HAVE_LINUX_PTRACE_H)
65 #undef PTRACE_SYSCALL
66 #include <linux/ptrace.h>
67 #endif
68
69
70 #ifdef LINUX
71 #include <asm/posix_types.h>
72 #undef GETGROUPS_T
73 #define GETGROUPS_T __kernel_gid_t
74 #endif /* LINUX */
75
76 #if defined(LINUX) && defined(IA64)
77 # include <asm/ptrace_offsets.h>
78 # include <asm/rse.h>
79 #endif
80
81 #ifdef HAVE_PRCTL
82 #include <sys/prctl.h>
83 #endif
84
85 #ifndef WCOREDUMP
86 #define WCOREDUMP(status) ((status) & 0200)
87 #endif
88
89 /* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
90 #if defined(HAVE_PRCTL)
91 static struct xlat prctl_options[] = {
92 #ifdef PR_MAXPROCS
93         { PR_MAXPROCS,          "PR_MAXPROCS"           },
94 #endif
95 #ifdef PR_ISBLOCKED
96         { PR_ISBLOCKED,         "PR_ISBLOCKED"          },
97 #endif
98 #ifdef PR_SETSTACKSIZE
99         { PR_SETSTACKSIZE,      "PR_SETSTACKSIZE"       },
100 #endif
101 #ifdef PR_GETSTACKSIZE
102         { PR_GETSTACKSIZE,      "PR_GETSTACKSIZE"       },
103 #endif
104 #ifdef PR_MAXPPROCS
105         { PR_MAXPPROCS,         "PR_MAXPPROCS"          },
106 #endif
107 #ifdef PR_UNBLKONEXEC
108         { PR_UNBLKONEXEC,       "PR_UNBLKONEXEC"        },
109 #endif
110 #ifdef PR_ATOMICSIM
111         { PR_ATOMICSIM,         "PR_ATOMICSIM"          },
112 #endif
113 #ifdef PR_SETEXITSIG
114         { PR_SETEXITSIG,        "PR_SETEXITSIG"         },
115 #endif
116 #ifdef PR_RESIDENT
117         { PR_RESIDENT,          "PR_RESIDENT"           },
118 #endif
119 #ifdef PR_ATTACHADDR
120         { PR_ATTACHADDR,        "PR_ATTACHADDR"         },
121 #endif
122 #ifdef PR_DETACHADDR
123         { PR_DETACHADDR,        "PR_DETACHADDR"         },
124 #endif
125 #ifdef PR_TERMCHILD
126         { PR_TERMCHILD,         "PR_TERMCHILD"          },
127 #endif
128 #ifdef PR_GETSHMASK
129         { PR_GETSHMASK,         "PR_GETSHMASK"          },
130 #endif
131 #ifdef PR_GETNSHARE
132         { PR_GETNSHARE,         "PR_GETNSHARE"          },
133 #endif
134 #if defined(PR_SET_PDEATHSIG)
135         { PR_SET_PDEATHSIG,     "PR_SET_PDEATHSIG"      },
136 #endif
137 #ifdef PR_COREPID
138         { PR_COREPID,           "PR_COREPID"            },
139 #endif
140 #ifdef PR_ATTACHADDRPERM
141         { PR_ATTACHADDRPERM,    "PR_ATTACHADDRPERM"     },
142 #endif
143 #ifdef PR_PTHREADEXIT
144         { PR_PTHREADEXIT,       "PR_PTHREADEXIT"        },
145 #endif
146 #ifdef PR_SET_PDEATHSIG
147         { PR_SET_PDEATHSIG,     "PR_SET_PDEATHSIG"      },
148 #endif
149 #ifdef PR_GET_PDEATHSIG
150         { PR_GET_PDEATHSIG,     "PR_GET_PDEATHSIG"      },
151 #endif
152 #ifdef PR_GET_UNALIGN
153         { PR_GET_UNALIGN,       "PR_GET_UNALIGN"        },
154 #endif
155 #ifdef PR_SET_UNALIGN
156         { PR_SET_UNALIGN,       "PR_SET_UNALIGN"        },
157 #endif
158 #ifdef PR_GET_KEEPCAPS
159         { PR_GET_KEEPCAPS,      "PR_GET_KEEP_CAPS"      },
160 #endif
161 #ifdef PR_SET_KEEPCAPS
162         { PR_SET_KEEPCAPS,      "PR_SET_KEEP_CAPS"      },
163 #endif
164         { 0,                    NULL                    },
165 };
166
167
168 const char *
169 unalignctl_string (unsigned int ctl)
170 {
171         static char buf[16];
172
173         switch (ctl) {
174 #ifdef PR_UNALIGN_NOPRINT
175               case PR_UNALIGN_NOPRINT:
176                 return "NOPRINT";
177 #endif
178 #ifdef PR_UNALIGN_SIGBUS
179               case PR_UNALIGN_SIGBUS:
180                 return "SIGBUS";
181 #endif
182               default:
183                 break;
184         }
185         sprintf(buf, "%x", ctl);
186         return buf;
187 }
188
189
190 int
191 sys_prctl(tcp)
192 struct tcb *tcp;
193 {
194         int i;
195
196         if (entering(tcp)) {
197                 printxval(prctl_options, tcp->u_arg[0], "PR_???");
198                 switch (tcp->u_arg[0]) {
199 #ifdef PR_GETNSHARE
200                 case PR_GETNSHARE:
201                         break;
202 #endif
203 #ifdef PR_SET_DEATHSIG
204                 case PR_GET_PDEATHSIG:
205                         break;
206 #endif
207 #ifdef PR_SET_UNALIGN
208                 case PR_SET_UNALIGN:
209                         tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
210                         break;
211 #endif
212 #ifdef PR_GET_UNALIGN
213                 case PR_GET_UNALIGN:
214                         tprintf(", %#lx", tcp->u_arg[1]);
215                         break;
216 #endif
217                 default:
218                         for (i = 1; i < tcp->u_nargs; i++)
219                                 tprintf(", %#lx", tcp->u_arg[i]);
220                         break;
221                 }
222         } else {
223                 switch (tcp->u_arg[0]) {
224 #ifdef PR_GET_PDEATHSIG
225                 case PR_GET_PDEATHSIG:
226                         for (i=1; i<tcp->u_nargs; i++)
227                                 tprintf(", %#lx", tcp->u_arg[i]);
228                         break;
229 #endif
230 #ifdef PR_SET_UNALIGN
231                 case PR_SET_UNALIGN:
232                         break;
233 #endif
234 #ifdef PR_GET_UNALIGN
235                 case PR_GET_UNALIGN:
236                 {
237                         int ctl;
238
239                         umove(tcp, tcp->u_arg[1], &ctl);
240                         tcp->auxstr = unalignctl_string(ctl);
241                         return RVAL_STR;
242                 }
243 #endif
244                 default:
245                         break;
246                 }
247         }
248         return 0;
249 }
250
251 #endif /* HAVE_PRCTL */
252
253 int
254 sys_gethostid(tcp)
255 struct tcb *tcp;
256 {
257         if (exiting(tcp))
258                 return RVAL_HEX;
259         return 0;
260 }
261
262 int
263 sys_sethostname(tcp)
264 struct tcb *tcp;
265 {
266         if (entering(tcp)) {
267                 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
268                 tprintf(", %lu", tcp->u_arg[1]);
269         }
270         return 0;
271 }
272
273 int
274 sys_gethostname(tcp)
275 struct tcb *tcp;
276 {
277         if (exiting(tcp)) {
278                 if (syserror(tcp))
279                         tprintf("%#lx", tcp->u_arg[0]);
280                 else
281                         printpath(tcp, tcp->u_arg[0]);
282                 tprintf(", %lu", tcp->u_arg[1]);
283         }
284         return 0;
285 }
286
287 int
288 sys_setdomainname(tcp)
289 struct tcb *tcp;
290 {
291         if (entering(tcp)) {
292                 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
293                 tprintf(", %lu", tcp->u_arg[1]);
294         }
295         return 0;
296 }
297
298 #if !defined(LINUX)
299
300 int
301 sys_getdomainname(tcp)
302 struct tcb *tcp;
303 {
304         if (exiting(tcp)) {
305                 if (syserror(tcp))
306                         tprintf("%#lx", tcp->u_arg[0]);
307                 else
308                         printpath(tcp, tcp->u_arg[0]);
309                 tprintf(", %lu", tcp->u_arg[1]);
310         }
311         return 0;
312 }
313 #endif /* !LINUX */
314
315 int
316 sys_exit(tcp)
317 struct tcb *tcp;
318 {
319         if (exiting(tcp)) {
320                 fprintf(stderr, "_exit returned!\n");
321                 return -1;
322         }
323         /* special case: we stop tracing this process, finish line now */
324         tprintf("%ld) ", tcp->u_arg[0]);
325         tabto(acolumn);
326         tprintf("= ?");
327         printtrailer(tcp);
328         return 0;
329 }
330
331 int
332 internal_exit(tcp)
333 struct tcb *tcp;
334 {
335         if (entering(tcp))
336                 tcp->flags |= TCB_EXITING;
337         return 0;
338 }
339
340 #ifdef USE_PROCFS
341
342 int
343 sys_fork(tcp)
344 struct tcb *tcp;
345 {
346         if (exiting(tcp)) {
347                 if (getrval2(tcp)) {
348                         tcp->auxstr = "child process";
349                         return RVAL_UDECIMAL | RVAL_STR;
350                 }
351         }
352         return 0;
353 }
354
355 int
356 internal_fork(tcp)
357 struct tcb *tcp;
358 {
359         struct tcb *tcpchild;
360
361         if (exiting(tcp)) {
362                 if (getrval2(tcp))
363                         return 0;
364                 if (!followfork)
365                         return 0;
366                 if (nprocs == MAX_PROCS) {
367                         tcp->flags &= ~TCB_FOLLOWFORK;
368                         fprintf(stderr, "sys_fork: tcb table full\n");
369                         return 0;
370                 }
371                 else
372                         tcp->flags |= TCB_FOLLOWFORK;
373                 if (syserror(tcp))
374                         return 0;
375                 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
376                         fprintf(stderr, "sys_fork: tcb table full\n");
377                         return 0;
378                 }
379                 if (proc_open(tcpchild, 2) < 0)
380                         droptcb(tcpchild);
381         }
382         return 0;
383 }
384
385 #else /* !USE_PROCFS */
386
387 #ifdef LINUX
388
389 /* defines copied from linux/sched.h since we can't include that
390  * ourselves (it conflicts with *lots* of libc includes)
391  */
392 #define CSIGNAL         0x000000ff      /* signal mask to be sent at exit */
393 #define CLONE_VM        0x00000100      /* set if VM shared between processes */
394 #define CLONE_FS        0x00000200      /* set if fs info shared between processes */
395 #define CLONE_FILES     0x00000400      /* set if open files shared between processes */
396 #define CLONE_SIGHAND   0x00000800      /* set if signal handlers shared */
397 #define CLONE_PID       0x00001000      /* set if pid shared */
398 #define CLONE_PTRACE    0x00002000      /* set if we want to let tracing continue on the child too */
399 #define CLONE_VFORK     0x00004000      /* set if the parent wants the child to wake it up on mm_release */
400 #define CLONE_PARENT    0x00008000      /* set if we want to have the same parent as the cloner */
401
402 static struct xlat clone_flags[] = {
403     { CLONE_VM,         "CLONE_VM"      },
404     { CLONE_FS,         "CLONE_FS"      },
405     { CLONE_FILES,      "CLONE_FILES"   },
406     { CLONE_SIGHAND,    "CLONE_SIGHAND" },
407     { CLONE_PID,        "CLONE_PID"     },
408     { CLONE_PTRACE,     "CLONE_PTRACE"  },
409     { CLONE_VFORK,      "CLONE_VFORK"   },
410     { CLONE_PARENT,     "CLONE_PARENT"  },
411     { 0,                NULL            },
412 };
413
414 int
415 sys_clone(tcp)
416 struct tcb *tcp;
417 {
418         if (exiting(tcp)) {
419                 tprintf("child_stack=%#lx, flags=", tcp->u_arg[1]);
420                 if (printflags(clone_flags, tcp->u_arg[0]) == 0)
421                         tprintf("0");
422         }
423         return 0;
424 }
425
426 #endif
427
428 int
429 sys_fork(tcp)
430 struct tcb *tcp;
431 {
432         if (exiting(tcp))
433                 return RVAL_UDECIMAL;
434         return 0;
435 }
436
437 int
438 change_syscall(tcp, new)
439 struct tcb *tcp;
440 int new;
441 {
442 #if defined(LINUX)
443 #if defined(I386)
444         /* Attempt to make vfork into fork, which we can follow. */
445         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0) 
446                 return -1;
447         return 0;
448 #elif defined(POWERPC)
449         if (ptrace(PTRACE_POKEUSER, tcp->pid, (CHAR*)(4*PT_R0), new) < 0)
450                 return -1;
451 #elif defined(S390)
452         long    pc;
453         if (upeek(tcp->pid, PT_PSWADDR,&pc)<0)
454                 return -1;
455         if (ptrace(PTRACE_POKETEXT, tcp->pid, (char*)(pc-4), new)<0)
456                 return -1;
457         return 0;
458 #elif defined(M68K)
459         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
460                 return -1;
461         return 0;
462 #elif defined(SPARC)
463         struct pt_regs regs;
464         if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
465                 return -1;
466         reg.r_g1=new;
467         if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
468                 return -1;
469         return 0;
470 #elif defined(MIPS)
471         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
472                 return -1;
473         return 0;
474 #elif defined(ALPHA)
475         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
476                 return -1;
477         return 0;
478 #else
479 #warning Do not know how to handle change_syscall for this architecture
480 #endif /* architecture */
481 #endif /* LINUX */
482         return -1;
483 }
484
485 int
486 setarg(tcp, argnum)
487         struct tcb *tcp;
488         int argnum;
489 {
490 #if defined (IA64)
491         {
492                 unsigned long *bsp, *ap;
493
494                 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
495                         return -1;
496
497                 ap = ia64_rse_skip_regs(bsp, argnum);
498                 errno = 0;
499                 ptrace(PTRACE_POKEDATA, tcp->pid, ap, tcp->u_arg[argnum]);
500                 if (errno)
501                         return -1;
502
503         }
504 #elif defined(I386)
505         {
506                 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
507                 if (errno)
508                         return -1;
509         }
510 #elif defined(MIPS)
511         {
512                 errno = 0;
513                 if (argnum < 4)
514                         ptrace(PTRACE_POKEUSER, tcp->pid,
515                                (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
516                 else {
517                         unsigned long *sp;
518
519                         if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
520                                 return -1;
521
522                         ptrace(PTRACE_POKEDATA, tcp->pid,
523                                (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
524                 }
525                 if (errno)
526                         return -1;
527         }
528 #else
529 # warning Sorry, setargs not implemented for this architecture.
530 #endif
531         return 0;
532 }
533
534 #ifdef SYS_clone
535 int
536 internal_clone(tcp)
537 struct tcb *tcp;
538 {
539         struct tcb *tcpchild;
540         int pid;
541         if (entering(tcp)) {
542                 if (!followfork)
543                         return 0;
544                 if (nprocs == MAX_PROCS) {
545                         tcp->flags &= ~TCB_FOLLOWFORK;
546                         fprintf(stderr, "sys_fork: tcb table full\n");
547                         return 0;
548                 }
549                 tcp->flags |= TCB_FOLLOWFORK;
550
551
552                 if (setbpt(tcp) < 0)
553                         return 0;
554         } else {
555                 int bpt = tcp->flags & TCB_BPTSET;
556
557                 if (!(tcp->flags & TCB_FOLLOWFORK))
558                         return 0;
559
560                 if (bpt)
561                         clearbpt(tcp);
562
563                 if (syserror(tcp))
564                         return 0;
565
566                 pid = tcp->u_rval;
567                 if ((tcpchild = alloctcb(pid)) == NULL) {
568                         fprintf(stderr, " [tcb table full]\n");
569                         kill(pid, SIGKILL); /* XXX */
570                         return 0;
571                 }
572
573                 /* Attach to the new child */
574                 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
575                         perror("PTRACE_ATTACH");
576                         fprintf(stderr, "Too late?\n");
577                         droptcb(tcpchild);
578                         return 0;
579                 }
580
581                 tcpchild->flags |= TCB_ATTACHED;
582                 if (bpt) {
583                         tcpchild->flags |= TCB_BPTSET;
584                         tcpchild->baddr = tcp->baddr;
585                         memcpy(tcpchild->inst, tcp->inst,
586                                 sizeof tcpchild->inst);
587                 }
588                 newoutf(tcpchild);
589                 tcp->nchildren++;
590                 if (!qflag)
591                         fprintf(stderr, "Process %d attached\n", pid);
592         }
593         return 0;
594 }
595 #endif
596
597 int
598 internal_fork(tcp)
599 struct tcb *tcp;
600 {
601         struct tcb *tcpchild;
602         int pid;
603         int dont_follow = 0;
604
605 #ifdef SYS_vfork
606         if (tcp->scno == SYS_vfork) {
607                 /* Attempt to make vfork into fork, which we can follow. */
608                 if (!followvfork || 
609                     change_syscall(tcp, SYS_fork) < 0)
610                         dont_follow = 1;
611         }
612 #endif
613         if (entering(tcp)) {
614                 if (!followfork || dont_follow)
615                         return 0;
616                 if (nprocs == MAX_PROCS) {
617                         tcp->flags &= ~TCB_FOLLOWFORK;
618                         fprintf(stderr, "sys_fork: tcb table full\n");
619                         return 0;
620                 }
621                 tcp->flags |= TCB_FOLLOWFORK;
622                 if (setbpt(tcp) < 0)
623                         return 0;
624         }
625         else {
626                 int bpt = tcp->flags & TCB_BPTSET;
627
628                 if (!(tcp->flags & TCB_FOLLOWFORK))
629                         return 0;
630                 if (bpt)
631                         clearbpt(tcp);
632
633                 if (syserror(tcp))
634                         return 0;
635
636                 pid = tcp->u_rval;
637                 if ((tcpchild = alloctcb(pid)) == NULL) {
638                         fprintf(stderr, " [tcb table full]\n");
639                         kill(pid, SIGKILL); /* XXX */
640                         return 0;
641                 }
642 #ifdef LINUX
643                 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
644                         perror("PTRACE_ATTACH");
645                         fprintf(stderr, "Too late?\n");
646                         droptcb(tcpchild);
647                         return 0;
648                 }
649 #endif /* LINUX */
650 #ifdef SUNOS4
651 #ifdef oldway
652                 /* The child must have run before it can be attached. */
653                 {
654                         struct timeval tv;
655                         tv.tv_sec = 0;
656                         tv.tv_usec = 10000;
657                         select(0, NULL, NULL, NULL, &tv);
658                 }
659                 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
660                         perror("PTRACE_ATTACH");
661                         fprintf(stderr, "Too late?\n");
662                         droptcb(tcpchild);
663                         return 0;
664                 }
665 #else /* !oldway */
666                 /* Try to catch the new process as soon as possible. */
667                 {
668                         int i;
669                         for (i = 0; i < 1024; i++)
670                                 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
671                                         break;
672                         if (i == 1024) {
673                                 perror("PTRACE_ATTACH");
674                                 fprintf(stderr, "Too late?\n");
675                                 droptcb(tcpchild);
676                                 return 0;
677                         }
678                 }
679 #endif /* !oldway */
680 #endif /* SUNOS4 */
681                 tcpchild->flags |= TCB_ATTACHED;
682                 /* Child has BPT too, must be removed on first occasion */
683                 if (bpt) {
684                         tcpchild->flags |= TCB_BPTSET;
685                         tcpchild->baddr = tcp->baddr;
686                         memcpy(tcpchild->inst, tcp->inst,
687                                 sizeof tcpchild->inst);
688                 }
689                 newoutf(tcpchild);
690                 tcpchild->parent = tcp;
691                 tcp->nchildren++;
692                 if (!qflag)
693                         fprintf(stderr, "Process %d attached\n", pid);
694         }
695         return 0;
696 }
697
698 #endif /* !USE_PROCFS */
699
700 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
701
702 int
703 sys_vfork(tcp)
704 struct tcb *tcp;
705 {
706         if (exiting(tcp))
707                 return RVAL_UDECIMAL;
708         return 0;
709 }
710
711 #endif /* SUNOS4 || LINUX || FREEBSD */
712
713 #ifndef LINUX
714
715 static char idstr[16];
716
717 int
718 sys_getpid(tcp)
719 struct tcb *tcp;
720 {
721         if (exiting(tcp)) {
722                 sprintf(idstr, "ppid %lu", getrval2(tcp));
723                 tcp->auxstr = idstr;
724                 return RVAL_STR;
725         }
726         return 0;
727 }
728
729 int
730 sys_getuid(tcp)
731 struct tcb *tcp;
732 {
733         if (exiting(tcp)) {
734                 sprintf(idstr, "euid %lu", getrval2(tcp));
735                 tcp->auxstr = idstr;
736                 return RVAL_STR;
737         }
738         return 0;
739 }
740
741 int
742 sys_getgid(tcp)
743 struct tcb *tcp;
744 {
745         if (exiting(tcp)) {
746                 sprintf(idstr, "egid %lu", getrval2(tcp));
747                 tcp->auxstr = idstr;
748                 return RVAL_STR;
749         }
750         return 0;
751 }
752
753 #endif /* !LINUX */
754
755 #ifdef LINUX
756
757 int
758 sys_setuid(tcp)
759 struct tcb *tcp;
760 {
761         if (entering(tcp)) {
762                 tprintf("%u", (uid_t) tcp->u_arg[0]);
763         }
764         return 0;
765 }
766
767 int
768 sys_setgid(tcp)
769 struct tcb *tcp;
770 {
771         if (entering(tcp)) {
772                 tprintf("%u", (gid_t) tcp->u_arg[0]);
773         }
774         return 0;
775 }
776
777 int
778 sys_getresuid(tcp)
779     struct tcb *tcp;
780 {
781         if (exiting(tcp)) {
782                 __kernel_uid_t uid;
783                 if (syserror(tcp))
784                         tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
785                                 tcp->u_arg[1], tcp->u_arg[2]);
786                 else {
787                         if (umove(tcp, tcp->u_arg[0], &uid) < 0)
788                                 tprintf("%#lx, ", tcp->u_arg[0]);
789                         else
790                                 tprintf("ruid %lu, ", (unsigned long) uid);
791                         if (umove(tcp, tcp->u_arg[0], &uid) < 0)
792                                 tprintf("%#lx, ", tcp->u_arg[0]);
793                         else
794                                 tprintf("euid %lu, ", (unsigned long) uid);
795                         if (umove(tcp, tcp->u_arg[0], &uid) < 0)
796                                 tprintf("%#lx", tcp->u_arg[0]);
797                         else
798                                 tprintf("suid %lu", (unsigned long) uid);
799                 }
800         }
801         return 0;
802 }
803
804 int
805 sys_getresgid(tcp)
806 struct tcb *tcp;
807 {
808         if (exiting(tcp)) {
809                 __kernel_gid_t gid;
810                 if (syserror(tcp))
811                         tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
812                                 tcp->u_arg[1], tcp->u_arg[2]);
813                 else {
814                         if (umove(tcp, tcp->u_arg[0], &gid) < 0)
815                                 tprintf("%#lx, ", tcp->u_arg[0]);
816                         else
817                                 tprintf("rgid %lu, ", (unsigned long) gid);
818                         if (umove(tcp, tcp->u_arg[0], &gid) < 0)
819                                 tprintf("%#lx, ", tcp->u_arg[0]);
820                         else
821                                 tprintf("egid %lu, ", (unsigned long) gid);
822                         if (umove(tcp, tcp->u_arg[0], &gid) < 0)
823                                 tprintf("%#lx", tcp->u_arg[0]);
824                         else
825                                 tprintf("sgid %lu", (unsigned long) gid);
826                 }
827         }
828         return 0;
829 }
830
831 #endif /* LINUX */
832
833 int
834 sys_setreuid(tcp)
835 struct tcb *tcp;
836 {
837         if (entering(tcp)) {
838                 tprintf("%lu, %lu",
839                         (unsigned long) (uid_t) tcp->u_arg[0],
840                         (unsigned long) (uid_t) tcp->u_arg[1]);
841         }
842         return 0;
843 }
844
845 int
846 sys_setregid(tcp)
847 struct tcb *tcp;
848 {
849         if (entering(tcp)) {
850                 tprintf("%lu, %lu",
851                         (unsigned long) (gid_t) tcp->u_arg[0],
852                         (unsigned long) (gid_t) tcp->u_arg[1]);
853         }
854         return 0;
855 }
856
857 #if defined(LINUX) || defined(FREEBSD)
858 int
859 sys_setresuid(tcp)
860      struct tcb *tcp;
861 {
862         if (entering(tcp)) {
863                 tprintf("ruid %u, euid %u, suid %u",
864                                 (uid_t) tcp->u_arg[0],
865                                 (uid_t) tcp->u_arg[1],
866                                 (uid_t) tcp->u_arg[2]);
867         }
868         return 0;
869 }
870 int
871 sys_setresgid(tcp)
872      struct tcb *tcp;
873 {
874         if (entering(tcp)) {
875                 tprintf("rgid %u, egid %u, sgid %u",
876                                 (uid_t) tcp->u_arg[0],
877                                 (uid_t) tcp->u_arg[1],
878                                 (uid_t) tcp->u_arg[2]);
879         }
880         return 0;
881 }
882
883 #endif /* LINUX || FREEBSD */
884
885 int
886 sys_setgroups(tcp)
887 struct tcb *tcp;
888 {
889         int i, len;
890         GETGROUPS_T *gidset;
891
892         if (entering(tcp)) {
893                 len = tcp->u_arg[0];
894                 tprintf("%u, ", len);
895                 if (len <= 0) {
896                         tprintf("[]");
897                         return 0;
898                 }
899                 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
900                 if (gidset == NULL) {
901                         fprintf(stderr, "sys_setgroups: out of memory\n");
902                         return -1;
903                 }
904                 if (!verbose(tcp))
905                         tprintf("%#lx", tcp->u_arg[1]);
906                 else if (umoven(tcp, tcp->u_arg[1],
907                     len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
908                         tprintf("[?]");
909                 else {
910                         tprintf("[");
911                         for (i = 0; i < len; i++)
912                                 tprintf("%s%lu", i ? ", " : "",
913                                         (unsigned long) gidset[i]);
914                         tprintf("]");
915                 }
916                 free((char *) gidset);
917         }
918         return 0;
919 }
920
921 int
922 sys_getgroups(tcp)
923 struct tcb *tcp;
924 {
925         int i, len;
926         GETGROUPS_T *gidset;
927
928         if (entering(tcp)) {
929                 len = tcp->u_arg[0];
930                 tprintf("%u, ", len);
931         } else {
932                 len = tcp->u_rval;
933                 if (len <= 0) {
934                         tprintf("[]");
935                         return 0;
936                 }
937                 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
938                 if (gidset == NULL) {
939                         fprintf(stderr, "sys_getgroups: out of memory\n");
940                         return -1;
941                 }
942                 if (!tcp->u_arg[1])
943                         tprintf("NULL");
944                 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
945                         tprintf("%#lx", tcp->u_arg[1]);
946                 else if (umoven(tcp, tcp->u_arg[1],
947                     len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
948                         tprintf("[?]");
949                 else {
950                         tprintf("[");
951                         for (i = 0; i < len; i++)
952                                 tprintf("%s%lu", i ? ", " : "",
953                                         (unsigned long) gidset[i]);
954                         tprintf("]");
955                 }
956                 free((char *)gidset);
957         }
958         return 0;
959 }
960
961 int
962 sys_setpgrp(tcp)
963 struct tcb *tcp;
964 {
965         if (entering(tcp)) {
966 #ifndef SVR4
967                 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
968 #endif /* !SVR4 */
969         }
970         return 0;
971 }
972
973 int
974 sys_getpgrp(tcp)
975 struct tcb *tcp;
976 {
977         if (entering(tcp)) {
978 #ifndef SVR4
979                 tprintf("%lu", tcp->u_arg[0]);
980 #endif /* !SVR4 */
981         }
982         return 0;
983 }
984
985 int
986 sys_getsid(tcp)
987 struct tcb *tcp;
988 {
989         if (entering(tcp)) {
990                 tprintf("%lu", tcp->u_arg[0]);
991         }
992         return 0;
993 }
994
995 int
996 sys_setsid(tcp)
997 struct tcb *tcp;
998 {
999         return 0;
1000 }
1001
1002 int
1003 sys_getpgid(tcp)
1004 struct tcb *tcp;
1005 {
1006         if (entering(tcp)) {
1007                 tprintf("%lu", tcp->u_arg[0]);
1008         }
1009         return 0;
1010 }
1011
1012 int
1013 sys_setpgid(tcp)
1014 struct tcb *tcp;
1015 {
1016         if (entering(tcp)) {
1017                 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1018         }
1019         return 0;
1020 }
1021
1022 void
1023 fake_execve(tcp, program, argv, envp)
1024 struct tcb *tcp;
1025 char *program;
1026 char *argv[];
1027 char *envp[];
1028 {
1029         int i;
1030
1031 #ifdef ARM
1032         if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1033                 return;
1034 #else
1035         if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1036                 return;
1037 #endif /* !ARM */
1038         printleader(tcp);
1039         tprintf("execve(");
1040         string_quote(program);
1041         tprintf(", [");
1042         for (i = 0; argv[i] != NULL; i++) {
1043                 if (i != 0)
1044                         tprintf(", ");
1045                 string_quote(argv[i]);
1046         }
1047         for (i = 0; envp[i] != NULL; i++)
1048                 ;
1049         tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1050         tabto(acolumn);
1051         tprintf("= 0");
1052         printtrailer(tcp);
1053 }
1054
1055 static void
1056 printargv(tcp, addr)
1057 struct tcb *tcp;
1058 long addr;
1059 {
1060         char *cp;
1061         char *sep;
1062         int max = max_strlen / 2;
1063
1064         for (sep = ""; --max >= 0; sep = ", ") {
1065                 if (!abbrev(tcp))
1066                         max++;
1067                 if (umove(tcp, addr, &cp) < 0) {
1068                         tprintf("%#lx", addr);
1069                         return;
1070                 }
1071                 if (cp == 0)
1072                         break;
1073                 tprintf(sep);
1074                 printstr(tcp, (long) cp, -1);
1075                 addr += sizeof(char *);
1076         }
1077         if (cp)
1078                 tprintf(", ...");
1079 }
1080
1081 static void
1082 printargc(fmt, tcp, addr)
1083 char *fmt;
1084 struct tcb *tcp;
1085 long addr;
1086 {
1087         int count;
1088         char *cp;
1089
1090         for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1091                 addr += sizeof(char *);
1092         }
1093         tprintf(fmt, count, count == 1 ? "" : "s");
1094 }
1095
1096 int
1097 sys_execv(tcp)
1098 struct tcb *tcp;
1099 {
1100         if (entering(tcp)) {
1101                 printpath(tcp, tcp->u_arg[0]);
1102                 if (!verbose(tcp))
1103                         tprintf(", %#lx", tcp->u_arg[1]);
1104 #if 0
1105                 else if (abbrev(tcp))
1106                         printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1107 #endif
1108                 else {
1109                         tprintf(", [");
1110                         printargv(tcp, tcp->u_arg[1]);
1111                         tprintf("]");
1112                 }
1113         }
1114         return 0;
1115 }
1116
1117 int
1118 sys_execve(tcp)
1119 struct tcb *tcp;
1120 {
1121         if (entering(tcp)) {
1122                 printpath(tcp, tcp->u_arg[0]);
1123                 if (!verbose(tcp))
1124                         tprintf(", %#lx", tcp->u_arg[1]);
1125 #if 0
1126                 else if (abbrev(tcp))
1127                         printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1128 #endif
1129                 else {
1130                         tprintf(", [");
1131                         printargv(tcp, tcp->u_arg[1]);
1132                         tprintf("]");
1133                 }
1134                 if (!verbose(tcp))
1135                         tprintf(", %#lx", tcp->u_arg[2]);
1136                 else if (abbrev(tcp))
1137                         printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1138                 else {
1139                         tprintf(", [");
1140                         printargv(tcp, tcp->u_arg[2]);
1141                         tprintf("]");
1142                 }
1143         }
1144 #ifdef LINUX
1145 #if defined(ALPHA) || defined(SPARC) || defined(POWERPC)
1146         tcp->flags |= TCB_WAITEXECVE;
1147 #endif /* ALPHA || SPARC || POWERPC */
1148 #endif /* LINUX */
1149         return 0;
1150 }
1151
1152 int
1153 internal_exec(tcp)
1154 struct tcb *tcp;
1155 {
1156 #ifdef SUNOS4
1157         if (exiting(tcp) && !syserror(tcp) && followfork)
1158                 fixvfork(tcp);
1159 #endif /* SUNOS4 */
1160         return 0;
1161 }
1162
1163 #ifdef LINUX
1164 #ifndef __WCLONE
1165 #define __WCLONE        0x8000000
1166 #endif
1167 #endif /* LINUX */
1168
1169 static struct xlat wait4_options[] = {
1170         { WNOHANG,      "WNOHANG"       },
1171 #ifndef WSTOPPED
1172         { WUNTRACED,    "WUNTRACED"     },
1173 #endif
1174 #ifdef WEXITED
1175         { WEXITED,      "WEXITED"       },
1176 #endif
1177 #ifdef WTRAPPED
1178         { WTRAPPED,     "WTRAPPED"      },
1179 #endif
1180 #ifdef WSTOPPED
1181         { WSTOPPED,     "WSTOPPED"      },
1182 #endif
1183 #ifdef WCONTINUED
1184         { WCONTINUED,   "WCONTINUED"    },
1185 #endif
1186 #ifdef WNOWAIT
1187         { WNOWAIT,      "WNOWAIT"       },
1188 #endif
1189 #ifdef __WCLONE
1190         { __WCLONE,     "__WCLONE"      },
1191 #endif
1192         { 0,            NULL            },
1193 };
1194
1195 static int
1196 printstatus(status)
1197 int status;
1198 {
1199         int exited = 0;
1200
1201         /*
1202          * Here is a tricky presentation problem.  This solution
1203          * is still not entirely satisfactory but since there
1204          * are no wait status constructors it will have to do.
1205          */
1206         if (WIFSTOPPED(status))
1207                 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
1208                         signame(WSTOPSIG(status)));
1209         else if WIFSIGNALED(status)
1210                 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
1211                         signame(WTERMSIG(status)),
1212                         WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1213         else if WIFEXITED(status) {
1214                 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1215                         WEXITSTATUS(status));
1216                 exited = 1;
1217         }
1218         else
1219                 tprintf("[%#x]", status);
1220         return exited;
1221 }
1222
1223 static int
1224 printwaitn(tcp, n, bitness)
1225 struct tcb *tcp;
1226 int n;
1227 int bitness;
1228 {
1229         int status;
1230         int exited = 0;
1231
1232         if (entering(tcp)) {
1233                 tprintf("%ld, ", tcp->u_arg[0]);
1234         } else {
1235                 /* status */
1236                 if (!tcp->u_arg[1])
1237                         tprintf("NULL");
1238                 else if (syserror(tcp) || tcp->u_rval == 0)
1239                         tprintf("%#lx", tcp->u_arg[1]);
1240                 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1241                         tprintf("[?]");
1242                 else
1243                         exited = printstatus(status);
1244                 /* options */
1245                 tprintf(", ");
1246                 if (!printflags(wait4_options, tcp->u_arg[2]))
1247                         tprintf("0");
1248                 if (n == 4) {
1249                         tprintf(", ");
1250                         /* usage */
1251                         if (!tcp->u_arg[3])
1252                                 tprintf("NULL");
1253 #ifdef LINUX
1254                         else if (tcp->u_rval > 0) {
1255 #ifdef LINUX_64BIT
1256                                 if (bitness)
1257                                         printrusage32(tcp, tcp->u_arg[3]);
1258                                 else
1259 #endif
1260                                         printrusage(tcp, tcp->u_arg[3]);
1261                         }
1262 #endif /* LINUX */
1263 #ifdef SUNOS4
1264                         else if (tcp->u_rval > 0 && exited)
1265                                 printrusage(tcp, tcp->u_arg[3]);
1266 #endif /* SUNOS4 */
1267                         else
1268                                 tprintf("%#lx", tcp->u_arg[3]);
1269                 }
1270         }
1271         return 0;
1272 }
1273
1274 int
1275 internal_wait(tcp)
1276 struct tcb *tcp;
1277 {
1278         if (entering(tcp)) {
1279                 /* WTA: fix bug with hanging children */
1280                 if (!(tcp->u_arg[2] & WNOHANG) && tcp->nchildren > 0) {
1281                         /* There are traced children */
1282                         tcp->flags |= TCB_SUSPENDED;
1283                         tcp->waitpid = tcp->u_arg[0];
1284                 }
1285         }
1286         return 0;
1287 }
1288
1289 #ifdef SVR4
1290
1291 int
1292 sys_wait(tcp)
1293 struct tcb *tcp;
1294 {
1295         if (exiting(tcp)) {
1296                 /* The library wrapper stuffs this into the user variable. */
1297                 if (!syserror(tcp))
1298                         printstatus(getrval2(tcp));
1299         }
1300         return 0;
1301 }
1302
1303 #endif /* SVR4 */
1304
1305 #ifdef FREEBSD
1306 int
1307 sys_wait(tcp)
1308 struct tcb *tcp;
1309 {
1310         int status;
1311         
1312         if (exiting(tcp)) {
1313                 if (!syserror(tcp)) {
1314                         if (umove(tcp, tcp->u_arg[0], &status) < 0)
1315                                 tprintf("%#lx", tcp->u_arg[0]);
1316                         else
1317                                 printstatus(status);
1318                 }
1319         }
1320         return 0;
1321 }
1322 #endif
1323
1324 int
1325 sys_waitpid(tcp)
1326 struct tcb *tcp;
1327 {
1328         return printwaitn(tcp, 3, 0);
1329 }
1330
1331 int
1332 sys_wait4(tcp)
1333 struct tcb *tcp;
1334 {
1335         return printwaitn(tcp, 4, 0);
1336 }
1337
1338 #ifdef ALPHA
1339 int
1340 sys_osf_wait4(tcp)
1341 struct tcb *tcp;
1342 {
1343         return printwaitn(tcp, 4, 1);
1344 }
1345 #endif
1346
1347 #ifdef SVR4
1348
1349 static struct xlat waitid_types[] = {
1350         { P_PID,        "P_PID"         },
1351         { P_PPID,       "P_PPID"        },
1352         { P_PGID,       "P_PGID"        },
1353         { P_SID,        "P_SID"         },
1354         { P_CID,        "P_CID"         },
1355         { P_UID,        "P_UID"         },
1356         { P_GID,        "P_GID"         },
1357         { P_ALL,        "P_ALL"         },
1358 #ifdef P_LWPID
1359         { P_LWPID,      "P_LWPID"       },
1360 #endif
1361         { 0,            NULL            },
1362 };
1363
1364 static struct xlat siginfo_codes[] = {
1365 #ifdef SI_NOINFO
1366         { SI_NOINFO,    "SI_NOINFO"     },
1367 #endif
1368 #ifdef SI_USER
1369         { SI_USER,      "SI_USER"       },
1370 #endif
1371 #ifdef SI_LWP
1372         { SI_LWP,       "SI_LWP"        },
1373 #endif
1374 #ifdef SI_QUEUE
1375         { SI_QUEUE,     "SI_QUEUE"      },
1376 #endif
1377 #ifdef SI_TIMER
1378         { SI_TIMER,     "SI_TIMER"      },
1379 #endif
1380 #ifdef SI_ASYNCIO
1381         { SI_ASYNCIO,   "SI_ASYNCIO"    },
1382 #endif
1383 #ifdef SI_MESGQ
1384         { SI_MESGQ,     "SI_MESGQ"      },
1385 #endif
1386         { 0,            NULL            },
1387 };
1388
1389 static struct xlat sigtrap_codes[] = {
1390         { TRAP_BRKPT,   "TRAP_BRKPT"    },
1391         { TRAP_TRACE,   "TRAP_TRACE"    },
1392         { 0,            NULL            },
1393 };
1394
1395 static struct xlat sigcld_codes[] = {
1396         { CLD_EXITED,   "CLD_EXITED"    },
1397         { CLD_KILLED,   "CLD_KILLED"    },
1398         { CLD_DUMPED,   "CLD_DUMPED"    },
1399         { CLD_TRAPPED,  "CLD_TRAPPED"   },
1400         { CLD_STOPPED,  "CLD_STOPPED"   },
1401         { CLD_CONTINUED,"CLD_CONTINUED" },
1402         { 0,            NULL            },
1403 };
1404
1405 static struct xlat sigpoll_codes[] = {
1406         { POLL_IN,      "POLL_IN"       },
1407         { POLL_OUT,     "POLL_OUT"      },
1408         { POLL_MSG,     "POLL_MSG"      },
1409         { POLL_ERR,     "POLL_ERR"      },
1410         { POLL_PRI,     "POLL_PRI"      },
1411         { POLL_HUP,     "POLL_HUP"      },
1412         { 0,            NULL            },
1413 };
1414
1415 static struct xlat sigprof_codes[] = {
1416 #ifdef PROF_SIG
1417         { PROF_SIG,     "PROF_SIG"      },
1418 #endif
1419         { 0,            NULL            },
1420 };
1421
1422 static struct xlat sigill_codes[] = {
1423         { ILL_ILLOPC,   "ILL_ILLOPC"    },
1424         { ILL_ILLOPN,   "ILL_ILLOPN"    },
1425         { ILL_ILLADR,   "ILL_ILLADR"    },
1426         { ILL_ILLTRP,   "ILL_ILLTRP"    },
1427         { ILL_PRVOPC,   "ILL_PRVOPC"    },
1428         { ILL_PRVREG,   "ILL_PRVREG"    },
1429         { ILL_COPROC,   "ILL_COPROC"    },
1430         { ILL_BADSTK,   "ILL_BADSTK"    },
1431         { 0,            NULL            },
1432 };
1433
1434 static struct xlat sigemt_codes[] = {
1435 #ifdef EMT_TAGOVF
1436         { EMT_TAGOVF,   "EMT_TAGOVF"    },
1437 #endif
1438         { 0,            NULL            },
1439 };
1440
1441 static struct xlat sigfpe_codes[] = {
1442         { FPE_INTDIV,   "FPE_INTDIV"    },
1443         { FPE_INTOVF,   "FPE_INTOVF"    },
1444         { FPE_FLTDIV,   "FPE_FLTDIV"    },
1445         { FPE_FLTOVF,   "FPE_FLTOVF"    },
1446         { FPE_FLTUND,   "FPE_FLTUND"    },
1447         { FPE_FLTRES,   "FPE_FLTRES"    },
1448         { FPE_FLTINV,   "FPE_FLTINV"    },
1449         { FPE_FLTSUB,   "FPE_FLTSUB"    },
1450         { 0,            NULL            },
1451 };
1452
1453 static struct xlat sigsegv_codes[] = {
1454         { SEGV_MAPERR,  "SEGV_MAPERR"   },
1455         { SEGV_ACCERR,  "SEGV_ACCERR"   },
1456         { 0,            NULL            },
1457 };
1458
1459 static struct xlat sigbus_codes[] = {
1460         { BUS_ADRALN,   "BUS_ADRALN"    },
1461         { BUS_ADRERR,   "BUS_ADRERR"    },
1462         { BUS_OBJERR,   "BUS_OBJERR"    },
1463         { 0,            NULL            },
1464 };
1465
1466 void
1467 printsiginfo(sip)
1468 siginfo_t *sip;
1469 {
1470         char *code;
1471
1472         tprintf("{si_signo=");
1473         printsignal(sip->si_signo);
1474         code = xlookup(siginfo_codes, sip->si_code);
1475         if (!code) {
1476                 switch (sip->si_signo) {
1477                 case SIGTRAP:
1478                         code = xlookup(sigtrap_codes, sip->si_code);
1479                         break;
1480                 case SIGCHLD:
1481                         code = xlookup(sigcld_codes, sip->si_code);
1482                         break;
1483                 case SIGPOLL:
1484                         code = xlookup(sigpoll_codes, sip->si_code);
1485                         break;
1486                 case SIGPROF:
1487                         code = xlookup(sigprof_codes, sip->si_code);
1488                         break;
1489                 case SIGILL:
1490                         code = xlookup(sigill_codes, sip->si_code);
1491                         break;
1492                 case SIGEMT:
1493                         code = xlookup(sigemt_codes, sip->si_code);
1494                         break;
1495                 case SIGFPE:
1496                         code = xlookup(sigfpe_codes, sip->si_code);
1497                         break;
1498                 case SIGSEGV:
1499                         code = xlookup(sigsegv_codes, sip->si_code);
1500                         break;
1501                 case SIGBUS:
1502                         code = xlookup(sigbus_codes, sip->si_code);
1503                         break;
1504                 }
1505         }
1506         if (code)
1507                 tprintf(", si_code=%s", code);
1508         else
1509                 tprintf(", si_code=%#x", sip->si_code);
1510 #ifdef SI_NOINFO
1511         if (sip->si_code != SI_NOINFO) {
1512 #endif
1513                 if (sip->si_errno) {
1514                         if (sip->si_errno < 0 || sip->si_errno >= nerrnos)
1515                                 tprintf(", si_errno=%d", sip->si_errno);
1516                         else
1517                                 tprintf(", si_errno=%s",
1518                                         errnoent[sip->si_errno]);
1519                 }
1520                 if (SI_FROMUSER(sip)) {
1521 #ifdef SI_QUEUE
1522                         tprintf(", si_pid=%ld, si_uid=%ld",
1523                                 sip->si_pid, sip->si_uid);
1524                         switch (sip->si_code) {
1525                         case SI_QUEUE:
1526 #ifdef SI_TIMER
1527                         case SI_TIMER:
1528 #endif /* SI_QUEUE */
1529                         case SI_ASYNCIO:
1530 #ifdef SI_MESGQ
1531                         case SI_MESGQ:
1532 #endif /* SI_MESGQ */
1533                                 tprintf(", si_value=%d",
1534                                         sip->si_value.sival_int);
1535                                 break;
1536                         }
1537 #endif /* SI_QUEUE */
1538                 }
1539                 else {
1540                         switch (sip->si_signo) {
1541                         case SIGCHLD:
1542                                 tprintf(", si_pid=%ld, si_status=",
1543                                         sip->si_pid);
1544                                 if (sip->si_code == CLD_EXITED)
1545                                         tprintf("%d", sip->si_status);
1546                                 else
1547                                         printsignal(sip->si_status);
1548                                 break;
1549                         case SIGILL: case SIGFPE:
1550                         case SIGSEGV: case SIGBUS:
1551                                 tprintf(", si_addr=%#lx",
1552                                         (unsigned long) sip->si_addr);
1553                                 break;
1554                         case SIGPOLL:
1555                                 switch (sip->si_code) {
1556                                 case POLL_IN: case POLL_OUT: case POLL_MSG:
1557                                         tprintf(", si_band=%ld",
1558                                                 (long) sip->si_band);
1559                                         break;
1560                                 }
1561                                 break;
1562                         }
1563                 }
1564                 tprintf(", ...");
1565 #ifdef SI_NOINFO
1566         }
1567 #endif
1568         tprintf("}");
1569 }
1570
1571 int
1572 sys_waitid(tcp)
1573 struct tcb *tcp;
1574 {
1575         siginfo_t si;
1576         int exited;
1577
1578         if (entering(tcp)) {
1579                 printxval(waitid_types, tcp->u_arg[0], "P_???");
1580                 tprintf(", %ld, ", tcp->u_arg[1]);
1581                 if (tcp->nchildren > 0) {
1582                         /* There are traced children */
1583                         tcp->flags |= TCB_SUSPENDED;
1584                         tcp->waitpid = tcp->u_arg[0];
1585                 }
1586         }
1587         else {
1588                 /* siginfo */
1589                 exited = 0;
1590                 if (!tcp->u_arg[2])
1591                         tprintf("NULL");
1592                 else if (syserror(tcp))
1593                         tprintf("%#lx", tcp->u_arg[2]);
1594                 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1595                         tprintf("{???}");
1596                 else
1597                         printsiginfo(&si);
1598                 /* options */
1599                 tprintf(", ");
1600                 if (!printflags(wait4_options, tcp->u_arg[3]))
1601                         tprintf("0");
1602         }
1603         return 0;
1604 }
1605
1606 #endif /* SVR4 */
1607
1608 int
1609 sys_alarm(tcp)
1610 struct tcb *tcp;
1611 {
1612         if (entering(tcp))
1613                 tprintf("%lu", tcp->u_arg[0]);
1614         return 0;
1615 }
1616
1617 int
1618 sys_uname(tcp)
1619 struct tcb *tcp;
1620 {
1621         struct utsname uname;
1622
1623         if (exiting(tcp)) {
1624                 if (syserror(tcp) || !verbose(tcp))
1625                         tprintf("%#lx", tcp->u_arg[0]);
1626                 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1627                         tprintf("{...}");
1628                 else if (!abbrev(tcp)) {
1629
1630                         tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1631                                 uname.sysname, uname.nodename);
1632                         tprintf("release=\"%s\", version=\"%s\", ",
1633                                 uname.release, uname.version);
1634                         tprintf("machine=\"%s\"", uname.machine);
1635 #ifdef LINUX
1636 #ifndef __GLIBC__
1637                         tprintf(", domainname=\"%s\"", uname.domainname);
1638 #endif /* __GLIBC__ */
1639 #endif /* LINUX */
1640                         tprintf("}");
1641                 }
1642                 else
1643                         tprintf("{sys=\"%s\", node=\"%s\", ...}",
1644                                 uname.sysname, uname.nodename);
1645         }
1646         return 0;
1647 }
1648
1649 #ifndef SVR4
1650
1651 static struct xlat ptrace_cmds[] = {
1652 #ifndef FREEBSD 
1653         { PTRACE_TRACEME,       "PTRACE_TRACEME"        },
1654         { PTRACE_PEEKTEXT,      "PTRACE_PEEKTEXT",      },
1655         { PTRACE_PEEKDATA,      "PTRACE_PEEKDATA",      },
1656         { PTRACE_PEEKUSER,      "PTRACE_PEEKUSER",      },
1657         { PTRACE_POKETEXT,      "PTRACE_POKETEXT",      },
1658         { PTRACE_POKEDATA,      "PTRACE_POKEDATA",      },
1659         { PTRACE_POKEUSER,      "PTRACE_POKEUSER",      },
1660         { PTRACE_CONT,          "PTRACE_CONT"           },
1661         { PTRACE_KILL,          "PTRACE_KILL"           },
1662         { PTRACE_SINGLESTEP,    "PTRACE_SINGLESTEP"     },
1663         { PTRACE_ATTACH,        "PTRACE_ATTACH"         },
1664         { PTRACE_DETACH,        "PTRACE_DETACH"         },
1665 #ifdef SUNOS4
1666         { PTRACE_GETREGS,       "PTRACE_GETREGS"        },
1667         { PTRACE_SETREGS,       "PTRACE_SETREGS"        },
1668         { PTRACE_GETFPREGS,     "PTRACE_GETFPREGS",     },
1669         { PTRACE_SETFPREGS,     "PTRACE_SETFPREGS",     },
1670         { PTRACE_READDATA,      "PTRACE_READDATA"       },
1671         { PTRACE_WRITEDATA,     "PTRACE_WRITEDATA"      },
1672         { PTRACE_READTEXT,      "PTRACE_READTEXT"       },
1673         { PTRACE_WRITETEXT,     "PTRACE_WRITETEXT"      },
1674         { PTRACE_GETFPAREGS,    "PTRACE_GETFPAREGS"     },
1675         { PTRACE_SETFPAREGS,    "PTRACE_SETFPAREGS"     },
1676 #ifdef SPARC
1677         { PTRACE_GETWINDOW,     "PTRACE_GETWINDOW"      },
1678         { PTRACE_SETWINDOW,     "PTRACE_SETWINDOW"      },
1679 #else /* !SPARC */
1680         { PTRACE_22,            "PTRACE_PTRACE_22"      },
1681         { PTRACE_23,            "PTRACE_PTRACE_23"      },
1682 #endif /* !SPARC */
1683 #endif /* SUNOS4 */
1684         { PTRACE_SYSCALL,       "PTRACE_SYSCALL"        },
1685 #ifdef SUNOS4
1686         { PTRACE_DUMPCORE,      "PTRACE_DUMPCORE"       },
1687 #ifdef I386
1688         { PTRACE_SETWRBKPT,     "PTRACE_SETWRBKPT"      },
1689         { PTRACE_SETACBKPT,     "PTRACE_SETACBKPT"      },
1690         { PTRACE_CLRDR7,        "PTRACE_CLRDR7"         },
1691 #else /* !I386 */
1692         { PTRACE_26,            "PTRACE_26"             },
1693         { PTRACE_27,            "PTRACE_27"             },
1694         { PTRACE_28,            "PTRACE_28"             },
1695 #endif /* !I386 */
1696         { PTRACE_GETUCODE,      "PTRACE_GETUCODE"       },
1697 #endif /* SUNOS4 */
1698 #else /* FREEBSD */
1699         { PT_TRACE_ME,          "PT_TRACE_ME"           },
1700         { PT_READ_I,            "PT_READ_I"             },
1701         { PT_READ_D,            "PT_READ_D"             },
1702         { PT_WRITE_I,           "PT_WRITE_I"            },
1703         { PT_WRITE_D,           "PT_WRITE_D"            },
1704         { PT_READ_U,            "PT_WRITE_U"            },
1705         { PT_CONTINUE,          "PT_CONTINUE"           },
1706         { PT_KILL,              "PT_KILL"               },
1707         { PT_STEP,              "PT_STEP"               },
1708         { PT_ATTACH,            "PT_ATTACH"             },
1709         { PT_DETACH,            "PT_DETACH"             },
1710         { PT_GETREGS,           "PT_GETREGS"            },
1711         { PT_SETREGS,           "PT_SETREGS"            },
1712         { PT_GETFPREGS,         "PT_GETFPREGS"          },
1713         { PT_SETFPREGS,         "PT_SETFPREGS"          },
1714         { PT_GETDBREGS,         "PT_GETDBREGS"          },
1715         { PT_SETDBREGS,         "PT_SETDBREGS"          },
1716 #endif /* FREEBSD */
1717         { 0,                    NULL                    },
1718 };
1719
1720 #ifndef FREEBSD
1721 #ifndef SUNOS4_KERNEL_ARCH_KLUDGE
1722 static
1723 #endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
1724 struct xlat struct_user_offsets[] = {
1725 #ifdef LINUX
1726 #ifdef S390
1727         { PT_PSWMASK,           "psw_mask"                              },
1728         { PT_PSWADDR,           "psw_addr"                              },
1729         { PT_GPR0,              "gpr0"                                  },
1730         { PT_GPR1,              "gpr1"                                  },
1731         { PT_GPR2,              "gpr2"                                  },
1732         { PT_GPR3,              "gpr3"                                  },
1733         { PT_GPR4,              "gpr4"                                  },
1734         { PT_GPR5,              "gpr5"                                  },
1735         { PT_GPR6,              "gpr6"                                  },
1736         { PT_GPR7,              "gpr7"                                  },
1737         { PT_GPR8,              "gpr8"                                  },
1738         { PT_GPR9,              "gpr9"                                  },
1739         { PT_GPR10,             "gpr10"                                 },
1740         { PT_GPR11,             "gpr11"                                 },
1741         { PT_GPR12,             "gpr12"                                 },
1742         { PT_GPR13,             "gpr13"                                 },
1743         { PT_GPR14,             "gpr14"                                 },
1744         { PT_GPR15,             "gpr15"                                 },
1745         { PT_ACR0,              "acr0"                                  },
1746         { PT_ACR1,              "acr1"                                  },
1747         { PT_ACR2,              "acr2"                                  },
1748         { PT_ACR3,              "acr3"                                  },
1749         { PT_ACR4,              "acr4"                                  },
1750         { PT_ACR5,              "acr5"                                  },
1751         { PT_ACR6,              "acr6"                                  },
1752         { PT_ACR7,              "acr7"                                  },
1753         { PT_ACR8,              "acr8"                                  },
1754         { PT_ACR9,              "acr9"                                  },
1755         { PT_ACR10,             "acr10"                                 },
1756         { PT_ACR11,             "acr11"                                 },
1757         { PT_ACR12,             "acr12"                                 },
1758         { PT_ACR13,             "acr13"                                 },
1759         { PT_ACR14,             "acr14"                                 },
1760         { PT_ACR15,             "acr15"                                 },
1761         { PT_ORIGGPR2,          "orig_gpr2"                             },
1762         { PT_FPC,               "fpc"                                   },
1763         { PT_FPR0_HI,           "fpr0.hi"                               },
1764         { PT_FPR0_LO,           "fpr0.lo"                               },
1765         { PT_FPR1_HI,           "fpr1.hi"                               },
1766         { PT_FPR1_LO,           "fpr1.lo"                               },
1767         { PT_FPR2_HI,           "fpr2.hi"                               },
1768         { PT_FPR2_LO,           "fpr2.lo"                               },
1769         { PT_FPR3_HI,           "fpr3.hi"                               },
1770         { PT_FPR3_LO,           "fpr3.lo"                               },
1771         { PT_FPR4_HI,           "fpr4.hi"                               },
1772         { PT_FPR4_LO,           "fpr4.lo"                               },
1773         { PT_FPR5_HI,           "fpr5.hi"                               },
1774         { PT_FPR5_LO,           "fpr5.lo"                               },
1775         { PT_FPR6_HI,           "fpr6.hi"                               },
1776         { PT_FPR6_LO,           "fpr6.lo"                               },
1777         { PT_FPR7_HI,           "fpr7.hi"                               },
1778         { PT_FPR7_LO,           "fpr7.lo"                               },
1779         { PT_FPR8_HI,           "fpr8.hi"                               },
1780         { PT_FPR8_LO,           "fpr8.lo"                               },
1781         { PT_FPR9_HI,           "fpr9.hi"                               },
1782         { PT_FPR9_LO,           "fpr9.lo"                               },
1783         { PT_FPR10_HI,          "fpr10.hi"                              },
1784         { PT_FPR10_LO,          "fpr10.lo"                              },
1785         { PT_FPR11_HI,          "fpr11.hi"                              },
1786         { PT_FPR11_LO,          "fpr11.lo"                              },
1787         { PT_FPR12_HI,          "fpr12.hi"                              },
1788         { PT_FPR12_LO,          "fpr12.lo"                              },
1789         { PT_FPR13_HI,          "fpr13.hi"                              },
1790         { PT_FPR13_LO,          "fpr13.lo"                              },
1791         { PT_FPR14_HI,          "fpr14.hi"                              },
1792         { PT_FPR14_LO,          "fpr14.lo"                              },
1793         { PT_FPR15_HI,          "fpr15.hi"                              },
1794         { PT_FPR15_LO,          "fpr15.lo"                              },
1795         { PT_CR_9,              "cr9"                                   },
1796         { PT_CR_10,             "cr10"                                  },
1797         { PT_CR_11,             "cr11"                                  },
1798 #endif
1799 #if defined(SPARC)
1800         /* XXX No support for these offsets yet. */
1801 #elif defined(POWERPC)
1802         { 4*PT_R0,              "4*PT_R0"                               },
1803         { 4*PT_R1,              "4*PT_R1"                               },
1804         { 4*PT_R2,              "4*PT_R2"                               },
1805         { 4*PT_R3,              "4*PT_R3"                               },
1806         { 4*PT_R4,              "4*PT_R4"                               },
1807         { 4*PT_R5,              "4*PT_R5"                               },
1808         { 4*PT_R6,              "4*PT_R6"                               },
1809         { 4*PT_R7,              "4*PT_R7"                               },
1810         { 4*PT_R8,              "4*PT_R8"                               },
1811         { 4*PT_R9,              "4*PT_R9"                               },
1812         { 4*PT_R10,             "4*PT_R10"                              },
1813         { 4*PT_R11,             "4*PT_R11"                              },
1814         { 4*PT_R12,             "4*PT_R12"                              },
1815         { 4*PT_R13,             "4*PT_R13"                              },
1816         { 4*PT_R14,             "4*PT_R14"                              },
1817         { 4*PT_R15,             "4*PT_R15"                              },
1818         { 4*PT_R16,             "4*PT_R16"                              },
1819         { 4*PT_R17,             "4*PT_R17"                              },
1820         { 4*PT_R18,             "4*PT_R18"                              },
1821         { 4*PT_R19,             "4*PT_R19"                              },
1822         { 4*PT_R20,             "4*PT_R20"                              },
1823         { 4*PT_R21,             "4*PT_R21"                              },
1824         { 4*PT_R22,             "4*PT_R22"                              },
1825         { 4*PT_R23,             "4*PT_R23"                              },
1826         { 4*PT_R24,             "4*PT_R24"                              },
1827         { 4*PT_R25,             "4*PT_R25"                              },
1828         { 4*PT_R26,             "4*PT_R26"                              },
1829         { 4*PT_R27,             "4*PT_R27"                              },
1830         { 4*PT_R28,             "4*PT_R28"                              },
1831         { 4*PT_R29,             "4*PT_R29"                              },
1832         { 4*PT_R30,             "4*PT_R30"                              },
1833         { 4*PT_R31,             "4*PT_R31"                              },
1834         { 4*PT_NIP,             "4*PT_NIP"                              },
1835         { 4*PT_MSR,             "4*PT_MSR"                              },
1836         { 4*PT_ORIG_R3,         "4*PT_ORIG_R3"                          },
1837         { 4*PT_CTR,             "4*PT_CTR"                              },
1838         { 4*PT_LNK,             "4*PT_LNK"                              },
1839         { 4*PT_XER,             "4*PT_XER"                              },
1840         { 4*PT_CCR,             "4*PT_CCR"                              },
1841         { 4*PT_FPR0,            "4*PT_FPR0"                             },
1842 #else   
1843 #ifdef ALPHA
1844         { 0,                    "r0"                                    },
1845         { 1,                    "r1"                                    },
1846         { 2,                    "r2"                                    },
1847         { 3,                    "r3"                                    },
1848         { 4,                    "r4"                                    },
1849         { 5,                    "r5"                                    },
1850         { 6,                    "r6"                                    },
1851         { 7,                    "r7"                                    },
1852         { 8,                    "r8"                                    },
1853         { 9,                    "r9"                                    },
1854         { 10,                   "r10"                                   },
1855         { 11,                   "r11"                                   },
1856         { 12,                   "r12"                                   },
1857         { 13,                   "r13"                                   },
1858         { 14,                   "r14"                                   },
1859         { 15,                   "r15"                                   },
1860         { 16,                   "r16"                                   },
1861         { 17,                   "r17"                                   },
1862         { 18,                   "r18"                                   },
1863         { 19,                   "r19"                                   },
1864         { 20,                   "r20"                                   },
1865         { 21,                   "r21"                                   },
1866         { 22,                   "r22"                                   },
1867         { 23,                   "r23"                                   },
1868         { 24,                   "r24"                                   },
1869         { 25,                   "r25"                                   },
1870         { 26,                   "r26"                                   },
1871         { 27,                   "r27"                                   },
1872         { 28,                   "r28"                                   },
1873         { 29,                   "gp"                                    },
1874         { 30,                   "fp"                                    },
1875         { 31,                   "zero"                                  },
1876         { 32,                   "fp0"                                   },
1877         { 33,                   "fp"                                    },
1878         { 34,                   "fp2"                                   },
1879         { 35,                   "fp3"                                   },
1880         { 36,                   "fp4"                                   },
1881         { 37,                   "fp5"                                   },
1882         { 38,                   "fp6"                                   },
1883         { 39,                   "fp7"                                   },
1884         { 40,                   "fp8"                                   },
1885         { 41,                   "fp9"                                   },
1886         { 42,                   "fp10"                                  },
1887         { 43,                   "fp11"                                  },
1888         { 44,                   "fp12"                                  },
1889         { 45,                   "fp13"                                  },
1890         { 46,                   "fp14"                                  },
1891         { 47,                   "fp15"                                  },
1892         { 48,                   "fp16"                                  },
1893         { 49,                   "fp17"                                  },
1894         { 50,                   "fp18"                                  },
1895         { 51,                   "fp19"                                  },
1896         { 52,                   "fp20"                                  },
1897         { 53,                   "fp21"                                  },
1898         { 54,                   "fp22"                                  },
1899         { 55,                   "fp23"                                  },
1900         { 56,                   "fp24"                                  },
1901         { 57,                   "fp25"                                  },
1902         { 58,                   "fp26"                                  },
1903         { 59,                   "fp27"                                  },
1904         { 60,                   "fp28"                                  },
1905         { 61,                   "fp29"                                  },
1906         { 62,                   "fp30"                                  },
1907         { 63,                   "fp31"                                  },
1908         { 64,                   "pc"                                    },
1909 #else /* !ALPHA */
1910 #ifdef IA64
1911         { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
1912         { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
1913         { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
1914         { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
1915         { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
1916         { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
1917         { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
1918         { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
1919         { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
1920         { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
1921         { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
1922         { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
1923         { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
1924         { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
1925         { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
1926         { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
1927         { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
1928         { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
1929         { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
1930         { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
1931         { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
1932         { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
1933         { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
1934         { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
1935         { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
1936         { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
1937         { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
1938         { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
1939         { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
1940         { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
1941         { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
1942         { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
1943         /* switch stack: */
1944         { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
1945         { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
1946         { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
1947         { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
1948         { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
1949         { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
1950         { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
1951         { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
1952         { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
1953         { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
1954         { PT_K_B0, "kb0" },
1955         { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
1956         { PT_B4, "b4" }, { PT_B5, "b5" },
1957         { PT_K_AR_PFS, "kar.pfs" },
1958         { PT_AR_LC, "ar.lc" }, { PT_K_AR_UNAT, "kar.unat" },
1959         { PT_K_AR_RNAT, "kar.rnat" }, { PT_K_AR_BSPSTORE, "kar.bspstore" },
1960         { PT_K_PR, "k.pr" },
1961         /* pt_regs */
1962         { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
1963         { PT_CR_IFS, "cr.ifs" }, { PT_AR_UNAT, "ar.unat" },
1964         { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
1965         { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
1966         { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
1967         { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
1968         { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
1969         { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
1970         { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
1971         { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
1972         { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
1973         { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
1974         { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
1975         { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
1976         { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
1977         { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
1978         { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
1979 #else /* !IA64 */
1980 #ifdef I386
1981         { 4*EBX,                "4*EBX"                                 },
1982         { 4*ECX,                "4*ECX"                                 },
1983         { 4*EDX,                "4*EDX"                                 },
1984         { 4*ESI,                "4*ESI"                                 },
1985         { 4*EDI,                "4*EDI"                                 },
1986         { 4*EBP,                "4*EBP"                                 },
1987         { 4*EAX,                "4*EAX"                                 },
1988         { 4*DS,                 "4*DS"                                  },
1989         { 4*ES,                 "4*ES"                                  },
1990         { 4*FS,                 "4*FS"                                  },
1991         { 4*GS,                 "4*GS"                                  },
1992         { 4*ORIG_EAX,           "4*ORIG_EAX"                            },
1993         { 4*EIP,                "4*EIP"                                 },
1994         { 4*CS,                 "4*CS"                                  },
1995         { 4*EFL,                "4*EFL"                                 },
1996         { 4*UESP,               "4*UESP"                                },
1997         { 4*SS,                 "4*SS"                                  },
1998 #else /* !I386 */
1999 #ifdef M68K
2000         { 4*PT_D1,              "4*PT_D1"                               },
2001         { 4*PT_D2,              "4*PT_D2"                               },
2002         { 4*PT_D3,              "4*PT_D3"                               },
2003         { 4*PT_D4,              "4*PT_D4"                               },
2004         { 4*PT_D5,              "4*PT_D5"                               },
2005         { 4*PT_D6,              "4*PT_D6"                               },
2006         { 4*PT_D7,              "4*PT_D7"                               },
2007         { 4*PT_A0,              "4*PT_A0"                               },
2008         { 4*PT_A1,              "4*PT_A1"                               },
2009         { 4*PT_A2,              "4*PT_A2"                               },
2010         { 4*PT_A3,              "4*PT_A3"                               },
2011         { 4*PT_A4,              "4*PT_A4"                               },
2012         { 4*PT_A5,              "4*PT_A5"                               },
2013         { 4*PT_A6,              "4*PT_A6"                               },
2014         { 4*PT_D0,              "4*PT_D0"                               },
2015         { 4*PT_USP,             "4*PT_USP"                              },
2016         { 4*PT_ORIG_D0,         "4*PT_ORIG_D0"                          },
2017         { 4*PT_SR,              "4*PT_SR"                               },
2018         { 4*PT_PC,              "4*PT_PC"                               },
2019 #endif /* M68K */
2020 #endif /* !I386 */
2021 #if !defined(S390) && !defined(MIPS)
2022         { uoff(u_fpvalid),      "offsetof(struct user, u_fpvalid)"      },
2023 #endif
2024 #ifdef I386
2025         { uoff(i387),           "offsetof(struct user, i387)"           },
2026 #else /* !I386 */
2027 #ifdef M68K
2028         { uoff(m68kfp),         "offsetof(struct user, m68kfp)"         },
2029 #endif /* M68K */
2030 #endif /* !I386 */
2031         { uoff(u_tsize),        "offsetof(struct user, u_tsize)"        },
2032         { uoff(u_dsize),        "offsetof(struct user, u_dsize)"        },
2033         { uoff(u_ssize),        "offsetof(struct user, u_ssize)"        },
2034         { uoff(start_code),     "offsetof(struct user, start_code)"     },
2035         { uoff(start_stack),    "offsetof(struct user, start_stack)"    },
2036         { uoff(signal),         "offsetof(struct user, signal)"         },
2037 #if !defined(S390) && !defined(MIPS)
2038         { uoff(reserved),       "offsetof(struct user, reserved)"       },
2039 #endif
2040         { uoff(u_ar0),          "offsetof(struct user, u_ar0)"          },
2041 #if !defined(ARM) && !defined(MIPS) && !defined(S390)
2042         { uoff(u_fpstate),      "offsetof(struct user, u_fpstate)"      },
2043 #endif
2044         { uoff(magic),          "offsetof(struct user, magic)"          },
2045         { uoff(u_comm),         "offsetof(struct user, u_comm)"         },
2046 #ifdef I386
2047         { uoff(u_debugreg),     "offsetof(struct user, u_debugreg)"     },
2048 #endif /* I386 */
2049 #endif /* !IA64 */
2050 #endif /* !ALPHA */
2051 #endif /* !POWERPC/!SPARC */
2052 #endif /* LINUX */
2053 #ifdef SUNOS4
2054         { uoff(u_pcb),          "offsetof(struct user, u_pcb)"          },
2055         { uoff(u_procp),        "offsetof(struct user, u_procp)"        },
2056         { uoff(u_ar0),          "offsetof(struct user, u_ar0)"          },
2057         { uoff(u_comm[0]),      "offsetof(struct user, u_comm[0])"      },
2058         { uoff(u_arg[0]),       "offsetof(struct user, u_arg[0])"       },
2059         { uoff(u_ap),           "offsetof(struct user, u_ap)"           },
2060         { uoff(u_qsave),        "offsetof(struct user, u_qsave)"        },
2061         { uoff(u_rval1),        "offsetof(struct user, u_rval1)"        },
2062         { uoff(u_rval2),        "offsetof(struct user, u_rval2)"        },
2063         { uoff(u_error),        "offsetof(struct user, u_error)"        },
2064         { uoff(u_eosys),        "offsetof(struct user, u_eosys)"        },
2065         { uoff(u_ssave),        "offsetof(struct user, u_ssave)"        },
2066         { uoff(u_signal[0]),    "offsetof(struct user, u_signal)"       },
2067         { uoff(u_sigmask[0]),   "offsetof(struct user, u_sigmask)"      },
2068         { uoff(u_sigonstack),   "offsetof(struct user, u_sigonstack)"   },
2069         { uoff(u_sigintr),      "offsetof(struct user, u_sigintr)"      },
2070         { uoff(u_sigreset),     "offsetof(struct user, u_sigreset)"     },
2071         { uoff(u_oldmask),      "offsetof(struct user, u_oldmask)"      },
2072         { uoff(u_code),         "offsetof(struct user, u_code)"         },
2073         { uoff(u_addr),         "offsetof(struct user, u_addr)"         },
2074         { uoff(u_sigstack),     "offsetof(struct user, u_sigstack)"     },
2075         { uoff(u_ofile),        "offsetof(struct user, u_ofile)"        },
2076         { uoff(u_pofile),       "offsetof(struct user, u_pofile)"       },
2077         { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2078         { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2079         { uoff(u_lastfile),     "offsetof(struct user, u_lastfile)"     },
2080         { uoff(u_cwd),          "offsetof(struct user, u_cwd)"          },
2081         { uoff(u_cdir),         "offsetof(struct user, u_cdir)"         },
2082         { uoff(u_rdir),         "offsetof(struct user, u_rdir)"         },
2083         { uoff(u_cmask),        "offsetof(struct user, u_cmask)"        },
2084         { uoff(u_ru),           "offsetof(struct user, u_ru)"           },
2085         { uoff(u_cru),          "offsetof(struct user, u_cru)"          },
2086         { uoff(u_timer[0]),     "offsetof(struct user, u_timer[0])"     },
2087         { uoff(u_XXX[0]),       "offsetof(struct user, u_XXX[0])"       },
2088         { uoff(u_ioch),         "offsetof(struct user, u_ioch)"         },
2089         { uoff(u_start),        "offsetof(struct user, u_start)"        },
2090         { uoff(u_acflag),       "offsetof(struct user, u_acflag)"       },
2091         { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2092         { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2093         { uoff(u_prof.pr_off),  "offsetof(struct user, u_prof.pr_off)"  },
2094         { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2095         { uoff(u_rlimit[0]),    "offsetof(struct user, u_rlimit)"       },
2096         { uoff(u_exdata.Ux_A),  "offsetof(struct user, u_exdata.Ux_A)"  },
2097         { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2098         { uoff(u_lofault),      "offsetof(struct user, u_lofault)"      },
2099 #endif /* SUNOS4 */
2100         { sizeof(struct user),  "sizeof(struct user)"                   },
2101         { 0,                    NULL                                    },
2102 };
2103 #endif
2104
2105 int
2106 sys_ptrace(tcp)
2107 struct tcb *tcp;
2108 {
2109         char *cmd;
2110         struct xlat *x;
2111         long addr;
2112
2113         cmd = xlookup(ptrace_cmds, tcp->u_arg[0]);
2114         if (!cmd)
2115 #ifndef FREEBSD
2116                 cmd = "PTRACE_???";
2117 #else
2118                 cmd = "PT_???";
2119 #endif          
2120         if (entering(tcp)) {
2121                 tprintf("%s, %lu, ", cmd, tcp->u_arg[1]);
2122                 addr = tcp->u_arg[2];
2123 #ifndef FREEBSD
2124                 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2125                         || tcp->u_arg[0] == PTRACE_POKEUSER) {
2126                         for (x = struct_user_offsets; x->str; x++) {
2127                                 if (x->val >= addr)
2128                                         break;
2129                         }
2130                         if (!x->str)
2131                                 tprintf("%#lx, ", addr);
2132                         else if (x->val > addr && x != struct_user_offsets) {
2133                                 x--;
2134                                 tprintf("%s + %ld, ", x->str, addr - x->val);
2135                         }
2136                         else
2137                                 tprintf("%s, ", x->str);
2138                 }
2139                 else
2140 #endif
2141                         tprintf("%#lx, ", tcp->u_arg[2]);
2142 #ifdef LINUX
2143                 switch (tcp->u_arg[0]) {
2144                 case PTRACE_PEEKDATA:
2145                 case PTRACE_PEEKTEXT:
2146                 case PTRACE_PEEKUSER:
2147                         break;
2148                 case PTRACE_CONT:
2149                 case PTRACE_SINGLESTEP:
2150                 case PTRACE_SYSCALL:
2151                 case PTRACE_DETACH:
2152                         printsignal(tcp->u_arg[3]);
2153                         break;
2154                 default:
2155                         tprintf("%#lx", tcp->u_arg[3]);
2156                         break;
2157                 }
2158         } else {
2159                 switch (tcp->u_arg[0]) {
2160                 case PTRACE_PEEKDATA:
2161                 case PTRACE_PEEKTEXT:
2162                 case PTRACE_PEEKUSER:
2163                         printnum(tcp, tcp->u_arg[3], "%#x");
2164                         break;
2165                 }
2166         }
2167 #endif /* LINUX */
2168 #ifdef SUNOS4
2169                 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2170                         tcp->u_arg[0] == PTRACE_WRITETEXT) {
2171                         tprintf("%lu, ", tcp->u_arg[3]);
2172                         printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2173                 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2174                                 tcp->u_arg[0] != PTRACE_READTEXT) {
2175                         tprintf("%#lx", tcp->u_arg[3]);
2176                 }
2177         } else {
2178                 if (tcp->u_arg[0] == PTRACE_READDATA ||
2179                         tcp->u_arg[0] == PTRACE_READTEXT) {
2180                         tprintf("%lu, ", tcp->u_arg[3]);
2181                         printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2182                 }
2183         }
2184 #endif /* SUNOS4 */
2185 #ifdef FREEBSD
2186                 tprintf("%lu", tcp->u_arg[3]);
2187         }
2188 #endif /* FREEBSD */
2189         return 0;
2190 }
2191
2192 #endif /* !SVR4 */