blob: 965822ca0e5f3786e1fca8c93381f2c607db4575 [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
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>
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00005 * 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>
Wichert Akkermanccef6372002-05-01 16:39:22 +00009 * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH
10 * port by Greg Banks <gbanks@pocketpenguins.com>
11
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +000012 *
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000013 * All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * $Id$
38 */
39
40#include "defs.h"
41
42#include <fcntl.h>
43#include <sys/stat.h>
44#include <sys/time.h>
45#include <sys/wait.h>
46#include <sys/resource.h>
47#include <sys/utsname.h>
48#include <sys/user.h>
49#include <sys/syscall.h>
50#include <signal.h>
51#ifdef SUNOS4
52#include <machine/reg.h>
53#endif /* SUNOS4 */
54
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +000055#ifdef FREEBSD
56#include <sys/ptrace.h>
57#endif
58
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000059#if HAVE_ASM_REG_H
60#ifdef SPARC
61# define fpq kernel_fpq
62# define fq kernel_fq
63# define fpu kernel_fpu
64#endif
65#include <asm/reg.h>
66#ifdef SPARC
67# undef fpq
68# undef fq
Roland McGrath5a223472002-12-15 23:58:26 +000069# undef fpu
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000070#endif
71#endif /* HAVE_ASM_REG_H */
72
Wichert Akkerman36915a11999-07-13 15:45:02 +000073#ifdef HAVE_SYS_REG_H
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000074# include <sys/reg.h>
Wichert Akkerman15dea971999-10-06 13:06:34 +000075#ifndef PTRACE_PEEKUSR
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000076# define PTRACE_PEEKUSR PTRACE_PEEKUSER
Wichert Akkerman15dea971999-10-06 13:06:34 +000077#endif
78#ifndef PTRACE_POKEUSR
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000079# define PTRACE_POKEUSR PTRACE_POKEUSER
80#endif
Wichert Akkermanfaf72222000-02-19 23:59:03 +000081#elif defined(HAVE_LINUX_PTRACE_H)
82#undef PTRACE_SYSCALL
83#include <linux/ptrace.h>
Wichert Akkerman15dea971999-10-06 13:06:34 +000084#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000085
Roland McGrath5a223472002-12-15 23:58:26 +000086#ifdef HAVE_LINUX_FUTEX_H
87#include <linux/futex.h>
88#endif
89#if defined LINUX
90# ifndef FUTEX_WAIT
91# define FUTEX_WAIT 0
92# endif
93# ifndef FUTEX_WAKE
94# define FUTEX_WAKE 1
95# endif
96# ifndef FUTEX_FD
97# define FUTEX_FD 2
98# endif
99#endif
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000100
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000101#ifdef LINUX
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000102#include <asm/posix_types.h>
103#undef GETGROUPS_T
104#define GETGROUPS_T __kernel_gid_t
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000105#endif /* LINUX */
106
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000107#if defined(LINUX) && defined(IA64)
108# include <asm/ptrace_offsets.h>
109# include <asm/rse.h>
110#endif
111
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000112#ifdef HAVE_PRCTL
113#include <sys/prctl.h>
114#endif
115
116#ifndef WCOREDUMP
117#define WCOREDUMP(status) ((status) & 0200)
118#endif
119
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000120/* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000121#if defined(HAVE_PRCTL)
122static struct xlat prctl_options[] = {
123#ifdef PR_MAXPROCS
124 { PR_MAXPROCS, "PR_MAXPROCS" },
125#endif
126#ifdef PR_ISBLOCKED
127 { PR_ISBLOCKED, "PR_ISBLOCKED" },
128#endif
129#ifdef PR_SETSTACKSIZE
130 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
131#endif
132#ifdef PR_GETSTACKSIZE
133 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
134#endif
135#ifdef PR_MAXPPROCS
136 { PR_MAXPPROCS, "PR_MAXPPROCS" },
137#endif
138#ifdef PR_UNBLKONEXEC
139 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
140#endif
141#ifdef PR_ATOMICSIM
142 { PR_ATOMICSIM, "PR_ATOMICSIM" },
143#endif
144#ifdef PR_SETEXITSIG
145 { PR_SETEXITSIG, "PR_SETEXITSIG" },
146#endif
147#ifdef PR_RESIDENT
148 { PR_RESIDENT, "PR_RESIDENT" },
149#endif
150#ifdef PR_ATTACHADDR
151 { PR_ATTACHADDR, "PR_ATTACHADDR" },
152#endif
153#ifdef PR_DETACHADDR
154 { PR_DETACHADDR, "PR_DETACHADDR" },
155#endif
156#ifdef PR_TERMCHILD
157 { PR_TERMCHILD, "PR_TERMCHILD" },
158#endif
159#ifdef PR_GETSHMASK
160 { PR_GETSHMASK, "PR_GETSHMASK" },
161#endif
162#ifdef PR_GETNSHARE
163 { PR_GETNSHARE, "PR_GETNSHARE" },
164#endif
165#if defined(PR_SET_PDEATHSIG)
166 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
167#endif
Wichert Akkerman8829a551999-06-11 13:18:40 +0000168#ifdef PR_COREPID
169 { PR_COREPID, "PR_COREPID" },
170#endif
171#ifdef PR_ATTACHADDRPERM
172 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
173#endif
174#ifdef PR_PTHREADEXIT
175 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
176#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000177#ifdef PR_SET_PDEATHSIG
178 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
179#endif
180#ifdef PR_GET_PDEATHSIG
181 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
182#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000183#ifdef PR_GET_UNALIGN
184 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
185#endif
186#ifdef PR_SET_UNALIGN
187 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
188#endif
189#ifdef PR_GET_KEEPCAPS
190 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" },
191#endif
192#ifdef PR_SET_KEEPCAPS
193 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" },
194#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000195 { 0, NULL },
196};
197
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000198
199const char *
200unalignctl_string (unsigned int ctl)
201{
202 static char buf[16];
203
204 switch (ctl) {
205#ifdef PR_UNALIGN_NOPRINT
206 case PR_UNALIGN_NOPRINT:
207 return "NOPRINT";
208#endif
209#ifdef PR_UNALIGN_SIGBUS
210 case PR_UNALIGN_SIGBUS:
211 return "SIGBUS";
212#endif
213 default:
214 break;
215 }
216 sprintf(buf, "%x", ctl);
217 return buf;
218}
219
220
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000221int
222sys_prctl(tcp)
223struct tcb *tcp;
224{
225 int i;
226
227 if (entering(tcp)) {
228 printxval(prctl_options, tcp->u_arg[0], "PR_???");
229 switch (tcp->u_arg[0]) {
230#ifdef PR_GETNSHARE
231 case PR_GETNSHARE:
232 break;
233#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000234#ifdef PR_SET_DEATHSIG
235 case PR_GET_PDEATHSIG:
236 break;
237#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000238#ifdef PR_SET_UNALIGN
239 case PR_SET_UNALIGN:
240 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
241 break;
242#endif
243#ifdef PR_GET_UNALIGN
244 case PR_GET_UNALIGN:
245 tprintf(", %#lx", tcp->u_arg[1]);
246 break;
247#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000248 default:
249 for (i = 1; i < tcp->u_nargs; i++)
250 tprintf(", %#lx", tcp->u_arg[i]);
251 break;
252 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000253 } else {
254 switch (tcp->u_arg[0]) {
255#ifdef PR_GET_PDEATHSIG
256 case PR_GET_PDEATHSIG:
257 for (i=1; i<tcp->u_nargs; i++)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000258 tprintf(", %#lx", tcp->u_arg[i]);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000259 break;
260#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000261#ifdef PR_SET_UNALIGN
262 case PR_SET_UNALIGN:
263 break;
264#endif
265#ifdef PR_GET_UNALIGN
266 case PR_GET_UNALIGN:
267 {
268 int ctl;
269
270 umove(tcp, tcp->u_arg[1], &ctl);
271 tcp->auxstr = unalignctl_string(ctl);
272 return RVAL_STR;
273 }
274#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000275 default:
276 break;
277 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000278 }
279 return 0;
280}
281
282#endif /* HAVE_PRCTL */
283
284int
285sys_gethostid(tcp)
286struct tcb *tcp;
287{
288 if (exiting(tcp))
289 return RVAL_HEX;
290 return 0;
291}
292
293int
294sys_sethostname(tcp)
295struct tcb *tcp;
296{
297 if (entering(tcp)) {
298 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
299 tprintf(", %lu", tcp->u_arg[1]);
300 }
301 return 0;
302}
303
304int
305sys_gethostname(tcp)
306struct tcb *tcp;
307{
308 if (exiting(tcp)) {
309 if (syserror(tcp))
310 tprintf("%#lx", tcp->u_arg[0]);
311 else
312 printpath(tcp, tcp->u_arg[0]);
313 tprintf(", %lu", tcp->u_arg[1]);
314 }
315 return 0;
316}
317
318int
319sys_setdomainname(tcp)
320struct tcb *tcp;
321{
322 if (entering(tcp)) {
323 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
324 tprintf(", %lu", tcp->u_arg[1]);
325 }
326 return 0;
327}
328
Wichert Akkerman5daa0281999-03-15 19:49:42 +0000329#if !defined(LINUX)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000330
331int
332sys_getdomainname(tcp)
333struct tcb *tcp;
334{
335 if (exiting(tcp)) {
336 if (syserror(tcp))
337 tprintf("%#lx", tcp->u_arg[0]);
338 else
339 printpath(tcp, tcp->u_arg[0]);
340 tprintf(", %lu", tcp->u_arg[1]);
341 }
342 return 0;
343}
344#endif /* !LINUX */
345
346int
347sys_exit(tcp)
348struct tcb *tcp;
349{
350 if (exiting(tcp)) {
351 fprintf(stderr, "_exit returned!\n");
352 return -1;
353 }
354 /* special case: we stop tracing this process, finish line now */
355 tprintf("%ld) ", tcp->u_arg[0]);
356 tabto(acolumn);
357 tprintf("= ?");
358 printtrailer(tcp);
359 return 0;
360}
361
362int
363internal_exit(tcp)
364struct tcb *tcp;
365{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000366 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000367 tcp->flags |= TCB_EXITING;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000368#ifdef __NR_exit_group
369 if (tcp->scno == __NR_exit_group)
370 tcp->flags |= TCB_GROUP_EXITING;
371#endif
372 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000373 return 0;
374}
375
Roland McGrathee9d4352002-12-18 04:16:10 +0000376/* TCP is creating a child we want to follow.
377 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
378 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
379static int
380fork_tcb(struct tcb *tcp)
381{
382 if (nprocs == tcbtabsize) {
383 /* Allocate some more TCBs and expand the table.
384 We don't want to relocate the TCBs because our
385 callers have pointers and it would be a pain.
386 So tcbtab is a table of pointers. Since we never
387 free the TCBs, we allocate a single chunk of many. */
388 struct tcb **newtab = (struct tcb **)
389 realloc(tcbtab, 2 * tcbtabsize * sizeof tcbtab[0]);
390 struct tcb *newtcbs = (struct tcb *) calloc(tcbtabsize,
391 sizeof *newtcbs);
392 int i;
393 if (newtab == NULL || newtcbs == NULL) {
394 if (newtab != NULL)
395 free(newtab);
396 tcp->flags &= ~TCB_FOLLOWFORK;
397 fprintf(stderr, "sys_fork: tcb table full\n");
398 return 1;
399 }
400 for (i = tcbtabsize; i < 2 * tcbtabsize; ++i)
401 newtab[i] = &newtcbs[i - tcbtabsize];
402 tcbtabsize *= 2;
403 tcbtab = newtab;
404 }
405
406 tcp->flags |= TCB_FOLLOWFORK;
407 return 0;
408}
409
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000410#ifdef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000411
412int
413sys_fork(tcp)
414struct tcb *tcp;
415{
416 if (exiting(tcp)) {
417 if (getrval2(tcp)) {
418 tcp->auxstr = "child process";
419 return RVAL_UDECIMAL | RVAL_STR;
420 }
421 }
422 return 0;
423}
424
John Hughes4e36a812001-04-18 15:11:51 +0000425#if UNIXWARE > 2
426
427int
428sys_rfork(tcp)
429struct tcb *tcp;
430{
431 if (entering(tcp)) {
432 tprintf ("%ld", tcp->u_arg[0]);
433 }
434 else {
435 if (getrval2(tcp)) {
436 tcp->auxstr = "child process";
437 return RVAL_UDECIMAL | RVAL_STR;
438 }
439 }
440 return 0;
441}
442
443#endif
444
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000445int
446internal_fork(tcp)
447struct tcb *tcp;
448{
449 struct tcb *tcpchild;
450
451 if (exiting(tcp)) {
452 if (getrval2(tcp))
453 return 0;
454 if (!followfork)
455 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000456 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000457 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000458 if (syserror(tcp))
459 return 0;
460 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
461 fprintf(stderr, "sys_fork: tcb table full\n");
462 return 0;
463 }
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000464 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000465 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000466 }
467 return 0;
468}
469
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000470#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000471
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000472#ifdef LINUX
473
474/* defines copied from linux/sched.h since we can't include that
475 * ourselves (it conflicts with *lots* of libc includes)
476 */
477#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
478#define CLONE_VM 0x00000100 /* set if VM shared between processes */
479#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
480#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
481#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000482#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000483#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
484#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
485#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000486#define CLONE_THREAD 0x00010000 /* Same thread group? */
487#define CLONE_NEWNS 0x00020000 /* New namespace group? */
488#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
489#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
490#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
491#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
492#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
493#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
494#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000495
496static struct xlat clone_flags[] = {
497 { CLONE_VM, "CLONE_VM" },
498 { CLONE_FS, "CLONE_FS" },
499 { CLONE_FILES, "CLONE_FILES" },
500 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000501 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000502 { CLONE_PTRACE, "CLONE_PTRACE" },
503 { CLONE_VFORK, "CLONE_VFORK" },
504 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000505 { CLONE_THREAD, "CLONE_THREAD" },
506 { CLONE_NEWNS, "CLONE_NEWNS" },
507 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
508 { CLONE_SETTLS, "CLONE_SETTLS" },
509 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
510 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
511 { CLONE_DETACHED, "CLONE_DETACHED" },
512 { CLONE_UNTRACED, "CLONE_UNTRACED" },
513 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000514 { 0, NULL },
515};
516
Roland McGrath909875b2002-12-22 03:34:36 +0000517# ifdef I386
518# include <asm/ldt.h>
519extern void print_ldt_entry();
520# endif
521
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000522int
523sys_clone(tcp)
524struct tcb *tcp;
525{
526 if (exiting(tcp)) {
527 tprintf("child_stack=%#lx, flags=", tcp->u_arg[1]);
528 if (printflags(clone_flags, tcp->u_arg[0]) == 0)
529 tprintf("0");
Roland McGrath909875b2002-12-22 03:34:36 +0000530 if ((tcp->u_arg[0] & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
531 |CLONE_SETTLS)) == 0)
532 return 0;
533 if (tcp->u_arg[0] & CLONE_PARENT_SETTID) {
534 int pid;
535 if (umove(tcp, tcp->u_arg[2], &pid) == 0)
536 tprintf(", [%d]", pid);
537 else
538 tprintf(", %#lx", tcp->u_arg[2]);
539 }
540 else
541 tprintf(", <ignored>");
542#ifdef I386
543 if (tcp->u_arg[0] & CLONE_SETTLS) {
544 struct modify_ldt_ldt_s copy;
545 if (umove(tcp, tcp->u_arg[3], &copy) != -1) {
546 tprintf(", {entry_number:%d, ",
547 copy.entry_number);
548 if (!verbose(tcp))
549 tprintf("...}");
550 else
551 print_ldt_entry(&copy);
552 }
553 else
554 tprintf(", %#lx", tcp->u_arg[3]);
555 }
556 else
557 tprintf(", <ignored>");
558# define TIDARG 4
559#else
560# define TIDARG 3
561#endif
562 if (tcp->u_arg[0] & CLONE_CHILD_SETTID)
563 tprintf(", %#lx", tcp->u_arg[TIDARG]);
564#undef TIDARG
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000565 }
566 return 0;
567}
568
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000569int
570sys_clone2(tcp)
571struct tcb *tcp;
572{
573 if (exiting(tcp)) {
574 tprintf("child_stack=%#lx, stack_size=%#lx, flags=",
575 tcp->u_arg[1], tcp->u_arg[2]);
576 if (printflags(clone_flags, tcp->u_arg[0]) == 0)
577 tprintf("0");
578 }
579 return 0;
580}
581
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000582#endif
583
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000584int
585sys_fork(tcp)
586struct tcb *tcp;
587{
588 if (exiting(tcp))
589 return RVAL_UDECIMAL;
590 return 0;
591}
592
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000593int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000594change_syscall(tcp, new)
595struct tcb *tcp;
596int new;
597{
598#if defined(LINUX)
599#if defined(I386)
600 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000601 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000602 return -1;
603 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000604#elif defined(X86_64)
605 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000606 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000607 return -1;
608 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000609#elif defined(POWERPC)
Wichert Akkerman5c4c69b2001-04-12 09:00:47 +0000610 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000611 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000612 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000613#elif defined(S390) || defined(S390X)
614 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
615 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
616 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000617 return 0;
618#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000619 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000620 return -1;
621 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000622#elif defined(SPARC)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000623 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000624 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
625 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000626 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000627 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
628 return -1;
629 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000630#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000631 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000632 return -1;
633 return 0;
634#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000635 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000636 return -1;
637 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000638#elif defined(IA64)
639 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
640 return -1;
641 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000642#elif defined(HPPA)
643 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
644 return -1;
645 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000646#elif defined(SH)
647 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), new)<0)
648 return -1;
649 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000650#else
651#warning Do not know how to handle change_syscall for this architecture
652#endif /* architecture */
653#endif /* LINUX */
654 return -1;
655}
656
657int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000658setarg(tcp, argnum)
659 struct tcb *tcp;
660 int argnum;
661{
662#if defined (IA64)
663 {
664 unsigned long *bsp, *ap;
665
666 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
667 return -1;
668
669 ap = ia64_rse_skip_regs(bsp, argnum);
670 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000671 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000672 if (errno)
673 return -1;
674
675 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000676#elif defined(I386)
677 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000678 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000679 if (errno)
680 return -1;
681 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000682#elif defined(X86_64)
683 {
684 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
685 if (errno)
686 return -1;
687 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000688#elif defined(POWERPC)
689#ifndef PT_ORIG_R3
690#define PT_ORIG_R3 34
691#endif
692 {
693 ptrace(PTRACE_POKEUSER, tcp->pid,
694 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*4),
695 tcp->u_arg[argnum]);
696 if (errno)
697 return -1;
698 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000699#elif defined(MIPS)
700 {
701 errno = 0;
702 if (argnum < 4)
703 ptrace(PTRACE_POKEUSER, tcp->pid,
704 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
705 else {
706 unsigned long *sp;
707
708 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
709 return -1;
710
711 ptrace(PTRACE_POKEDATA, tcp->pid,
712 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
713 }
714 if (errno)
715 return -1;
716 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000717#elif defined(S390) || defined(S390X)
718 {
719 if(argnum <= 5)
720 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000721 (char *) (argnum==0 ? PT_ORIGGPR2 :
722 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000723 tcp->u_arg[argnum]);
724 else
725 return -E2BIG;
726 if (errno)
727 return -1;
728 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000729#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000730# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000731#endif
732 return 0;
733}
734
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000735#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000736int
737internal_clone(tcp)
738struct tcb *tcp;
739{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000740 struct tcb *tcpchild;
741 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000742 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000743 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000744 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000745 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000746 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000747 if (setbpt(tcp) < 0)
748 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000749 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000750 int bpt = tcp->flags & TCB_BPTSET;
751
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000752 if (!(tcp->flags & TCB_FOLLOWFORK))
753 return 0;
754
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000755 if (syserror(tcp)) {
756 if (bpt)
757 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000758 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000759 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000760
761 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000762
763#ifdef CLONE_PTRACE /* See new setbpt code. */
764 tcpchild = pid2tcb(pid);
765 if (tcpchild != NULL) {
766 /* The child already reported its startup trap
767 before the parent reported its syscall return. */
768 if ((tcpchild->flags
769 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
770 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
771 fprintf(stderr, "\
772[preattached child %d of %d in weird state!]\n",
773 pid, tcp->pid);
774 }
775 else
776#endif
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000777 if ((tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000778 if (bpt)
779 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000780 fprintf(stderr, " [tcb table full]\n");
781 kill(pid, SIGKILL); /* XXX */
782 return 0;
783 }
784
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000785#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000786 /* Attach to the new child */
787 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000788 if (bpt)
789 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000790 perror("PTRACE_ATTACH");
791 fprintf(stderr, "Too late?\n");
792 droptcb(tcpchild);
793 return 0;
794 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000795#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000796
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000797 if (bpt)
798 clearbpt(tcp);
799
Ulrich Drepper90512f01999-12-24 07:22:25 +0000800 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000801 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000802 if (bpt) {
803 tcpchild->flags |= TCB_BPTSET;
804 tcpchild->baddr = tcp->baddr;
805 memcpy(tcpchild->inst, tcp->inst,
806 sizeof tcpchild->inst);
807 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000808 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000809 tcp->nchildren++;
810 if (tcpchild->flags & TCB_SUSPENDED) {
811 /* The child was born suspended, due to our having
812 forced CLONE_PTRACE. */
813 if (bpt)
814 clearbpt(tcpchild);
815
816 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
817 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
818 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
819 return -1;
820 }
821
822 if (!qflag)
823 fprintf(stderr, "\
824Process %u resumed (parent %d ready)\n",
825 pid, tcp->pid);
826 }
827 else {
828 newoutf(tcpchild);
829 if (!qflag)
830 fprintf(stderr, "Process %d attached\n", pid);
831 }
832
833#ifdef TCB_CLONE_THREAD
834 if ((tcp->flags & TCB_CLONE_THREAD) && tcp->parent != NULL) {
835 /* The parent in this clone is itself a thread
836 belonging to another process. There is no
837 meaning to the parentage relationship of the new
838 child with the thread, only with the process.
839 We associate the new thread with our parent.
840 Since this is done for every new thread, there
841 will never be a TCB_CLONE_THREAD process that
842 has children. */
843 --tcp->nchildren;
844 tcp->u_arg[0] = tcp->parent->u_arg[0];
845 tcp = tcp->parent;
846 tcpchild->parent = tcp;
847 ++tcp->nchildren;
848 }
849
850 if (tcp->u_arg[0] & CLONE_THREAD) {
851 tcpchild->flags |= TCB_CLONE_THREAD;
852 ++tcp->nclone_threads;
853 }
854 if (tcp->u_arg[0] & CLONE_DETACHED) {
855 tcpchild->flags |= TCB_CLONE_DETACHED;
856 ++tcp->nclone_detached;
857 }
858#endif
859
860 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000861 return 0;
862}
863#endif
864
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000865int
866internal_fork(tcp)
867struct tcb *tcp;
868{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000869#ifdef LINUX
870 /* We do special magic with clone for any clone or fork. */
871 return internal_clone(tcp);
872#else
873
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000874 struct tcb *tcpchild;
875 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000876 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000877
878#ifdef SYS_vfork
Nate Sammonsccd8f211999-03-29 22:57:54 +0000879 if (tcp->scno == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000880 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000881 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000882 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000883 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000884 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000885#endif
886 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000887 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000888 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000889 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000890 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000891 if (setbpt(tcp) < 0)
892 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000893 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000894 else {
895 int bpt = tcp->flags & TCB_BPTSET;
896
897 if (!(tcp->flags & TCB_FOLLOWFORK))
898 return 0;
899 if (bpt)
900 clearbpt(tcp);
901
902 if (syserror(tcp))
903 return 0;
904
905 pid = tcp->u_rval;
906 if ((tcpchild = alloctcb(pid)) == NULL) {
907 fprintf(stderr, " [tcb table full]\n");
908 kill(pid, SIGKILL); /* XXX */
909 return 0;
910 }
911#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000912#ifdef HPPA
913 /* The child must have run before it can be attached. */
914 /* This must be a bug in the parisc kernel, but I havn't
915 * identified it yet. Seems to be an issue associated
916 * with attaching to a process (which sends it a signal)
917 * before that process has ever been scheduled. When
918 * debugging, I started seeing crashes in
919 * arch/parisc/kernel/signal.c:do_signal(), apparently
920 * caused by r8 getting corrupt over the dequeue_signal()
921 * call. Didn't make much sense though...
922 */
923 {
924 struct timeval tv;
925 tv.tv_sec = 0;
926 tv.tv_usec = 10000;
927 select(0, NULL, NULL, NULL, &tv);
928 }
929#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000930 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
931 perror("PTRACE_ATTACH");
932 fprintf(stderr, "Too late?\n");
933 droptcb(tcpchild);
934 return 0;
935 }
936#endif /* LINUX */
937#ifdef SUNOS4
938#ifdef oldway
939 /* The child must have run before it can be attached. */
940 {
941 struct timeval tv;
942 tv.tv_sec = 0;
943 tv.tv_usec = 10000;
944 select(0, NULL, NULL, NULL, &tv);
945 }
946 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
947 perror("PTRACE_ATTACH");
948 fprintf(stderr, "Too late?\n");
949 droptcb(tcpchild);
950 return 0;
951 }
952#else /* !oldway */
953 /* Try to catch the new process as soon as possible. */
954 {
955 int i;
956 for (i = 0; i < 1024; i++)
957 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
958 break;
959 if (i == 1024) {
960 perror("PTRACE_ATTACH");
961 fprintf(stderr, "Too late?\n");
962 droptcb(tcpchild);
963 return 0;
964 }
965 }
966#endif /* !oldway */
967#endif /* SUNOS4 */
968 tcpchild->flags |= TCB_ATTACHED;
969 /* Child has BPT too, must be removed on first occasion */
970 if (bpt) {
971 tcpchild->flags |= TCB_BPTSET;
972 tcpchild->baddr = tcp->baddr;
973 memcpy(tcpchild->inst, tcp->inst,
974 sizeof tcpchild->inst);
975 }
976 newoutf(tcpchild);
977 tcpchild->parent = tcp;
978 tcp->nchildren++;
979 if (!qflag)
980 fprintf(stderr, "Process %d attached\n", pid);
981 }
982 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000983#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000984}
985
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000986#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000987
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000988#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000989
990int
991sys_vfork(tcp)
992struct tcb *tcp;
993{
994 if (exiting(tcp))
995 return RVAL_UDECIMAL;
996 return 0;
997}
998
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000999#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001000
1001#ifndef LINUX
1002
1003static char idstr[16];
1004
1005int
1006sys_getpid(tcp)
1007struct tcb *tcp;
1008{
1009 if (exiting(tcp)) {
1010 sprintf(idstr, "ppid %lu", getrval2(tcp));
1011 tcp->auxstr = idstr;
1012 return RVAL_STR;
1013 }
1014 return 0;
1015}
1016
1017int
1018sys_getuid(tcp)
1019struct tcb *tcp;
1020{
1021 if (exiting(tcp)) {
1022 sprintf(idstr, "euid %lu", getrval2(tcp));
1023 tcp->auxstr = idstr;
1024 return RVAL_STR;
1025 }
1026 return 0;
1027}
1028
1029int
1030sys_getgid(tcp)
1031struct tcb *tcp;
1032{
1033 if (exiting(tcp)) {
1034 sprintf(idstr, "egid %lu", getrval2(tcp));
1035 tcp->auxstr = idstr;
1036 return RVAL_STR;
1037 }
1038 return 0;
1039}
1040
1041#endif /* !LINUX */
1042
1043#ifdef LINUX
1044
1045int
1046sys_setuid(tcp)
1047struct tcb *tcp;
1048{
1049 if (entering(tcp)) {
1050 tprintf("%u", (uid_t) tcp->u_arg[0]);
1051 }
1052 return 0;
1053}
1054
1055int
1056sys_setgid(tcp)
1057struct tcb *tcp;
1058{
1059 if (entering(tcp)) {
1060 tprintf("%u", (gid_t) tcp->u_arg[0]);
1061 }
1062 return 0;
1063}
1064
1065int
1066sys_getresuid(tcp)
1067 struct tcb *tcp;
1068{
1069 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001070 __kernel_uid_t uid;
1071 if (syserror(tcp))
1072 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1073 tcp->u_arg[1], tcp->u_arg[2]);
1074 else {
1075 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1076 tprintf("%#lx, ", tcp->u_arg[0]);
1077 else
1078 tprintf("ruid %lu, ", (unsigned long) uid);
1079 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1080 tprintf("%#lx, ", tcp->u_arg[0]);
1081 else
1082 tprintf("euid %lu, ", (unsigned long) uid);
1083 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1084 tprintf("%#lx", tcp->u_arg[0]);
1085 else
1086 tprintf("suid %lu", (unsigned long) uid);
1087 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001088 }
1089 return 0;
1090}
1091
1092int
1093sys_getresgid(tcp)
1094struct tcb *tcp;
1095{
1096 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001097 __kernel_gid_t gid;
1098 if (syserror(tcp))
1099 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1100 tcp->u_arg[1], tcp->u_arg[2]);
1101 else {
1102 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1103 tprintf("%#lx, ", tcp->u_arg[0]);
1104 else
1105 tprintf("rgid %lu, ", (unsigned long) gid);
1106 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1107 tprintf("%#lx, ", tcp->u_arg[0]);
1108 else
1109 tprintf("egid %lu, ", (unsigned long) gid);
1110 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1111 tprintf("%#lx", tcp->u_arg[0]);
1112 else
1113 tprintf("sgid %lu", (unsigned long) gid);
1114 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001115 }
1116 return 0;
1117}
1118
1119#endif /* LINUX */
1120
1121int
1122sys_setreuid(tcp)
1123struct tcb *tcp;
1124{
1125 if (entering(tcp)) {
1126 tprintf("%lu, %lu",
1127 (unsigned long) (uid_t) tcp->u_arg[0],
1128 (unsigned long) (uid_t) tcp->u_arg[1]);
1129 }
1130 return 0;
1131}
1132
1133int
1134sys_setregid(tcp)
1135struct tcb *tcp;
1136{
1137 if (entering(tcp)) {
1138 tprintf("%lu, %lu",
1139 (unsigned long) (gid_t) tcp->u_arg[0],
1140 (unsigned long) (gid_t) tcp->u_arg[1]);
1141 }
1142 return 0;
1143}
1144
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001145#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001146int
1147sys_setresuid(tcp)
1148 struct tcb *tcp;
1149{
1150 if (entering(tcp)) {
1151 tprintf("ruid %u, euid %u, suid %u",
1152 (uid_t) tcp->u_arg[0],
1153 (uid_t) tcp->u_arg[1],
1154 (uid_t) tcp->u_arg[2]);
1155 }
1156 return 0;
1157}
1158int
1159sys_setresgid(tcp)
1160 struct tcb *tcp;
1161{
1162 if (entering(tcp)) {
1163 tprintf("rgid %u, egid %u, sgid %u",
1164 (uid_t) tcp->u_arg[0],
1165 (uid_t) tcp->u_arg[1],
1166 (uid_t) tcp->u_arg[2]);
1167 }
1168 return 0;
1169}
1170
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001171#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001172
1173int
1174sys_setgroups(tcp)
1175struct tcb *tcp;
1176{
1177 int i, len;
1178 GETGROUPS_T *gidset;
1179
1180 if (entering(tcp)) {
1181 len = tcp->u_arg[0];
1182 tprintf("%u, ", len);
1183 if (len <= 0) {
1184 tprintf("[]");
1185 return 0;
1186 }
1187 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1188 if (gidset == NULL) {
1189 fprintf(stderr, "sys_setgroups: out of memory\n");
1190 return -1;
1191 }
1192 if (!verbose(tcp))
1193 tprintf("%#lx", tcp->u_arg[1]);
1194 else if (umoven(tcp, tcp->u_arg[1],
1195 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1196 tprintf("[?]");
1197 else {
1198 tprintf("[");
1199 for (i = 0; i < len; i++)
1200 tprintf("%s%lu", i ? ", " : "",
1201 (unsigned long) gidset[i]);
1202 tprintf("]");
1203 }
1204 free((char *) gidset);
1205 }
1206 return 0;
1207}
1208
1209int
1210sys_getgroups(tcp)
1211struct tcb *tcp;
1212{
1213 int i, len;
1214 GETGROUPS_T *gidset;
1215
1216 if (entering(tcp)) {
1217 len = tcp->u_arg[0];
1218 tprintf("%u, ", len);
1219 } else {
1220 len = tcp->u_rval;
1221 if (len <= 0) {
1222 tprintf("[]");
1223 return 0;
1224 }
1225 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1226 if (gidset == NULL) {
1227 fprintf(stderr, "sys_getgroups: out of memory\n");
1228 return -1;
1229 }
1230 if (!tcp->u_arg[1])
1231 tprintf("NULL");
1232 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1233 tprintf("%#lx", tcp->u_arg[1]);
1234 else if (umoven(tcp, tcp->u_arg[1],
1235 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1236 tprintf("[?]");
1237 else {
1238 tprintf("[");
1239 for (i = 0; i < len; i++)
1240 tprintf("%s%lu", i ? ", " : "",
1241 (unsigned long) gidset[i]);
1242 tprintf("]");
1243 }
1244 free((char *)gidset);
1245 }
1246 return 0;
1247}
1248
1249int
1250sys_setpgrp(tcp)
1251struct tcb *tcp;
1252{
1253 if (entering(tcp)) {
1254#ifndef SVR4
1255 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1256#endif /* !SVR4 */
1257 }
1258 return 0;
1259}
1260
1261int
1262sys_getpgrp(tcp)
1263struct tcb *tcp;
1264{
1265 if (entering(tcp)) {
1266#ifndef SVR4
1267 tprintf("%lu", tcp->u_arg[0]);
1268#endif /* !SVR4 */
1269 }
1270 return 0;
1271}
1272
1273int
1274sys_getsid(tcp)
1275struct tcb *tcp;
1276{
1277 if (entering(tcp)) {
1278 tprintf("%lu", tcp->u_arg[0]);
1279 }
1280 return 0;
1281}
1282
1283int
1284sys_setsid(tcp)
1285struct tcb *tcp;
1286{
1287 return 0;
1288}
1289
1290int
1291sys_getpgid(tcp)
1292struct tcb *tcp;
1293{
1294 if (entering(tcp)) {
1295 tprintf("%lu", tcp->u_arg[0]);
1296 }
1297 return 0;
1298}
1299
1300int
1301sys_setpgid(tcp)
1302struct tcb *tcp;
1303{
1304 if (entering(tcp)) {
1305 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1306 }
1307 return 0;
1308}
1309
John Hughesc61eb3d2002-05-17 11:37:50 +00001310#if UNIXWARE >= 2
1311
1312#include <sys/privilege.h>
1313
1314
1315static struct xlat procpriv_cmds [] = {
1316 { SETPRV, "SETPRV" },
1317 { CLRPRV, "CLRPRV" },
1318 { PUTPRV, "PUTPRV" },
1319 { GETPRV, "GETPRV" },
1320 { CNTPRV, "CNTPRV" },
1321 { 0, NULL },
1322};
1323
1324
1325static struct xlat procpriv_priv [] = {
1326 { P_OWNER, "P_OWNER" },
1327 { P_AUDIT, "P_AUDIT" },
1328 { P_COMPAT, "P_COMPAT" },
1329 { P_DACREAD, "P_DACREAD" },
1330 { P_DACWRITE, "P_DACWRITE" },
1331 { P_DEV, "P_DEV" },
1332 { P_FILESYS, "P_FILESYS" },
1333 { P_MACREAD, "P_MACREAD" },
1334 { P_MACWRITE, "P_MACWRITE" },
1335 { P_MOUNT, "P_MOUNT" },
1336 { P_MULTIDIR, "P_MULTIDIR" },
1337 { P_SETPLEVEL, "P_SETPLEVEL" },
1338 { P_SETSPRIV, "P_SETSPRIV" },
1339 { P_SETUID, "P_SETUID" },
1340 { P_SYSOPS, "P_SYSOPS" },
1341 { P_SETUPRIV, "P_SETUPRIV" },
1342 { P_DRIVER, "P_DRIVER" },
1343 { P_RTIME, "P_RTIME" },
1344 { P_MACUPGRADE, "P_MACUPGRADE" },
1345 { P_FSYSRANGE, "P_FSYSRANGE" },
1346 { P_SETFLEVEL, "P_SETFLEVEL" },
1347 { P_AUDITWR, "P_AUDITWR" },
1348 { P_TSHAR, "P_TSHAR" },
1349 { P_PLOCK, "P_PLOCK" },
1350 { P_CORE, "P_CORE" },
1351 { P_LOADMOD, "P_LOADMOD" },
1352 { P_BIND, "P_BIND" },
1353 { P_ALLPRIVS, "P_ALLPRIVS" },
1354 { 0, NULL },
1355};
1356
1357
1358static struct xlat procpriv_type [] = {
1359 { PS_FIX, "PS_FIX" },
1360 { PS_INH, "PS_INH" },
1361 { PS_MAX, "PS_MAX" },
1362 { PS_WKG, "PS_WKG" },
1363 { 0, NULL },
1364};
1365
1366
1367static void
1368printpriv(tcp, addr, len, opt)
1369struct tcb *tcp;
1370long addr;
1371int len;
1372struct xlat *opt;
1373{
1374 priv_t buf [128];
1375 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1376 int dots = len > max;
1377 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001378
John Hughesc61eb3d2002-05-17 11:37:50 +00001379 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001380
John Hughesc61eb3d2002-05-17 11:37:50 +00001381 if (len <= 0 ||
1382 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1383 {
1384 tprintf ("%#lx", addr);
1385 return;
1386 }
1387
1388 tprintf ("[");
1389
1390 for (i = 0; i < len; ++i) {
1391 char *t, *p;
1392
1393 if (i) tprintf (", ");
1394
1395 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1396 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1397 {
1398 tprintf ("%s|%s", t, p);
1399 }
1400 else {
1401 tprintf ("%#lx", buf [i]);
1402 }
1403 }
1404
1405 if (dots) tprintf (" ...");
1406
1407 tprintf ("]");
1408}
1409
1410
1411int
1412sys_procpriv(tcp)
1413struct tcb *tcp;
1414{
1415 if (entering(tcp)) {
1416 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1417 switch (tcp->u_arg[0]) {
1418 case CNTPRV:
1419 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1420 break;
1421
1422 case GETPRV:
1423 break;
1424
1425 default:
1426 tprintf (", ");
1427 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1428 tprintf (", %ld", tcp->u_arg[2]);
1429 }
1430 }
1431 else if (tcp->u_arg[0] == GETPRV) {
1432 if (syserror (tcp)) {
1433 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1434 }
1435 else {
1436 tprintf (", ");
1437 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1438 tprintf (", %ld", tcp->u_arg[2]);
1439 }
1440 }
Roland McGrath5a223472002-12-15 23:58:26 +00001441
John Hughesc61eb3d2002-05-17 11:37:50 +00001442 return 0;
1443}
1444
1445#endif
1446
1447
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001448void
1449fake_execve(tcp, program, argv, envp)
1450struct tcb *tcp;
1451char *program;
1452char *argv[];
1453char *envp[];
1454{
1455 int i;
1456
1457#ifdef ARM
1458 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1459 return;
1460#else
1461 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1462 return;
1463#endif /* !ARM */
1464 printleader(tcp);
1465 tprintf("execve(");
1466 string_quote(program);
1467 tprintf(", [");
1468 for (i = 0; argv[i] != NULL; i++) {
1469 if (i != 0)
1470 tprintf(", ");
1471 string_quote(argv[i]);
1472 }
1473 for (i = 0; envp[i] != NULL; i++)
1474 ;
1475 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1476 tabto(acolumn);
1477 tprintf("= 0");
1478 printtrailer(tcp);
1479}
1480
1481static void
1482printargv(tcp, addr)
1483struct tcb *tcp;
1484long addr;
1485{
1486 char *cp;
1487 char *sep;
1488 int max = max_strlen / 2;
1489
1490 for (sep = ""; --max >= 0; sep = ", ") {
1491 if (!abbrev(tcp))
1492 max++;
1493 if (umove(tcp, addr, &cp) < 0) {
1494 tprintf("%#lx", addr);
1495 return;
1496 }
1497 if (cp == 0)
1498 break;
1499 tprintf(sep);
1500 printstr(tcp, (long) cp, -1);
1501 addr += sizeof(char *);
1502 }
1503 if (cp)
1504 tprintf(", ...");
1505}
1506
1507static void
1508printargc(fmt, tcp, addr)
1509char *fmt;
1510struct tcb *tcp;
1511long addr;
1512{
1513 int count;
1514 char *cp;
1515
1516 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1517 addr += sizeof(char *);
1518 }
1519 tprintf(fmt, count, count == 1 ? "" : "s");
1520}
1521
1522int
1523sys_execv(tcp)
1524struct tcb *tcp;
1525{
1526 if (entering(tcp)) {
1527 printpath(tcp, tcp->u_arg[0]);
1528 if (!verbose(tcp))
1529 tprintf(", %#lx", tcp->u_arg[1]);
1530#if 0
1531 else if (abbrev(tcp))
1532 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1533#endif
1534 else {
1535 tprintf(", [");
1536 printargv(tcp, tcp->u_arg[1]);
1537 tprintf("]");
1538 }
1539 }
1540 return 0;
1541}
1542
1543int
1544sys_execve(tcp)
1545struct tcb *tcp;
1546{
1547 if (entering(tcp)) {
1548 printpath(tcp, tcp->u_arg[0]);
1549 if (!verbose(tcp))
1550 tprintf(", %#lx", tcp->u_arg[1]);
1551#if 0
1552 else if (abbrev(tcp))
1553 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1554#endif
1555 else {
1556 tprintf(", [");
1557 printargv(tcp, tcp->u_arg[1]);
1558 tprintf("]");
1559 }
1560 if (!verbose(tcp))
1561 tprintf(", %#lx", tcp->u_arg[2]);
1562 else if (abbrev(tcp))
1563 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1564 else {
1565 tprintf(", [");
1566 printargv(tcp, tcp->u_arg[2]);
1567 tprintf("]");
1568 }
1569 }
1570#ifdef LINUX
Wichert Akkermanccef6372002-05-01 16:39:22 +00001571#if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001572 tcp->flags |= TCB_WAITEXECVE;
Wichert Akkermanccef6372002-05-01 16:39:22 +00001573#endif /* ALPHA || SPARC || POWERPC || IA64 || HPPA || SH */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001574#endif /* LINUX */
1575 return 0;
1576}
1577
John Hughes4e36a812001-04-18 15:11:51 +00001578#if UNIXWARE > 2
1579
1580int sys_rexecve(tcp)
1581struct tcb *tcp;
1582{
1583 if (entering (tcp)) {
1584 sys_execve (tcp);
1585 tprintf (", %ld", tcp->u_arg[3]);
1586 }
1587 return 0;
1588}
1589
1590#endif
1591
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001592int
1593internal_exec(tcp)
1594struct tcb *tcp;
1595{
1596#ifdef SUNOS4
1597 if (exiting(tcp) && !syserror(tcp) && followfork)
1598 fixvfork(tcp);
1599#endif /* SUNOS4 */
1600 return 0;
1601}
1602
1603#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001604#ifndef __WNOTHREAD
1605#define __WNOTHREAD 0x20000000
1606#endif
1607#ifndef __WALL
1608#define __WALL 0x40000000
1609#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001610#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001611#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001612#endif
1613#endif /* LINUX */
1614
1615static struct xlat wait4_options[] = {
1616 { WNOHANG, "WNOHANG" },
1617#ifndef WSTOPPED
1618 { WUNTRACED, "WUNTRACED" },
1619#endif
1620#ifdef WEXITED
1621 { WEXITED, "WEXITED" },
1622#endif
1623#ifdef WTRAPPED
1624 { WTRAPPED, "WTRAPPED" },
1625#endif
1626#ifdef WSTOPPED
1627 { WSTOPPED, "WSTOPPED" },
1628#endif
1629#ifdef WCONTINUED
1630 { WCONTINUED, "WCONTINUED" },
1631#endif
1632#ifdef WNOWAIT
1633 { WNOWAIT, "WNOWAIT" },
1634#endif
1635#ifdef __WCLONE
1636 { __WCLONE, "__WCLONE" },
1637#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001638#ifdef __WALL
1639 { __WALL, "__WALL" },
1640#endif
1641#ifdef __WNOTHREAD
1642 { __WNOTHREAD, "__WNOTHREAD" },
1643#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001644 { 0, NULL },
1645};
1646
1647static int
1648printstatus(status)
1649int status;
1650{
1651 int exited = 0;
1652
1653 /*
1654 * Here is a tricky presentation problem. This solution
1655 * is still not entirely satisfactory but since there
1656 * are no wait status constructors it will have to do.
1657 */
1658 if (WIFSTOPPED(status))
1659 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001660 signame(WSTOPSIG(status)));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001661 else if WIFSIGNALED(status)
1662 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001663 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001664 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1665 else if WIFEXITED(status) {
1666 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1667 WEXITSTATUS(status));
1668 exited = 1;
1669 }
1670 else
1671 tprintf("[%#x]", status);
1672 return exited;
1673}
1674
1675static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001676printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001677struct tcb *tcp;
1678int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001679int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001680{
1681 int status;
1682 int exited = 0;
1683
1684 if (entering(tcp)) {
1685 tprintf("%ld, ", tcp->u_arg[0]);
1686 } else {
1687 /* status */
1688 if (!tcp->u_arg[1])
1689 tprintf("NULL");
1690 else if (syserror(tcp) || tcp->u_rval == 0)
1691 tprintf("%#lx", tcp->u_arg[1]);
1692 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1693 tprintf("[?]");
1694 else
1695 exited = printstatus(status);
1696 /* options */
1697 tprintf(", ");
1698 if (!printflags(wait4_options, tcp->u_arg[2]))
1699 tprintf("0");
1700 if (n == 4) {
1701 tprintf(", ");
1702 /* usage */
1703 if (!tcp->u_arg[3])
1704 tprintf("NULL");
1705#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001706 else if (tcp->u_rval > 0) {
1707#ifdef LINUX_64BIT
1708 if (bitness)
1709 printrusage32(tcp, tcp->u_arg[3]);
1710 else
1711#endif
1712 printrusage(tcp, tcp->u_arg[3]);
1713 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001714#endif /* LINUX */
1715#ifdef SUNOS4
1716 else if (tcp->u_rval > 0 && exited)
1717 printrusage(tcp, tcp->u_arg[3]);
1718#endif /* SUNOS4 */
1719 else
1720 tprintf("%#lx", tcp->u_arg[3]);
1721 }
1722 }
1723 return 0;
1724}
1725
1726int
1727internal_wait(tcp)
1728struct tcb *tcp;
1729{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001730 int got_kids;
1731
1732#ifdef TCB_CLONE_THREAD
1733 if (tcp->flags & TCB_CLONE_THREAD)
1734 /* The children we wait for are our parent's children. */
1735 got_kids = (tcp->parent->nchildren
1736 > tcp->parent->nclone_detached);
1737 else
1738 got_kids = (tcp->nchildren > tcp->nclone_detached);
1739#else
1740 got_kids = tcp->nchildren > 0;
1741#endif
1742
1743 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001744 /* There are children that this parent should block for.
1745 But ptrace made us the parent of the traced children
1746 and the real parent will get ECHILD from the wait call.
1747
1748 XXX If we attached with strace -f -p PID, then there
1749 may be untraced dead children the parent could be reaping
1750 now, but we make him block. */
1751
1752 /* ??? WTA: fix bug with hanging children */
1753
1754 if (!(tcp->u_arg[2] & WNOHANG)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001755 /* There are traced children */
1756 tcp->flags |= TCB_SUSPENDED;
1757 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001758#ifdef TCB_CLONE_THREAD
1759 if (tcp->flags & TCB_CLONE_THREAD)
1760 tcp->parent->nclone_waiting++;
1761#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001762 }
1763 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001764 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001765 if (tcp->u_arg[2] & WNOHANG) {
1766 /* We must force a fake result of 0 instead of
1767 the ECHILD error. */
1768 extern int force_result();
1769 return force_result(tcp, 0, 0);
1770 }
1771 else
1772 fprintf(stderr,
1773 "internal_wait: should not have resumed %d\n",
1774 tcp->pid);
1775 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001776 return 0;
1777}
1778
1779#ifdef SVR4
1780
1781int
1782sys_wait(tcp)
1783struct tcb *tcp;
1784{
1785 if (exiting(tcp)) {
1786 /* The library wrapper stuffs this into the user variable. */
1787 if (!syserror(tcp))
1788 printstatus(getrval2(tcp));
1789 }
1790 return 0;
1791}
1792
1793#endif /* SVR4 */
1794
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001795#ifdef FREEBSD
1796int
1797sys_wait(tcp)
1798struct tcb *tcp;
1799{
1800 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001801
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001802 if (exiting(tcp)) {
1803 if (!syserror(tcp)) {
1804 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1805 tprintf("%#lx", tcp->u_arg[0]);
1806 else
1807 printstatus(status);
1808 }
1809 }
1810 return 0;
1811}
1812#endif
1813
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001814int
1815sys_waitpid(tcp)
1816struct tcb *tcp;
1817{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001818 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001819}
1820
1821int
1822sys_wait4(tcp)
1823struct tcb *tcp;
1824{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001825 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001826}
1827
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001828#ifdef ALPHA
1829int
1830sys_osf_wait4(tcp)
1831struct tcb *tcp;
1832{
1833 return printwaitn(tcp, 4, 1);
1834}
1835#endif
1836
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001837#ifdef SVR4
1838
1839static struct xlat waitid_types[] = {
1840 { P_PID, "P_PID" },
1841 { P_PPID, "P_PPID" },
1842 { P_PGID, "P_PGID" },
1843 { P_SID, "P_SID" },
1844 { P_CID, "P_CID" },
1845 { P_UID, "P_UID" },
1846 { P_GID, "P_GID" },
1847 { P_ALL, "P_ALL" },
1848#ifdef P_LWPID
1849 { P_LWPID, "P_LWPID" },
1850#endif
1851 { 0, NULL },
1852};
1853
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001854int
1855sys_waitid(tcp)
1856struct tcb *tcp;
1857{
1858 siginfo_t si;
1859 int exited;
1860
1861 if (entering(tcp)) {
1862 printxval(waitid_types, tcp->u_arg[0], "P_???");
1863 tprintf(", %ld, ", tcp->u_arg[1]);
1864 if (tcp->nchildren > 0) {
1865 /* There are traced children */
1866 tcp->flags |= TCB_SUSPENDED;
1867 tcp->waitpid = tcp->u_arg[0];
1868 }
1869 }
1870 else {
1871 /* siginfo */
1872 exited = 0;
1873 if (!tcp->u_arg[2])
1874 tprintf("NULL");
1875 else if (syserror(tcp))
1876 tprintf("%#lx", tcp->u_arg[2]);
1877 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1878 tprintf("{???}");
1879 else
John Hughes58265892001-10-18 15:13:53 +00001880 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001881 /* options */
1882 tprintf(", ");
1883 if (!printflags(wait4_options, tcp->u_arg[3]))
1884 tprintf("0");
1885 }
1886 return 0;
1887}
1888
1889#endif /* SVR4 */
1890
1891int
1892sys_alarm(tcp)
1893struct tcb *tcp;
1894{
1895 if (entering(tcp))
1896 tprintf("%lu", tcp->u_arg[0]);
1897 return 0;
1898}
1899
1900int
1901sys_uname(tcp)
1902struct tcb *tcp;
1903{
1904 struct utsname uname;
1905
1906 if (exiting(tcp)) {
1907 if (syserror(tcp) || !verbose(tcp))
1908 tprintf("%#lx", tcp->u_arg[0]);
1909 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1910 tprintf("{...}");
1911 else if (!abbrev(tcp)) {
1912
1913 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1914 uname.sysname, uname.nodename);
1915 tprintf("release=\"%s\", version=\"%s\", ",
1916 uname.release, uname.version);
1917 tprintf("machine=\"%s\"", uname.machine);
1918#ifdef LINUX
1919#ifndef __GLIBC__
1920 tprintf(", domainname=\"%s\"", uname.domainname);
1921#endif /* __GLIBC__ */
1922#endif /* LINUX */
1923 tprintf("}");
1924 }
1925 else
1926 tprintf("{sys=\"%s\", node=\"%s\", ...}",
1927 uname.sysname, uname.nodename);
1928 }
1929 return 0;
1930}
1931
1932#ifndef SVR4
1933
1934static struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00001935#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001936 { PTRACE_TRACEME, "PTRACE_TRACEME" },
1937 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
1938 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
1939 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
1940 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
1941 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
1942 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
1943 { PTRACE_CONT, "PTRACE_CONT" },
1944 { PTRACE_KILL, "PTRACE_KILL" },
1945 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
1946 { PTRACE_ATTACH, "PTRACE_ATTACH" },
1947 { PTRACE_DETACH, "PTRACE_DETACH" },
1948#ifdef SUNOS4
1949 { PTRACE_GETREGS, "PTRACE_GETREGS" },
1950 { PTRACE_SETREGS, "PTRACE_SETREGS" },
1951 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
1952 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
1953 { PTRACE_READDATA, "PTRACE_READDATA" },
1954 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
1955 { PTRACE_READTEXT, "PTRACE_READTEXT" },
1956 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
1957 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
1958 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
1959#ifdef SPARC
1960 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
1961 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
1962#else /* !SPARC */
1963 { PTRACE_22, "PTRACE_PTRACE_22" },
1964 { PTRACE_23, "PTRACE_PTRACE_23" },
1965#endif /* !SPARC */
1966#endif /* SUNOS4 */
1967 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
1968#ifdef SUNOS4
1969 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
1970#ifdef I386
1971 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
1972 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
1973 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
1974#else /* !I386 */
1975 { PTRACE_26, "PTRACE_26" },
1976 { PTRACE_27, "PTRACE_27" },
1977 { PTRACE_28, "PTRACE_28" },
1978#endif /* !I386 */
1979 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
1980#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001981#else /* FREEBSD */
1982 { PT_TRACE_ME, "PT_TRACE_ME" },
1983 { PT_READ_I, "PT_READ_I" },
1984 { PT_READ_D, "PT_READ_D" },
1985 { PT_WRITE_I, "PT_WRITE_I" },
1986 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00001987#ifdef PT_READ_U
1988 { PT_READ_U, "PT_READ_U" },
1989#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001990 { PT_CONTINUE, "PT_CONTINUE" },
1991 { PT_KILL, "PT_KILL" },
1992 { PT_STEP, "PT_STEP" },
1993 { PT_ATTACH, "PT_ATTACH" },
1994 { PT_DETACH, "PT_DETACH" },
1995 { PT_GETREGS, "PT_GETREGS" },
1996 { PT_SETREGS, "PT_SETREGS" },
1997 { PT_GETFPREGS, "PT_GETFPREGS" },
1998 { PT_SETFPREGS, "PT_SETFPREGS" },
1999 { PT_GETDBREGS, "PT_GETDBREGS" },
2000 { PT_SETDBREGS, "PT_SETDBREGS" },
2001#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002002 { 0, NULL },
2003};
2004
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002005#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002006#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2007static
2008#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2009struct xlat struct_user_offsets[] = {
2010#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002011#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002012 { PT_PSWMASK, "psw_mask" },
2013 { PT_PSWADDR, "psw_addr" },
2014 { PT_GPR0, "gpr0" },
2015 { PT_GPR1, "gpr1" },
2016 { PT_GPR2, "gpr2" },
2017 { PT_GPR3, "gpr3" },
2018 { PT_GPR4, "gpr4" },
2019 { PT_GPR5, "gpr5" },
2020 { PT_GPR6, "gpr6" },
2021 { PT_GPR7, "gpr7" },
2022 { PT_GPR8, "gpr8" },
2023 { PT_GPR9, "gpr9" },
2024 { PT_GPR10, "gpr10" },
2025 { PT_GPR11, "gpr11" },
2026 { PT_GPR12, "gpr12" },
2027 { PT_GPR13, "gpr13" },
2028 { PT_GPR14, "gpr14" },
2029 { PT_GPR15, "gpr15" },
2030 { PT_ACR0, "acr0" },
2031 { PT_ACR1, "acr1" },
2032 { PT_ACR2, "acr2" },
2033 { PT_ACR3, "acr3" },
2034 { PT_ACR4, "acr4" },
2035 { PT_ACR5, "acr5" },
2036 { PT_ACR6, "acr6" },
2037 { PT_ACR7, "acr7" },
2038 { PT_ACR8, "acr8" },
2039 { PT_ACR9, "acr9" },
2040 { PT_ACR10, "acr10" },
2041 { PT_ACR11, "acr11" },
2042 { PT_ACR12, "acr12" },
2043 { PT_ACR13, "acr13" },
2044 { PT_ACR14, "acr14" },
2045 { PT_ACR15, "acr15" },
2046 { PT_ORIGGPR2, "orig_gpr2" },
2047 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002048#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002049 { PT_FPR0_HI, "fpr0.hi" },
2050 { PT_FPR0_LO, "fpr0.lo" },
2051 { PT_FPR1_HI, "fpr1.hi" },
2052 { PT_FPR1_LO, "fpr1.lo" },
2053 { PT_FPR2_HI, "fpr2.hi" },
2054 { PT_FPR2_LO, "fpr2.lo" },
2055 { PT_FPR3_HI, "fpr3.hi" },
2056 { PT_FPR3_LO, "fpr3.lo" },
2057 { PT_FPR4_HI, "fpr4.hi" },
2058 { PT_FPR4_LO, "fpr4.lo" },
2059 { PT_FPR5_HI, "fpr5.hi" },
2060 { PT_FPR5_LO, "fpr5.lo" },
2061 { PT_FPR6_HI, "fpr6.hi" },
2062 { PT_FPR6_LO, "fpr6.lo" },
2063 { PT_FPR7_HI, "fpr7.hi" },
2064 { PT_FPR7_LO, "fpr7.lo" },
2065 { PT_FPR8_HI, "fpr8.hi" },
2066 { PT_FPR8_LO, "fpr8.lo" },
2067 { PT_FPR9_HI, "fpr9.hi" },
2068 { PT_FPR9_LO, "fpr9.lo" },
2069 { PT_FPR10_HI, "fpr10.hi" },
2070 { PT_FPR10_LO, "fpr10.lo" },
2071 { PT_FPR11_HI, "fpr11.hi" },
2072 { PT_FPR11_LO, "fpr11.lo" },
2073 { PT_FPR12_HI, "fpr12.hi" },
2074 { PT_FPR12_LO, "fpr12.lo" },
2075 { PT_FPR13_HI, "fpr13.hi" },
2076 { PT_FPR13_LO, "fpr13.lo" },
2077 { PT_FPR14_HI, "fpr14.hi" },
2078 { PT_FPR14_LO, "fpr14.lo" },
2079 { PT_FPR15_HI, "fpr15.hi" },
2080 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002081#endif
2082#if defined(S390X)
2083 { PT_FPR0, "fpr0" },
2084 { PT_FPR1, "fpr1" },
2085 { PT_FPR2, "fpr2" },
2086 { PT_FPR3, "fpr3" },
2087 { PT_FPR4, "fpr4" },
2088 { PT_FPR5, "fpr5" },
2089 { PT_FPR6, "fpr6" },
2090 { PT_FPR7, "fpr7" },
2091 { PT_FPR8, "fpr8" },
2092 { PT_FPR9, "fpr9" },
2093 { PT_FPR10, "fpr10" },
2094 { PT_FPR11, "fpr11" },
2095 { PT_FPR12, "fpr12" },
2096 { PT_FPR13, "fpr13" },
2097 { PT_FPR14, "fpr14" },
2098 { PT_FPR15, "fpr15" },
2099#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002100 { PT_CR_9, "cr9" },
2101 { PT_CR_10, "cr10" },
2102 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002103 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002104#endif
2105#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002106 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002107#elif defined(HPPA)
2108 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002109#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002110#ifndef PT_ORIG_R3
2111#define PT_ORIG_R3 34
2112#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002113 { 4*PT_R0, "4*PT_R0" },
2114 { 4*PT_R1, "4*PT_R1" },
2115 { 4*PT_R2, "4*PT_R2" },
2116 { 4*PT_R3, "4*PT_R3" },
2117 { 4*PT_R4, "4*PT_R4" },
2118 { 4*PT_R5, "4*PT_R5" },
2119 { 4*PT_R6, "4*PT_R6" },
2120 { 4*PT_R7, "4*PT_R7" },
2121 { 4*PT_R8, "4*PT_R8" },
2122 { 4*PT_R9, "4*PT_R9" },
2123 { 4*PT_R10, "4*PT_R10" },
2124 { 4*PT_R11, "4*PT_R11" },
2125 { 4*PT_R12, "4*PT_R12" },
2126 { 4*PT_R13, "4*PT_R13" },
2127 { 4*PT_R14, "4*PT_R14" },
2128 { 4*PT_R15, "4*PT_R15" },
2129 { 4*PT_R16, "4*PT_R16" },
2130 { 4*PT_R17, "4*PT_R17" },
2131 { 4*PT_R18, "4*PT_R18" },
2132 { 4*PT_R19, "4*PT_R19" },
2133 { 4*PT_R20, "4*PT_R20" },
2134 { 4*PT_R21, "4*PT_R21" },
2135 { 4*PT_R22, "4*PT_R22" },
2136 { 4*PT_R23, "4*PT_R23" },
2137 { 4*PT_R24, "4*PT_R24" },
2138 { 4*PT_R25, "4*PT_R25" },
2139 { 4*PT_R26, "4*PT_R26" },
2140 { 4*PT_R27, "4*PT_R27" },
2141 { 4*PT_R28, "4*PT_R28" },
2142 { 4*PT_R29, "4*PT_R29" },
2143 { 4*PT_R30, "4*PT_R30" },
2144 { 4*PT_R31, "4*PT_R31" },
2145 { 4*PT_NIP, "4*PT_NIP" },
2146 { 4*PT_MSR, "4*PT_MSR" },
2147 { 4*PT_ORIG_R3, "4*PT_ORIG_R3" },
2148 { 4*PT_CTR, "4*PT_CTR" },
2149 { 4*PT_LNK, "4*PT_LNK" },
2150 { 4*PT_XER, "4*PT_XER" },
2151 { 4*PT_CCR, "4*PT_CCR" },
2152 { 4*PT_FPR0, "4*PT_FPR0" },
Roland McGrath5a223472002-12-15 23:58:26 +00002153#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002154#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002155 { 0, "r0" },
2156 { 1, "r1" },
2157 { 2, "r2" },
2158 { 3, "r3" },
2159 { 4, "r4" },
2160 { 5, "r5" },
2161 { 6, "r6" },
2162 { 7, "r7" },
2163 { 8, "r8" },
2164 { 9, "r9" },
2165 { 10, "r10" },
2166 { 11, "r11" },
2167 { 12, "r12" },
2168 { 13, "r13" },
2169 { 14, "r14" },
2170 { 15, "r15" },
2171 { 16, "r16" },
2172 { 17, "r17" },
2173 { 18, "r18" },
2174 { 19, "r19" },
2175 { 20, "r20" },
2176 { 21, "r21" },
2177 { 22, "r22" },
2178 { 23, "r23" },
2179 { 24, "r24" },
2180 { 25, "r25" },
2181 { 26, "r26" },
2182 { 27, "r27" },
2183 { 28, "r28" },
2184 { 29, "gp" },
2185 { 30, "fp" },
2186 { 31, "zero" },
2187 { 32, "fp0" },
2188 { 33, "fp" },
2189 { 34, "fp2" },
2190 { 35, "fp3" },
2191 { 36, "fp4" },
2192 { 37, "fp5" },
2193 { 38, "fp6" },
2194 { 39, "fp7" },
2195 { 40, "fp8" },
2196 { 41, "fp9" },
2197 { 42, "fp10" },
2198 { 43, "fp11" },
2199 { 44, "fp12" },
2200 { 45, "fp13" },
2201 { 46, "fp14" },
2202 { 47, "fp15" },
2203 { 48, "fp16" },
2204 { 49, "fp17" },
2205 { 50, "fp18" },
2206 { 51, "fp19" },
2207 { 52, "fp20" },
2208 { 53, "fp21" },
2209 { 54, "fp22" },
2210 { 55, "fp23" },
2211 { 56, "fp24" },
2212 { 57, "fp25" },
2213 { 58, "fp26" },
2214 { 59, "fp27" },
2215 { 60, "fp28" },
2216 { 61, "fp29" },
2217 { 62, "fp30" },
2218 { 63, "fp31" },
2219 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002220#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002221#ifdef IA64
2222 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2223 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2224 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2225 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2226 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2227 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2228 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2229 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2230 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2231 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2232 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2233 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2234 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2235 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2236 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2237 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2238 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2239 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2240 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2241 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2242 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2243 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2244 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2245 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2246 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2247 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2248 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2249 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2250 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2251 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2252 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2253 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2254 /* switch stack: */
2255 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2256 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2257 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2258 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2259 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2260 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2261 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2262 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2263 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2264 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002265 { PT_B0, "kb0" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002266 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2267 { PT_B4, "b4" }, { PT_B5, "b5" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002268 { PT_AR_PFS, "kar.pfs" },
2269 { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" },
2270 { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" },
2271 { PT_PR, "k.pr" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002272 /* pt_regs */
2273 { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002274 /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002275 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2276 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2277 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2278 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2279 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2280 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2281 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2282 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2283 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2284 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2285 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2286 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2287 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2288 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2289 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2290#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002291#ifdef I386
2292 { 4*EBX, "4*EBX" },
2293 { 4*ECX, "4*ECX" },
2294 { 4*EDX, "4*EDX" },
2295 { 4*ESI, "4*ESI" },
2296 { 4*EDI, "4*EDI" },
2297 { 4*EBP, "4*EBP" },
2298 { 4*EAX, "4*EAX" },
2299 { 4*DS, "4*DS" },
2300 { 4*ES, "4*ES" },
2301 { 4*FS, "4*FS" },
2302 { 4*GS, "4*GS" },
2303 { 4*ORIG_EAX, "4*ORIG_EAX" },
2304 { 4*EIP, "4*EIP" },
2305 { 4*CS, "4*CS" },
2306 { 4*EFL, "4*EFL" },
2307 { 4*UESP, "4*UESP" },
2308 { 4*SS, "4*SS" },
2309#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002310#ifdef X86_64
2311 { 8*RDI, "8*RDI" },
2312 { 8*RSI, "8*RSI" },
2313 { 8*RDX, "8*RDX" },
2314 { 8*R10, "8*R10" },
2315 { 8*R8, "8*R8" },
2316 { 8*R9, "8*R9" },
2317 { 8*RBX, "8*RBX" },
2318 { 8*RCX, "8*RCX" },
2319 { 8*RBP, "8*RBP" },
2320 { 8*RAX, "8*RAX" },
2321#if 0
2322 { 8*DS, "8*DS" },
2323 { 8*ES, "8*ES" },
2324 { 8*FS, "8*FS" },
2325 { 8*GS, "8*GS" },
2326#endif
2327 { 8*ORIG_RAX, "8*ORIG_EAX" },
2328 { 8*RIP, "8*RIP" },
2329 { 8*CS, "8*CS" },
2330 { 8*EFLAGS, "8*EFL" },
2331 { 8*RSP, "8*RSP" },
2332 { 8*SS, "8*SS" },
2333 { 8*R11, "8*R11" },
2334 { 8*R12, "8*R12" },
2335 { 8*R13, "8*R13" },
2336 { 8*R14, "8*R14" },
2337 { 8*R15, "8*R15" },
2338#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002339#ifdef M68K
2340 { 4*PT_D1, "4*PT_D1" },
2341 { 4*PT_D2, "4*PT_D2" },
2342 { 4*PT_D3, "4*PT_D3" },
2343 { 4*PT_D4, "4*PT_D4" },
2344 { 4*PT_D5, "4*PT_D5" },
2345 { 4*PT_D6, "4*PT_D6" },
2346 { 4*PT_D7, "4*PT_D7" },
2347 { 4*PT_A0, "4*PT_A0" },
2348 { 4*PT_A1, "4*PT_A1" },
2349 { 4*PT_A2, "4*PT_A2" },
2350 { 4*PT_A3, "4*PT_A3" },
2351 { 4*PT_A4, "4*PT_A4" },
2352 { 4*PT_A5, "4*PT_A5" },
2353 { 4*PT_A6, "4*PT_A6" },
2354 { 4*PT_D0, "4*PT_D0" },
2355 { 4*PT_USP, "4*PT_USP" },
2356 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2357 { 4*PT_SR, "4*PT_SR" },
2358 { 4*PT_PC, "4*PT_PC" },
2359#endif /* M68K */
2360#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002361#ifdef SH
2362 { 4*REG_REG0, "4*REG_REG0" },
2363 { 4*(REG_REG0+1), "4*REG_REG1" },
2364 { 4*(REG_REG0+2), "4*REG_REG2" },
2365 { 4*(REG_REG0+3), "4*REG_REG3" },
2366 { 4*(REG_REG0+4), "4*REG_REG4" },
2367 { 4*(REG_REG0+5), "4*REG_REG5" },
2368 { 4*(REG_REG0+6), "4*REG_REG6" },
2369 { 4*(REG_REG0+7), "4*REG_REG7" },
2370 { 4*(REG_REG0+8), "4*REG_REG8" },
2371 { 4*(REG_REG0+9), "4*REG_REG9" },
2372 { 4*(REG_REG0+10), "4*REG_REG10" },
2373 { 4*(REG_REG0+11), "4*REG_REG11" },
2374 { 4*(REG_REG0+12), "4*REG_REG12" },
2375 { 4*(REG_REG0+13), "4*REG_REG13" },
2376 { 4*(REG_REG0+14), "4*REG_REG14" },
2377 { 4*REG_REG15, "4*REG_REG15" },
2378 { 4*REG_PC, "4*REG_PC" },
2379 { 4*REG_PR, "4*REG_PR" },
2380 { 4*REG_SR, "4*REG_SR" },
2381 { 4*REG_GBR, "4*REG_GBR" },
2382 { 4*REG_MACH, "4*REG_MACH" },
2383 { 4*REG_MACL, "4*REG_MACL" },
2384 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2385 { 4*REG_FPUL, "4*REG_FPUL" },
2386 { 4*REG_FPREG0, "4*REG_FPREG0" },
2387 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2388 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2389 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2390 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2391 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2392 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2393 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2394 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2395 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2396 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2397 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2398 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2399 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2400 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2401 { 4*REG_FPREG15, "4*REG_FPREG15" },
2402 { 4*REG_XDREG0, "4*REG_XDREG0" },
2403 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2404 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2405 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2406 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2407 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2408 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2409 { 4*REG_XDREG14, "4*REG_XDREG14" },
2410 { 4*REG_FPSCR, "4*REG_FPSCR" },
2411#endif /* SH */
2412
Michal Ludvig10a88d02002-10-07 14:31:00 +00002413#if !defined(S390) && !defined(S390X) && !defined(MIPS)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002414 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002415#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002416#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002417 { uoff(i387), "offsetof(struct user, i387)" },
2418#else /* !I386 */
2419#ifdef M68K
2420 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2421#endif /* M68K */
2422#endif /* !I386 */
2423 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2424 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2425 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2426 { uoff(start_code), "offsetof(struct user, start_code)" },
2427 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2428 { uoff(signal), "offsetof(struct user, signal)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002429#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002430 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002431#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002432 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002433#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002434 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2435#endif
2436 { uoff(magic), "offsetof(struct user, magic)" },
2437 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002438#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002439 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2440#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002441#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002442#endif /* !ALPHA */
2443#endif /* !POWERPC/!SPARC */
2444#endif /* LINUX */
2445#ifdef SUNOS4
2446 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2447 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2448 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2449 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2450 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2451 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2452 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2453 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2454 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2455 { uoff(u_error), "offsetof(struct user, u_error)" },
2456 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2457 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2458 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2459 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2460 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2461 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2462 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2463 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2464 { uoff(u_code), "offsetof(struct user, u_code)" },
2465 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2466 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2467 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2468 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2469 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2470 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2471 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2472 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2473 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2474 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2475 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2476 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2477 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2478 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2479 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2480 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2481 { uoff(u_start), "offsetof(struct user, u_start)" },
2482 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2483 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2484 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2485 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2486 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2487 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2488 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2489 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2490 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2491#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002492#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002493 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002494#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002495 { 0, NULL },
2496};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002497#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002498
2499int
2500sys_ptrace(tcp)
2501struct tcb *tcp;
2502{
2503 char *cmd;
2504 struct xlat *x;
2505 long addr;
2506
2507 cmd = xlookup(ptrace_cmds, tcp->u_arg[0]);
2508 if (!cmd)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002509#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002510 cmd = "PTRACE_???";
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002511#else
2512 cmd = "PT_???";
Roland McGrath5a223472002-12-15 23:58:26 +00002513#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002514 if (entering(tcp)) {
2515 tprintf("%s, %lu, ", cmd, tcp->u_arg[1]);
2516 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002517#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002518 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2519 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2520 for (x = struct_user_offsets; x->str; x++) {
2521 if (x->val >= addr)
2522 break;
2523 }
2524 if (!x->str)
2525 tprintf("%#lx, ", addr);
2526 else if (x->val > addr && x != struct_user_offsets) {
2527 x--;
2528 tprintf("%s + %ld, ", x->str, addr - x->val);
2529 }
2530 else
2531 tprintf("%s, ", x->str);
2532 }
2533 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002534#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002535 tprintf("%#lx, ", tcp->u_arg[2]);
2536#ifdef LINUX
2537 switch (tcp->u_arg[0]) {
2538 case PTRACE_PEEKDATA:
2539 case PTRACE_PEEKTEXT:
2540 case PTRACE_PEEKUSER:
2541 break;
2542 case PTRACE_CONT:
2543 case PTRACE_SINGLESTEP:
2544 case PTRACE_SYSCALL:
2545 case PTRACE_DETACH:
2546 printsignal(tcp->u_arg[3]);
2547 break;
2548 default:
2549 tprintf("%#lx", tcp->u_arg[3]);
2550 break;
2551 }
2552 } else {
2553 switch (tcp->u_arg[0]) {
2554 case PTRACE_PEEKDATA:
2555 case PTRACE_PEEKTEXT:
2556 case PTRACE_PEEKUSER:
2557 printnum(tcp, tcp->u_arg[3], "%#x");
2558 break;
2559 }
2560 }
2561#endif /* LINUX */
2562#ifdef SUNOS4
2563 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2564 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2565 tprintf("%lu, ", tcp->u_arg[3]);
2566 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2567 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2568 tcp->u_arg[0] != PTRACE_READTEXT) {
2569 tprintf("%#lx", tcp->u_arg[3]);
2570 }
2571 } else {
2572 if (tcp->u_arg[0] == PTRACE_READDATA ||
2573 tcp->u_arg[0] == PTRACE_READTEXT) {
2574 tprintf("%lu, ", tcp->u_arg[3]);
2575 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2576 }
2577 }
2578#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002579#ifdef FREEBSD
2580 tprintf("%lu", tcp->u_arg[3]);
2581 }
2582#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002583 return 0;
2584}
2585
2586#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002587
2588#ifdef LINUX
2589static struct xlat futexops[] = {
2590 { FUTEX_WAIT, "FUTEX_WAIT" },
2591 { FUTEX_WAKE, "FUTEX_WAKE" },
2592 { FUTEX_FD, "FUTEX_FD" },
2593 { 0, NULL }
2594};
2595
2596int
2597sys_futex(tcp)
2598struct tcb *tcp;
2599{
2600 if (entering(tcp)) {
2601 tprintf("%p, ", (void *) tcp->u_arg[0]);
2602 printflags(futexops, tcp->u_arg[1]);
2603 tprintf(", %ld, ", tcp->u_arg[2]);
2604 printtv(tcp, tcp->u_arg[3]);
2605 }
2606 return 0;
2607}
2608
2609static void
2610print_affinitylist(list, len)
2611unsigned long *list;
2612unsigned int len;
2613{
2614 int first = 1;
2615 tprintf(" {");
2616 while (len > sizeof (unsigned long)) {
2617 tprintf("%s %lx", first ? "" : ",", *list++);
2618 first = 0;
2619 len -= sizeof (unsigned long);
2620 }
2621 tprintf(" }");
2622}
2623
2624int
2625sys_sched_setaffinity(tcp)
2626struct tcb *tcp;
2627{
2628 if (entering(tcp)) {
2629 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2630 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2631 }
2632 return 0;
2633}
2634
2635int
2636sys_sched_getaffinity(tcp)
2637struct tcb *tcp;
2638{
2639 if (entering(tcp)) {
2640 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2641 } else {
2642 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);
2643 }
2644 return 0;
2645}
2646#endif