blob: c66e7c2ff2950f5c6d39b2aa312f59f9b6133ea9 [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
Roland McGrathbf621d42003-01-14 09:46:21 +000073#ifdef HAVE_LINUX_PTRACE_H
74#undef PTRACE_SYSCALL
75#include <linux/ptrace.h>
76#endif
77
Wichert Akkerman36915a11999-07-13 15:45:02 +000078#ifdef HAVE_SYS_REG_H
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000079# include <sys/reg.h>
Wichert Akkerman15dea971999-10-06 13:06:34 +000080#ifndef PTRACE_PEEKUSR
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000081# define PTRACE_PEEKUSR PTRACE_PEEKUSER
Wichert Akkerman15dea971999-10-06 13:06:34 +000082#endif
83#ifndef PTRACE_POKEUSR
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000084# define PTRACE_POKEUSR PTRACE_POKEUSER
85#endif
Wichert Akkerman15dea971999-10-06 13:06:34 +000086#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000087
Roland McGrath5a223472002-12-15 23:58:26 +000088#ifdef HAVE_LINUX_FUTEX_H
89#include <linux/futex.h>
90#endif
91#if defined LINUX
92# ifndef FUTEX_WAIT
93# define FUTEX_WAIT 0
94# endif
95# ifndef FUTEX_WAKE
96# define FUTEX_WAKE 1
97# endif
98# ifndef FUTEX_FD
99# define FUTEX_FD 2
100# endif
101#endif
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000102
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000103#ifdef LINUX
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000104#include <asm/posix_types.h>
105#undef GETGROUPS_T
106#define GETGROUPS_T __kernel_gid_t
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000107#endif /* LINUX */
108
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000109#if defined(LINUX) && defined(IA64)
110# include <asm/ptrace_offsets.h>
111# include <asm/rse.h>
112#endif
113
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000114#ifdef HAVE_PRCTL
115#include <sys/prctl.h>
116#endif
117
118#ifndef WCOREDUMP
119#define WCOREDUMP(status) ((status) & 0200)
120#endif
121
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000122/* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000123#if defined(HAVE_PRCTL)
124static struct xlat prctl_options[] = {
125#ifdef PR_MAXPROCS
126 { PR_MAXPROCS, "PR_MAXPROCS" },
127#endif
128#ifdef PR_ISBLOCKED
129 { PR_ISBLOCKED, "PR_ISBLOCKED" },
130#endif
131#ifdef PR_SETSTACKSIZE
132 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
133#endif
134#ifdef PR_GETSTACKSIZE
135 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
136#endif
137#ifdef PR_MAXPPROCS
138 { PR_MAXPPROCS, "PR_MAXPPROCS" },
139#endif
140#ifdef PR_UNBLKONEXEC
141 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
142#endif
143#ifdef PR_ATOMICSIM
144 { PR_ATOMICSIM, "PR_ATOMICSIM" },
145#endif
146#ifdef PR_SETEXITSIG
147 { PR_SETEXITSIG, "PR_SETEXITSIG" },
148#endif
149#ifdef PR_RESIDENT
150 { PR_RESIDENT, "PR_RESIDENT" },
151#endif
152#ifdef PR_ATTACHADDR
153 { PR_ATTACHADDR, "PR_ATTACHADDR" },
154#endif
155#ifdef PR_DETACHADDR
156 { PR_DETACHADDR, "PR_DETACHADDR" },
157#endif
158#ifdef PR_TERMCHILD
159 { PR_TERMCHILD, "PR_TERMCHILD" },
160#endif
161#ifdef PR_GETSHMASK
162 { PR_GETSHMASK, "PR_GETSHMASK" },
163#endif
164#ifdef PR_GETNSHARE
165 { PR_GETNSHARE, "PR_GETNSHARE" },
166#endif
167#if defined(PR_SET_PDEATHSIG)
168 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
169#endif
Wichert Akkerman8829a551999-06-11 13:18:40 +0000170#ifdef PR_COREPID
171 { PR_COREPID, "PR_COREPID" },
172#endif
173#ifdef PR_ATTACHADDRPERM
174 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
175#endif
176#ifdef PR_PTHREADEXIT
177 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
178#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000179#ifdef PR_SET_PDEATHSIG
180 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
181#endif
182#ifdef PR_GET_PDEATHSIG
183 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
184#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000185#ifdef PR_GET_UNALIGN
186 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
187#endif
188#ifdef PR_SET_UNALIGN
189 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
190#endif
191#ifdef PR_GET_KEEPCAPS
192 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" },
193#endif
194#ifdef PR_SET_KEEPCAPS
195 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" },
196#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000197 { 0, NULL },
198};
199
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000200
201const char *
202unalignctl_string (unsigned int ctl)
203{
204 static char buf[16];
205
206 switch (ctl) {
207#ifdef PR_UNALIGN_NOPRINT
208 case PR_UNALIGN_NOPRINT:
209 return "NOPRINT";
210#endif
211#ifdef PR_UNALIGN_SIGBUS
212 case PR_UNALIGN_SIGBUS:
213 return "SIGBUS";
214#endif
215 default:
216 break;
217 }
218 sprintf(buf, "%x", ctl);
219 return buf;
220}
221
222
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000223int
224sys_prctl(tcp)
225struct tcb *tcp;
226{
227 int i;
228
229 if (entering(tcp)) {
230 printxval(prctl_options, tcp->u_arg[0], "PR_???");
231 switch (tcp->u_arg[0]) {
232#ifdef PR_GETNSHARE
233 case PR_GETNSHARE:
234 break;
235#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000236#ifdef PR_SET_DEATHSIG
237 case PR_GET_PDEATHSIG:
238 break;
239#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000240#ifdef PR_SET_UNALIGN
241 case PR_SET_UNALIGN:
242 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
243 break;
244#endif
245#ifdef PR_GET_UNALIGN
246 case PR_GET_UNALIGN:
247 tprintf(", %#lx", tcp->u_arg[1]);
248 break;
249#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000250 default:
251 for (i = 1; i < tcp->u_nargs; i++)
252 tprintf(", %#lx", tcp->u_arg[i]);
253 break;
254 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000255 } else {
256 switch (tcp->u_arg[0]) {
257#ifdef PR_GET_PDEATHSIG
258 case PR_GET_PDEATHSIG:
259 for (i=1; i<tcp->u_nargs; i++)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000260 tprintf(", %#lx", tcp->u_arg[i]);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000261 break;
262#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000263#ifdef PR_SET_UNALIGN
264 case PR_SET_UNALIGN:
265 break;
266#endif
267#ifdef PR_GET_UNALIGN
268 case PR_GET_UNALIGN:
269 {
270 int ctl;
271
272 umove(tcp, tcp->u_arg[1], &ctl);
273 tcp->auxstr = unalignctl_string(ctl);
274 return RVAL_STR;
275 }
276#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000277 default:
278 break;
279 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000280 }
281 return 0;
282}
283
284#endif /* HAVE_PRCTL */
285
286int
287sys_gethostid(tcp)
288struct tcb *tcp;
289{
290 if (exiting(tcp))
291 return RVAL_HEX;
292 return 0;
293}
294
295int
296sys_sethostname(tcp)
297struct tcb *tcp;
298{
299 if (entering(tcp)) {
300 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
301 tprintf(", %lu", tcp->u_arg[1]);
302 }
303 return 0;
304}
305
306int
307sys_gethostname(tcp)
308struct tcb *tcp;
309{
310 if (exiting(tcp)) {
311 if (syserror(tcp))
312 tprintf("%#lx", tcp->u_arg[0]);
313 else
314 printpath(tcp, tcp->u_arg[0]);
315 tprintf(", %lu", tcp->u_arg[1]);
316 }
317 return 0;
318}
319
320int
321sys_setdomainname(tcp)
322struct tcb *tcp;
323{
324 if (entering(tcp)) {
325 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
326 tprintf(", %lu", tcp->u_arg[1]);
327 }
328 return 0;
329}
330
Wichert Akkerman5daa0281999-03-15 19:49:42 +0000331#if !defined(LINUX)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000332
333int
334sys_getdomainname(tcp)
335struct tcb *tcp;
336{
337 if (exiting(tcp)) {
338 if (syserror(tcp))
339 tprintf("%#lx", tcp->u_arg[0]);
340 else
341 printpath(tcp, tcp->u_arg[0]);
342 tprintf(", %lu", tcp->u_arg[1]);
343 }
344 return 0;
345}
346#endif /* !LINUX */
347
348int
349sys_exit(tcp)
350struct tcb *tcp;
351{
352 if (exiting(tcp)) {
353 fprintf(stderr, "_exit returned!\n");
354 return -1;
355 }
356 /* special case: we stop tracing this process, finish line now */
357 tprintf("%ld) ", tcp->u_arg[0]);
358 tabto(acolumn);
359 tprintf("= ?");
360 printtrailer(tcp);
361 return 0;
362}
363
364int
365internal_exit(tcp)
366struct tcb *tcp;
367{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000368 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000369 tcp->flags |= TCB_EXITING;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000370#ifdef __NR_exit_group
371 if (tcp->scno == __NR_exit_group)
372 tcp->flags |= TCB_GROUP_EXITING;
373#endif
374 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000375 return 0;
376}
377
Roland McGrathee9d4352002-12-18 04:16:10 +0000378/* TCP is creating a child we want to follow.
379 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
380 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
381static int
382fork_tcb(struct tcb *tcp)
383{
384 if (nprocs == tcbtabsize) {
385 /* Allocate some more TCBs and expand the table.
386 We don't want to relocate the TCBs because our
387 callers have pointers and it would be a pain.
388 So tcbtab is a table of pointers. Since we never
389 free the TCBs, we allocate a single chunk of many. */
390 struct tcb **newtab = (struct tcb **)
391 realloc(tcbtab, 2 * tcbtabsize * sizeof tcbtab[0]);
392 struct tcb *newtcbs = (struct tcb *) calloc(tcbtabsize,
393 sizeof *newtcbs);
394 int i;
395 if (newtab == NULL || newtcbs == NULL) {
396 if (newtab != NULL)
397 free(newtab);
398 tcp->flags &= ~TCB_FOLLOWFORK;
399 fprintf(stderr, "sys_fork: tcb table full\n");
400 return 1;
401 }
402 for (i = tcbtabsize; i < 2 * tcbtabsize; ++i)
403 newtab[i] = &newtcbs[i - tcbtabsize];
404 tcbtabsize *= 2;
405 tcbtab = newtab;
406 }
407
408 tcp->flags |= TCB_FOLLOWFORK;
409 return 0;
410}
411
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000412#ifdef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000413
414int
415sys_fork(tcp)
416struct tcb *tcp;
417{
418 if (exiting(tcp)) {
419 if (getrval2(tcp)) {
420 tcp->auxstr = "child process";
421 return RVAL_UDECIMAL | RVAL_STR;
422 }
423 }
424 return 0;
425}
426
John Hughes4e36a812001-04-18 15:11:51 +0000427#if UNIXWARE > 2
428
429int
430sys_rfork(tcp)
431struct tcb *tcp;
432{
433 if (entering(tcp)) {
434 tprintf ("%ld", tcp->u_arg[0]);
435 }
436 else {
437 if (getrval2(tcp)) {
438 tcp->auxstr = "child process";
439 return RVAL_UDECIMAL | RVAL_STR;
440 }
441 }
442 return 0;
443}
444
445#endif
446
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000447int
448internal_fork(tcp)
449struct tcb *tcp;
450{
451 struct tcb *tcpchild;
452
453 if (exiting(tcp)) {
454 if (getrval2(tcp))
455 return 0;
456 if (!followfork)
457 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000458 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000459 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000460 if (syserror(tcp))
461 return 0;
462 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
463 fprintf(stderr, "sys_fork: tcb table full\n");
464 return 0;
465 }
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000466 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000467 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000468 }
469 return 0;
470}
471
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000472#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000473
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000474#ifdef LINUX
475
476/* defines copied from linux/sched.h since we can't include that
477 * ourselves (it conflicts with *lots* of libc includes)
478 */
479#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
480#define CLONE_VM 0x00000100 /* set if VM shared between processes */
481#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
482#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
483#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000484#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000485#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
486#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
487#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000488#define CLONE_THREAD 0x00010000 /* Same thread group? */
489#define CLONE_NEWNS 0x00020000 /* New namespace group? */
490#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
491#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
492#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
493#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
494#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
495#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
496#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000497
498static struct xlat clone_flags[] = {
499 { CLONE_VM, "CLONE_VM" },
500 { CLONE_FS, "CLONE_FS" },
501 { CLONE_FILES, "CLONE_FILES" },
502 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000503 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000504 { CLONE_PTRACE, "CLONE_PTRACE" },
505 { CLONE_VFORK, "CLONE_VFORK" },
506 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000507 { CLONE_THREAD, "CLONE_THREAD" },
508 { CLONE_NEWNS, "CLONE_NEWNS" },
509 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
510 { CLONE_SETTLS, "CLONE_SETTLS" },
511 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
512 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
513 { CLONE_DETACHED, "CLONE_DETACHED" },
514 { CLONE_UNTRACED, "CLONE_UNTRACED" },
515 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000516 { 0, NULL },
517};
518
Roland McGrath909875b2002-12-22 03:34:36 +0000519# ifdef I386
520# include <asm/ldt.h>
521extern void print_ldt_entry();
522# endif
523
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000524int
525sys_clone(tcp)
526struct tcb *tcp;
527{
528 if (exiting(tcp)) {
529 tprintf("child_stack=%#lx, flags=", tcp->u_arg[1]);
530 if (printflags(clone_flags, tcp->u_arg[0]) == 0)
531 tprintf("0");
Roland McGrath909875b2002-12-22 03:34:36 +0000532 if ((tcp->u_arg[0] & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
533 |CLONE_SETTLS)) == 0)
534 return 0;
535 if (tcp->u_arg[0] & CLONE_PARENT_SETTID) {
536 int pid;
537 if (umove(tcp, tcp->u_arg[2], &pid) == 0)
538 tprintf(", [%d]", pid);
539 else
540 tprintf(", %#lx", tcp->u_arg[2]);
541 }
542 else
543 tprintf(", <ignored>");
544#ifdef I386
545 if (tcp->u_arg[0] & CLONE_SETTLS) {
546 struct modify_ldt_ldt_s copy;
547 if (umove(tcp, tcp->u_arg[3], &copy) != -1) {
548 tprintf(", {entry_number:%d, ",
549 copy.entry_number);
550 if (!verbose(tcp))
551 tprintf("...}");
552 else
553 print_ldt_entry(&copy);
554 }
555 else
556 tprintf(", %#lx", tcp->u_arg[3]);
557 }
558 else
559 tprintf(", <ignored>");
560# define TIDARG 4
561#else
562# define TIDARG 3
563#endif
564 if (tcp->u_arg[0] & CLONE_CHILD_SETTID)
565 tprintf(", %#lx", tcp->u_arg[TIDARG]);
566#undef TIDARG
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000567 }
568 return 0;
569}
570
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000571int
572sys_clone2(tcp)
573struct tcb *tcp;
574{
575 if (exiting(tcp)) {
576 tprintf("child_stack=%#lx, stack_size=%#lx, flags=",
577 tcp->u_arg[1], tcp->u_arg[2]);
578 if (printflags(clone_flags, tcp->u_arg[0]) == 0)
579 tprintf("0");
580 }
581 return 0;
582}
583
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000584#endif
585
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000586int
587sys_fork(tcp)
588struct tcb *tcp;
589{
590 if (exiting(tcp))
591 return RVAL_UDECIMAL;
592 return 0;
593}
594
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000595int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000596change_syscall(tcp, new)
597struct tcb *tcp;
598int new;
599{
600#if defined(LINUX)
601#if defined(I386)
602 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000603 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000604 return -1;
605 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000606#elif defined(X86_64)
607 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000608 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000609 return -1;
610 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000611#elif defined(POWERPC)
Wichert Akkerman5c4c69b2001-04-12 09:00:47 +0000612 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000613 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000614 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000615#elif defined(S390) || defined(S390X)
616 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
617 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
618 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000619 return 0;
620#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000621 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000622 return -1;
623 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000624#elif defined(SPARC)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000625 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000626 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
627 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000628 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000629 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
630 return -1;
631 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000632#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000633 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000634 return -1;
635 return 0;
636#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000637 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000638 return -1;
639 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000640#elif defined(IA64)
641 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
642 return -1;
643 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000644#elif defined(HPPA)
645 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
646 return -1;
647 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000648#elif defined(SH)
649 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), new)<0)
650 return -1;
651 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000652#else
653#warning Do not know how to handle change_syscall for this architecture
654#endif /* architecture */
655#endif /* LINUX */
656 return -1;
657}
658
659int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000660setarg(tcp, argnum)
661 struct tcb *tcp;
662 int argnum;
663{
664#if defined (IA64)
665 {
666 unsigned long *bsp, *ap;
667
668 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
669 return -1;
670
671 ap = ia64_rse_skip_regs(bsp, argnum);
672 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000673 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000674 if (errno)
675 return -1;
676
677 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000678#elif defined(I386)
679 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000680 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000681 if (errno)
682 return -1;
683 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000684#elif defined(X86_64)
685 {
686 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
687 if (errno)
688 return -1;
689 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000690#elif defined(POWERPC)
691#ifndef PT_ORIG_R3
692#define PT_ORIG_R3 34
693#endif
694 {
695 ptrace(PTRACE_POKEUSER, tcp->pid,
696 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*4),
697 tcp->u_arg[argnum]);
698 if (errno)
699 return -1;
700 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000701#elif defined(MIPS)
702 {
703 errno = 0;
704 if (argnum < 4)
705 ptrace(PTRACE_POKEUSER, tcp->pid,
706 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
707 else {
708 unsigned long *sp;
709
710 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
711 return -1;
712
713 ptrace(PTRACE_POKEDATA, tcp->pid,
714 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
715 }
716 if (errno)
717 return -1;
718 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000719#elif defined(S390) || defined(S390X)
720 {
721 if(argnum <= 5)
722 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000723 (char *) (argnum==0 ? PT_ORIGGPR2 :
724 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000725 tcp->u_arg[argnum]);
726 else
727 return -E2BIG;
728 if (errno)
729 return -1;
730 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000731#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000732# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000733#endif
734 return 0;
735}
736
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000737#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000738int
739internal_clone(tcp)
740struct tcb *tcp;
741{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000742 struct tcb *tcpchild;
743 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000744 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000745 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000746 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000747 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000748 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000749 if (setbpt(tcp) < 0)
750 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000751 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000752 int bpt = tcp->flags & TCB_BPTSET;
753
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000754 if (!(tcp->flags & TCB_FOLLOWFORK))
755 return 0;
756
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000757 if (syserror(tcp)) {
758 if (bpt)
759 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000760 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000761 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000762
763 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000764
765#ifdef CLONE_PTRACE /* See new setbpt code. */
766 tcpchild = pid2tcb(pid);
767 if (tcpchild != NULL) {
768 /* The child already reported its startup trap
769 before the parent reported its syscall return. */
770 if ((tcpchild->flags
771 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
772 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
773 fprintf(stderr, "\
774[preattached child %d of %d in weird state!]\n",
775 pid, tcp->pid);
776 }
777 else
778#endif
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000779 if ((tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000780 if (bpt)
781 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000782 fprintf(stderr, " [tcb table full]\n");
783 kill(pid, SIGKILL); /* XXX */
784 return 0;
785 }
786
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000787#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000788 /* Attach to the new child */
789 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000790 if (bpt)
791 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000792 perror("PTRACE_ATTACH");
793 fprintf(stderr, "Too late?\n");
794 droptcb(tcpchild);
795 return 0;
796 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000797#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000798
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000799 if (bpt)
800 clearbpt(tcp);
801
Ulrich Drepper90512f01999-12-24 07:22:25 +0000802 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000803 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000804 if (bpt) {
805 tcpchild->flags |= TCB_BPTSET;
806 tcpchild->baddr = tcp->baddr;
807 memcpy(tcpchild->inst, tcp->inst,
808 sizeof tcpchild->inst);
809 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000810 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000811 tcp->nchildren++;
812 if (tcpchild->flags & TCB_SUSPENDED) {
813 /* The child was born suspended, due to our having
814 forced CLONE_PTRACE. */
815 if (bpt)
816 clearbpt(tcpchild);
817
818 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
819 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
820 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
821 return -1;
822 }
823
824 if (!qflag)
825 fprintf(stderr, "\
826Process %u resumed (parent %d ready)\n",
827 pid, tcp->pid);
828 }
829 else {
830 newoutf(tcpchild);
831 if (!qflag)
832 fprintf(stderr, "Process %d attached\n", pid);
833 }
834
835#ifdef TCB_CLONE_THREAD
836 if ((tcp->flags & TCB_CLONE_THREAD) && tcp->parent != NULL) {
837 /* The parent in this clone is itself a thread
838 belonging to another process. There is no
839 meaning to the parentage relationship of the new
840 child with the thread, only with the process.
841 We associate the new thread with our parent.
842 Since this is done for every new thread, there
843 will never be a TCB_CLONE_THREAD process that
844 has children. */
845 --tcp->nchildren;
846 tcp->u_arg[0] = tcp->parent->u_arg[0];
847 tcp = tcp->parent;
848 tcpchild->parent = tcp;
849 ++tcp->nchildren;
850 }
851
852 if (tcp->u_arg[0] & CLONE_THREAD) {
853 tcpchild->flags |= TCB_CLONE_THREAD;
854 ++tcp->nclone_threads;
855 }
856 if (tcp->u_arg[0] & CLONE_DETACHED) {
857 tcpchild->flags |= TCB_CLONE_DETACHED;
858 ++tcp->nclone_detached;
859 }
860#endif
861
862 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000863 return 0;
864}
865#endif
866
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000867int
868internal_fork(tcp)
869struct tcb *tcp;
870{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000871#ifdef LINUX
872 /* We do special magic with clone for any clone or fork. */
873 return internal_clone(tcp);
874#else
875
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000876 struct tcb *tcpchild;
877 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000878 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000879
880#ifdef SYS_vfork
Nate Sammonsccd8f211999-03-29 22:57:54 +0000881 if (tcp->scno == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000882 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000883 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000884 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000885 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000886 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000887#endif
888 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000889 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000890 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000891 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000892 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000893 if (setbpt(tcp) < 0)
894 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000895 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000896 else {
897 int bpt = tcp->flags & TCB_BPTSET;
898
899 if (!(tcp->flags & TCB_FOLLOWFORK))
900 return 0;
901 if (bpt)
902 clearbpt(tcp);
903
904 if (syserror(tcp))
905 return 0;
906
907 pid = tcp->u_rval;
908 if ((tcpchild = alloctcb(pid)) == NULL) {
909 fprintf(stderr, " [tcb table full]\n");
910 kill(pid, SIGKILL); /* XXX */
911 return 0;
912 }
913#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000914#ifdef HPPA
915 /* The child must have run before it can be attached. */
916 /* This must be a bug in the parisc kernel, but I havn't
917 * identified it yet. Seems to be an issue associated
918 * with attaching to a process (which sends it a signal)
919 * before that process has ever been scheduled. When
920 * debugging, I started seeing crashes in
921 * arch/parisc/kernel/signal.c:do_signal(), apparently
922 * caused by r8 getting corrupt over the dequeue_signal()
923 * call. Didn't make much sense though...
924 */
925 {
926 struct timeval tv;
927 tv.tv_sec = 0;
928 tv.tv_usec = 10000;
929 select(0, NULL, NULL, NULL, &tv);
930 }
931#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000932 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
933 perror("PTRACE_ATTACH");
934 fprintf(stderr, "Too late?\n");
935 droptcb(tcpchild);
936 return 0;
937 }
938#endif /* LINUX */
939#ifdef SUNOS4
940#ifdef oldway
941 /* The child must have run before it can be attached. */
942 {
943 struct timeval tv;
944 tv.tv_sec = 0;
945 tv.tv_usec = 10000;
946 select(0, NULL, NULL, NULL, &tv);
947 }
948 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
949 perror("PTRACE_ATTACH");
950 fprintf(stderr, "Too late?\n");
951 droptcb(tcpchild);
952 return 0;
953 }
954#else /* !oldway */
955 /* Try to catch the new process as soon as possible. */
956 {
957 int i;
958 for (i = 0; i < 1024; i++)
959 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
960 break;
961 if (i == 1024) {
962 perror("PTRACE_ATTACH");
963 fprintf(stderr, "Too late?\n");
964 droptcb(tcpchild);
965 return 0;
966 }
967 }
968#endif /* !oldway */
969#endif /* SUNOS4 */
970 tcpchild->flags |= TCB_ATTACHED;
971 /* Child has BPT too, must be removed on first occasion */
972 if (bpt) {
973 tcpchild->flags |= TCB_BPTSET;
974 tcpchild->baddr = tcp->baddr;
975 memcpy(tcpchild->inst, tcp->inst,
976 sizeof tcpchild->inst);
977 }
978 newoutf(tcpchild);
979 tcpchild->parent = tcp;
980 tcp->nchildren++;
981 if (!qflag)
982 fprintf(stderr, "Process %d attached\n", pid);
983 }
984 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000985#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000986}
987
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000988#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000989
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000990#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000991
992int
993sys_vfork(tcp)
994struct tcb *tcp;
995{
996 if (exiting(tcp))
997 return RVAL_UDECIMAL;
998 return 0;
999}
1000
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001001#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001002
1003#ifndef LINUX
1004
1005static char idstr[16];
1006
1007int
1008sys_getpid(tcp)
1009struct tcb *tcp;
1010{
1011 if (exiting(tcp)) {
1012 sprintf(idstr, "ppid %lu", getrval2(tcp));
1013 tcp->auxstr = idstr;
1014 return RVAL_STR;
1015 }
1016 return 0;
1017}
1018
1019int
1020sys_getuid(tcp)
1021struct tcb *tcp;
1022{
1023 if (exiting(tcp)) {
1024 sprintf(idstr, "euid %lu", getrval2(tcp));
1025 tcp->auxstr = idstr;
1026 return RVAL_STR;
1027 }
1028 return 0;
1029}
1030
1031int
1032sys_getgid(tcp)
1033struct tcb *tcp;
1034{
1035 if (exiting(tcp)) {
1036 sprintf(idstr, "egid %lu", getrval2(tcp));
1037 tcp->auxstr = idstr;
1038 return RVAL_STR;
1039 }
1040 return 0;
1041}
1042
1043#endif /* !LINUX */
1044
1045#ifdef LINUX
1046
1047int
1048sys_setuid(tcp)
1049struct tcb *tcp;
1050{
1051 if (entering(tcp)) {
1052 tprintf("%u", (uid_t) tcp->u_arg[0]);
1053 }
1054 return 0;
1055}
1056
1057int
1058sys_setgid(tcp)
1059struct tcb *tcp;
1060{
1061 if (entering(tcp)) {
1062 tprintf("%u", (gid_t) tcp->u_arg[0]);
1063 }
1064 return 0;
1065}
1066
1067int
1068sys_getresuid(tcp)
1069 struct tcb *tcp;
1070{
1071 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001072 __kernel_uid_t uid;
1073 if (syserror(tcp))
1074 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1075 tcp->u_arg[1], tcp->u_arg[2]);
1076 else {
1077 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1078 tprintf("%#lx, ", tcp->u_arg[0]);
1079 else
1080 tprintf("ruid %lu, ", (unsigned long) uid);
1081 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1082 tprintf("%#lx, ", tcp->u_arg[0]);
1083 else
1084 tprintf("euid %lu, ", (unsigned long) uid);
1085 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1086 tprintf("%#lx", tcp->u_arg[0]);
1087 else
1088 tprintf("suid %lu", (unsigned long) uid);
1089 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001090 }
1091 return 0;
1092}
1093
1094int
1095sys_getresgid(tcp)
1096struct tcb *tcp;
1097{
1098 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001099 __kernel_gid_t gid;
1100 if (syserror(tcp))
1101 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1102 tcp->u_arg[1], tcp->u_arg[2]);
1103 else {
1104 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1105 tprintf("%#lx, ", tcp->u_arg[0]);
1106 else
1107 tprintf("rgid %lu, ", (unsigned long) gid);
1108 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1109 tprintf("%#lx, ", tcp->u_arg[0]);
1110 else
1111 tprintf("egid %lu, ", (unsigned long) gid);
1112 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1113 tprintf("%#lx", tcp->u_arg[0]);
1114 else
1115 tprintf("sgid %lu", (unsigned long) gid);
1116 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001117 }
1118 return 0;
1119}
1120
1121#endif /* LINUX */
1122
1123int
1124sys_setreuid(tcp)
1125struct tcb *tcp;
1126{
1127 if (entering(tcp)) {
1128 tprintf("%lu, %lu",
1129 (unsigned long) (uid_t) tcp->u_arg[0],
1130 (unsigned long) (uid_t) tcp->u_arg[1]);
1131 }
1132 return 0;
1133}
1134
1135int
1136sys_setregid(tcp)
1137struct tcb *tcp;
1138{
1139 if (entering(tcp)) {
1140 tprintf("%lu, %lu",
1141 (unsigned long) (gid_t) tcp->u_arg[0],
1142 (unsigned long) (gid_t) tcp->u_arg[1]);
1143 }
1144 return 0;
1145}
1146
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001147#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001148int
1149sys_setresuid(tcp)
1150 struct tcb *tcp;
1151{
1152 if (entering(tcp)) {
1153 tprintf("ruid %u, euid %u, suid %u",
1154 (uid_t) tcp->u_arg[0],
1155 (uid_t) tcp->u_arg[1],
1156 (uid_t) tcp->u_arg[2]);
1157 }
1158 return 0;
1159}
1160int
1161sys_setresgid(tcp)
1162 struct tcb *tcp;
1163{
1164 if (entering(tcp)) {
1165 tprintf("rgid %u, egid %u, sgid %u",
1166 (uid_t) tcp->u_arg[0],
1167 (uid_t) tcp->u_arg[1],
1168 (uid_t) tcp->u_arg[2]);
1169 }
1170 return 0;
1171}
1172
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001173#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001174
1175int
1176sys_setgroups(tcp)
1177struct tcb *tcp;
1178{
1179 int i, len;
1180 GETGROUPS_T *gidset;
1181
1182 if (entering(tcp)) {
1183 len = tcp->u_arg[0];
1184 tprintf("%u, ", len);
1185 if (len <= 0) {
1186 tprintf("[]");
1187 return 0;
1188 }
1189 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1190 if (gidset == NULL) {
1191 fprintf(stderr, "sys_setgroups: out of memory\n");
1192 return -1;
1193 }
1194 if (!verbose(tcp))
1195 tprintf("%#lx", tcp->u_arg[1]);
1196 else if (umoven(tcp, tcp->u_arg[1],
1197 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1198 tprintf("[?]");
1199 else {
1200 tprintf("[");
1201 for (i = 0; i < len; i++)
1202 tprintf("%s%lu", i ? ", " : "",
1203 (unsigned long) gidset[i]);
1204 tprintf("]");
1205 }
1206 free((char *) gidset);
1207 }
1208 return 0;
1209}
1210
1211int
1212sys_getgroups(tcp)
1213struct tcb *tcp;
1214{
1215 int i, len;
1216 GETGROUPS_T *gidset;
1217
1218 if (entering(tcp)) {
1219 len = tcp->u_arg[0];
1220 tprintf("%u, ", len);
1221 } else {
1222 len = tcp->u_rval;
1223 if (len <= 0) {
1224 tprintf("[]");
1225 return 0;
1226 }
1227 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1228 if (gidset == NULL) {
1229 fprintf(stderr, "sys_getgroups: out of memory\n");
1230 return -1;
1231 }
1232 if (!tcp->u_arg[1])
1233 tprintf("NULL");
1234 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1235 tprintf("%#lx", tcp->u_arg[1]);
1236 else if (umoven(tcp, tcp->u_arg[1],
1237 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1238 tprintf("[?]");
1239 else {
1240 tprintf("[");
1241 for (i = 0; i < len; i++)
1242 tprintf("%s%lu", i ? ", " : "",
1243 (unsigned long) gidset[i]);
1244 tprintf("]");
1245 }
1246 free((char *)gidset);
1247 }
1248 return 0;
1249}
1250
1251int
1252sys_setpgrp(tcp)
1253struct tcb *tcp;
1254{
1255 if (entering(tcp)) {
1256#ifndef SVR4
1257 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1258#endif /* !SVR4 */
1259 }
1260 return 0;
1261}
1262
1263int
1264sys_getpgrp(tcp)
1265struct tcb *tcp;
1266{
1267 if (entering(tcp)) {
1268#ifndef SVR4
1269 tprintf("%lu", tcp->u_arg[0]);
1270#endif /* !SVR4 */
1271 }
1272 return 0;
1273}
1274
1275int
1276sys_getsid(tcp)
1277struct tcb *tcp;
1278{
1279 if (entering(tcp)) {
1280 tprintf("%lu", tcp->u_arg[0]);
1281 }
1282 return 0;
1283}
1284
1285int
1286sys_setsid(tcp)
1287struct tcb *tcp;
1288{
1289 return 0;
1290}
1291
1292int
1293sys_getpgid(tcp)
1294struct tcb *tcp;
1295{
1296 if (entering(tcp)) {
1297 tprintf("%lu", tcp->u_arg[0]);
1298 }
1299 return 0;
1300}
1301
1302int
1303sys_setpgid(tcp)
1304struct tcb *tcp;
1305{
1306 if (entering(tcp)) {
1307 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1308 }
1309 return 0;
1310}
1311
John Hughesc61eb3d2002-05-17 11:37:50 +00001312#if UNIXWARE >= 2
1313
1314#include <sys/privilege.h>
1315
1316
1317static struct xlat procpriv_cmds [] = {
1318 { SETPRV, "SETPRV" },
1319 { CLRPRV, "CLRPRV" },
1320 { PUTPRV, "PUTPRV" },
1321 { GETPRV, "GETPRV" },
1322 { CNTPRV, "CNTPRV" },
1323 { 0, NULL },
1324};
1325
1326
1327static struct xlat procpriv_priv [] = {
1328 { P_OWNER, "P_OWNER" },
1329 { P_AUDIT, "P_AUDIT" },
1330 { P_COMPAT, "P_COMPAT" },
1331 { P_DACREAD, "P_DACREAD" },
1332 { P_DACWRITE, "P_DACWRITE" },
1333 { P_DEV, "P_DEV" },
1334 { P_FILESYS, "P_FILESYS" },
1335 { P_MACREAD, "P_MACREAD" },
1336 { P_MACWRITE, "P_MACWRITE" },
1337 { P_MOUNT, "P_MOUNT" },
1338 { P_MULTIDIR, "P_MULTIDIR" },
1339 { P_SETPLEVEL, "P_SETPLEVEL" },
1340 { P_SETSPRIV, "P_SETSPRIV" },
1341 { P_SETUID, "P_SETUID" },
1342 { P_SYSOPS, "P_SYSOPS" },
1343 { P_SETUPRIV, "P_SETUPRIV" },
1344 { P_DRIVER, "P_DRIVER" },
1345 { P_RTIME, "P_RTIME" },
1346 { P_MACUPGRADE, "P_MACUPGRADE" },
1347 { P_FSYSRANGE, "P_FSYSRANGE" },
1348 { P_SETFLEVEL, "P_SETFLEVEL" },
1349 { P_AUDITWR, "P_AUDITWR" },
1350 { P_TSHAR, "P_TSHAR" },
1351 { P_PLOCK, "P_PLOCK" },
1352 { P_CORE, "P_CORE" },
1353 { P_LOADMOD, "P_LOADMOD" },
1354 { P_BIND, "P_BIND" },
1355 { P_ALLPRIVS, "P_ALLPRIVS" },
1356 { 0, NULL },
1357};
1358
1359
1360static struct xlat procpriv_type [] = {
1361 { PS_FIX, "PS_FIX" },
1362 { PS_INH, "PS_INH" },
1363 { PS_MAX, "PS_MAX" },
1364 { PS_WKG, "PS_WKG" },
1365 { 0, NULL },
1366};
1367
1368
1369static void
1370printpriv(tcp, addr, len, opt)
1371struct tcb *tcp;
1372long addr;
1373int len;
1374struct xlat *opt;
1375{
1376 priv_t buf [128];
1377 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1378 int dots = len > max;
1379 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001380
John Hughesc61eb3d2002-05-17 11:37:50 +00001381 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001382
John Hughesc61eb3d2002-05-17 11:37:50 +00001383 if (len <= 0 ||
1384 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1385 {
1386 tprintf ("%#lx", addr);
1387 return;
1388 }
1389
1390 tprintf ("[");
1391
1392 for (i = 0; i < len; ++i) {
1393 char *t, *p;
1394
1395 if (i) tprintf (", ");
1396
1397 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1398 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1399 {
1400 tprintf ("%s|%s", t, p);
1401 }
1402 else {
1403 tprintf ("%#lx", buf [i]);
1404 }
1405 }
1406
1407 if (dots) tprintf (" ...");
1408
1409 tprintf ("]");
1410}
1411
1412
1413int
1414sys_procpriv(tcp)
1415struct tcb *tcp;
1416{
1417 if (entering(tcp)) {
1418 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1419 switch (tcp->u_arg[0]) {
1420 case CNTPRV:
1421 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1422 break;
1423
1424 case GETPRV:
1425 break;
1426
1427 default:
1428 tprintf (", ");
1429 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1430 tprintf (", %ld", tcp->u_arg[2]);
1431 }
1432 }
1433 else if (tcp->u_arg[0] == GETPRV) {
1434 if (syserror (tcp)) {
1435 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1436 }
1437 else {
1438 tprintf (", ");
1439 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1440 tprintf (", %ld", tcp->u_arg[2]);
1441 }
1442 }
Roland McGrath5a223472002-12-15 23:58:26 +00001443
John Hughesc61eb3d2002-05-17 11:37:50 +00001444 return 0;
1445}
1446
1447#endif
1448
1449
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001450void
1451fake_execve(tcp, program, argv, envp)
1452struct tcb *tcp;
1453char *program;
1454char *argv[];
1455char *envp[];
1456{
1457 int i;
1458
1459#ifdef ARM
1460 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1461 return;
1462#else
1463 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1464 return;
1465#endif /* !ARM */
1466 printleader(tcp);
1467 tprintf("execve(");
1468 string_quote(program);
1469 tprintf(", [");
1470 for (i = 0; argv[i] != NULL; i++) {
1471 if (i != 0)
1472 tprintf(", ");
1473 string_quote(argv[i]);
1474 }
1475 for (i = 0; envp[i] != NULL; i++)
1476 ;
1477 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1478 tabto(acolumn);
1479 tprintf("= 0");
1480 printtrailer(tcp);
1481}
1482
1483static void
1484printargv(tcp, addr)
1485struct tcb *tcp;
1486long addr;
1487{
1488 char *cp;
1489 char *sep;
1490 int max = max_strlen / 2;
1491
1492 for (sep = ""; --max >= 0; sep = ", ") {
1493 if (!abbrev(tcp))
1494 max++;
1495 if (umove(tcp, addr, &cp) < 0) {
1496 tprintf("%#lx", addr);
1497 return;
1498 }
1499 if (cp == 0)
1500 break;
1501 tprintf(sep);
1502 printstr(tcp, (long) cp, -1);
1503 addr += sizeof(char *);
1504 }
1505 if (cp)
1506 tprintf(", ...");
1507}
1508
1509static void
1510printargc(fmt, tcp, addr)
1511char *fmt;
1512struct tcb *tcp;
1513long addr;
1514{
1515 int count;
1516 char *cp;
1517
1518 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1519 addr += sizeof(char *);
1520 }
1521 tprintf(fmt, count, count == 1 ? "" : "s");
1522}
1523
1524int
1525sys_execv(tcp)
1526struct tcb *tcp;
1527{
1528 if (entering(tcp)) {
1529 printpath(tcp, tcp->u_arg[0]);
1530 if (!verbose(tcp))
1531 tprintf(", %#lx", tcp->u_arg[1]);
1532#if 0
1533 else if (abbrev(tcp))
1534 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1535#endif
1536 else {
1537 tprintf(", [");
1538 printargv(tcp, tcp->u_arg[1]);
1539 tprintf("]");
1540 }
1541 }
1542 return 0;
1543}
1544
1545int
1546sys_execve(tcp)
1547struct tcb *tcp;
1548{
1549 if (entering(tcp)) {
1550 printpath(tcp, tcp->u_arg[0]);
1551 if (!verbose(tcp))
1552 tprintf(", %#lx", tcp->u_arg[1]);
1553#if 0
1554 else if (abbrev(tcp))
1555 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1556#endif
1557 else {
1558 tprintf(", [");
1559 printargv(tcp, tcp->u_arg[1]);
1560 tprintf("]");
1561 }
1562 if (!verbose(tcp))
1563 tprintf(", %#lx", tcp->u_arg[2]);
1564 else if (abbrev(tcp))
1565 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1566 else {
1567 tprintf(", [");
1568 printargv(tcp, tcp->u_arg[2]);
1569 tprintf("]");
1570 }
1571 }
1572#ifdef LINUX
Wichert Akkermanccef6372002-05-01 16:39:22 +00001573#if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001574 tcp->flags |= TCB_WAITEXECVE;
Wichert Akkermanccef6372002-05-01 16:39:22 +00001575#endif /* ALPHA || SPARC || POWERPC || IA64 || HPPA || SH */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001576#endif /* LINUX */
1577 return 0;
1578}
1579
John Hughes4e36a812001-04-18 15:11:51 +00001580#if UNIXWARE > 2
1581
1582int sys_rexecve(tcp)
1583struct tcb *tcp;
1584{
1585 if (entering (tcp)) {
1586 sys_execve (tcp);
1587 tprintf (", %ld", tcp->u_arg[3]);
1588 }
1589 return 0;
1590}
1591
1592#endif
1593
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001594int
1595internal_exec(tcp)
1596struct tcb *tcp;
1597{
1598#ifdef SUNOS4
1599 if (exiting(tcp) && !syserror(tcp) && followfork)
1600 fixvfork(tcp);
1601#endif /* SUNOS4 */
1602 return 0;
1603}
1604
1605#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001606#ifndef __WNOTHREAD
1607#define __WNOTHREAD 0x20000000
1608#endif
1609#ifndef __WALL
1610#define __WALL 0x40000000
1611#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001612#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001613#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001614#endif
1615#endif /* LINUX */
1616
1617static struct xlat wait4_options[] = {
1618 { WNOHANG, "WNOHANG" },
1619#ifndef WSTOPPED
1620 { WUNTRACED, "WUNTRACED" },
1621#endif
1622#ifdef WEXITED
1623 { WEXITED, "WEXITED" },
1624#endif
1625#ifdef WTRAPPED
1626 { WTRAPPED, "WTRAPPED" },
1627#endif
1628#ifdef WSTOPPED
1629 { WSTOPPED, "WSTOPPED" },
1630#endif
1631#ifdef WCONTINUED
1632 { WCONTINUED, "WCONTINUED" },
1633#endif
1634#ifdef WNOWAIT
1635 { WNOWAIT, "WNOWAIT" },
1636#endif
1637#ifdef __WCLONE
1638 { __WCLONE, "__WCLONE" },
1639#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001640#ifdef __WALL
1641 { __WALL, "__WALL" },
1642#endif
1643#ifdef __WNOTHREAD
1644 { __WNOTHREAD, "__WNOTHREAD" },
1645#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001646 { 0, NULL },
1647};
1648
1649static int
1650printstatus(status)
1651int status;
1652{
1653 int exited = 0;
1654
1655 /*
1656 * Here is a tricky presentation problem. This solution
1657 * is still not entirely satisfactory but since there
1658 * are no wait status constructors it will have to do.
1659 */
1660 if (WIFSTOPPED(status))
1661 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001662 signame(WSTOPSIG(status)));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001663 else if WIFSIGNALED(status)
1664 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001665 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001666 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1667 else if WIFEXITED(status) {
1668 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1669 WEXITSTATUS(status));
1670 exited = 1;
1671 }
1672 else
1673 tprintf("[%#x]", status);
1674 return exited;
1675}
1676
1677static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001678printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001679struct tcb *tcp;
1680int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001681int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001682{
1683 int status;
1684 int exited = 0;
1685
1686 if (entering(tcp)) {
1687 tprintf("%ld, ", tcp->u_arg[0]);
1688 } else {
1689 /* status */
1690 if (!tcp->u_arg[1])
1691 tprintf("NULL");
1692 else if (syserror(tcp) || tcp->u_rval == 0)
1693 tprintf("%#lx", tcp->u_arg[1]);
1694 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1695 tprintf("[?]");
1696 else
1697 exited = printstatus(status);
1698 /* options */
1699 tprintf(", ");
1700 if (!printflags(wait4_options, tcp->u_arg[2]))
1701 tprintf("0");
1702 if (n == 4) {
1703 tprintf(", ");
1704 /* usage */
1705 if (!tcp->u_arg[3])
1706 tprintf("NULL");
1707#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001708 else if (tcp->u_rval > 0) {
1709#ifdef LINUX_64BIT
1710 if (bitness)
1711 printrusage32(tcp, tcp->u_arg[3]);
1712 else
1713#endif
1714 printrusage(tcp, tcp->u_arg[3]);
1715 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001716#endif /* LINUX */
1717#ifdef SUNOS4
1718 else if (tcp->u_rval > 0 && exited)
1719 printrusage(tcp, tcp->u_arg[3]);
1720#endif /* SUNOS4 */
1721 else
1722 tprintf("%#lx", tcp->u_arg[3]);
1723 }
1724 }
1725 return 0;
1726}
1727
1728int
1729internal_wait(tcp)
1730struct tcb *tcp;
1731{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001732 int got_kids;
1733
1734#ifdef TCB_CLONE_THREAD
1735 if (tcp->flags & TCB_CLONE_THREAD)
1736 /* The children we wait for are our parent's children. */
1737 got_kids = (tcp->parent->nchildren
1738 > tcp->parent->nclone_detached);
1739 else
1740 got_kids = (tcp->nchildren > tcp->nclone_detached);
1741#else
1742 got_kids = tcp->nchildren > 0;
1743#endif
1744
1745 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001746 /* There are children that this parent should block for.
1747 But ptrace made us the parent of the traced children
1748 and the real parent will get ECHILD from the wait call.
1749
1750 XXX If we attached with strace -f -p PID, then there
1751 may be untraced dead children the parent could be reaping
1752 now, but we make him block. */
1753
1754 /* ??? WTA: fix bug with hanging children */
1755
1756 if (!(tcp->u_arg[2] & WNOHANG)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001757 /* There are traced children */
1758 tcp->flags |= TCB_SUSPENDED;
1759 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001760#ifdef TCB_CLONE_THREAD
1761 if (tcp->flags & TCB_CLONE_THREAD)
1762 tcp->parent->nclone_waiting++;
1763#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001764 }
1765 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001766 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001767 if (tcp->u_arg[2] & WNOHANG) {
1768 /* We must force a fake result of 0 instead of
1769 the ECHILD error. */
1770 extern int force_result();
1771 return force_result(tcp, 0, 0);
1772 }
1773 else
1774 fprintf(stderr,
1775 "internal_wait: should not have resumed %d\n",
1776 tcp->pid);
1777 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001778 return 0;
1779}
1780
1781#ifdef SVR4
1782
1783int
1784sys_wait(tcp)
1785struct tcb *tcp;
1786{
1787 if (exiting(tcp)) {
1788 /* The library wrapper stuffs this into the user variable. */
1789 if (!syserror(tcp))
1790 printstatus(getrval2(tcp));
1791 }
1792 return 0;
1793}
1794
1795#endif /* SVR4 */
1796
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001797#ifdef FREEBSD
1798int
1799sys_wait(tcp)
1800struct tcb *tcp;
1801{
1802 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001803
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001804 if (exiting(tcp)) {
1805 if (!syserror(tcp)) {
1806 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1807 tprintf("%#lx", tcp->u_arg[0]);
1808 else
1809 printstatus(status);
1810 }
1811 }
1812 return 0;
1813}
1814#endif
1815
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001816int
1817sys_waitpid(tcp)
1818struct tcb *tcp;
1819{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001820 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001821}
1822
1823int
1824sys_wait4(tcp)
1825struct tcb *tcp;
1826{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001827 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001828}
1829
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001830#ifdef ALPHA
1831int
1832sys_osf_wait4(tcp)
1833struct tcb *tcp;
1834{
1835 return printwaitn(tcp, 4, 1);
1836}
1837#endif
1838
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001839#ifdef SVR4
1840
1841static struct xlat waitid_types[] = {
1842 { P_PID, "P_PID" },
1843 { P_PPID, "P_PPID" },
1844 { P_PGID, "P_PGID" },
1845 { P_SID, "P_SID" },
1846 { P_CID, "P_CID" },
1847 { P_UID, "P_UID" },
1848 { P_GID, "P_GID" },
1849 { P_ALL, "P_ALL" },
1850#ifdef P_LWPID
1851 { P_LWPID, "P_LWPID" },
1852#endif
1853 { 0, NULL },
1854};
1855
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001856int
1857sys_waitid(tcp)
1858struct tcb *tcp;
1859{
1860 siginfo_t si;
1861 int exited;
1862
1863 if (entering(tcp)) {
1864 printxval(waitid_types, tcp->u_arg[0], "P_???");
1865 tprintf(", %ld, ", tcp->u_arg[1]);
1866 if (tcp->nchildren > 0) {
1867 /* There are traced children */
1868 tcp->flags |= TCB_SUSPENDED;
1869 tcp->waitpid = tcp->u_arg[0];
1870 }
1871 }
1872 else {
1873 /* siginfo */
1874 exited = 0;
1875 if (!tcp->u_arg[2])
1876 tprintf("NULL");
1877 else if (syserror(tcp))
1878 tprintf("%#lx", tcp->u_arg[2]);
1879 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1880 tprintf("{???}");
1881 else
John Hughes58265892001-10-18 15:13:53 +00001882 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001883 /* options */
1884 tprintf(", ");
1885 if (!printflags(wait4_options, tcp->u_arg[3]))
1886 tprintf("0");
1887 }
1888 return 0;
1889}
1890
1891#endif /* SVR4 */
1892
1893int
1894sys_alarm(tcp)
1895struct tcb *tcp;
1896{
1897 if (entering(tcp))
1898 tprintf("%lu", tcp->u_arg[0]);
1899 return 0;
1900}
1901
1902int
1903sys_uname(tcp)
1904struct tcb *tcp;
1905{
1906 struct utsname uname;
1907
1908 if (exiting(tcp)) {
1909 if (syserror(tcp) || !verbose(tcp))
1910 tprintf("%#lx", tcp->u_arg[0]);
1911 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1912 tprintf("{...}");
1913 else if (!abbrev(tcp)) {
1914
1915 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1916 uname.sysname, uname.nodename);
1917 tprintf("release=\"%s\", version=\"%s\", ",
1918 uname.release, uname.version);
1919 tprintf("machine=\"%s\"", uname.machine);
1920#ifdef LINUX
1921#ifndef __GLIBC__
1922 tprintf(", domainname=\"%s\"", uname.domainname);
1923#endif /* __GLIBC__ */
1924#endif /* LINUX */
1925 tprintf("}");
1926 }
1927 else
1928 tprintf("{sys=\"%s\", node=\"%s\", ...}",
1929 uname.sysname, uname.nodename);
1930 }
1931 return 0;
1932}
1933
1934#ifndef SVR4
1935
1936static struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00001937#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001938 { PTRACE_TRACEME, "PTRACE_TRACEME" },
1939 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
1940 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
1941 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
1942 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
1943 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
1944 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
1945 { PTRACE_CONT, "PTRACE_CONT" },
1946 { PTRACE_KILL, "PTRACE_KILL" },
1947 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
1948 { PTRACE_ATTACH, "PTRACE_ATTACH" },
1949 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001950#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001951 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001952#endif
1953#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001954 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001955#endif
1956#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001957 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00001958#endif
1959#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001960 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00001961#endif
1962#ifdef PTRACE_GETFPXREGS
1963 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
1964#endif
1965#ifdef PTRACE_SETFPXREGS
1966 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
1967#endif
1968#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001969 { PTRACE_READDATA, "PTRACE_READDATA" },
1970 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
1971 { PTRACE_READTEXT, "PTRACE_READTEXT" },
1972 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
1973 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
1974 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
1975#ifdef SPARC
1976 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
1977 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
1978#else /* !SPARC */
1979 { PTRACE_22, "PTRACE_PTRACE_22" },
1980 { PTRACE_23, "PTRACE_PTRACE_23" },
1981#endif /* !SPARC */
1982#endif /* SUNOS4 */
1983 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
1984#ifdef SUNOS4
1985 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
1986#ifdef I386
1987 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
1988 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
1989 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
1990#else /* !I386 */
1991 { PTRACE_26, "PTRACE_26" },
1992 { PTRACE_27, "PTRACE_27" },
1993 { PTRACE_28, "PTRACE_28" },
1994#endif /* !I386 */
1995 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
1996#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001997#else /* FREEBSD */
1998 { PT_TRACE_ME, "PT_TRACE_ME" },
1999 { PT_READ_I, "PT_READ_I" },
2000 { PT_READ_D, "PT_READ_D" },
2001 { PT_WRITE_I, "PT_WRITE_I" },
2002 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002003#ifdef PT_READ_U
2004 { PT_READ_U, "PT_READ_U" },
2005#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002006 { PT_CONTINUE, "PT_CONTINUE" },
2007 { PT_KILL, "PT_KILL" },
2008 { PT_STEP, "PT_STEP" },
2009 { PT_ATTACH, "PT_ATTACH" },
2010 { PT_DETACH, "PT_DETACH" },
2011 { PT_GETREGS, "PT_GETREGS" },
2012 { PT_SETREGS, "PT_SETREGS" },
2013 { PT_GETFPREGS, "PT_GETFPREGS" },
2014 { PT_SETFPREGS, "PT_SETFPREGS" },
2015 { PT_GETDBREGS, "PT_GETDBREGS" },
2016 { PT_SETDBREGS, "PT_SETDBREGS" },
2017#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002018 { 0, NULL },
2019};
2020
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002021#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002022#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2023static
2024#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2025struct xlat struct_user_offsets[] = {
2026#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002027#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002028 { PT_PSWMASK, "psw_mask" },
2029 { PT_PSWADDR, "psw_addr" },
2030 { PT_GPR0, "gpr0" },
2031 { PT_GPR1, "gpr1" },
2032 { PT_GPR2, "gpr2" },
2033 { PT_GPR3, "gpr3" },
2034 { PT_GPR4, "gpr4" },
2035 { PT_GPR5, "gpr5" },
2036 { PT_GPR6, "gpr6" },
2037 { PT_GPR7, "gpr7" },
2038 { PT_GPR8, "gpr8" },
2039 { PT_GPR9, "gpr9" },
2040 { PT_GPR10, "gpr10" },
2041 { PT_GPR11, "gpr11" },
2042 { PT_GPR12, "gpr12" },
2043 { PT_GPR13, "gpr13" },
2044 { PT_GPR14, "gpr14" },
2045 { PT_GPR15, "gpr15" },
2046 { PT_ACR0, "acr0" },
2047 { PT_ACR1, "acr1" },
2048 { PT_ACR2, "acr2" },
2049 { PT_ACR3, "acr3" },
2050 { PT_ACR4, "acr4" },
2051 { PT_ACR5, "acr5" },
2052 { PT_ACR6, "acr6" },
2053 { PT_ACR7, "acr7" },
2054 { PT_ACR8, "acr8" },
2055 { PT_ACR9, "acr9" },
2056 { PT_ACR10, "acr10" },
2057 { PT_ACR11, "acr11" },
2058 { PT_ACR12, "acr12" },
2059 { PT_ACR13, "acr13" },
2060 { PT_ACR14, "acr14" },
2061 { PT_ACR15, "acr15" },
2062 { PT_ORIGGPR2, "orig_gpr2" },
2063 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002064#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002065 { PT_FPR0_HI, "fpr0.hi" },
2066 { PT_FPR0_LO, "fpr0.lo" },
2067 { PT_FPR1_HI, "fpr1.hi" },
2068 { PT_FPR1_LO, "fpr1.lo" },
2069 { PT_FPR2_HI, "fpr2.hi" },
2070 { PT_FPR2_LO, "fpr2.lo" },
2071 { PT_FPR3_HI, "fpr3.hi" },
2072 { PT_FPR3_LO, "fpr3.lo" },
2073 { PT_FPR4_HI, "fpr4.hi" },
2074 { PT_FPR4_LO, "fpr4.lo" },
2075 { PT_FPR5_HI, "fpr5.hi" },
2076 { PT_FPR5_LO, "fpr5.lo" },
2077 { PT_FPR6_HI, "fpr6.hi" },
2078 { PT_FPR6_LO, "fpr6.lo" },
2079 { PT_FPR7_HI, "fpr7.hi" },
2080 { PT_FPR7_LO, "fpr7.lo" },
2081 { PT_FPR8_HI, "fpr8.hi" },
2082 { PT_FPR8_LO, "fpr8.lo" },
2083 { PT_FPR9_HI, "fpr9.hi" },
2084 { PT_FPR9_LO, "fpr9.lo" },
2085 { PT_FPR10_HI, "fpr10.hi" },
2086 { PT_FPR10_LO, "fpr10.lo" },
2087 { PT_FPR11_HI, "fpr11.hi" },
2088 { PT_FPR11_LO, "fpr11.lo" },
2089 { PT_FPR12_HI, "fpr12.hi" },
2090 { PT_FPR12_LO, "fpr12.lo" },
2091 { PT_FPR13_HI, "fpr13.hi" },
2092 { PT_FPR13_LO, "fpr13.lo" },
2093 { PT_FPR14_HI, "fpr14.hi" },
2094 { PT_FPR14_LO, "fpr14.lo" },
2095 { PT_FPR15_HI, "fpr15.hi" },
2096 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002097#endif
2098#if defined(S390X)
2099 { PT_FPR0, "fpr0" },
2100 { PT_FPR1, "fpr1" },
2101 { PT_FPR2, "fpr2" },
2102 { PT_FPR3, "fpr3" },
2103 { PT_FPR4, "fpr4" },
2104 { PT_FPR5, "fpr5" },
2105 { PT_FPR6, "fpr6" },
2106 { PT_FPR7, "fpr7" },
2107 { PT_FPR8, "fpr8" },
2108 { PT_FPR9, "fpr9" },
2109 { PT_FPR10, "fpr10" },
2110 { PT_FPR11, "fpr11" },
2111 { PT_FPR12, "fpr12" },
2112 { PT_FPR13, "fpr13" },
2113 { PT_FPR14, "fpr14" },
2114 { PT_FPR15, "fpr15" },
2115#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002116 { PT_CR_9, "cr9" },
2117 { PT_CR_10, "cr10" },
2118 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002119 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002120#endif
2121#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002122 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002123#elif defined(HPPA)
2124 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002125#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002126#ifndef PT_ORIG_R3
2127#define PT_ORIG_R3 34
2128#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002129 { 4*PT_R0, "4*PT_R0" },
2130 { 4*PT_R1, "4*PT_R1" },
2131 { 4*PT_R2, "4*PT_R2" },
2132 { 4*PT_R3, "4*PT_R3" },
2133 { 4*PT_R4, "4*PT_R4" },
2134 { 4*PT_R5, "4*PT_R5" },
2135 { 4*PT_R6, "4*PT_R6" },
2136 { 4*PT_R7, "4*PT_R7" },
2137 { 4*PT_R8, "4*PT_R8" },
2138 { 4*PT_R9, "4*PT_R9" },
2139 { 4*PT_R10, "4*PT_R10" },
2140 { 4*PT_R11, "4*PT_R11" },
2141 { 4*PT_R12, "4*PT_R12" },
2142 { 4*PT_R13, "4*PT_R13" },
2143 { 4*PT_R14, "4*PT_R14" },
2144 { 4*PT_R15, "4*PT_R15" },
2145 { 4*PT_R16, "4*PT_R16" },
2146 { 4*PT_R17, "4*PT_R17" },
2147 { 4*PT_R18, "4*PT_R18" },
2148 { 4*PT_R19, "4*PT_R19" },
2149 { 4*PT_R20, "4*PT_R20" },
2150 { 4*PT_R21, "4*PT_R21" },
2151 { 4*PT_R22, "4*PT_R22" },
2152 { 4*PT_R23, "4*PT_R23" },
2153 { 4*PT_R24, "4*PT_R24" },
2154 { 4*PT_R25, "4*PT_R25" },
2155 { 4*PT_R26, "4*PT_R26" },
2156 { 4*PT_R27, "4*PT_R27" },
2157 { 4*PT_R28, "4*PT_R28" },
2158 { 4*PT_R29, "4*PT_R29" },
2159 { 4*PT_R30, "4*PT_R30" },
2160 { 4*PT_R31, "4*PT_R31" },
2161 { 4*PT_NIP, "4*PT_NIP" },
2162 { 4*PT_MSR, "4*PT_MSR" },
2163 { 4*PT_ORIG_R3, "4*PT_ORIG_R3" },
2164 { 4*PT_CTR, "4*PT_CTR" },
2165 { 4*PT_LNK, "4*PT_LNK" },
2166 { 4*PT_XER, "4*PT_XER" },
2167 { 4*PT_CCR, "4*PT_CCR" },
2168 { 4*PT_FPR0, "4*PT_FPR0" },
Roland McGrath5a223472002-12-15 23:58:26 +00002169#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002170#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002171 { 0, "r0" },
2172 { 1, "r1" },
2173 { 2, "r2" },
2174 { 3, "r3" },
2175 { 4, "r4" },
2176 { 5, "r5" },
2177 { 6, "r6" },
2178 { 7, "r7" },
2179 { 8, "r8" },
2180 { 9, "r9" },
2181 { 10, "r10" },
2182 { 11, "r11" },
2183 { 12, "r12" },
2184 { 13, "r13" },
2185 { 14, "r14" },
2186 { 15, "r15" },
2187 { 16, "r16" },
2188 { 17, "r17" },
2189 { 18, "r18" },
2190 { 19, "r19" },
2191 { 20, "r20" },
2192 { 21, "r21" },
2193 { 22, "r22" },
2194 { 23, "r23" },
2195 { 24, "r24" },
2196 { 25, "r25" },
2197 { 26, "r26" },
2198 { 27, "r27" },
2199 { 28, "r28" },
2200 { 29, "gp" },
2201 { 30, "fp" },
2202 { 31, "zero" },
2203 { 32, "fp0" },
2204 { 33, "fp" },
2205 { 34, "fp2" },
2206 { 35, "fp3" },
2207 { 36, "fp4" },
2208 { 37, "fp5" },
2209 { 38, "fp6" },
2210 { 39, "fp7" },
2211 { 40, "fp8" },
2212 { 41, "fp9" },
2213 { 42, "fp10" },
2214 { 43, "fp11" },
2215 { 44, "fp12" },
2216 { 45, "fp13" },
2217 { 46, "fp14" },
2218 { 47, "fp15" },
2219 { 48, "fp16" },
2220 { 49, "fp17" },
2221 { 50, "fp18" },
2222 { 51, "fp19" },
2223 { 52, "fp20" },
2224 { 53, "fp21" },
2225 { 54, "fp22" },
2226 { 55, "fp23" },
2227 { 56, "fp24" },
2228 { 57, "fp25" },
2229 { 58, "fp26" },
2230 { 59, "fp27" },
2231 { 60, "fp28" },
2232 { 61, "fp29" },
2233 { 62, "fp30" },
2234 { 63, "fp31" },
2235 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002236#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002237#ifdef IA64
2238 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2239 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2240 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2241 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2242 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2243 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2244 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2245 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2246 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2247 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2248 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2249 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2250 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2251 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2252 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2253 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2254 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2255 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2256 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2257 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2258 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2259 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2260 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2261 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2262 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2263 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2264 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2265 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2266 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2267 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2268 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2269 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2270 /* switch stack: */
2271 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2272 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2273 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2274 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2275 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2276 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2277 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2278 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2279 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2280 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002281 { PT_B0, "kb0" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002282 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2283 { PT_B4, "b4" }, { PT_B5, "b5" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002284 { PT_AR_PFS, "kar.pfs" },
2285 { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" },
2286 { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" },
2287 { PT_PR, "k.pr" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002288 /* pt_regs */
2289 { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002290 /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002291 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2292 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2293 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2294 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2295 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2296 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2297 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2298 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2299 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2300 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2301 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2302 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2303 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2304 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2305 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2306#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002307#ifdef I386
2308 { 4*EBX, "4*EBX" },
2309 { 4*ECX, "4*ECX" },
2310 { 4*EDX, "4*EDX" },
2311 { 4*ESI, "4*ESI" },
2312 { 4*EDI, "4*EDI" },
2313 { 4*EBP, "4*EBP" },
2314 { 4*EAX, "4*EAX" },
2315 { 4*DS, "4*DS" },
2316 { 4*ES, "4*ES" },
2317 { 4*FS, "4*FS" },
2318 { 4*GS, "4*GS" },
2319 { 4*ORIG_EAX, "4*ORIG_EAX" },
2320 { 4*EIP, "4*EIP" },
2321 { 4*CS, "4*CS" },
2322 { 4*EFL, "4*EFL" },
2323 { 4*UESP, "4*UESP" },
2324 { 4*SS, "4*SS" },
2325#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002326#ifdef X86_64
2327 { 8*RDI, "8*RDI" },
2328 { 8*RSI, "8*RSI" },
2329 { 8*RDX, "8*RDX" },
2330 { 8*R10, "8*R10" },
2331 { 8*R8, "8*R8" },
2332 { 8*R9, "8*R9" },
2333 { 8*RBX, "8*RBX" },
2334 { 8*RCX, "8*RCX" },
2335 { 8*RBP, "8*RBP" },
2336 { 8*RAX, "8*RAX" },
2337#if 0
2338 { 8*DS, "8*DS" },
2339 { 8*ES, "8*ES" },
2340 { 8*FS, "8*FS" },
2341 { 8*GS, "8*GS" },
2342#endif
2343 { 8*ORIG_RAX, "8*ORIG_EAX" },
2344 { 8*RIP, "8*RIP" },
2345 { 8*CS, "8*CS" },
2346 { 8*EFLAGS, "8*EFL" },
2347 { 8*RSP, "8*RSP" },
2348 { 8*SS, "8*SS" },
2349 { 8*R11, "8*R11" },
2350 { 8*R12, "8*R12" },
2351 { 8*R13, "8*R13" },
2352 { 8*R14, "8*R14" },
2353 { 8*R15, "8*R15" },
2354#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002355#ifdef M68K
2356 { 4*PT_D1, "4*PT_D1" },
2357 { 4*PT_D2, "4*PT_D2" },
2358 { 4*PT_D3, "4*PT_D3" },
2359 { 4*PT_D4, "4*PT_D4" },
2360 { 4*PT_D5, "4*PT_D5" },
2361 { 4*PT_D6, "4*PT_D6" },
2362 { 4*PT_D7, "4*PT_D7" },
2363 { 4*PT_A0, "4*PT_A0" },
2364 { 4*PT_A1, "4*PT_A1" },
2365 { 4*PT_A2, "4*PT_A2" },
2366 { 4*PT_A3, "4*PT_A3" },
2367 { 4*PT_A4, "4*PT_A4" },
2368 { 4*PT_A5, "4*PT_A5" },
2369 { 4*PT_A6, "4*PT_A6" },
2370 { 4*PT_D0, "4*PT_D0" },
2371 { 4*PT_USP, "4*PT_USP" },
2372 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2373 { 4*PT_SR, "4*PT_SR" },
2374 { 4*PT_PC, "4*PT_PC" },
2375#endif /* M68K */
2376#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002377#ifdef SH
2378 { 4*REG_REG0, "4*REG_REG0" },
2379 { 4*(REG_REG0+1), "4*REG_REG1" },
2380 { 4*(REG_REG0+2), "4*REG_REG2" },
2381 { 4*(REG_REG0+3), "4*REG_REG3" },
2382 { 4*(REG_REG0+4), "4*REG_REG4" },
2383 { 4*(REG_REG0+5), "4*REG_REG5" },
2384 { 4*(REG_REG0+6), "4*REG_REG6" },
2385 { 4*(REG_REG0+7), "4*REG_REG7" },
2386 { 4*(REG_REG0+8), "4*REG_REG8" },
2387 { 4*(REG_REG0+9), "4*REG_REG9" },
2388 { 4*(REG_REG0+10), "4*REG_REG10" },
2389 { 4*(REG_REG0+11), "4*REG_REG11" },
2390 { 4*(REG_REG0+12), "4*REG_REG12" },
2391 { 4*(REG_REG0+13), "4*REG_REG13" },
2392 { 4*(REG_REG0+14), "4*REG_REG14" },
2393 { 4*REG_REG15, "4*REG_REG15" },
2394 { 4*REG_PC, "4*REG_PC" },
2395 { 4*REG_PR, "4*REG_PR" },
2396 { 4*REG_SR, "4*REG_SR" },
2397 { 4*REG_GBR, "4*REG_GBR" },
2398 { 4*REG_MACH, "4*REG_MACH" },
2399 { 4*REG_MACL, "4*REG_MACL" },
2400 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2401 { 4*REG_FPUL, "4*REG_FPUL" },
2402 { 4*REG_FPREG0, "4*REG_FPREG0" },
2403 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2404 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2405 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2406 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2407 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2408 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2409 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2410 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2411 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2412 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2413 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2414 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2415 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2416 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2417 { 4*REG_FPREG15, "4*REG_FPREG15" },
2418 { 4*REG_XDREG0, "4*REG_XDREG0" },
2419 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2420 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2421 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2422 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2423 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2424 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2425 { 4*REG_XDREG14, "4*REG_XDREG14" },
2426 { 4*REG_FPSCR, "4*REG_FPSCR" },
2427#endif /* SH */
2428
Michal Ludvig10a88d02002-10-07 14:31:00 +00002429#if !defined(S390) && !defined(S390X) && !defined(MIPS)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002430 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002431#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002432#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002433 { uoff(i387), "offsetof(struct user, i387)" },
2434#else /* !I386 */
2435#ifdef M68K
2436 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2437#endif /* M68K */
2438#endif /* !I386 */
2439 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2440 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2441 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2442 { uoff(start_code), "offsetof(struct user, start_code)" },
2443 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2444 { uoff(signal), "offsetof(struct user, signal)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002445#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002446 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002447#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002448 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002449#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002450 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2451#endif
2452 { uoff(magic), "offsetof(struct user, magic)" },
2453 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002454#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002455 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2456#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002457#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002458#endif /* !ALPHA */
2459#endif /* !POWERPC/!SPARC */
2460#endif /* LINUX */
2461#ifdef SUNOS4
2462 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2463 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2464 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2465 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2466 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2467 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2468 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2469 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2470 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2471 { uoff(u_error), "offsetof(struct user, u_error)" },
2472 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2473 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2474 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2475 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2476 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2477 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2478 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2479 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2480 { uoff(u_code), "offsetof(struct user, u_code)" },
2481 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2482 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2483 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2484 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2485 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2486 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2487 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2488 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2489 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2490 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2491 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2492 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2493 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2494 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2495 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2496 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2497 { uoff(u_start), "offsetof(struct user, u_start)" },
2498 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2499 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2500 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2501 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2502 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2503 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2504 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2505 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2506 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2507#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002508#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002509 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002510#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002511 { 0, NULL },
2512};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002513#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002514
2515int
2516sys_ptrace(tcp)
2517struct tcb *tcp;
2518{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002519 struct xlat *x;
2520 long addr;
2521
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002522 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002523 printxval(ptrace_cmds, tcp->u_arg[0],
2524#ifndef FREEBSD
2525 "PTRACE_???"
2526#else
2527 "PT_???"
2528#endif
2529 );
2530 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002531 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002532#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002533 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2534 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2535 for (x = struct_user_offsets; x->str; x++) {
2536 if (x->val >= addr)
2537 break;
2538 }
2539 if (!x->str)
2540 tprintf("%#lx, ", addr);
2541 else if (x->val > addr && x != struct_user_offsets) {
2542 x--;
2543 tprintf("%s + %ld, ", x->str, addr - x->val);
2544 }
2545 else
2546 tprintf("%s, ", x->str);
2547 }
2548 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002549#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002550 tprintf("%#lx, ", tcp->u_arg[2]);
2551#ifdef LINUX
2552 switch (tcp->u_arg[0]) {
2553 case PTRACE_PEEKDATA:
2554 case PTRACE_PEEKTEXT:
2555 case PTRACE_PEEKUSER:
2556 break;
2557 case PTRACE_CONT:
2558 case PTRACE_SINGLESTEP:
2559 case PTRACE_SYSCALL:
2560 case PTRACE_DETACH:
2561 printsignal(tcp->u_arg[3]);
2562 break;
2563 default:
2564 tprintf("%#lx", tcp->u_arg[3]);
2565 break;
2566 }
2567 } else {
2568 switch (tcp->u_arg[0]) {
2569 case PTRACE_PEEKDATA:
2570 case PTRACE_PEEKTEXT:
2571 case PTRACE_PEEKUSER:
2572 printnum(tcp, tcp->u_arg[3], "%#x");
2573 break;
2574 }
2575 }
2576#endif /* LINUX */
2577#ifdef SUNOS4
2578 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2579 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2580 tprintf("%lu, ", tcp->u_arg[3]);
2581 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2582 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2583 tcp->u_arg[0] != PTRACE_READTEXT) {
2584 tprintf("%#lx", tcp->u_arg[3]);
2585 }
2586 } else {
2587 if (tcp->u_arg[0] == PTRACE_READDATA ||
2588 tcp->u_arg[0] == PTRACE_READTEXT) {
2589 tprintf("%lu, ", tcp->u_arg[3]);
2590 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2591 }
2592 }
2593#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002594#ifdef FREEBSD
2595 tprintf("%lu", tcp->u_arg[3]);
2596 }
2597#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002598 return 0;
2599}
2600
2601#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002602
2603#ifdef LINUX
2604static struct xlat futexops[] = {
2605 { FUTEX_WAIT, "FUTEX_WAIT" },
2606 { FUTEX_WAKE, "FUTEX_WAKE" },
2607 { FUTEX_FD, "FUTEX_FD" },
2608 { 0, NULL }
2609};
2610
2611int
2612sys_futex(tcp)
2613struct tcb *tcp;
2614{
2615 if (entering(tcp)) {
2616 tprintf("%p, ", (void *) tcp->u_arg[0]);
2617 printflags(futexops, tcp->u_arg[1]);
2618 tprintf(", %ld, ", tcp->u_arg[2]);
2619 printtv(tcp, tcp->u_arg[3]);
2620 }
2621 return 0;
2622}
2623
2624static void
2625print_affinitylist(list, len)
2626unsigned long *list;
2627unsigned int len;
2628{
2629 int first = 1;
2630 tprintf(" {");
2631 while (len > sizeof (unsigned long)) {
2632 tprintf("%s %lx", first ? "" : ",", *list++);
2633 first = 0;
2634 len -= sizeof (unsigned long);
2635 }
2636 tprintf(" }");
2637}
2638
2639int
2640sys_sched_setaffinity(tcp)
2641struct tcb *tcp;
2642{
2643 if (entering(tcp)) {
2644 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2645 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2646 }
2647 return 0;
2648}
2649
2650int
2651sys_sched_getaffinity(tcp)
2652struct tcb *tcp;
2653{
2654 if (entering(tcp)) {
2655 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2656 } else {
2657 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);
2658 }
2659 return 0;
2660}
2661#endif