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