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