blob: 8c7ca1280a13aca9bd059f2b374fa95687b25fc2 [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 McGrathb4968be2003-01-20 09:04:33 +0000573 if (flags & CLONE_PARENT_SETTID) {
Roland McGrath909875b2002-12-22 03:34:36 +0000574 int pid;
Roland McGrath9677b3a2003-03-12 09:54:36 +0000575 if (umove(tcp, tcp->u_arg[ARG_PTID], &pid) == 0)
576 tprintf(", parent_tidptr=[%d]", pid);
Roland McGrath909875b2002-12-22 03:34:36 +0000577 else
Roland McGrath9677b3a2003-03-12 09:54:36 +0000578 tprintf(", parent_tidptr=%#lx",
579 tcp->u_arg[ARG_PTID]);
Roland McGrath909875b2002-12-22 03:34:36 +0000580 }
Roland McGrathb4968be2003-01-20 09:04:33 +0000581 if (flags & CLONE_SETTLS) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000582# ifdef I386
Roland McGrath909875b2002-12-22 03:34:36 +0000583 struct modify_ldt_ldt_s copy;
Roland McGrath9677b3a2003-03-12 09:54:36 +0000584 if (umove(tcp, tcp->u_arg[ARG_TLS], &copy) != -1) {
Roland McGrath909875b2002-12-22 03:34:36 +0000585 tprintf(", {entry_number:%d, ",
586 copy.entry_number);
587 if (!verbose(tcp))
588 tprintf("...}");
589 else
590 print_ldt_entry(&copy);
591 }
592 else
Roland McGrath9677b3a2003-03-12 09:54:36 +0000593# endif
Roland McGrath43f2c842003-03-12 09:58:14 +0000594 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
Roland McGrath909875b2002-12-22 03:34:36 +0000595 }
Roland McGrath9677b3a2003-03-12 09:54:36 +0000596 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
597 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000598 }
599 return 0;
600}
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000601#endif
602
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000603int
604sys_fork(tcp)
605struct tcb *tcp;
606{
607 if (exiting(tcp))
608 return RVAL_UDECIMAL;
609 return 0;
610}
611
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000612int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000613change_syscall(tcp, new)
614struct tcb *tcp;
615int new;
616{
617#if defined(LINUX)
618#if defined(I386)
619 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000620 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000621 return -1;
622 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000623#elif defined(X86_64)
624 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000625 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000626 return -1;
627 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000628#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000629 if (ptrace(PTRACE_POKEUSER, tcp->pid,
630 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000631 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000632 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000633#elif defined(S390) || defined(S390X)
634 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
635 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
636 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000637 return 0;
638#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000639 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000640 return -1;
641 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000642#elif defined(SPARC)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000643 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000644 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
645 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000646 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000647 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
648 return -1;
649 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000650#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000651 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000652 return -1;
653 return 0;
654#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000655 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000656 return -1;
657 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000658#elif defined(IA64)
659 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
660 return -1;
661 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000662#elif defined(HPPA)
663 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
664 return -1;
665 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000666#elif defined(SH)
667 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), new)<0)
668 return -1;
669 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000670#else
671#warning Do not know how to handle change_syscall for this architecture
672#endif /* architecture */
673#endif /* LINUX */
674 return -1;
675}
676
677int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000678setarg(tcp, argnum)
679 struct tcb *tcp;
680 int argnum;
681{
682#if defined (IA64)
683 {
684 unsigned long *bsp, *ap;
685
686 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
687 return -1;
688
689 ap = ia64_rse_skip_regs(bsp, argnum);
690 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000691 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000692 if (errno)
693 return -1;
694
695 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000696#elif defined(I386)
697 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000698 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000699 if (errno)
700 return -1;
701 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000702#elif defined(X86_64)
703 {
704 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
705 if (errno)
706 return -1;
707 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000708#elif defined(POWERPC)
709#ifndef PT_ORIG_R3
710#define PT_ORIG_R3 34
711#endif
712 {
713 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000714 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000715 tcp->u_arg[argnum]);
716 if (errno)
717 return -1;
718 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000719#elif defined(MIPS)
720 {
721 errno = 0;
722 if (argnum < 4)
723 ptrace(PTRACE_POKEUSER, tcp->pid,
724 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
725 else {
726 unsigned long *sp;
727
728 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
729 return -1;
730
731 ptrace(PTRACE_POKEDATA, tcp->pid,
732 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
733 }
734 if (errno)
735 return -1;
736 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000737#elif defined(S390) || defined(S390X)
738 {
739 if(argnum <= 5)
740 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000741 (char *) (argnum==0 ? PT_ORIGGPR2 :
742 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000743 tcp->u_arg[argnum]);
744 else
745 return -E2BIG;
746 if (errno)
747 return -1;
748 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000749#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000750# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000751#endif
752 return 0;
753}
754
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000755#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000756int
757internal_clone(tcp)
758struct tcb *tcp;
759{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000760 struct tcb *tcpchild;
761 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000762 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000763 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000764 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000765 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000766 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000767 if (setbpt(tcp) < 0)
768 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000769 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000770 int bpt = tcp->flags & TCB_BPTSET;
771
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000772 if (!(tcp->flags & TCB_FOLLOWFORK))
773 return 0;
774
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000775 if (syserror(tcp)) {
776 if (bpt)
777 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000778 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000779 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000780
781 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000782
783#ifdef CLONE_PTRACE /* See new setbpt code. */
784 tcpchild = pid2tcb(pid);
785 if (tcpchild != NULL) {
786 /* The child already reported its startup trap
787 before the parent reported its syscall return. */
788 if ((tcpchild->flags
789 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
790 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
791 fprintf(stderr, "\
792[preattached child %d of %d in weird state!]\n",
793 pid, tcp->pid);
794 }
795 else
796#endif
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000797 if ((tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000798 if (bpt)
799 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000800 fprintf(stderr, " [tcb table full]\n");
801 kill(pid, SIGKILL); /* XXX */
802 return 0;
803 }
804
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000805#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000806 /* Attach to the new child */
807 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000808 if (bpt)
809 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000810 perror("PTRACE_ATTACH");
811 fprintf(stderr, "Too late?\n");
812 droptcb(tcpchild);
813 return 0;
814 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000815#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000816
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000817 if (bpt)
818 clearbpt(tcp);
819
Ulrich Drepper90512f01999-12-24 07:22:25 +0000820 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000821 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000822 if (bpt) {
823 tcpchild->flags |= TCB_BPTSET;
824 tcpchild->baddr = tcp->baddr;
825 memcpy(tcpchild->inst, tcp->inst,
826 sizeof tcpchild->inst);
827 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000828 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000829 tcp->nchildren++;
830 if (tcpchild->flags & TCB_SUSPENDED) {
831 /* The child was born suspended, due to our having
832 forced CLONE_PTRACE. */
833 if (bpt)
834 clearbpt(tcpchild);
835
836 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
837 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
838 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
839 return -1;
840 }
841
842 if (!qflag)
843 fprintf(stderr, "\
844Process %u resumed (parent %d ready)\n",
845 pid, tcp->pid);
846 }
847 else {
848 newoutf(tcpchild);
849 if (!qflag)
850 fprintf(stderr, "Process %d attached\n", pid);
851 }
852
853#ifdef TCB_CLONE_THREAD
854 if ((tcp->flags & TCB_CLONE_THREAD) && tcp->parent != NULL) {
855 /* The parent in this clone is itself a thread
856 belonging to another process. There is no
857 meaning to the parentage relationship of the new
858 child with the thread, only with the process.
859 We associate the new thread with our parent.
860 Since this is done for every new thread, there
861 will never be a TCB_CLONE_THREAD process that
862 has children. */
863 --tcp->nchildren;
864 tcp->u_arg[0] = tcp->parent->u_arg[0];
865 tcp = tcp->parent;
866 tcpchild->parent = tcp;
867 ++tcp->nchildren;
868 }
869
870 if (tcp->u_arg[0] & CLONE_THREAD) {
871 tcpchild->flags |= TCB_CLONE_THREAD;
872 ++tcp->nclone_threads;
873 }
874 if (tcp->u_arg[0] & CLONE_DETACHED) {
875 tcpchild->flags |= TCB_CLONE_DETACHED;
876 ++tcp->nclone_detached;
877 }
878#endif
879
880 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000881 return 0;
882}
883#endif
884
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000885int
886internal_fork(tcp)
887struct tcb *tcp;
888{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000889#ifdef LINUX
890 /* We do special magic with clone for any clone or fork. */
891 return internal_clone(tcp);
892#else
893
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000894 struct tcb *tcpchild;
895 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000896 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000897
898#ifdef SYS_vfork
Nate Sammonsccd8f211999-03-29 22:57:54 +0000899 if (tcp->scno == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000900 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000901 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000902 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000903 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000904 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000905#endif
906 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000907 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000908 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000909 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000910 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000911 if (setbpt(tcp) < 0)
912 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000913 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000914 else {
915 int bpt = tcp->flags & TCB_BPTSET;
916
917 if (!(tcp->flags & TCB_FOLLOWFORK))
918 return 0;
919 if (bpt)
920 clearbpt(tcp);
921
922 if (syserror(tcp))
923 return 0;
924
925 pid = tcp->u_rval;
926 if ((tcpchild = alloctcb(pid)) == NULL) {
927 fprintf(stderr, " [tcb table full]\n");
928 kill(pid, SIGKILL); /* XXX */
929 return 0;
930 }
931#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000932#ifdef HPPA
933 /* The child must have run before it can be attached. */
934 /* This must be a bug in the parisc kernel, but I havn't
935 * identified it yet. Seems to be an issue associated
936 * with attaching to a process (which sends it a signal)
937 * before that process has ever been scheduled. When
938 * debugging, I started seeing crashes in
939 * arch/parisc/kernel/signal.c:do_signal(), apparently
940 * caused by r8 getting corrupt over the dequeue_signal()
941 * call. Didn't make much sense though...
942 */
943 {
944 struct timeval tv;
945 tv.tv_sec = 0;
946 tv.tv_usec = 10000;
947 select(0, NULL, NULL, NULL, &tv);
948 }
949#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000950 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
951 perror("PTRACE_ATTACH");
952 fprintf(stderr, "Too late?\n");
953 droptcb(tcpchild);
954 return 0;
955 }
956#endif /* LINUX */
957#ifdef SUNOS4
958#ifdef oldway
959 /* The child must have run before it can be attached. */
960 {
961 struct timeval tv;
962 tv.tv_sec = 0;
963 tv.tv_usec = 10000;
964 select(0, NULL, NULL, NULL, &tv);
965 }
966 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
967 perror("PTRACE_ATTACH");
968 fprintf(stderr, "Too late?\n");
969 droptcb(tcpchild);
970 return 0;
971 }
972#else /* !oldway */
973 /* Try to catch the new process as soon as possible. */
974 {
975 int i;
976 for (i = 0; i < 1024; i++)
977 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
978 break;
979 if (i == 1024) {
980 perror("PTRACE_ATTACH");
981 fprintf(stderr, "Too late?\n");
982 droptcb(tcpchild);
983 return 0;
984 }
985 }
986#endif /* !oldway */
987#endif /* SUNOS4 */
988 tcpchild->flags |= TCB_ATTACHED;
989 /* Child has BPT too, must be removed on first occasion */
990 if (bpt) {
991 tcpchild->flags |= TCB_BPTSET;
992 tcpchild->baddr = tcp->baddr;
993 memcpy(tcpchild->inst, tcp->inst,
994 sizeof tcpchild->inst);
995 }
996 newoutf(tcpchild);
997 tcpchild->parent = tcp;
998 tcp->nchildren++;
999 if (!qflag)
1000 fprintf(stderr, "Process %d attached\n", pid);
1001 }
1002 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001003#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001004}
1005
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001006#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001007
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001008#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001009
1010int
1011sys_vfork(tcp)
1012struct tcb *tcp;
1013{
1014 if (exiting(tcp))
1015 return RVAL_UDECIMAL;
1016 return 0;
1017}
1018
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001019#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001020
1021#ifndef LINUX
1022
1023static char idstr[16];
1024
1025int
1026sys_getpid(tcp)
1027struct tcb *tcp;
1028{
1029 if (exiting(tcp)) {
1030 sprintf(idstr, "ppid %lu", getrval2(tcp));
1031 tcp->auxstr = idstr;
1032 return RVAL_STR;
1033 }
1034 return 0;
1035}
1036
1037int
1038sys_getuid(tcp)
1039struct tcb *tcp;
1040{
1041 if (exiting(tcp)) {
1042 sprintf(idstr, "euid %lu", getrval2(tcp));
1043 tcp->auxstr = idstr;
1044 return RVAL_STR;
1045 }
1046 return 0;
1047}
1048
1049int
1050sys_getgid(tcp)
1051struct tcb *tcp;
1052{
1053 if (exiting(tcp)) {
1054 sprintf(idstr, "egid %lu", getrval2(tcp));
1055 tcp->auxstr = idstr;
1056 return RVAL_STR;
1057 }
1058 return 0;
1059}
1060
1061#endif /* !LINUX */
1062
1063#ifdef LINUX
1064
1065int
1066sys_setuid(tcp)
1067struct tcb *tcp;
1068{
1069 if (entering(tcp)) {
1070 tprintf("%u", (uid_t) tcp->u_arg[0]);
1071 }
1072 return 0;
1073}
1074
1075int
1076sys_setgid(tcp)
1077struct tcb *tcp;
1078{
1079 if (entering(tcp)) {
1080 tprintf("%u", (gid_t) tcp->u_arg[0]);
1081 }
1082 return 0;
1083}
1084
1085int
1086sys_getresuid(tcp)
1087 struct tcb *tcp;
1088{
1089 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001090 __kernel_uid_t uid;
1091 if (syserror(tcp))
1092 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1093 tcp->u_arg[1], tcp->u_arg[2]);
1094 else {
1095 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1096 tprintf("%#lx, ", tcp->u_arg[0]);
1097 else
1098 tprintf("ruid %lu, ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001099 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1100 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001101 else
1102 tprintf("euid %lu, ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001103 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1104 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001105 else
1106 tprintf("suid %lu", (unsigned long) uid);
1107 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001108 }
1109 return 0;
1110}
1111
1112int
1113sys_getresgid(tcp)
1114struct tcb *tcp;
1115{
1116 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001117 __kernel_gid_t gid;
1118 if (syserror(tcp))
1119 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1120 tcp->u_arg[1], tcp->u_arg[2]);
1121 else {
1122 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1123 tprintf("%#lx, ", tcp->u_arg[0]);
1124 else
1125 tprintf("rgid %lu, ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001126 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1127 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001128 else
1129 tprintf("egid %lu, ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001130 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1131 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001132 else
1133 tprintf("sgid %lu", (unsigned long) gid);
1134 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001135 }
1136 return 0;
1137}
1138
1139#endif /* LINUX */
1140
1141int
1142sys_setreuid(tcp)
1143struct tcb *tcp;
1144{
1145 if (entering(tcp)) {
1146 tprintf("%lu, %lu",
1147 (unsigned long) (uid_t) tcp->u_arg[0],
1148 (unsigned long) (uid_t) tcp->u_arg[1]);
1149 }
1150 return 0;
1151}
1152
1153int
1154sys_setregid(tcp)
1155struct tcb *tcp;
1156{
1157 if (entering(tcp)) {
1158 tprintf("%lu, %lu",
1159 (unsigned long) (gid_t) tcp->u_arg[0],
1160 (unsigned long) (gid_t) tcp->u_arg[1]);
1161 }
1162 return 0;
1163}
1164
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001165#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001166int
1167sys_setresuid(tcp)
1168 struct tcb *tcp;
1169{
1170 if (entering(tcp)) {
1171 tprintf("ruid %u, euid %u, suid %u",
1172 (uid_t) tcp->u_arg[0],
1173 (uid_t) tcp->u_arg[1],
1174 (uid_t) tcp->u_arg[2]);
1175 }
1176 return 0;
1177}
1178int
1179sys_setresgid(tcp)
1180 struct tcb *tcp;
1181{
1182 if (entering(tcp)) {
1183 tprintf("rgid %u, egid %u, sgid %u",
1184 (uid_t) tcp->u_arg[0],
1185 (uid_t) tcp->u_arg[1],
1186 (uid_t) tcp->u_arg[2]);
1187 }
1188 return 0;
1189}
1190
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001191#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001192
1193int
1194sys_setgroups(tcp)
1195struct tcb *tcp;
1196{
1197 int i, len;
1198 GETGROUPS_T *gidset;
1199
1200 if (entering(tcp)) {
1201 len = tcp->u_arg[0];
1202 tprintf("%u, ", len);
1203 if (len <= 0) {
1204 tprintf("[]");
1205 return 0;
1206 }
1207 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1208 if (gidset == NULL) {
1209 fprintf(stderr, "sys_setgroups: out of memory\n");
1210 return -1;
1211 }
1212 if (!verbose(tcp))
1213 tprintf("%#lx", tcp->u_arg[1]);
1214 else if (umoven(tcp, tcp->u_arg[1],
1215 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1216 tprintf("[?]");
1217 else {
1218 tprintf("[");
1219 for (i = 0; i < len; i++)
1220 tprintf("%s%lu", i ? ", " : "",
1221 (unsigned long) gidset[i]);
1222 tprintf("]");
1223 }
1224 free((char *) gidset);
1225 }
1226 return 0;
1227}
1228
1229int
1230sys_getgroups(tcp)
1231struct tcb *tcp;
1232{
1233 int i, len;
1234 GETGROUPS_T *gidset;
1235
1236 if (entering(tcp)) {
1237 len = tcp->u_arg[0];
1238 tprintf("%u, ", len);
1239 } else {
1240 len = tcp->u_rval;
1241 if (len <= 0) {
1242 tprintf("[]");
1243 return 0;
1244 }
1245 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1246 if (gidset == NULL) {
1247 fprintf(stderr, "sys_getgroups: out of memory\n");
1248 return -1;
1249 }
1250 if (!tcp->u_arg[1])
1251 tprintf("NULL");
1252 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1253 tprintf("%#lx", tcp->u_arg[1]);
1254 else if (umoven(tcp, tcp->u_arg[1],
1255 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1256 tprintf("[?]");
1257 else {
1258 tprintf("[");
1259 for (i = 0; i < len; i++)
1260 tprintf("%s%lu", i ? ", " : "",
1261 (unsigned long) gidset[i]);
1262 tprintf("]");
1263 }
1264 free((char *)gidset);
1265 }
1266 return 0;
1267}
1268
1269int
1270sys_setpgrp(tcp)
1271struct tcb *tcp;
1272{
1273 if (entering(tcp)) {
1274#ifndef SVR4
1275 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1276#endif /* !SVR4 */
1277 }
1278 return 0;
1279}
1280
1281int
1282sys_getpgrp(tcp)
1283struct tcb *tcp;
1284{
1285 if (entering(tcp)) {
1286#ifndef SVR4
1287 tprintf("%lu", tcp->u_arg[0]);
1288#endif /* !SVR4 */
1289 }
1290 return 0;
1291}
1292
1293int
1294sys_getsid(tcp)
1295struct tcb *tcp;
1296{
1297 if (entering(tcp)) {
1298 tprintf("%lu", tcp->u_arg[0]);
1299 }
1300 return 0;
1301}
1302
1303int
1304sys_setsid(tcp)
1305struct tcb *tcp;
1306{
1307 return 0;
1308}
1309
1310int
1311sys_getpgid(tcp)
1312struct tcb *tcp;
1313{
1314 if (entering(tcp)) {
1315 tprintf("%lu", tcp->u_arg[0]);
1316 }
1317 return 0;
1318}
1319
1320int
1321sys_setpgid(tcp)
1322struct tcb *tcp;
1323{
1324 if (entering(tcp)) {
1325 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1326 }
1327 return 0;
1328}
1329
John Hughesc61eb3d2002-05-17 11:37:50 +00001330#if UNIXWARE >= 2
1331
1332#include <sys/privilege.h>
1333
1334
1335static struct xlat procpriv_cmds [] = {
1336 { SETPRV, "SETPRV" },
1337 { CLRPRV, "CLRPRV" },
1338 { PUTPRV, "PUTPRV" },
1339 { GETPRV, "GETPRV" },
1340 { CNTPRV, "CNTPRV" },
1341 { 0, NULL },
1342};
1343
1344
1345static struct xlat procpriv_priv [] = {
1346 { P_OWNER, "P_OWNER" },
1347 { P_AUDIT, "P_AUDIT" },
1348 { P_COMPAT, "P_COMPAT" },
1349 { P_DACREAD, "P_DACREAD" },
1350 { P_DACWRITE, "P_DACWRITE" },
1351 { P_DEV, "P_DEV" },
1352 { P_FILESYS, "P_FILESYS" },
1353 { P_MACREAD, "P_MACREAD" },
1354 { P_MACWRITE, "P_MACWRITE" },
1355 { P_MOUNT, "P_MOUNT" },
1356 { P_MULTIDIR, "P_MULTIDIR" },
1357 { P_SETPLEVEL, "P_SETPLEVEL" },
1358 { P_SETSPRIV, "P_SETSPRIV" },
1359 { P_SETUID, "P_SETUID" },
1360 { P_SYSOPS, "P_SYSOPS" },
1361 { P_SETUPRIV, "P_SETUPRIV" },
1362 { P_DRIVER, "P_DRIVER" },
1363 { P_RTIME, "P_RTIME" },
1364 { P_MACUPGRADE, "P_MACUPGRADE" },
1365 { P_FSYSRANGE, "P_FSYSRANGE" },
1366 { P_SETFLEVEL, "P_SETFLEVEL" },
1367 { P_AUDITWR, "P_AUDITWR" },
1368 { P_TSHAR, "P_TSHAR" },
1369 { P_PLOCK, "P_PLOCK" },
1370 { P_CORE, "P_CORE" },
1371 { P_LOADMOD, "P_LOADMOD" },
1372 { P_BIND, "P_BIND" },
1373 { P_ALLPRIVS, "P_ALLPRIVS" },
1374 { 0, NULL },
1375};
1376
1377
1378static struct xlat procpriv_type [] = {
1379 { PS_FIX, "PS_FIX" },
1380 { PS_INH, "PS_INH" },
1381 { PS_MAX, "PS_MAX" },
1382 { PS_WKG, "PS_WKG" },
1383 { 0, NULL },
1384};
1385
1386
1387static void
1388printpriv(tcp, addr, len, opt)
1389struct tcb *tcp;
1390long addr;
1391int len;
1392struct xlat *opt;
1393{
1394 priv_t buf [128];
1395 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1396 int dots = len > max;
1397 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001398
John Hughesc61eb3d2002-05-17 11:37:50 +00001399 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001400
John Hughesc61eb3d2002-05-17 11:37:50 +00001401 if (len <= 0 ||
1402 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1403 {
1404 tprintf ("%#lx", addr);
1405 return;
1406 }
1407
1408 tprintf ("[");
1409
1410 for (i = 0; i < len; ++i) {
1411 char *t, *p;
1412
1413 if (i) tprintf (", ");
1414
1415 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1416 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1417 {
1418 tprintf ("%s|%s", t, p);
1419 }
1420 else {
1421 tprintf ("%#lx", buf [i]);
1422 }
1423 }
1424
1425 if (dots) tprintf (" ...");
1426
1427 tprintf ("]");
1428}
1429
1430
1431int
1432sys_procpriv(tcp)
1433struct tcb *tcp;
1434{
1435 if (entering(tcp)) {
1436 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1437 switch (tcp->u_arg[0]) {
1438 case CNTPRV:
1439 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1440 break;
1441
1442 case GETPRV:
1443 break;
1444
1445 default:
1446 tprintf (", ");
1447 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1448 tprintf (", %ld", tcp->u_arg[2]);
1449 }
1450 }
1451 else if (tcp->u_arg[0] == GETPRV) {
1452 if (syserror (tcp)) {
1453 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1454 }
1455 else {
1456 tprintf (", ");
1457 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1458 tprintf (", %ld", tcp->u_arg[2]);
1459 }
1460 }
Roland McGrath5a223472002-12-15 23:58:26 +00001461
John Hughesc61eb3d2002-05-17 11:37:50 +00001462 return 0;
1463}
1464
1465#endif
1466
1467
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001468void
1469fake_execve(tcp, program, argv, envp)
1470struct tcb *tcp;
1471char *program;
1472char *argv[];
1473char *envp[];
1474{
1475 int i;
1476
1477#ifdef ARM
1478 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1479 return;
1480#else
1481 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1482 return;
1483#endif /* !ARM */
1484 printleader(tcp);
1485 tprintf("execve(");
1486 string_quote(program);
1487 tprintf(", [");
1488 for (i = 0; argv[i] != NULL; i++) {
1489 if (i != 0)
1490 tprintf(", ");
1491 string_quote(argv[i]);
1492 }
1493 for (i = 0; envp[i] != NULL; i++)
1494 ;
1495 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1496 tabto(acolumn);
1497 tprintf("= 0");
1498 printtrailer(tcp);
1499}
1500
1501static void
1502printargv(tcp, addr)
1503struct tcb *tcp;
1504long addr;
1505{
1506 char *cp;
1507 char *sep;
1508 int max = max_strlen / 2;
1509
1510 for (sep = ""; --max >= 0; sep = ", ") {
1511 if (!abbrev(tcp))
1512 max++;
1513 if (umove(tcp, addr, &cp) < 0) {
1514 tprintf("%#lx", addr);
1515 return;
1516 }
1517 if (cp == 0)
1518 break;
1519 tprintf(sep);
1520 printstr(tcp, (long) cp, -1);
1521 addr += sizeof(char *);
1522 }
1523 if (cp)
1524 tprintf(", ...");
1525}
1526
1527static void
1528printargc(fmt, tcp, addr)
1529char *fmt;
1530struct tcb *tcp;
1531long addr;
1532{
1533 int count;
1534 char *cp;
1535
1536 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1537 addr += sizeof(char *);
1538 }
1539 tprintf(fmt, count, count == 1 ? "" : "s");
1540}
1541
1542int
1543sys_execv(tcp)
1544struct tcb *tcp;
1545{
1546 if (entering(tcp)) {
1547 printpath(tcp, tcp->u_arg[0]);
1548 if (!verbose(tcp))
1549 tprintf(", %#lx", tcp->u_arg[1]);
1550#if 0
1551 else if (abbrev(tcp))
1552 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1553#endif
1554 else {
1555 tprintf(", [");
1556 printargv(tcp, tcp->u_arg[1]);
1557 tprintf("]");
1558 }
1559 }
1560 return 0;
1561}
1562
1563int
1564sys_execve(tcp)
1565struct tcb *tcp;
1566{
1567 if (entering(tcp)) {
1568 printpath(tcp, tcp->u_arg[0]);
1569 if (!verbose(tcp))
1570 tprintf(", %#lx", tcp->u_arg[1]);
1571#if 0
1572 else if (abbrev(tcp))
1573 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1574#endif
1575 else {
1576 tprintf(", [");
1577 printargv(tcp, tcp->u_arg[1]);
1578 tprintf("]");
1579 }
1580 if (!verbose(tcp))
1581 tprintf(", %#lx", tcp->u_arg[2]);
1582 else if (abbrev(tcp))
1583 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1584 else {
1585 tprintf(", [");
1586 printargv(tcp, tcp->u_arg[2]);
1587 tprintf("]");
1588 }
1589 }
Roland McGrathb4968be2003-01-20 09:04:33 +00001590#if defined LINUX && defined TCB_WAITEXECVE
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001591 tcp->flags |= TCB_WAITEXECVE;
Roland McGrathb4968be2003-01-20 09:04:33 +00001592#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001593 return 0;
1594}
1595
John Hughes4e36a812001-04-18 15:11:51 +00001596#if UNIXWARE > 2
1597
1598int sys_rexecve(tcp)
1599struct tcb *tcp;
1600{
1601 if (entering (tcp)) {
1602 sys_execve (tcp);
1603 tprintf (", %ld", tcp->u_arg[3]);
1604 }
1605 return 0;
1606}
1607
1608#endif
1609
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001610int
1611internal_exec(tcp)
1612struct tcb *tcp;
1613{
1614#ifdef SUNOS4
1615 if (exiting(tcp) && !syserror(tcp) && followfork)
1616 fixvfork(tcp);
1617#endif /* SUNOS4 */
1618 return 0;
1619}
1620
1621#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001622#ifndef __WNOTHREAD
1623#define __WNOTHREAD 0x20000000
1624#endif
1625#ifndef __WALL
1626#define __WALL 0x40000000
1627#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001628#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001629#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001630#endif
1631#endif /* LINUX */
1632
1633static struct xlat wait4_options[] = {
1634 { WNOHANG, "WNOHANG" },
1635#ifndef WSTOPPED
1636 { WUNTRACED, "WUNTRACED" },
1637#endif
1638#ifdef WEXITED
1639 { WEXITED, "WEXITED" },
1640#endif
1641#ifdef WTRAPPED
1642 { WTRAPPED, "WTRAPPED" },
1643#endif
1644#ifdef WSTOPPED
1645 { WSTOPPED, "WSTOPPED" },
1646#endif
1647#ifdef WCONTINUED
1648 { WCONTINUED, "WCONTINUED" },
1649#endif
1650#ifdef WNOWAIT
1651 { WNOWAIT, "WNOWAIT" },
1652#endif
1653#ifdef __WCLONE
1654 { __WCLONE, "__WCLONE" },
1655#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001656#ifdef __WALL
1657 { __WALL, "__WALL" },
1658#endif
1659#ifdef __WNOTHREAD
1660 { __WNOTHREAD, "__WNOTHREAD" },
1661#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001662 { 0, NULL },
1663};
1664
1665static int
1666printstatus(status)
1667int status;
1668{
1669 int exited = 0;
1670
1671 /*
1672 * Here is a tricky presentation problem. This solution
1673 * is still not entirely satisfactory but since there
1674 * are no wait status constructors it will have to do.
1675 */
1676 if (WIFSTOPPED(status))
1677 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001678 signame(WSTOPSIG(status)));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001679 else if WIFSIGNALED(status)
1680 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001681 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001682 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1683 else if WIFEXITED(status) {
1684 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1685 WEXITSTATUS(status));
1686 exited = 1;
1687 }
1688 else
1689 tprintf("[%#x]", status);
1690 return exited;
1691}
1692
1693static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001694printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001695struct tcb *tcp;
1696int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001697int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001698{
1699 int status;
1700 int exited = 0;
1701
1702 if (entering(tcp)) {
1703 tprintf("%ld, ", tcp->u_arg[0]);
1704 } else {
1705 /* status */
1706 if (!tcp->u_arg[1])
1707 tprintf("NULL");
1708 else if (syserror(tcp) || tcp->u_rval == 0)
1709 tprintf("%#lx", tcp->u_arg[1]);
1710 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1711 tprintf("[?]");
1712 else
1713 exited = printstatus(status);
1714 /* options */
1715 tprintf(", ");
1716 if (!printflags(wait4_options, tcp->u_arg[2]))
1717 tprintf("0");
1718 if (n == 4) {
1719 tprintf(", ");
1720 /* usage */
1721 if (!tcp->u_arg[3])
1722 tprintf("NULL");
1723#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001724 else if (tcp->u_rval > 0) {
1725#ifdef LINUX_64BIT
1726 if (bitness)
1727 printrusage32(tcp, tcp->u_arg[3]);
1728 else
1729#endif
1730 printrusage(tcp, tcp->u_arg[3]);
1731 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001732#endif /* LINUX */
1733#ifdef SUNOS4
1734 else if (tcp->u_rval > 0 && exited)
1735 printrusage(tcp, tcp->u_arg[3]);
1736#endif /* SUNOS4 */
1737 else
1738 tprintf("%#lx", tcp->u_arg[3]);
1739 }
1740 }
1741 return 0;
1742}
1743
1744int
1745internal_wait(tcp)
1746struct tcb *tcp;
1747{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001748 int got_kids;
1749
1750#ifdef TCB_CLONE_THREAD
1751 if (tcp->flags & TCB_CLONE_THREAD)
1752 /* The children we wait for are our parent's children. */
1753 got_kids = (tcp->parent->nchildren
1754 > tcp->parent->nclone_detached);
1755 else
1756 got_kids = (tcp->nchildren > tcp->nclone_detached);
1757#else
1758 got_kids = tcp->nchildren > 0;
1759#endif
1760
1761 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001762 /* There are children that this parent should block for.
1763 But ptrace made us the parent of the traced children
1764 and the real parent will get ECHILD from the wait call.
1765
1766 XXX If we attached with strace -f -p PID, then there
1767 may be untraced dead children the parent could be reaping
1768 now, but we make him block. */
1769
1770 /* ??? WTA: fix bug with hanging children */
1771
1772 if (!(tcp->u_arg[2] & WNOHANG)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001773 /* There are traced children */
1774 tcp->flags |= TCB_SUSPENDED;
1775 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001776#ifdef TCB_CLONE_THREAD
1777 if (tcp->flags & TCB_CLONE_THREAD)
1778 tcp->parent->nclone_waiting++;
1779#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001780 }
1781 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001782 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001783 if (tcp->u_arg[2] & WNOHANG) {
1784 /* We must force a fake result of 0 instead of
1785 the ECHILD error. */
1786 extern int force_result();
1787 return force_result(tcp, 0, 0);
1788 }
1789 else
1790 fprintf(stderr,
1791 "internal_wait: should not have resumed %d\n",
1792 tcp->pid);
1793 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001794 return 0;
1795}
1796
1797#ifdef SVR4
1798
1799int
1800sys_wait(tcp)
1801struct tcb *tcp;
1802{
1803 if (exiting(tcp)) {
1804 /* The library wrapper stuffs this into the user variable. */
1805 if (!syserror(tcp))
1806 printstatus(getrval2(tcp));
1807 }
1808 return 0;
1809}
1810
1811#endif /* SVR4 */
1812
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001813#ifdef FREEBSD
1814int
1815sys_wait(tcp)
1816struct tcb *tcp;
1817{
1818 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001819
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001820 if (exiting(tcp)) {
1821 if (!syserror(tcp)) {
1822 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1823 tprintf("%#lx", tcp->u_arg[0]);
1824 else
1825 printstatus(status);
1826 }
1827 }
1828 return 0;
1829}
1830#endif
1831
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001832int
1833sys_waitpid(tcp)
1834struct tcb *tcp;
1835{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001836 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001837}
1838
1839int
1840sys_wait4(tcp)
1841struct tcb *tcp;
1842{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001843 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001844}
1845
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001846#ifdef ALPHA
1847int
1848sys_osf_wait4(tcp)
1849struct tcb *tcp;
1850{
1851 return printwaitn(tcp, 4, 1);
1852}
1853#endif
1854
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001855#ifdef SVR4
1856
1857static struct xlat waitid_types[] = {
1858 { P_PID, "P_PID" },
1859 { P_PPID, "P_PPID" },
1860 { P_PGID, "P_PGID" },
1861 { P_SID, "P_SID" },
1862 { P_CID, "P_CID" },
1863 { P_UID, "P_UID" },
1864 { P_GID, "P_GID" },
1865 { P_ALL, "P_ALL" },
1866#ifdef P_LWPID
1867 { P_LWPID, "P_LWPID" },
1868#endif
1869 { 0, NULL },
1870};
1871
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001872int
1873sys_waitid(tcp)
1874struct tcb *tcp;
1875{
1876 siginfo_t si;
1877 int exited;
1878
1879 if (entering(tcp)) {
1880 printxval(waitid_types, tcp->u_arg[0], "P_???");
1881 tprintf(", %ld, ", tcp->u_arg[1]);
1882 if (tcp->nchildren > 0) {
1883 /* There are traced children */
1884 tcp->flags |= TCB_SUSPENDED;
1885 tcp->waitpid = tcp->u_arg[0];
1886 }
1887 }
1888 else {
1889 /* siginfo */
1890 exited = 0;
1891 if (!tcp->u_arg[2])
1892 tprintf("NULL");
1893 else if (syserror(tcp))
1894 tprintf("%#lx", tcp->u_arg[2]);
1895 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1896 tprintf("{???}");
1897 else
John Hughes58265892001-10-18 15:13:53 +00001898 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001899 /* options */
1900 tprintf(", ");
1901 if (!printflags(wait4_options, tcp->u_arg[3]))
1902 tprintf("0");
1903 }
1904 return 0;
1905}
1906
1907#endif /* SVR4 */
1908
1909int
1910sys_alarm(tcp)
1911struct tcb *tcp;
1912{
1913 if (entering(tcp))
1914 tprintf("%lu", tcp->u_arg[0]);
1915 return 0;
1916}
1917
1918int
1919sys_uname(tcp)
1920struct tcb *tcp;
1921{
1922 struct utsname uname;
1923
1924 if (exiting(tcp)) {
1925 if (syserror(tcp) || !verbose(tcp))
1926 tprintf("%#lx", tcp->u_arg[0]);
1927 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1928 tprintf("{...}");
1929 else if (!abbrev(tcp)) {
1930
1931 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1932 uname.sysname, uname.nodename);
1933 tprintf("release=\"%s\", version=\"%s\", ",
1934 uname.release, uname.version);
1935 tprintf("machine=\"%s\"", uname.machine);
1936#ifdef LINUX
1937#ifndef __GLIBC__
1938 tprintf(", domainname=\"%s\"", uname.domainname);
1939#endif /* __GLIBC__ */
1940#endif /* LINUX */
1941 tprintf("}");
1942 }
1943 else
1944 tprintf("{sys=\"%s\", node=\"%s\", ...}",
1945 uname.sysname, uname.nodename);
1946 }
1947 return 0;
1948}
1949
1950#ifndef SVR4
1951
1952static struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00001953#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001954 { PTRACE_TRACEME, "PTRACE_TRACEME" },
1955 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
1956 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
1957 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
1958 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
1959 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
1960 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
1961 { PTRACE_CONT, "PTRACE_CONT" },
1962 { PTRACE_KILL, "PTRACE_KILL" },
1963 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
1964 { PTRACE_ATTACH, "PTRACE_ATTACH" },
1965 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001966#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001967 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001968#endif
1969#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001970 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001971#endif
1972#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001973 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00001974#endif
1975#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001976 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00001977#endif
1978#ifdef PTRACE_GETFPXREGS
1979 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
1980#endif
1981#ifdef PTRACE_SETFPXREGS
1982 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
1983#endif
1984#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001985 { PTRACE_READDATA, "PTRACE_READDATA" },
1986 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
1987 { PTRACE_READTEXT, "PTRACE_READTEXT" },
1988 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
1989 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
1990 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
1991#ifdef SPARC
1992 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
1993 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
1994#else /* !SPARC */
1995 { PTRACE_22, "PTRACE_PTRACE_22" },
1996 { PTRACE_23, "PTRACE_PTRACE_23" },
1997#endif /* !SPARC */
1998#endif /* SUNOS4 */
1999 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2000#ifdef SUNOS4
2001 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2002#ifdef I386
2003 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2004 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2005 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2006#else /* !I386 */
2007 { PTRACE_26, "PTRACE_26" },
2008 { PTRACE_27, "PTRACE_27" },
2009 { PTRACE_28, "PTRACE_28" },
2010#endif /* !I386 */
2011 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2012#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002013#else /* FREEBSD */
2014 { PT_TRACE_ME, "PT_TRACE_ME" },
2015 { PT_READ_I, "PT_READ_I" },
2016 { PT_READ_D, "PT_READ_D" },
2017 { PT_WRITE_I, "PT_WRITE_I" },
2018 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002019#ifdef PT_READ_U
2020 { PT_READ_U, "PT_READ_U" },
2021#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002022 { PT_CONTINUE, "PT_CONTINUE" },
2023 { PT_KILL, "PT_KILL" },
2024 { PT_STEP, "PT_STEP" },
2025 { PT_ATTACH, "PT_ATTACH" },
2026 { PT_DETACH, "PT_DETACH" },
2027 { PT_GETREGS, "PT_GETREGS" },
2028 { PT_SETREGS, "PT_SETREGS" },
2029 { PT_GETFPREGS, "PT_GETFPREGS" },
2030 { PT_SETFPREGS, "PT_SETFPREGS" },
2031 { PT_GETDBREGS, "PT_GETDBREGS" },
2032 { PT_SETDBREGS, "PT_SETDBREGS" },
2033#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002034 { 0, NULL },
2035};
2036
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002037#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002038#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2039static
2040#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2041struct xlat struct_user_offsets[] = {
2042#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002043#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002044 { PT_PSWMASK, "psw_mask" },
2045 { PT_PSWADDR, "psw_addr" },
2046 { PT_GPR0, "gpr0" },
2047 { PT_GPR1, "gpr1" },
2048 { PT_GPR2, "gpr2" },
2049 { PT_GPR3, "gpr3" },
2050 { PT_GPR4, "gpr4" },
2051 { PT_GPR5, "gpr5" },
2052 { PT_GPR6, "gpr6" },
2053 { PT_GPR7, "gpr7" },
2054 { PT_GPR8, "gpr8" },
2055 { PT_GPR9, "gpr9" },
2056 { PT_GPR10, "gpr10" },
2057 { PT_GPR11, "gpr11" },
2058 { PT_GPR12, "gpr12" },
2059 { PT_GPR13, "gpr13" },
2060 { PT_GPR14, "gpr14" },
2061 { PT_GPR15, "gpr15" },
2062 { PT_ACR0, "acr0" },
2063 { PT_ACR1, "acr1" },
2064 { PT_ACR2, "acr2" },
2065 { PT_ACR3, "acr3" },
2066 { PT_ACR4, "acr4" },
2067 { PT_ACR5, "acr5" },
2068 { PT_ACR6, "acr6" },
2069 { PT_ACR7, "acr7" },
2070 { PT_ACR8, "acr8" },
2071 { PT_ACR9, "acr9" },
2072 { PT_ACR10, "acr10" },
2073 { PT_ACR11, "acr11" },
2074 { PT_ACR12, "acr12" },
2075 { PT_ACR13, "acr13" },
2076 { PT_ACR14, "acr14" },
2077 { PT_ACR15, "acr15" },
2078 { PT_ORIGGPR2, "orig_gpr2" },
2079 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002080#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002081 { PT_FPR0_HI, "fpr0.hi" },
2082 { PT_FPR0_LO, "fpr0.lo" },
2083 { PT_FPR1_HI, "fpr1.hi" },
2084 { PT_FPR1_LO, "fpr1.lo" },
2085 { PT_FPR2_HI, "fpr2.hi" },
2086 { PT_FPR2_LO, "fpr2.lo" },
2087 { PT_FPR3_HI, "fpr3.hi" },
2088 { PT_FPR3_LO, "fpr3.lo" },
2089 { PT_FPR4_HI, "fpr4.hi" },
2090 { PT_FPR4_LO, "fpr4.lo" },
2091 { PT_FPR5_HI, "fpr5.hi" },
2092 { PT_FPR5_LO, "fpr5.lo" },
2093 { PT_FPR6_HI, "fpr6.hi" },
2094 { PT_FPR6_LO, "fpr6.lo" },
2095 { PT_FPR7_HI, "fpr7.hi" },
2096 { PT_FPR7_LO, "fpr7.lo" },
2097 { PT_FPR8_HI, "fpr8.hi" },
2098 { PT_FPR8_LO, "fpr8.lo" },
2099 { PT_FPR9_HI, "fpr9.hi" },
2100 { PT_FPR9_LO, "fpr9.lo" },
2101 { PT_FPR10_HI, "fpr10.hi" },
2102 { PT_FPR10_LO, "fpr10.lo" },
2103 { PT_FPR11_HI, "fpr11.hi" },
2104 { PT_FPR11_LO, "fpr11.lo" },
2105 { PT_FPR12_HI, "fpr12.hi" },
2106 { PT_FPR12_LO, "fpr12.lo" },
2107 { PT_FPR13_HI, "fpr13.hi" },
2108 { PT_FPR13_LO, "fpr13.lo" },
2109 { PT_FPR14_HI, "fpr14.hi" },
2110 { PT_FPR14_LO, "fpr14.lo" },
2111 { PT_FPR15_HI, "fpr15.hi" },
2112 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002113#endif
2114#if defined(S390X)
2115 { PT_FPR0, "fpr0" },
2116 { PT_FPR1, "fpr1" },
2117 { PT_FPR2, "fpr2" },
2118 { PT_FPR3, "fpr3" },
2119 { PT_FPR4, "fpr4" },
2120 { PT_FPR5, "fpr5" },
2121 { PT_FPR6, "fpr6" },
2122 { PT_FPR7, "fpr7" },
2123 { PT_FPR8, "fpr8" },
2124 { PT_FPR9, "fpr9" },
2125 { PT_FPR10, "fpr10" },
2126 { PT_FPR11, "fpr11" },
2127 { PT_FPR12, "fpr12" },
2128 { PT_FPR13, "fpr13" },
2129 { PT_FPR14, "fpr14" },
2130 { PT_FPR15, "fpr15" },
2131#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002132 { PT_CR_9, "cr9" },
2133 { PT_CR_10, "cr10" },
2134 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002135 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002136#endif
2137#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002138 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002139#elif defined(HPPA)
2140 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002141#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002142#ifndef PT_ORIG_R3
2143#define PT_ORIG_R3 34
2144#endif
Roland McGratheb285352003-01-14 09:59:00 +00002145#define REGSIZE (sizeof(unsigned long))
2146 { REGSIZE*PT_R0, "r0" },
2147 { REGSIZE*PT_R1, "r1" },
2148 { REGSIZE*PT_R2, "r2" },
2149 { REGSIZE*PT_R3, "r3" },
2150 { REGSIZE*PT_R4, "r4" },
2151 { REGSIZE*PT_R5, "r5" },
2152 { REGSIZE*PT_R6, "r6" },
2153 { REGSIZE*PT_R7, "r7" },
2154 { REGSIZE*PT_R8, "r8" },
2155 { REGSIZE*PT_R9, "r9" },
2156 { REGSIZE*PT_R10, "r10" },
2157 { REGSIZE*PT_R11, "r11" },
2158 { REGSIZE*PT_R12, "r12" },
2159 { REGSIZE*PT_R13, "r13" },
2160 { REGSIZE*PT_R14, "r14" },
2161 { REGSIZE*PT_R15, "r15" },
2162 { REGSIZE*PT_R16, "r16" },
2163 { REGSIZE*PT_R17, "r17" },
2164 { REGSIZE*PT_R18, "r18" },
2165 { REGSIZE*PT_R19, "r19" },
2166 { REGSIZE*PT_R20, "r20" },
2167 { REGSIZE*PT_R21, "r21" },
2168 { REGSIZE*PT_R22, "r22" },
2169 { REGSIZE*PT_R23, "r23" },
2170 { REGSIZE*PT_R24, "r24" },
2171 { REGSIZE*PT_R25, "r25" },
2172 { REGSIZE*PT_R26, "r26" },
2173 { REGSIZE*PT_R27, "r27" },
2174 { REGSIZE*PT_R28, "r28" },
2175 { REGSIZE*PT_R29, "r29" },
2176 { REGSIZE*PT_R30, "r30" },
2177 { REGSIZE*PT_R31, "r31" },
2178 { REGSIZE*PT_NIP, "NIP" },
2179 { REGSIZE*PT_MSR, "MSR" },
2180 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2181 { REGSIZE*PT_CTR, "CTR" },
2182 { REGSIZE*PT_LNK, "LNK" },
2183 { REGSIZE*PT_XER, "XER" },
2184 { REGSIZE*PT_CCR, "CCR" },
2185 { REGSIZE*PT_FPR0, "FPR0" },
2186#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002187#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002188#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002189 { 0, "r0" },
2190 { 1, "r1" },
2191 { 2, "r2" },
2192 { 3, "r3" },
2193 { 4, "r4" },
2194 { 5, "r5" },
2195 { 6, "r6" },
2196 { 7, "r7" },
2197 { 8, "r8" },
2198 { 9, "r9" },
2199 { 10, "r10" },
2200 { 11, "r11" },
2201 { 12, "r12" },
2202 { 13, "r13" },
2203 { 14, "r14" },
2204 { 15, "r15" },
2205 { 16, "r16" },
2206 { 17, "r17" },
2207 { 18, "r18" },
2208 { 19, "r19" },
2209 { 20, "r20" },
2210 { 21, "r21" },
2211 { 22, "r22" },
2212 { 23, "r23" },
2213 { 24, "r24" },
2214 { 25, "r25" },
2215 { 26, "r26" },
2216 { 27, "r27" },
2217 { 28, "r28" },
2218 { 29, "gp" },
2219 { 30, "fp" },
2220 { 31, "zero" },
2221 { 32, "fp0" },
2222 { 33, "fp" },
2223 { 34, "fp2" },
2224 { 35, "fp3" },
2225 { 36, "fp4" },
2226 { 37, "fp5" },
2227 { 38, "fp6" },
2228 { 39, "fp7" },
2229 { 40, "fp8" },
2230 { 41, "fp9" },
2231 { 42, "fp10" },
2232 { 43, "fp11" },
2233 { 44, "fp12" },
2234 { 45, "fp13" },
2235 { 46, "fp14" },
2236 { 47, "fp15" },
2237 { 48, "fp16" },
2238 { 49, "fp17" },
2239 { 50, "fp18" },
2240 { 51, "fp19" },
2241 { 52, "fp20" },
2242 { 53, "fp21" },
2243 { 54, "fp22" },
2244 { 55, "fp23" },
2245 { 56, "fp24" },
2246 { 57, "fp25" },
2247 { 58, "fp26" },
2248 { 59, "fp27" },
2249 { 60, "fp28" },
2250 { 61, "fp29" },
2251 { 62, "fp30" },
2252 { 63, "fp31" },
2253 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002254#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002255#ifdef IA64
2256 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2257 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2258 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2259 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2260 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2261 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2262 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2263 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2264 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2265 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2266 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2267 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2268 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2269 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2270 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2271 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2272 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2273 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2274 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2275 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2276 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2277 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2278 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2279 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2280 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2281 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2282 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2283 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2284 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2285 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2286 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2287 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2288 /* switch stack: */
2289 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2290 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2291 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2292 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2293 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2294 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2295 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2296 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2297 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2298 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002299 { PT_B0, "kb0" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002300 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2301 { PT_B4, "b4" }, { PT_B5, "b5" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002302 { PT_AR_PFS, "kar.pfs" },
2303 { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" },
2304 { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" },
2305 { PT_PR, "k.pr" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002306 /* pt_regs */
2307 { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002308 /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002309 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2310 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2311 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2312 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2313 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2314 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2315 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2316 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2317 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2318 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2319 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2320 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2321 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2322 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2323 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2324#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002325#ifdef I386
2326 { 4*EBX, "4*EBX" },
2327 { 4*ECX, "4*ECX" },
2328 { 4*EDX, "4*EDX" },
2329 { 4*ESI, "4*ESI" },
2330 { 4*EDI, "4*EDI" },
2331 { 4*EBP, "4*EBP" },
2332 { 4*EAX, "4*EAX" },
2333 { 4*DS, "4*DS" },
2334 { 4*ES, "4*ES" },
2335 { 4*FS, "4*FS" },
2336 { 4*GS, "4*GS" },
2337 { 4*ORIG_EAX, "4*ORIG_EAX" },
2338 { 4*EIP, "4*EIP" },
2339 { 4*CS, "4*CS" },
2340 { 4*EFL, "4*EFL" },
2341 { 4*UESP, "4*UESP" },
2342 { 4*SS, "4*SS" },
2343#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002344#ifdef X86_64
2345 { 8*RDI, "8*RDI" },
2346 { 8*RSI, "8*RSI" },
2347 { 8*RDX, "8*RDX" },
2348 { 8*R10, "8*R10" },
2349 { 8*R8, "8*R8" },
2350 { 8*R9, "8*R9" },
2351 { 8*RBX, "8*RBX" },
2352 { 8*RCX, "8*RCX" },
2353 { 8*RBP, "8*RBP" },
2354 { 8*RAX, "8*RAX" },
2355#if 0
2356 { 8*DS, "8*DS" },
2357 { 8*ES, "8*ES" },
2358 { 8*FS, "8*FS" },
2359 { 8*GS, "8*GS" },
2360#endif
2361 { 8*ORIG_RAX, "8*ORIG_EAX" },
2362 { 8*RIP, "8*RIP" },
2363 { 8*CS, "8*CS" },
2364 { 8*EFLAGS, "8*EFL" },
2365 { 8*RSP, "8*RSP" },
2366 { 8*SS, "8*SS" },
2367 { 8*R11, "8*R11" },
2368 { 8*R12, "8*R12" },
2369 { 8*R13, "8*R13" },
2370 { 8*R14, "8*R14" },
2371 { 8*R15, "8*R15" },
2372#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002373#ifdef M68K
2374 { 4*PT_D1, "4*PT_D1" },
2375 { 4*PT_D2, "4*PT_D2" },
2376 { 4*PT_D3, "4*PT_D3" },
2377 { 4*PT_D4, "4*PT_D4" },
2378 { 4*PT_D5, "4*PT_D5" },
2379 { 4*PT_D6, "4*PT_D6" },
2380 { 4*PT_D7, "4*PT_D7" },
2381 { 4*PT_A0, "4*PT_A0" },
2382 { 4*PT_A1, "4*PT_A1" },
2383 { 4*PT_A2, "4*PT_A2" },
2384 { 4*PT_A3, "4*PT_A3" },
2385 { 4*PT_A4, "4*PT_A4" },
2386 { 4*PT_A5, "4*PT_A5" },
2387 { 4*PT_A6, "4*PT_A6" },
2388 { 4*PT_D0, "4*PT_D0" },
2389 { 4*PT_USP, "4*PT_USP" },
2390 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2391 { 4*PT_SR, "4*PT_SR" },
2392 { 4*PT_PC, "4*PT_PC" },
2393#endif /* M68K */
2394#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002395#ifdef SH
2396 { 4*REG_REG0, "4*REG_REG0" },
2397 { 4*(REG_REG0+1), "4*REG_REG1" },
2398 { 4*(REG_REG0+2), "4*REG_REG2" },
2399 { 4*(REG_REG0+3), "4*REG_REG3" },
2400 { 4*(REG_REG0+4), "4*REG_REG4" },
2401 { 4*(REG_REG0+5), "4*REG_REG5" },
2402 { 4*(REG_REG0+6), "4*REG_REG6" },
2403 { 4*(REG_REG0+7), "4*REG_REG7" },
2404 { 4*(REG_REG0+8), "4*REG_REG8" },
2405 { 4*(REG_REG0+9), "4*REG_REG9" },
2406 { 4*(REG_REG0+10), "4*REG_REG10" },
2407 { 4*(REG_REG0+11), "4*REG_REG11" },
2408 { 4*(REG_REG0+12), "4*REG_REG12" },
2409 { 4*(REG_REG0+13), "4*REG_REG13" },
2410 { 4*(REG_REG0+14), "4*REG_REG14" },
2411 { 4*REG_REG15, "4*REG_REG15" },
2412 { 4*REG_PC, "4*REG_PC" },
2413 { 4*REG_PR, "4*REG_PR" },
2414 { 4*REG_SR, "4*REG_SR" },
2415 { 4*REG_GBR, "4*REG_GBR" },
2416 { 4*REG_MACH, "4*REG_MACH" },
2417 { 4*REG_MACL, "4*REG_MACL" },
2418 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2419 { 4*REG_FPUL, "4*REG_FPUL" },
2420 { 4*REG_FPREG0, "4*REG_FPREG0" },
2421 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2422 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2423 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2424 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2425 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2426 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2427 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2428 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2429 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2430 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2431 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2432 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2433 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2434 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2435 { 4*REG_FPREG15, "4*REG_FPREG15" },
2436 { 4*REG_XDREG0, "4*REG_XDREG0" },
2437 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2438 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2439 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2440 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2441 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2442 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2443 { 4*REG_XDREG14, "4*REG_XDREG14" },
2444 { 4*REG_FPSCR, "4*REG_FPSCR" },
2445#endif /* SH */
2446
Michal Ludvig10a88d02002-10-07 14:31:00 +00002447#if !defined(S390) && !defined(S390X) && !defined(MIPS)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002448 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002449#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002450#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002451 { uoff(i387), "offsetof(struct user, i387)" },
2452#else /* !I386 */
2453#ifdef M68K
2454 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2455#endif /* M68K */
2456#endif /* !I386 */
2457 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2458 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2459 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2460 { uoff(start_code), "offsetof(struct user, start_code)" },
2461 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2462 { uoff(signal), "offsetof(struct user, signal)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002463#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002464 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002465#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002466 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002467#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002468 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2469#endif
2470 { uoff(magic), "offsetof(struct user, magic)" },
2471 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002472#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002473 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2474#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002475#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002476#endif /* !ALPHA */
2477#endif /* !POWERPC/!SPARC */
2478#endif /* LINUX */
2479#ifdef SUNOS4
2480 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2481 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2482 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2483 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2484 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2485 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2486 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2487 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2488 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2489 { uoff(u_error), "offsetof(struct user, u_error)" },
2490 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2491 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2492 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2493 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2494 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2495 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2496 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2497 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2498 { uoff(u_code), "offsetof(struct user, u_code)" },
2499 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2500 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2501 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2502 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2503 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2504 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2505 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2506 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2507 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2508 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2509 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2510 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2511 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2512 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2513 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2514 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2515 { uoff(u_start), "offsetof(struct user, u_start)" },
2516 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2517 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2518 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2519 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2520 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2521 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2522 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2523 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2524 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2525#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002526#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002527 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002528#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002529 { 0, NULL },
2530};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002531#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002532
2533int
2534sys_ptrace(tcp)
2535struct tcb *tcp;
2536{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002537 struct xlat *x;
2538 long addr;
2539
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002540 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002541 printxval(ptrace_cmds, tcp->u_arg[0],
2542#ifndef FREEBSD
2543 "PTRACE_???"
2544#else
2545 "PT_???"
2546#endif
2547 );
2548 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002549 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002550#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002551 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2552 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2553 for (x = struct_user_offsets; x->str; x++) {
2554 if (x->val >= addr)
2555 break;
2556 }
2557 if (!x->str)
2558 tprintf("%#lx, ", addr);
2559 else if (x->val > addr && x != struct_user_offsets) {
2560 x--;
2561 tprintf("%s + %ld, ", x->str, addr - x->val);
2562 }
2563 else
2564 tprintf("%s, ", x->str);
2565 }
2566 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002567#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002568 tprintf("%#lx, ", tcp->u_arg[2]);
2569#ifdef LINUX
2570 switch (tcp->u_arg[0]) {
2571 case PTRACE_PEEKDATA:
2572 case PTRACE_PEEKTEXT:
2573 case PTRACE_PEEKUSER:
2574 break;
2575 case PTRACE_CONT:
2576 case PTRACE_SINGLESTEP:
2577 case PTRACE_SYSCALL:
2578 case PTRACE_DETACH:
2579 printsignal(tcp->u_arg[3]);
2580 break;
2581 default:
2582 tprintf("%#lx", tcp->u_arg[3]);
2583 break;
2584 }
2585 } else {
2586 switch (tcp->u_arg[0]) {
2587 case PTRACE_PEEKDATA:
2588 case PTRACE_PEEKTEXT:
2589 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00002590 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002591 break;
2592 }
2593 }
2594#endif /* LINUX */
2595#ifdef SUNOS4
2596 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2597 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2598 tprintf("%lu, ", tcp->u_arg[3]);
2599 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2600 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2601 tcp->u_arg[0] != PTRACE_READTEXT) {
2602 tprintf("%#lx", tcp->u_arg[3]);
2603 }
2604 } else {
2605 if (tcp->u_arg[0] == PTRACE_READDATA ||
2606 tcp->u_arg[0] == PTRACE_READTEXT) {
2607 tprintf("%lu, ", tcp->u_arg[3]);
2608 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2609 }
2610 }
2611#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002612#ifdef FREEBSD
2613 tprintf("%lu", tcp->u_arg[3]);
2614 }
2615#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002616 return 0;
2617}
2618
2619#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002620
2621#ifdef LINUX
2622static struct xlat futexops[] = {
2623 { FUTEX_WAIT, "FUTEX_WAIT" },
2624 { FUTEX_WAKE, "FUTEX_WAKE" },
2625 { FUTEX_FD, "FUTEX_FD" },
2626 { 0, NULL }
2627};
2628
2629int
2630sys_futex(tcp)
2631struct tcb *tcp;
2632{
2633 if (entering(tcp)) {
2634 tprintf("%p, ", (void *) tcp->u_arg[0]);
2635 printflags(futexops, tcp->u_arg[1]);
Roland McGrath8dfa04a2003-03-05 04:07:55 +00002636 tprintf(", %ld", tcp->u_arg[2]);
2637 if (tcp->u_arg[1] == FUTEX_WAIT) {
2638 tprintf(", ");
2639 printtv(tcp, tcp->u_arg[3]);
2640 }
Roland McGrath5a223472002-12-15 23:58:26 +00002641 }
2642 return 0;
2643}
2644
2645static void
2646print_affinitylist(list, len)
2647unsigned long *list;
2648unsigned int len;
2649{
2650 int first = 1;
2651 tprintf(" {");
2652 while (len > sizeof (unsigned long)) {
2653 tprintf("%s %lx", first ? "" : ",", *list++);
2654 first = 0;
2655 len -= sizeof (unsigned long);
2656 }
2657 tprintf(" }");
2658}
2659
2660int
2661sys_sched_setaffinity(tcp)
2662struct tcb *tcp;
2663{
2664 if (entering(tcp)) {
2665 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2666 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2667 }
2668 return 0;
2669}
2670
2671int
2672sys_sched_getaffinity(tcp)
2673struct tcb *tcp;
2674{
2675 if (entering(tcp)) {
2676 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2677 } else {
2678 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);
2679 }
2680 return 0;
2681}
2682#endif