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