blob: 1b69d214e51759664e65cc14b54d4d1cc53970de [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 Akkerman15dea971999-10-06 13:06:34 +000081#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000082
Roland McGrath5bd7cf82003-01-24 04:31:18 +000083#ifdef HAVE_LINUX_PTRACE_H
84#undef PTRACE_SYSCALL
85#include <linux/ptrace.h>
86#endif
87
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)) {
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000454#ifdef SYS_rfork
455 if (tcp->scno == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
456 return 0;
457#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000458 if (getrval2(tcp))
459 return 0;
460 if (!followfork)
461 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000462 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000463 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000464 if (syserror(tcp))
465 return 0;
466 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
467 fprintf(stderr, "sys_fork: tcb table full\n");
468 return 0;
469 }
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000470 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000471 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000472 }
473 return 0;
474}
475
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000476#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000477
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000478#ifdef LINUX
479
480/* defines copied from linux/sched.h since we can't include that
481 * ourselves (it conflicts with *lots* of libc includes)
482 */
483#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
484#define CLONE_VM 0x00000100 /* set if VM shared between processes */
485#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
486#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
487#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000488#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000489#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
490#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
491#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000492#define CLONE_THREAD 0x00010000 /* Same thread group? */
493#define CLONE_NEWNS 0x00020000 /* New namespace group? */
494#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
495#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
496#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
497#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
498#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
499#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
500#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000501
502static struct xlat clone_flags[] = {
503 { CLONE_VM, "CLONE_VM" },
504 { CLONE_FS, "CLONE_FS" },
505 { CLONE_FILES, "CLONE_FILES" },
506 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000507 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000508 { CLONE_PTRACE, "CLONE_PTRACE" },
509 { CLONE_VFORK, "CLONE_VFORK" },
510 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000511 { CLONE_THREAD, "CLONE_THREAD" },
512 { CLONE_NEWNS, "CLONE_NEWNS" },
513 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
514 { CLONE_SETTLS, "CLONE_SETTLS" },
515 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
516 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
517 { CLONE_DETACHED, "CLONE_DETACHED" },
518 { CLONE_UNTRACED, "CLONE_UNTRACED" },
519 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000520 { 0, NULL },
521};
522
Roland McGrath909875b2002-12-22 03:34:36 +0000523# ifdef I386
524# include <asm/ldt.h>
525extern void print_ldt_entry();
526# endif
527
Roland McGrath9677b3a2003-03-12 09:54:36 +0000528# if defined IA64
529# define ARG_FLAGS 0
530# define ARG_STACK 1
531# define ARG_STACKSIZE (tcp->scno == SYS_clone2 ? 2 : -1)
Roland McGrathc03981d2003-03-14 10:32:36 +0000532# define ARG_PTID (tcp->scno == SYS_clone2 ? 3 : 2)
533# define ARG_CTID (tcp->scno == SYS_clone2 ? 4 : 3)
534# define ARG_TLS (tcp->scno == SYS_clone2 ? 5 : 4)
Roland McGrath9677b3a2003-03-12 09:54:36 +0000535# elif defined S390
536# define ARG_STACK 0
537# define ARG_FLAGS 1
538# define ARG_PTID 2
539# define ARG_TLS 3
540# define ARG_CTID 4
Roland McGrath361aac52003-03-18 07:43:42 +0000541# elif defined X86_64
542# define ARG_FLAGS 0
543# define ARG_STACK 1
544# define ARG_PTID 2
545# define ARG_CTID 3
546# define ARG_TLS 4
Roland McGrath9677b3a2003-03-12 09:54:36 +0000547# else
548# define ARG_FLAGS 0
549# define ARG_STACK 1
550# define ARG_PTID 2
551# define ARG_TLS 3
552# define ARG_CTID 4
553# endif
554
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000555int
556sys_clone(tcp)
557struct tcb *tcp;
558{
559 if (exiting(tcp)) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000560 unsigned long flags = tcp->u_arg[ARG_FLAGS];
561 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
562# ifdef ARG_STACKSIZE
563 if (ARG_STACKSIZE != -1)
564 tprintf("stack_size=%#lx, ",
565 tcp->u_arg[ARG_STACKSIZE]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000566# endif
Roland McGrath9677b3a2003-03-12 09:54:36 +0000567 tprintf("flags=");
Roland McGrathb4968be2003-01-20 09:04:33 +0000568 if (printflags(clone_flags, flags) == 0)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000569 tprintf("0");
Roland McGrathb4968be2003-01-20 09:04:33 +0000570 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
Roland McGrath9677b3a2003-03-12 09:54:36 +0000571 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
Roland McGrath909875b2002-12-22 03:34:36 +0000572 return 0;
Roland McGrath6f67a982003-03-21 07:33:15 +0000573 if (flags & CLONE_PARENT_SETTID)
574 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000575 if (flags & CLONE_SETTLS) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000576# ifdef I386
Roland McGrath909875b2002-12-22 03:34:36 +0000577 struct modify_ldt_ldt_s copy;
Roland McGrath9677b3a2003-03-12 09:54:36 +0000578 if (umove(tcp, tcp->u_arg[ARG_TLS], &copy) != -1) {
Roland McGrath909875b2002-12-22 03:34:36 +0000579 tprintf(", {entry_number:%d, ",
580 copy.entry_number);
581 if (!verbose(tcp))
582 tprintf("...}");
583 else
584 print_ldt_entry(&copy);
585 }
586 else
Roland McGrath9677b3a2003-03-12 09:54:36 +0000587# endif
Roland McGrath43f2c842003-03-12 09:58:14 +0000588 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
Roland McGrath909875b2002-12-22 03:34:36 +0000589 }
Roland McGrath9677b3a2003-03-12 09:54:36 +0000590 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
591 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000592 }
593 return 0;
594}
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000595#endif
596
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000597int
598sys_fork(tcp)
599struct tcb *tcp;
600{
601 if (exiting(tcp))
602 return RVAL_UDECIMAL;
603 return 0;
604}
605
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000606int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000607change_syscall(tcp, new)
608struct tcb *tcp;
609int new;
610{
611#if defined(LINUX)
612#if defined(I386)
613 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000614 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000615 return -1;
616 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000617#elif defined(X86_64)
618 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000619 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000620 return -1;
621 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000622#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000623 if (ptrace(PTRACE_POKEUSER, tcp->pid,
624 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000625 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000626 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000627#elif defined(S390) || defined(S390X)
628 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
629 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
630 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000631 return 0;
632#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000633 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000634 return -1;
635 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000636#elif defined(SPARC)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000637 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000638 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
639 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000640 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000641 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
642 return -1;
643 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000644#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000645 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000646 return -1;
647 return 0;
648#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000649 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000650 return -1;
651 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000652#elif defined(IA64)
653 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
654 return -1;
655 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000656#elif defined(HPPA)
657 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
658 return -1;
659 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000660#elif defined(SH)
661 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), new)<0)
662 return -1;
663 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000664#else
665#warning Do not know how to handle change_syscall for this architecture
666#endif /* architecture */
667#endif /* LINUX */
668 return -1;
669}
670
671int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000672setarg(tcp, argnum)
673 struct tcb *tcp;
674 int argnum;
675{
676#if defined (IA64)
677 {
678 unsigned long *bsp, *ap;
679
680 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
681 return -1;
682
683 ap = ia64_rse_skip_regs(bsp, argnum);
684 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000685 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000686 if (errno)
687 return -1;
688
689 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000690#elif defined(I386)
691 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000692 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000693 if (errno)
694 return -1;
695 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000696#elif defined(X86_64)
697 {
698 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
699 if (errno)
700 return -1;
701 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000702#elif defined(POWERPC)
703#ifndef PT_ORIG_R3
704#define PT_ORIG_R3 34
705#endif
706 {
707 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000708 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000709 tcp->u_arg[argnum]);
710 if (errno)
711 return -1;
712 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000713#elif defined(MIPS)
714 {
715 errno = 0;
716 if (argnum < 4)
717 ptrace(PTRACE_POKEUSER, tcp->pid,
718 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
719 else {
720 unsigned long *sp;
721
722 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
723 return -1;
724
725 ptrace(PTRACE_POKEDATA, tcp->pid,
726 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
727 }
728 if (errno)
729 return -1;
730 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000731#elif defined(S390) || defined(S390X)
732 {
733 if(argnum <= 5)
734 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000735 (char *) (argnum==0 ? PT_ORIGGPR2 :
736 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000737 tcp->u_arg[argnum]);
738 else
739 return -E2BIG;
740 if (errno)
741 return -1;
742 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000743#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000744# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000745#endif
746 return 0;
747}
748
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000749#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000750int
751internal_clone(tcp)
752struct tcb *tcp;
753{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000754 struct tcb *tcpchild;
755 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000756 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000757 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000758 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000759 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000760 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000761 if (setbpt(tcp) < 0)
762 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000763 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000764 int bpt = tcp->flags & TCB_BPTSET;
765
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000766 if (!(tcp->flags & TCB_FOLLOWFORK))
767 return 0;
768
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000769 if (syserror(tcp)) {
770 if (bpt)
771 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000772 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000773 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000774
775 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000776
777#ifdef CLONE_PTRACE /* See new setbpt code. */
778 tcpchild = pid2tcb(pid);
779 if (tcpchild != NULL) {
780 /* The child already reported its startup trap
781 before the parent reported its syscall return. */
782 if ((tcpchild->flags
783 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
784 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
785 fprintf(stderr, "\
786[preattached child %d of %d in weird state!]\n",
787 pid, tcp->pid);
788 }
789 else
790#endif
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000791 if ((tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000792 if (bpt)
793 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000794 fprintf(stderr, " [tcb table full]\n");
795 kill(pid, SIGKILL); /* XXX */
796 return 0;
797 }
798
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000799#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000800 /* Attach to the new child */
801 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000802 if (bpt)
803 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000804 perror("PTRACE_ATTACH");
805 fprintf(stderr, "Too late?\n");
806 droptcb(tcpchild);
807 return 0;
808 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000809#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000810
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000811 if (bpt)
812 clearbpt(tcp);
813
Ulrich Drepper90512f01999-12-24 07:22:25 +0000814 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000815 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000816 if (bpt) {
817 tcpchild->flags |= TCB_BPTSET;
818 tcpchild->baddr = tcp->baddr;
819 memcpy(tcpchild->inst, tcp->inst,
820 sizeof tcpchild->inst);
821 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000822 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000823 tcp->nchildren++;
824 if (tcpchild->flags & TCB_SUSPENDED) {
825 /* The child was born suspended, due to our having
826 forced CLONE_PTRACE. */
827 if (bpt)
828 clearbpt(tcpchild);
829
830 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
831 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
832 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
833 return -1;
834 }
835
836 if (!qflag)
837 fprintf(stderr, "\
838Process %u resumed (parent %d ready)\n",
839 pid, tcp->pid);
840 }
841 else {
842 newoutf(tcpchild);
843 if (!qflag)
844 fprintf(stderr, "Process %d attached\n", pid);
845 }
846
847#ifdef TCB_CLONE_THREAD
848 if ((tcp->flags & TCB_CLONE_THREAD) && tcp->parent != NULL) {
849 /* The parent in this clone is itself a thread
850 belonging to another process. There is no
851 meaning to the parentage relationship of the new
852 child with the thread, only with the process.
853 We associate the new thread with our parent.
854 Since this is done for every new thread, there
855 will never be a TCB_CLONE_THREAD process that
856 has children. */
857 --tcp->nchildren;
858 tcp->u_arg[0] = tcp->parent->u_arg[0];
859 tcp = tcp->parent;
860 tcpchild->parent = tcp;
861 ++tcp->nchildren;
862 }
863
864 if (tcp->u_arg[0] & CLONE_THREAD) {
865 tcpchild->flags |= TCB_CLONE_THREAD;
866 ++tcp->nclone_threads;
867 }
868 if (tcp->u_arg[0] & CLONE_DETACHED) {
869 tcpchild->flags |= TCB_CLONE_DETACHED;
870 ++tcp->nclone_detached;
871 }
872#endif
873
874 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000875 return 0;
876}
877#endif
878
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000879int
880internal_fork(tcp)
881struct tcb *tcp;
882{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000883#ifdef LINUX
884 /* We do special magic with clone for any clone or fork. */
885 return internal_clone(tcp);
886#else
887
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000888 struct tcb *tcpchild;
889 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000890 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000891
892#ifdef SYS_vfork
Nate Sammonsccd8f211999-03-29 22:57:54 +0000893 if (tcp->scno == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000894 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000895 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000896 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000897 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000898 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000899#endif
900 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000901 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000902 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000903 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000904 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000905 if (setbpt(tcp) < 0)
906 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000907 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000908 else {
909 int bpt = tcp->flags & TCB_BPTSET;
910
911 if (!(tcp->flags & TCB_FOLLOWFORK))
912 return 0;
913 if (bpt)
914 clearbpt(tcp);
915
916 if (syserror(tcp))
917 return 0;
918
919 pid = tcp->u_rval;
920 if ((tcpchild = alloctcb(pid)) == NULL) {
921 fprintf(stderr, " [tcb table full]\n");
922 kill(pid, SIGKILL); /* XXX */
923 return 0;
924 }
925#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000926#ifdef HPPA
927 /* The child must have run before it can be attached. */
928 /* This must be a bug in the parisc kernel, but I havn't
929 * identified it yet. Seems to be an issue associated
930 * with attaching to a process (which sends it a signal)
931 * before that process has ever been scheduled. When
932 * debugging, I started seeing crashes in
933 * arch/parisc/kernel/signal.c:do_signal(), apparently
934 * caused by r8 getting corrupt over the dequeue_signal()
935 * call. Didn't make much sense though...
936 */
937 {
938 struct timeval tv;
939 tv.tv_sec = 0;
940 tv.tv_usec = 10000;
941 select(0, NULL, NULL, NULL, &tv);
942 }
943#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000944 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
945 perror("PTRACE_ATTACH");
946 fprintf(stderr, "Too late?\n");
947 droptcb(tcpchild);
948 return 0;
949 }
950#endif /* LINUX */
951#ifdef SUNOS4
952#ifdef oldway
953 /* The child must have run before it can be attached. */
954 {
955 struct timeval tv;
956 tv.tv_sec = 0;
957 tv.tv_usec = 10000;
958 select(0, NULL, NULL, NULL, &tv);
959 }
960 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
961 perror("PTRACE_ATTACH");
962 fprintf(stderr, "Too late?\n");
963 droptcb(tcpchild);
964 return 0;
965 }
966#else /* !oldway */
967 /* Try to catch the new process as soon as possible. */
968 {
969 int i;
970 for (i = 0; i < 1024; i++)
971 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
972 break;
973 if (i == 1024) {
974 perror("PTRACE_ATTACH");
975 fprintf(stderr, "Too late?\n");
976 droptcb(tcpchild);
977 return 0;
978 }
979 }
980#endif /* !oldway */
981#endif /* SUNOS4 */
982 tcpchild->flags |= TCB_ATTACHED;
983 /* Child has BPT too, must be removed on first occasion */
984 if (bpt) {
985 tcpchild->flags |= TCB_BPTSET;
986 tcpchild->baddr = tcp->baddr;
987 memcpy(tcpchild->inst, tcp->inst,
988 sizeof tcpchild->inst);
989 }
990 newoutf(tcpchild);
991 tcpchild->parent = tcp;
992 tcp->nchildren++;
993 if (!qflag)
994 fprintf(stderr, "Process %d attached\n", pid);
995 }
996 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000997#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000998}
999
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001000#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001001
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001002#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001003
1004int
1005sys_vfork(tcp)
1006struct tcb *tcp;
1007{
1008 if (exiting(tcp))
1009 return RVAL_UDECIMAL;
1010 return 0;
1011}
1012
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001013#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001014
1015#ifndef LINUX
1016
1017static char idstr[16];
1018
1019int
1020sys_getpid(tcp)
1021struct tcb *tcp;
1022{
1023 if (exiting(tcp)) {
1024 sprintf(idstr, "ppid %lu", getrval2(tcp));
1025 tcp->auxstr = idstr;
1026 return RVAL_STR;
1027 }
1028 return 0;
1029}
1030
1031int
1032sys_getuid(tcp)
1033struct tcb *tcp;
1034{
1035 if (exiting(tcp)) {
1036 sprintf(idstr, "euid %lu", getrval2(tcp));
1037 tcp->auxstr = idstr;
1038 return RVAL_STR;
1039 }
1040 return 0;
1041}
1042
1043int
1044sys_getgid(tcp)
1045struct tcb *tcp;
1046{
1047 if (exiting(tcp)) {
1048 sprintf(idstr, "egid %lu", getrval2(tcp));
1049 tcp->auxstr = idstr;
1050 return RVAL_STR;
1051 }
1052 return 0;
1053}
1054
1055#endif /* !LINUX */
1056
1057#ifdef LINUX
1058
1059int
1060sys_setuid(tcp)
1061struct tcb *tcp;
1062{
1063 if (entering(tcp)) {
1064 tprintf("%u", (uid_t) tcp->u_arg[0]);
1065 }
1066 return 0;
1067}
1068
1069int
1070sys_setgid(tcp)
1071struct tcb *tcp;
1072{
1073 if (entering(tcp)) {
1074 tprintf("%u", (gid_t) tcp->u_arg[0]);
1075 }
1076 return 0;
1077}
1078
1079int
1080sys_getresuid(tcp)
1081 struct tcb *tcp;
1082{
1083 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001084 __kernel_uid_t uid;
1085 if (syserror(tcp))
1086 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1087 tcp->u_arg[1], tcp->u_arg[2]);
1088 else {
1089 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1090 tprintf("%#lx, ", tcp->u_arg[0]);
1091 else
1092 tprintf("ruid %lu, ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001093 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1094 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001095 else
1096 tprintf("euid %lu, ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001097 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1098 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001099 else
1100 tprintf("suid %lu", (unsigned long) uid);
1101 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001102 }
1103 return 0;
1104}
1105
1106int
1107sys_getresgid(tcp)
1108struct tcb *tcp;
1109{
1110 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001111 __kernel_gid_t gid;
1112 if (syserror(tcp))
1113 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1114 tcp->u_arg[1], tcp->u_arg[2]);
1115 else {
1116 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1117 tprintf("%#lx, ", tcp->u_arg[0]);
1118 else
1119 tprintf("rgid %lu, ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001120 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1121 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001122 else
1123 tprintf("egid %lu, ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001124 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1125 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001126 else
1127 tprintf("sgid %lu", (unsigned long) gid);
1128 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001129 }
1130 return 0;
1131}
1132
1133#endif /* LINUX */
1134
1135int
1136sys_setreuid(tcp)
1137struct tcb *tcp;
1138{
1139 if (entering(tcp)) {
1140 tprintf("%lu, %lu",
1141 (unsigned long) (uid_t) tcp->u_arg[0],
1142 (unsigned long) (uid_t) tcp->u_arg[1]);
1143 }
1144 return 0;
1145}
1146
1147int
1148sys_setregid(tcp)
1149struct tcb *tcp;
1150{
1151 if (entering(tcp)) {
1152 tprintf("%lu, %lu",
1153 (unsigned long) (gid_t) tcp->u_arg[0],
1154 (unsigned long) (gid_t) tcp->u_arg[1]);
1155 }
1156 return 0;
1157}
1158
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001159#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001160int
1161sys_setresuid(tcp)
1162 struct tcb *tcp;
1163{
1164 if (entering(tcp)) {
1165 tprintf("ruid %u, euid %u, suid %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}
1172int
1173sys_setresgid(tcp)
1174 struct tcb *tcp;
1175{
1176 if (entering(tcp)) {
1177 tprintf("rgid %u, egid %u, sgid %u",
1178 (uid_t) tcp->u_arg[0],
1179 (uid_t) tcp->u_arg[1],
1180 (uid_t) tcp->u_arg[2]);
1181 }
1182 return 0;
1183}
1184
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001185#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001186
1187int
1188sys_setgroups(tcp)
1189struct tcb *tcp;
1190{
1191 int i, len;
1192 GETGROUPS_T *gidset;
1193
1194 if (entering(tcp)) {
1195 len = tcp->u_arg[0];
1196 tprintf("%u, ", len);
1197 if (len <= 0) {
1198 tprintf("[]");
1199 return 0;
1200 }
1201 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1202 if (gidset == NULL) {
1203 fprintf(stderr, "sys_setgroups: out of memory\n");
1204 return -1;
1205 }
1206 if (!verbose(tcp))
1207 tprintf("%#lx", tcp->u_arg[1]);
1208 else if (umoven(tcp, tcp->u_arg[1],
1209 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1210 tprintf("[?]");
1211 else {
1212 tprintf("[");
1213 for (i = 0; i < len; i++)
1214 tprintf("%s%lu", i ? ", " : "",
1215 (unsigned long) gidset[i]);
1216 tprintf("]");
1217 }
1218 free((char *) gidset);
1219 }
1220 return 0;
1221}
1222
1223int
1224sys_getgroups(tcp)
1225struct tcb *tcp;
1226{
1227 int i, len;
1228 GETGROUPS_T *gidset;
1229
1230 if (entering(tcp)) {
1231 len = tcp->u_arg[0];
1232 tprintf("%u, ", len);
1233 } else {
1234 len = tcp->u_rval;
1235 if (len <= 0) {
1236 tprintf("[]");
1237 return 0;
1238 }
1239 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1240 if (gidset == NULL) {
1241 fprintf(stderr, "sys_getgroups: out of memory\n");
1242 return -1;
1243 }
1244 if (!tcp->u_arg[1])
1245 tprintf("NULL");
1246 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1247 tprintf("%#lx", tcp->u_arg[1]);
1248 else if (umoven(tcp, tcp->u_arg[1],
1249 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1250 tprintf("[?]");
1251 else {
1252 tprintf("[");
1253 for (i = 0; i < len; i++)
1254 tprintf("%s%lu", i ? ", " : "",
1255 (unsigned long) gidset[i]);
1256 tprintf("]");
1257 }
1258 free((char *)gidset);
1259 }
1260 return 0;
1261}
1262
1263int
1264sys_setpgrp(tcp)
1265struct tcb *tcp;
1266{
1267 if (entering(tcp)) {
1268#ifndef SVR4
1269 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1270#endif /* !SVR4 */
1271 }
1272 return 0;
1273}
1274
1275int
1276sys_getpgrp(tcp)
1277struct tcb *tcp;
1278{
1279 if (entering(tcp)) {
1280#ifndef SVR4
1281 tprintf("%lu", tcp->u_arg[0]);
1282#endif /* !SVR4 */
1283 }
1284 return 0;
1285}
1286
1287int
1288sys_getsid(tcp)
1289struct tcb *tcp;
1290{
1291 if (entering(tcp)) {
1292 tprintf("%lu", tcp->u_arg[0]);
1293 }
1294 return 0;
1295}
1296
1297int
1298sys_setsid(tcp)
1299struct tcb *tcp;
1300{
1301 return 0;
1302}
1303
1304int
1305sys_getpgid(tcp)
1306struct tcb *tcp;
1307{
1308 if (entering(tcp)) {
1309 tprintf("%lu", tcp->u_arg[0]);
1310 }
1311 return 0;
1312}
1313
1314int
1315sys_setpgid(tcp)
1316struct tcb *tcp;
1317{
1318 if (entering(tcp)) {
1319 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1320 }
1321 return 0;
1322}
1323
John Hughesc61eb3d2002-05-17 11:37:50 +00001324#if UNIXWARE >= 2
1325
1326#include <sys/privilege.h>
1327
1328
1329static struct xlat procpriv_cmds [] = {
1330 { SETPRV, "SETPRV" },
1331 { CLRPRV, "CLRPRV" },
1332 { PUTPRV, "PUTPRV" },
1333 { GETPRV, "GETPRV" },
1334 { CNTPRV, "CNTPRV" },
1335 { 0, NULL },
1336};
1337
1338
1339static struct xlat procpriv_priv [] = {
1340 { P_OWNER, "P_OWNER" },
1341 { P_AUDIT, "P_AUDIT" },
1342 { P_COMPAT, "P_COMPAT" },
1343 { P_DACREAD, "P_DACREAD" },
1344 { P_DACWRITE, "P_DACWRITE" },
1345 { P_DEV, "P_DEV" },
1346 { P_FILESYS, "P_FILESYS" },
1347 { P_MACREAD, "P_MACREAD" },
1348 { P_MACWRITE, "P_MACWRITE" },
1349 { P_MOUNT, "P_MOUNT" },
1350 { P_MULTIDIR, "P_MULTIDIR" },
1351 { P_SETPLEVEL, "P_SETPLEVEL" },
1352 { P_SETSPRIV, "P_SETSPRIV" },
1353 { P_SETUID, "P_SETUID" },
1354 { P_SYSOPS, "P_SYSOPS" },
1355 { P_SETUPRIV, "P_SETUPRIV" },
1356 { P_DRIVER, "P_DRIVER" },
1357 { P_RTIME, "P_RTIME" },
1358 { P_MACUPGRADE, "P_MACUPGRADE" },
1359 { P_FSYSRANGE, "P_FSYSRANGE" },
1360 { P_SETFLEVEL, "P_SETFLEVEL" },
1361 { P_AUDITWR, "P_AUDITWR" },
1362 { P_TSHAR, "P_TSHAR" },
1363 { P_PLOCK, "P_PLOCK" },
1364 { P_CORE, "P_CORE" },
1365 { P_LOADMOD, "P_LOADMOD" },
1366 { P_BIND, "P_BIND" },
1367 { P_ALLPRIVS, "P_ALLPRIVS" },
1368 { 0, NULL },
1369};
1370
1371
1372static struct xlat procpriv_type [] = {
1373 { PS_FIX, "PS_FIX" },
1374 { PS_INH, "PS_INH" },
1375 { PS_MAX, "PS_MAX" },
1376 { PS_WKG, "PS_WKG" },
1377 { 0, NULL },
1378};
1379
1380
1381static void
1382printpriv(tcp, addr, len, opt)
1383struct tcb *tcp;
1384long addr;
1385int len;
1386struct xlat *opt;
1387{
1388 priv_t buf [128];
1389 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1390 int dots = len > max;
1391 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001392
John Hughesc61eb3d2002-05-17 11:37:50 +00001393 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001394
John Hughesc61eb3d2002-05-17 11:37:50 +00001395 if (len <= 0 ||
1396 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1397 {
1398 tprintf ("%#lx", addr);
1399 return;
1400 }
1401
1402 tprintf ("[");
1403
1404 for (i = 0; i < len; ++i) {
1405 char *t, *p;
1406
1407 if (i) tprintf (", ");
1408
1409 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1410 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1411 {
1412 tprintf ("%s|%s", t, p);
1413 }
1414 else {
1415 tprintf ("%#lx", buf [i]);
1416 }
1417 }
1418
1419 if (dots) tprintf (" ...");
1420
1421 tprintf ("]");
1422}
1423
1424
1425int
1426sys_procpriv(tcp)
1427struct tcb *tcp;
1428{
1429 if (entering(tcp)) {
1430 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1431 switch (tcp->u_arg[0]) {
1432 case CNTPRV:
1433 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1434 break;
1435
1436 case GETPRV:
1437 break;
1438
1439 default:
1440 tprintf (", ");
1441 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1442 tprintf (", %ld", tcp->u_arg[2]);
1443 }
1444 }
1445 else if (tcp->u_arg[0] == GETPRV) {
1446 if (syserror (tcp)) {
1447 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1448 }
1449 else {
1450 tprintf (", ");
1451 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1452 tprintf (", %ld", tcp->u_arg[2]);
1453 }
1454 }
Roland McGrath5a223472002-12-15 23:58:26 +00001455
John Hughesc61eb3d2002-05-17 11:37:50 +00001456 return 0;
1457}
1458
1459#endif
1460
1461
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001462void
1463fake_execve(tcp, program, argv, envp)
1464struct tcb *tcp;
1465char *program;
1466char *argv[];
1467char *envp[];
1468{
1469 int i;
1470
1471#ifdef ARM
1472 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1473 return;
1474#else
1475 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1476 return;
1477#endif /* !ARM */
1478 printleader(tcp);
1479 tprintf("execve(");
1480 string_quote(program);
1481 tprintf(", [");
1482 for (i = 0; argv[i] != NULL; i++) {
1483 if (i != 0)
1484 tprintf(", ");
1485 string_quote(argv[i]);
1486 }
1487 for (i = 0; envp[i] != NULL; i++)
1488 ;
1489 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1490 tabto(acolumn);
1491 tprintf("= 0");
1492 printtrailer(tcp);
1493}
1494
1495static void
1496printargv(tcp, addr)
1497struct tcb *tcp;
1498long addr;
1499{
1500 char *cp;
1501 char *sep;
1502 int max = max_strlen / 2;
1503
1504 for (sep = ""; --max >= 0; sep = ", ") {
1505 if (!abbrev(tcp))
1506 max++;
1507 if (umove(tcp, addr, &cp) < 0) {
1508 tprintf("%#lx", addr);
1509 return;
1510 }
1511 if (cp == 0)
1512 break;
1513 tprintf(sep);
1514 printstr(tcp, (long) cp, -1);
1515 addr += sizeof(char *);
1516 }
1517 if (cp)
1518 tprintf(", ...");
1519}
1520
1521static void
1522printargc(fmt, tcp, addr)
1523char *fmt;
1524struct tcb *tcp;
1525long addr;
1526{
1527 int count;
1528 char *cp;
1529
1530 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1531 addr += sizeof(char *);
1532 }
1533 tprintf(fmt, count, count == 1 ? "" : "s");
1534}
1535
1536int
1537sys_execv(tcp)
1538struct tcb *tcp;
1539{
1540 if (entering(tcp)) {
1541 printpath(tcp, tcp->u_arg[0]);
1542 if (!verbose(tcp))
1543 tprintf(", %#lx", tcp->u_arg[1]);
1544#if 0
1545 else if (abbrev(tcp))
1546 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1547#endif
1548 else {
1549 tprintf(", [");
1550 printargv(tcp, tcp->u_arg[1]);
1551 tprintf("]");
1552 }
1553 }
1554 return 0;
1555}
1556
1557int
1558sys_execve(tcp)
1559struct tcb *tcp;
1560{
1561 if (entering(tcp)) {
1562 printpath(tcp, tcp->u_arg[0]);
1563 if (!verbose(tcp))
1564 tprintf(", %#lx", tcp->u_arg[1]);
1565#if 0
1566 else if (abbrev(tcp))
1567 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1568#endif
1569 else {
1570 tprintf(", [");
1571 printargv(tcp, tcp->u_arg[1]);
1572 tprintf("]");
1573 }
1574 if (!verbose(tcp))
1575 tprintf(", %#lx", tcp->u_arg[2]);
1576 else if (abbrev(tcp))
1577 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1578 else {
1579 tprintf(", [");
1580 printargv(tcp, tcp->u_arg[2]);
1581 tprintf("]");
1582 }
1583 }
Roland McGrathb4968be2003-01-20 09:04:33 +00001584#if defined LINUX && defined TCB_WAITEXECVE
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001585 tcp->flags |= TCB_WAITEXECVE;
Roland McGrathb4968be2003-01-20 09:04:33 +00001586#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001587 return 0;
1588}
1589
John Hughes4e36a812001-04-18 15:11:51 +00001590#if UNIXWARE > 2
1591
1592int sys_rexecve(tcp)
1593struct tcb *tcp;
1594{
1595 if (entering (tcp)) {
1596 sys_execve (tcp);
1597 tprintf (", %ld", tcp->u_arg[3]);
1598 }
1599 return 0;
1600}
1601
1602#endif
1603
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001604int
1605internal_exec(tcp)
1606struct tcb *tcp;
1607{
1608#ifdef SUNOS4
1609 if (exiting(tcp) && !syserror(tcp) && followfork)
1610 fixvfork(tcp);
1611#endif /* SUNOS4 */
1612 return 0;
1613}
1614
1615#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001616#ifndef __WNOTHREAD
1617#define __WNOTHREAD 0x20000000
1618#endif
1619#ifndef __WALL
1620#define __WALL 0x40000000
1621#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001622#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001623#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001624#endif
1625#endif /* LINUX */
1626
1627static struct xlat wait4_options[] = {
1628 { WNOHANG, "WNOHANG" },
1629#ifndef WSTOPPED
1630 { WUNTRACED, "WUNTRACED" },
1631#endif
1632#ifdef WEXITED
1633 { WEXITED, "WEXITED" },
1634#endif
1635#ifdef WTRAPPED
1636 { WTRAPPED, "WTRAPPED" },
1637#endif
1638#ifdef WSTOPPED
1639 { WSTOPPED, "WSTOPPED" },
1640#endif
1641#ifdef WCONTINUED
1642 { WCONTINUED, "WCONTINUED" },
1643#endif
1644#ifdef WNOWAIT
1645 { WNOWAIT, "WNOWAIT" },
1646#endif
1647#ifdef __WCLONE
1648 { __WCLONE, "__WCLONE" },
1649#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001650#ifdef __WALL
1651 { __WALL, "__WALL" },
1652#endif
1653#ifdef __WNOTHREAD
1654 { __WNOTHREAD, "__WNOTHREAD" },
1655#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001656 { 0, NULL },
1657};
1658
1659static int
1660printstatus(status)
1661int status;
1662{
1663 int exited = 0;
1664
1665 /*
1666 * Here is a tricky presentation problem. This solution
1667 * is still not entirely satisfactory but since there
1668 * are no wait status constructors it will have to do.
1669 */
1670 if (WIFSTOPPED(status))
1671 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001672 signame(WSTOPSIG(status)));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001673 else if WIFSIGNALED(status)
1674 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001675 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001676 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1677 else if WIFEXITED(status) {
1678 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1679 WEXITSTATUS(status));
1680 exited = 1;
1681 }
1682 else
1683 tprintf("[%#x]", status);
1684 return exited;
1685}
1686
1687static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001688printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001689struct tcb *tcp;
1690int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001691int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001692{
1693 int status;
1694 int exited = 0;
1695
1696 if (entering(tcp)) {
1697 tprintf("%ld, ", tcp->u_arg[0]);
1698 } else {
1699 /* status */
1700 if (!tcp->u_arg[1])
1701 tprintf("NULL");
1702 else if (syserror(tcp) || tcp->u_rval == 0)
1703 tprintf("%#lx", tcp->u_arg[1]);
1704 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1705 tprintf("[?]");
1706 else
1707 exited = printstatus(status);
1708 /* options */
1709 tprintf(", ");
1710 if (!printflags(wait4_options, tcp->u_arg[2]))
1711 tprintf("0");
1712 if (n == 4) {
1713 tprintf(", ");
1714 /* usage */
1715 if (!tcp->u_arg[3])
1716 tprintf("NULL");
1717#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001718 else if (tcp->u_rval > 0) {
1719#ifdef LINUX_64BIT
1720 if (bitness)
1721 printrusage32(tcp, tcp->u_arg[3]);
1722 else
1723#endif
1724 printrusage(tcp, tcp->u_arg[3]);
1725 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001726#endif /* LINUX */
1727#ifdef SUNOS4
1728 else if (tcp->u_rval > 0 && exited)
1729 printrusage(tcp, tcp->u_arg[3]);
1730#endif /* SUNOS4 */
1731 else
1732 tprintf("%#lx", tcp->u_arg[3]);
1733 }
1734 }
1735 return 0;
1736}
1737
1738int
1739internal_wait(tcp)
1740struct tcb *tcp;
1741{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001742 int got_kids;
1743
1744#ifdef TCB_CLONE_THREAD
1745 if (tcp->flags & TCB_CLONE_THREAD)
1746 /* The children we wait for are our parent's children. */
1747 got_kids = (tcp->parent->nchildren
1748 > tcp->parent->nclone_detached);
1749 else
1750 got_kids = (tcp->nchildren > tcp->nclone_detached);
1751#else
1752 got_kids = tcp->nchildren > 0;
1753#endif
1754
1755 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001756 /* There are children that this parent should block for.
1757 But ptrace made us the parent of the traced children
1758 and the real parent will get ECHILD from the wait call.
1759
1760 XXX If we attached with strace -f -p PID, then there
1761 may be untraced dead children the parent could be reaping
1762 now, but we make him block. */
1763
1764 /* ??? WTA: fix bug with hanging children */
1765
1766 if (!(tcp->u_arg[2] & WNOHANG)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001767 /* There are traced children */
1768 tcp->flags |= TCB_SUSPENDED;
1769 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001770#ifdef TCB_CLONE_THREAD
1771 if (tcp->flags & TCB_CLONE_THREAD)
1772 tcp->parent->nclone_waiting++;
1773#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001774 }
1775 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001776 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001777 if (tcp->u_arg[2] & WNOHANG) {
1778 /* We must force a fake result of 0 instead of
1779 the ECHILD error. */
1780 extern int force_result();
1781 return force_result(tcp, 0, 0);
1782 }
1783 else
1784 fprintf(stderr,
1785 "internal_wait: should not have resumed %d\n",
1786 tcp->pid);
1787 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001788 return 0;
1789}
1790
1791#ifdef SVR4
1792
1793int
1794sys_wait(tcp)
1795struct tcb *tcp;
1796{
1797 if (exiting(tcp)) {
1798 /* The library wrapper stuffs this into the user variable. */
1799 if (!syserror(tcp))
1800 printstatus(getrval2(tcp));
1801 }
1802 return 0;
1803}
1804
1805#endif /* SVR4 */
1806
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001807#ifdef FREEBSD
1808int
1809sys_wait(tcp)
1810struct tcb *tcp;
1811{
1812 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001813
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001814 if (exiting(tcp)) {
1815 if (!syserror(tcp)) {
1816 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1817 tprintf("%#lx", tcp->u_arg[0]);
1818 else
1819 printstatus(status);
1820 }
1821 }
1822 return 0;
1823}
1824#endif
1825
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001826int
1827sys_waitpid(tcp)
1828struct tcb *tcp;
1829{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001830 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001831}
1832
1833int
1834sys_wait4(tcp)
1835struct tcb *tcp;
1836{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001837 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001838}
1839
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001840#ifdef ALPHA
1841int
1842sys_osf_wait4(tcp)
1843struct tcb *tcp;
1844{
1845 return printwaitn(tcp, 4, 1);
1846}
1847#endif
1848
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001849#ifdef SVR4
1850
1851static struct xlat waitid_types[] = {
1852 { P_PID, "P_PID" },
1853 { P_PPID, "P_PPID" },
1854 { P_PGID, "P_PGID" },
1855 { P_SID, "P_SID" },
1856 { P_CID, "P_CID" },
1857 { P_UID, "P_UID" },
1858 { P_GID, "P_GID" },
1859 { P_ALL, "P_ALL" },
1860#ifdef P_LWPID
1861 { P_LWPID, "P_LWPID" },
1862#endif
1863 { 0, NULL },
1864};
1865
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001866int
1867sys_waitid(tcp)
1868struct tcb *tcp;
1869{
1870 siginfo_t si;
1871 int exited;
1872
1873 if (entering(tcp)) {
1874 printxval(waitid_types, tcp->u_arg[0], "P_???");
1875 tprintf(", %ld, ", tcp->u_arg[1]);
1876 if (tcp->nchildren > 0) {
1877 /* There are traced children */
1878 tcp->flags |= TCB_SUSPENDED;
1879 tcp->waitpid = tcp->u_arg[0];
1880 }
1881 }
1882 else {
1883 /* siginfo */
1884 exited = 0;
1885 if (!tcp->u_arg[2])
1886 tprintf("NULL");
1887 else if (syserror(tcp))
1888 tprintf("%#lx", tcp->u_arg[2]);
1889 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1890 tprintf("{???}");
1891 else
John Hughes58265892001-10-18 15:13:53 +00001892 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001893 /* options */
1894 tprintf(", ");
1895 if (!printflags(wait4_options, tcp->u_arg[3]))
1896 tprintf("0");
1897 }
1898 return 0;
1899}
1900
1901#endif /* SVR4 */
1902
1903int
1904sys_alarm(tcp)
1905struct tcb *tcp;
1906{
1907 if (entering(tcp))
1908 tprintf("%lu", tcp->u_arg[0]);
1909 return 0;
1910}
1911
1912int
1913sys_uname(tcp)
1914struct tcb *tcp;
1915{
1916 struct utsname uname;
1917
1918 if (exiting(tcp)) {
1919 if (syserror(tcp) || !verbose(tcp))
1920 tprintf("%#lx", tcp->u_arg[0]);
1921 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1922 tprintf("{...}");
1923 else if (!abbrev(tcp)) {
1924
1925 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1926 uname.sysname, uname.nodename);
1927 tprintf("release=\"%s\", version=\"%s\", ",
1928 uname.release, uname.version);
1929 tprintf("machine=\"%s\"", uname.machine);
1930#ifdef LINUX
1931#ifndef __GLIBC__
1932 tprintf(", domainname=\"%s\"", uname.domainname);
1933#endif /* __GLIBC__ */
1934#endif /* LINUX */
1935 tprintf("}");
1936 }
1937 else
1938 tprintf("{sys=\"%s\", node=\"%s\", ...}",
1939 uname.sysname, uname.nodename);
1940 }
1941 return 0;
1942}
1943
1944#ifndef SVR4
1945
1946static struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00001947#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001948 { PTRACE_TRACEME, "PTRACE_TRACEME" },
1949 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
1950 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
1951 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
1952 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
1953 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
1954 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
1955 { PTRACE_CONT, "PTRACE_CONT" },
1956 { PTRACE_KILL, "PTRACE_KILL" },
1957 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
1958 { PTRACE_ATTACH, "PTRACE_ATTACH" },
1959 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001960#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001961 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001962#endif
1963#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001964 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001965#endif
1966#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001967 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00001968#endif
1969#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001970 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00001971#endif
1972#ifdef PTRACE_GETFPXREGS
1973 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
1974#endif
1975#ifdef PTRACE_SETFPXREGS
1976 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
1977#endif
1978#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001979 { PTRACE_READDATA, "PTRACE_READDATA" },
1980 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
1981 { PTRACE_READTEXT, "PTRACE_READTEXT" },
1982 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
1983 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
1984 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
1985#ifdef SPARC
1986 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
1987 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
1988#else /* !SPARC */
1989 { PTRACE_22, "PTRACE_PTRACE_22" },
1990 { PTRACE_23, "PTRACE_PTRACE_23" },
1991#endif /* !SPARC */
1992#endif /* SUNOS4 */
1993 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
1994#ifdef SUNOS4
1995 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
1996#ifdef I386
1997 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
1998 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
1999 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2000#else /* !I386 */
2001 { PTRACE_26, "PTRACE_26" },
2002 { PTRACE_27, "PTRACE_27" },
2003 { PTRACE_28, "PTRACE_28" },
2004#endif /* !I386 */
2005 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2006#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002007#else /* FREEBSD */
2008 { PT_TRACE_ME, "PT_TRACE_ME" },
2009 { PT_READ_I, "PT_READ_I" },
2010 { PT_READ_D, "PT_READ_D" },
2011 { PT_WRITE_I, "PT_WRITE_I" },
2012 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002013#ifdef PT_READ_U
2014 { PT_READ_U, "PT_READ_U" },
2015#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002016 { PT_CONTINUE, "PT_CONTINUE" },
2017 { PT_KILL, "PT_KILL" },
2018 { PT_STEP, "PT_STEP" },
2019 { PT_ATTACH, "PT_ATTACH" },
2020 { PT_DETACH, "PT_DETACH" },
2021 { PT_GETREGS, "PT_GETREGS" },
2022 { PT_SETREGS, "PT_SETREGS" },
2023 { PT_GETFPREGS, "PT_GETFPREGS" },
2024 { PT_SETFPREGS, "PT_SETFPREGS" },
2025 { PT_GETDBREGS, "PT_GETDBREGS" },
2026 { PT_SETDBREGS, "PT_SETDBREGS" },
2027#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002028 { 0, NULL },
2029};
2030
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002031#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002032#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2033static
2034#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2035struct xlat struct_user_offsets[] = {
2036#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002037#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002038 { PT_PSWMASK, "psw_mask" },
2039 { PT_PSWADDR, "psw_addr" },
2040 { PT_GPR0, "gpr0" },
2041 { PT_GPR1, "gpr1" },
2042 { PT_GPR2, "gpr2" },
2043 { PT_GPR3, "gpr3" },
2044 { PT_GPR4, "gpr4" },
2045 { PT_GPR5, "gpr5" },
2046 { PT_GPR6, "gpr6" },
2047 { PT_GPR7, "gpr7" },
2048 { PT_GPR8, "gpr8" },
2049 { PT_GPR9, "gpr9" },
2050 { PT_GPR10, "gpr10" },
2051 { PT_GPR11, "gpr11" },
2052 { PT_GPR12, "gpr12" },
2053 { PT_GPR13, "gpr13" },
2054 { PT_GPR14, "gpr14" },
2055 { PT_GPR15, "gpr15" },
2056 { PT_ACR0, "acr0" },
2057 { PT_ACR1, "acr1" },
2058 { PT_ACR2, "acr2" },
2059 { PT_ACR3, "acr3" },
2060 { PT_ACR4, "acr4" },
2061 { PT_ACR5, "acr5" },
2062 { PT_ACR6, "acr6" },
2063 { PT_ACR7, "acr7" },
2064 { PT_ACR8, "acr8" },
2065 { PT_ACR9, "acr9" },
2066 { PT_ACR10, "acr10" },
2067 { PT_ACR11, "acr11" },
2068 { PT_ACR12, "acr12" },
2069 { PT_ACR13, "acr13" },
2070 { PT_ACR14, "acr14" },
2071 { PT_ACR15, "acr15" },
2072 { PT_ORIGGPR2, "orig_gpr2" },
2073 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002074#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002075 { PT_FPR0_HI, "fpr0.hi" },
2076 { PT_FPR0_LO, "fpr0.lo" },
2077 { PT_FPR1_HI, "fpr1.hi" },
2078 { PT_FPR1_LO, "fpr1.lo" },
2079 { PT_FPR2_HI, "fpr2.hi" },
2080 { PT_FPR2_LO, "fpr2.lo" },
2081 { PT_FPR3_HI, "fpr3.hi" },
2082 { PT_FPR3_LO, "fpr3.lo" },
2083 { PT_FPR4_HI, "fpr4.hi" },
2084 { PT_FPR4_LO, "fpr4.lo" },
2085 { PT_FPR5_HI, "fpr5.hi" },
2086 { PT_FPR5_LO, "fpr5.lo" },
2087 { PT_FPR6_HI, "fpr6.hi" },
2088 { PT_FPR6_LO, "fpr6.lo" },
2089 { PT_FPR7_HI, "fpr7.hi" },
2090 { PT_FPR7_LO, "fpr7.lo" },
2091 { PT_FPR8_HI, "fpr8.hi" },
2092 { PT_FPR8_LO, "fpr8.lo" },
2093 { PT_FPR9_HI, "fpr9.hi" },
2094 { PT_FPR9_LO, "fpr9.lo" },
2095 { PT_FPR10_HI, "fpr10.hi" },
2096 { PT_FPR10_LO, "fpr10.lo" },
2097 { PT_FPR11_HI, "fpr11.hi" },
2098 { PT_FPR11_LO, "fpr11.lo" },
2099 { PT_FPR12_HI, "fpr12.hi" },
2100 { PT_FPR12_LO, "fpr12.lo" },
2101 { PT_FPR13_HI, "fpr13.hi" },
2102 { PT_FPR13_LO, "fpr13.lo" },
2103 { PT_FPR14_HI, "fpr14.hi" },
2104 { PT_FPR14_LO, "fpr14.lo" },
2105 { PT_FPR15_HI, "fpr15.hi" },
2106 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002107#endif
2108#if defined(S390X)
2109 { PT_FPR0, "fpr0" },
2110 { PT_FPR1, "fpr1" },
2111 { PT_FPR2, "fpr2" },
2112 { PT_FPR3, "fpr3" },
2113 { PT_FPR4, "fpr4" },
2114 { PT_FPR5, "fpr5" },
2115 { PT_FPR6, "fpr6" },
2116 { PT_FPR7, "fpr7" },
2117 { PT_FPR8, "fpr8" },
2118 { PT_FPR9, "fpr9" },
2119 { PT_FPR10, "fpr10" },
2120 { PT_FPR11, "fpr11" },
2121 { PT_FPR12, "fpr12" },
2122 { PT_FPR13, "fpr13" },
2123 { PT_FPR14, "fpr14" },
2124 { PT_FPR15, "fpr15" },
2125#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002126 { PT_CR_9, "cr9" },
2127 { PT_CR_10, "cr10" },
2128 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002129 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002130#endif
2131#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002132 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002133#elif defined(HPPA)
2134 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002135#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002136#ifndef PT_ORIG_R3
2137#define PT_ORIG_R3 34
2138#endif
Roland McGratheb285352003-01-14 09:59:00 +00002139#define REGSIZE (sizeof(unsigned long))
2140 { REGSIZE*PT_R0, "r0" },
2141 { REGSIZE*PT_R1, "r1" },
2142 { REGSIZE*PT_R2, "r2" },
2143 { REGSIZE*PT_R3, "r3" },
2144 { REGSIZE*PT_R4, "r4" },
2145 { REGSIZE*PT_R5, "r5" },
2146 { REGSIZE*PT_R6, "r6" },
2147 { REGSIZE*PT_R7, "r7" },
2148 { REGSIZE*PT_R8, "r8" },
2149 { REGSIZE*PT_R9, "r9" },
2150 { REGSIZE*PT_R10, "r10" },
2151 { REGSIZE*PT_R11, "r11" },
2152 { REGSIZE*PT_R12, "r12" },
2153 { REGSIZE*PT_R13, "r13" },
2154 { REGSIZE*PT_R14, "r14" },
2155 { REGSIZE*PT_R15, "r15" },
2156 { REGSIZE*PT_R16, "r16" },
2157 { REGSIZE*PT_R17, "r17" },
2158 { REGSIZE*PT_R18, "r18" },
2159 { REGSIZE*PT_R19, "r19" },
2160 { REGSIZE*PT_R20, "r20" },
2161 { REGSIZE*PT_R21, "r21" },
2162 { REGSIZE*PT_R22, "r22" },
2163 { REGSIZE*PT_R23, "r23" },
2164 { REGSIZE*PT_R24, "r24" },
2165 { REGSIZE*PT_R25, "r25" },
2166 { REGSIZE*PT_R26, "r26" },
2167 { REGSIZE*PT_R27, "r27" },
2168 { REGSIZE*PT_R28, "r28" },
2169 { REGSIZE*PT_R29, "r29" },
2170 { REGSIZE*PT_R30, "r30" },
2171 { REGSIZE*PT_R31, "r31" },
2172 { REGSIZE*PT_NIP, "NIP" },
2173 { REGSIZE*PT_MSR, "MSR" },
2174 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2175 { REGSIZE*PT_CTR, "CTR" },
2176 { REGSIZE*PT_LNK, "LNK" },
2177 { REGSIZE*PT_XER, "XER" },
2178 { REGSIZE*PT_CCR, "CCR" },
2179 { REGSIZE*PT_FPR0, "FPR0" },
2180#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002181#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002182#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002183 { 0, "r0" },
2184 { 1, "r1" },
2185 { 2, "r2" },
2186 { 3, "r3" },
2187 { 4, "r4" },
2188 { 5, "r5" },
2189 { 6, "r6" },
2190 { 7, "r7" },
2191 { 8, "r8" },
2192 { 9, "r9" },
2193 { 10, "r10" },
2194 { 11, "r11" },
2195 { 12, "r12" },
2196 { 13, "r13" },
2197 { 14, "r14" },
2198 { 15, "r15" },
2199 { 16, "r16" },
2200 { 17, "r17" },
2201 { 18, "r18" },
2202 { 19, "r19" },
2203 { 20, "r20" },
2204 { 21, "r21" },
2205 { 22, "r22" },
2206 { 23, "r23" },
2207 { 24, "r24" },
2208 { 25, "r25" },
2209 { 26, "r26" },
2210 { 27, "r27" },
2211 { 28, "r28" },
2212 { 29, "gp" },
2213 { 30, "fp" },
2214 { 31, "zero" },
2215 { 32, "fp0" },
2216 { 33, "fp" },
2217 { 34, "fp2" },
2218 { 35, "fp3" },
2219 { 36, "fp4" },
2220 { 37, "fp5" },
2221 { 38, "fp6" },
2222 { 39, "fp7" },
2223 { 40, "fp8" },
2224 { 41, "fp9" },
2225 { 42, "fp10" },
2226 { 43, "fp11" },
2227 { 44, "fp12" },
2228 { 45, "fp13" },
2229 { 46, "fp14" },
2230 { 47, "fp15" },
2231 { 48, "fp16" },
2232 { 49, "fp17" },
2233 { 50, "fp18" },
2234 { 51, "fp19" },
2235 { 52, "fp20" },
2236 { 53, "fp21" },
2237 { 54, "fp22" },
2238 { 55, "fp23" },
2239 { 56, "fp24" },
2240 { 57, "fp25" },
2241 { 58, "fp26" },
2242 { 59, "fp27" },
2243 { 60, "fp28" },
2244 { 61, "fp29" },
2245 { 62, "fp30" },
2246 { 63, "fp31" },
2247 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002248#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002249#ifdef IA64
2250 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2251 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2252 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2253 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2254 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2255 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2256 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2257 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2258 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2259 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2260 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2261 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2262 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2263 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2264 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2265 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2266 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2267 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2268 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2269 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2270 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2271 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2272 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2273 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2274 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2275 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2276 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2277 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2278 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2279 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2280 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2281 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2282 /* switch stack: */
2283 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2284 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2285 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2286 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2287 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2288 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2289 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2290 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2291 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2292 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002293 { PT_B0, "kb0" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002294 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2295 { PT_B4, "b4" }, { PT_B5, "b5" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002296 { PT_AR_PFS, "kar.pfs" },
2297 { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" },
2298 { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" },
2299 { PT_PR, "k.pr" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002300 /* pt_regs */
2301 { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002302 /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002303 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2304 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2305 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2306 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2307 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2308 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2309 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2310 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2311 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2312 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2313 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2314 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2315 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2316 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2317 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2318#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002319#ifdef I386
2320 { 4*EBX, "4*EBX" },
2321 { 4*ECX, "4*ECX" },
2322 { 4*EDX, "4*EDX" },
2323 { 4*ESI, "4*ESI" },
2324 { 4*EDI, "4*EDI" },
2325 { 4*EBP, "4*EBP" },
2326 { 4*EAX, "4*EAX" },
2327 { 4*DS, "4*DS" },
2328 { 4*ES, "4*ES" },
2329 { 4*FS, "4*FS" },
2330 { 4*GS, "4*GS" },
2331 { 4*ORIG_EAX, "4*ORIG_EAX" },
2332 { 4*EIP, "4*EIP" },
2333 { 4*CS, "4*CS" },
2334 { 4*EFL, "4*EFL" },
2335 { 4*UESP, "4*UESP" },
2336 { 4*SS, "4*SS" },
2337#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002338#ifdef X86_64
2339 { 8*RDI, "8*RDI" },
2340 { 8*RSI, "8*RSI" },
2341 { 8*RDX, "8*RDX" },
2342 { 8*R10, "8*R10" },
2343 { 8*R8, "8*R8" },
2344 { 8*R9, "8*R9" },
2345 { 8*RBX, "8*RBX" },
2346 { 8*RCX, "8*RCX" },
2347 { 8*RBP, "8*RBP" },
2348 { 8*RAX, "8*RAX" },
2349#if 0
2350 { 8*DS, "8*DS" },
2351 { 8*ES, "8*ES" },
2352 { 8*FS, "8*FS" },
2353 { 8*GS, "8*GS" },
2354#endif
2355 { 8*ORIG_RAX, "8*ORIG_EAX" },
2356 { 8*RIP, "8*RIP" },
2357 { 8*CS, "8*CS" },
2358 { 8*EFLAGS, "8*EFL" },
2359 { 8*RSP, "8*RSP" },
2360 { 8*SS, "8*SS" },
2361 { 8*R11, "8*R11" },
2362 { 8*R12, "8*R12" },
2363 { 8*R13, "8*R13" },
2364 { 8*R14, "8*R14" },
2365 { 8*R15, "8*R15" },
2366#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002367#ifdef M68K
2368 { 4*PT_D1, "4*PT_D1" },
2369 { 4*PT_D2, "4*PT_D2" },
2370 { 4*PT_D3, "4*PT_D3" },
2371 { 4*PT_D4, "4*PT_D4" },
2372 { 4*PT_D5, "4*PT_D5" },
2373 { 4*PT_D6, "4*PT_D6" },
2374 { 4*PT_D7, "4*PT_D7" },
2375 { 4*PT_A0, "4*PT_A0" },
2376 { 4*PT_A1, "4*PT_A1" },
2377 { 4*PT_A2, "4*PT_A2" },
2378 { 4*PT_A3, "4*PT_A3" },
2379 { 4*PT_A4, "4*PT_A4" },
2380 { 4*PT_A5, "4*PT_A5" },
2381 { 4*PT_A6, "4*PT_A6" },
2382 { 4*PT_D0, "4*PT_D0" },
2383 { 4*PT_USP, "4*PT_USP" },
2384 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2385 { 4*PT_SR, "4*PT_SR" },
2386 { 4*PT_PC, "4*PT_PC" },
2387#endif /* M68K */
2388#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002389#ifdef SH
2390 { 4*REG_REG0, "4*REG_REG0" },
2391 { 4*(REG_REG0+1), "4*REG_REG1" },
2392 { 4*(REG_REG0+2), "4*REG_REG2" },
2393 { 4*(REG_REG0+3), "4*REG_REG3" },
2394 { 4*(REG_REG0+4), "4*REG_REG4" },
2395 { 4*(REG_REG0+5), "4*REG_REG5" },
2396 { 4*(REG_REG0+6), "4*REG_REG6" },
2397 { 4*(REG_REG0+7), "4*REG_REG7" },
2398 { 4*(REG_REG0+8), "4*REG_REG8" },
2399 { 4*(REG_REG0+9), "4*REG_REG9" },
2400 { 4*(REG_REG0+10), "4*REG_REG10" },
2401 { 4*(REG_REG0+11), "4*REG_REG11" },
2402 { 4*(REG_REG0+12), "4*REG_REG12" },
2403 { 4*(REG_REG0+13), "4*REG_REG13" },
2404 { 4*(REG_REG0+14), "4*REG_REG14" },
2405 { 4*REG_REG15, "4*REG_REG15" },
2406 { 4*REG_PC, "4*REG_PC" },
2407 { 4*REG_PR, "4*REG_PR" },
2408 { 4*REG_SR, "4*REG_SR" },
2409 { 4*REG_GBR, "4*REG_GBR" },
2410 { 4*REG_MACH, "4*REG_MACH" },
2411 { 4*REG_MACL, "4*REG_MACL" },
2412 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2413 { 4*REG_FPUL, "4*REG_FPUL" },
2414 { 4*REG_FPREG0, "4*REG_FPREG0" },
2415 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2416 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2417 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2418 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2419 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2420 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2421 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2422 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2423 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2424 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2425 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2426 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2427 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2428 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2429 { 4*REG_FPREG15, "4*REG_FPREG15" },
2430 { 4*REG_XDREG0, "4*REG_XDREG0" },
2431 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2432 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2433 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2434 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2435 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2436 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2437 { 4*REG_XDREG14, "4*REG_XDREG14" },
2438 { 4*REG_FPSCR, "4*REG_FPSCR" },
2439#endif /* SH */
2440
Michal Ludvig10a88d02002-10-07 14:31:00 +00002441#if !defined(S390) && !defined(S390X) && !defined(MIPS)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002442 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002443#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002444#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002445 { uoff(i387), "offsetof(struct user, i387)" },
2446#else /* !I386 */
2447#ifdef M68K
2448 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2449#endif /* M68K */
2450#endif /* !I386 */
2451 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2452 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2453 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2454 { uoff(start_code), "offsetof(struct user, start_code)" },
2455 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2456 { uoff(signal), "offsetof(struct user, signal)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002457#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002458 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002459#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002460 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002461#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002462 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2463#endif
2464 { uoff(magic), "offsetof(struct user, magic)" },
2465 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002466#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002467 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2468#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002469#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002470#endif /* !ALPHA */
2471#endif /* !POWERPC/!SPARC */
2472#endif /* LINUX */
2473#ifdef SUNOS4
2474 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2475 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2476 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2477 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2478 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2479 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2480 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2481 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2482 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2483 { uoff(u_error), "offsetof(struct user, u_error)" },
2484 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2485 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2486 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2487 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2488 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2489 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2490 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2491 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2492 { uoff(u_code), "offsetof(struct user, u_code)" },
2493 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2494 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2495 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2496 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2497 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2498 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2499 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2500 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2501 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2502 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2503 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2504 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2505 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2506 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2507 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2508 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2509 { uoff(u_start), "offsetof(struct user, u_start)" },
2510 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2511 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2512 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2513 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2514 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2515 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2516 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2517 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2518 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2519#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002520#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002521 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002522#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002523 { 0, NULL },
2524};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002525#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002526
2527int
2528sys_ptrace(tcp)
2529struct tcb *tcp;
2530{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002531 struct xlat *x;
2532 long addr;
2533
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002534 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002535 printxval(ptrace_cmds, tcp->u_arg[0],
2536#ifndef FREEBSD
2537 "PTRACE_???"
2538#else
2539 "PT_???"
2540#endif
2541 );
2542 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002543 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002544#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002545 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2546 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2547 for (x = struct_user_offsets; x->str; x++) {
2548 if (x->val >= addr)
2549 break;
2550 }
2551 if (!x->str)
2552 tprintf("%#lx, ", addr);
2553 else if (x->val > addr && x != struct_user_offsets) {
2554 x--;
2555 tprintf("%s + %ld, ", x->str, addr - x->val);
2556 }
2557 else
2558 tprintf("%s, ", x->str);
2559 }
2560 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002561#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002562 tprintf("%#lx, ", tcp->u_arg[2]);
2563#ifdef LINUX
2564 switch (tcp->u_arg[0]) {
2565 case PTRACE_PEEKDATA:
2566 case PTRACE_PEEKTEXT:
2567 case PTRACE_PEEKUSER:
2568 break;
2569 case PTRACE_CONT:
2570 case PTRACE_SINGLESTEP:
2571 case PTRACE_SYSCALL:
2572 case PTRACE_DETACH:
2573 printsignal(tcp->u_arg[3]);
2574 break;
2575 default:
2576 tprintf("%#lx", tcp->u_arg[3]);
2577 break;
2578 }
2579 } else {
2580 switch (tcp->u_arg[0]) {
2581 case PTRACE_PEEKDATA:
2582 case PTRACE_PEEKTEXT:
2583 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00002584 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002585 break;
2586 }
2587 }
2588#endif /* LINUX */
2589#ifdef SUNOS4
2590 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2591 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2592 tprintf("%lu, ", tcp->u_arg[3]);
2593 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2594 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2595 tcp->u_arg[0] != PTRACE_READTEXT) {
2596 tprintf("%#lx", tcp->u_arg[3]);
2597 }
2598 } else {
2599 if (tcp->u_arg[0] == PTRACE_READDATA ||
2600 tcp->u_arg[0] == PTRACE_READTEXT) {
2601 tprintf("%lu, ", tcp->u_arg[3]);
2602 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2603 }
2604 }
2605#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002606#ifdef FREEBSD
2607 tprintf("%lu", tcp->u_arg[3]);
2608 }
2609#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002610 return 0;
2611}
2612
2613#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002614
2615#ifdef LINUX
2616static struct xlat futexops[] = {
2617 { FUTEX_WAIT, "FUTEX_WAIT" },
2618 { FUTEX_WAKE, "FUTEX_WAKE" },
2619 { FUTEX_FD, "FUTEX_FD" },
2620 { 0, NULL }
2621};
2622
2623int
2624sys_futex(tcp)
2625struct tcb *tcp;
2626{
2627 if (entering(tcp)) {
2628 tprintf("%p, ", (void *) tcp->u_arg[0]);
2629 printflags(futexops, tcp->u_arg[1]);
Roland McGrath8dfa04a2003-03-05 04:07:55 +00002630 tprintf(", %ld", tcp->u_arg[2]);
2631 if (tcp->u_arg[1] == FUTEX_WAIT) {
2632 tprintf(", ");
2633 printtv(tcp, tcp->u_arg[3]);
2634 }
Roland McGrath5a223472002-12-15 23:58:26 +00002635 }
2636 return 0;
2637}
2638
2639static void
2640print_affinitylist(list, len)
2641unsigned long *list;
2642unsigned int len;
2643{
2644 int first = 1;
2645 tprintf(" {");
2646 while (len > sizeof (unsigned long)) {
2647 tprintf("%s %lx", first ? "" : ",", *list++);
2648 first = 0;
2649 len -= sizeof (unsigned long);
2650 }
2651 tprintf(" }");
2652}
2653
2654int
2655sys_sched_setaffinity(tcp)
2656struct tcb *tcp;
2657{
2658 if (entering(tcp)) {
2659 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2660 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2661 }
2662 return 0;
2663}
2664
2665int
2666sys_sched_getaffinity(tcp)
2667struct tcb *tcp;
2668{
2669 if (entering(tcp)) {
2670 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2671 } else {
2672 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);
2673 }
2674 return 0;
2675}
2676#endif