blob: 0a6f8398f507b859f5bad7f81addd258367c46e8 [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 McGrathfe5fdb22003-05-23 00:29:05 +0000535# elif defined S390 || defined S390X
Roland McGrath9677b3a2003-03-12 09:54:36 +0000536# define ARG_STACK 0
537# define ARG_FLAGS 1
538# define ARG_PTID 2
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000539# define ARG_CTID 3
540# define ARG_TLS 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 McGrath984154d2003-05-23 01:08:42 +0000568 if (printflags(clone_flags, flags &~ CSIGNAL) == 0)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000569 tprintf("0");
Roland McGrath984154d2003-05-23 01:08:42 +0000570 if ((flags & CSIGNAL) != 0)
571 tprintf("|%s", signame(flags & CSIGNAL));
Roland McGrathb4968be2003-01-20 09:04:33 +0000572 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
Roland McGrath9677b3a2003-03-12 09:54:36 +0000573 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
Roland McGrath909875b2002-12-22 03:34:36 +0000574 return 0;
Roland McGrath6f67a982003-03-21 07:33:15 +0000575 if (flags & CLONE_PARENT_SETTID)
576 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000577 if (flags & CLONE_SETTLS) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000578# ifdef I386
Roland McGrath909875b2002-12-22 03:34:36 +0000579 struct modify_ldt_ldt_s copy;
Roland McGrath9677b3a2003-03-12 09:54:36 +0000580 if (umove(tcp, tcp->u_arg[ARG_TLS], &copy) != -1) {
Roland McGrath909875b2002-12-22 03:34:36 +0000581 tprintf(", {entry_number:%d, ",
582 copy.entry_number);
583 if (!verbose(tcp))
584 tprintf("...}");
585 else
586 print_ldt_entry(&copy);
587 }
588 else
Roland McGrath9677b3a2003-03-12 09:54:36 +0000589# endif
Roland McGrath43f2c842003-03-12 09:58:14 +0000590 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
Roland McGrath909875b2002-12-22 03:34:36 +0000591 }
Roland McGrath9677b3a2003-03-12 09:54:36 +0000592 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
593 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000594 }
595 return 0;
596}
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000597#endif
598
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000599int
600sys_fork(tcp)
601struct tcb *tcp;
602{
603 if (exiting(tcp))
604 return RVAL_UDECIMAL;
605 return 0;
606}
607
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000608int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000609change_syscall(tcp, new)
610struct tcb *tcp;
611int new;
612{
613#if defined(LINUX)
614#if defined(I386)
615 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000616 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000617 return -1;
618 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000619#elif defined(X86_64)
620 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000621 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000622 return -1;
623 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000624#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000625 if (ptrace(PTRACE_POKEUSER, tcp->pid,
626 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000627 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000628 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000629#elif defined(S390) || defined(S390X)
630 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
631 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
632 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000633 return 0;
634#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000635 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000636 return -1;
637 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000638#elif defined(SPARC)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000639 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000640 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
641 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000642 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000643 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
644 return -1;
645 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000646#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000647 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000648 return -1;
649 return 0;
650#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000651 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000652 return -1;
653 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000654#elif defined(IA64)
655 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
656 return -1;
657 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000658#elif defined(HPPA)
659 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
660 return -1;
661 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000662#elif defined(SH)
Roland McGrathac971c22003-03-31 01:03:33 +0000663 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
Wichert Akkermanccef6372002-05-01 16:39:22 +0000664 return -1;
665 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000666#else
667#warning Do not know how to handle change_syscall for this architecture
668#endif /* architecture */
669#endif /* LINUX */
670 return -1;
671}
672
673int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000674setarg(tcp, argnum)
675 struct tcb *tcp;
676 int argnum;
677{
678#if defined (IA64)
679 {
680 unsigned long *bsp, *ap;
681
682 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
683 return -1;
684
685 ap = ia64_rse_skip_regs(bsp, argnum);
686 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000687 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000688 if (errno)
689 return -1;
690
691 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000692#elif defined(I386)
693 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000694 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000695 if (errno)
696 return -1;
697 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000698#elif defined(X86_64)
699 {
700 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
701 if (errno)
702 return -1;
703 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000704#elif defined(POWERPC)
705#ifndef PT_ORIG_R3
706#define PT_ORIG_R3 34
707#endif
708 {
709 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000710 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000711 tcp->u_arg[argnum]);
712 if (errno)
713 return -1;
714 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000715#elif defined(MIPS)
716 {
717 errno = 0;
718 if (argnum < 4)
719 ptrace(PTRACE_POKEUSER, tcp->pid,
720 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
721 else {
722 unsigned long *sp;
723
724 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
725 return -1;
726
727 ptrace(PTRACE_POKEDATA, tcp->pid,
728 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
729 }
730 if (errno)
731 return -1;
732 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000733#elif defined(S390) || defined(S390X)
734 {
735 if(argnum <= 5)
736 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000737 (char *) (argnum==0 ? PT_ORIGGPR2 :
738 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000739 tcp->u_arg[argnum]);
740 else
741 return -E2BIG;
742 if (errno)
743 return -1;
744 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000745#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000746# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000747#endif
748 return 0;
749}
750
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000751#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000752int
753internal_clone(tcp)
754struct tcb *tcp;
755{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000756 struct tcb *tcpchild;
757 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000758 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000759 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000760 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000761 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000762 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000763 if (setbpt(tcp) < 0)
764 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000765 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000766 int bpt = tcp->flags & TCB_BPTSET;
767
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000768 if (!(tcp->flags & TCB_FOLLOWFORK))
769 return 0;
770
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000771 if (syserror(tcp)) {
772 if (bpt)
773 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000774 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000775 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000776
777 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000778
779#ifdef CLONE_PTRACE /* See new setbpt code. */
780 tcpchild = pid2tcb(pid);
781 if (tcpchild != NULL) {
782 /* The child already reported its startup trap
783 before the parent reported its syscall return. */
784 if ((tcpchild->flags
785 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
786 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
787 fprintf(stderr, "\
788[preattached child %d of %d in weird state!]\n",
789 pid, tcp->pid);
790 }
791 else
792#endif
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000793 if ((tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000794 if (bpt)
795 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000796 fprintf(stderr, " [tcb table full]\n");
797 kill(pid, SIGKILL); /* XXX */
798 return 0;
799 }
800
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000801#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000802 /* Attach to the new child */
803 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000804 if (bpt)
805 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000806 perror("PTRACE_ATTACH");
807 fprintf(stderr, "Too late?\n");
808 droptcb(tcpchild);
809 return 0;
810 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000811#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000812
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000813 if (bpt)
814 clearbpt(tcp);
815
Ulrich Drepper90512f01999-12-24 07:22:25 +0000816 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000817 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000818 if (bpt) {
819 tcpchild->flags |= TCB_BPTSET;
820 tcpchild->baddr = tcp->baddr;
821 memcpy(tcpchild->inst, tcp->inst,
822 sizeof tcpchild->inst);
823 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000824 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000825 tcp->nchildren++;
826 if (tcpchild->flags & TCB_SUSPENDED) {
827 /* The child was born suspended, due to our having
828 forced CLONE_PTRACE. */
829 if (bpt)
830 clearbpt(tcpchild);
831
832 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
833 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
834 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
835 return -1;
836 }
837
838 if (!qflag)
839 fprintf(stderr, "\
840Process %u resumed (parent %d ready)\n",
841 pid, tcp->pid);
842 }
843 else {
844 newoutf(tcpchild);
845 if (!qflag)
846 fprintf(stderr, "Process %d attached\n", pid);
847 }
848
849#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000850 {
851 /*
852 * Save the flags used in this call,
853 * in case we point TCP to our parent below.
854 */
855 int call_flags = tcp->u_arg[ARG_FLAGS];
856 if ((tcp->flags & TCB_CLONE_THREAD) &&
857 tcp->parent != NULL) {
858 /* The parent in this clone is itself a
859 thread belonging to another process.
860 There is no meaning to the parentage
861 relationship of the new child with the
862 thread, only with the process. We
863 associate the new thread with our
864 parent. Since this is done for every
865 new thread, there will never be a
866 TCB_CLONE_THREAD process that has
867 children. */
868 --tcp->nchildren;
869 tcp = tcp->parent;
870 tcpchild->parent = tcp;
871 ++tcp->nchildren;
872 }
873 if (call_flags & CLONE_THREAD) {
874 tcpchild->flags |= TCB_CLONE_THREAD;
875 ++tcp->nclone_threads;
876 }
877 if (call_flags & CLONE_DETACHED) {
878 tcpchild->flags |= TCB_CLONE_DETACHED;
879 ++tcp->nclone_detached;
880 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000881 }
882#endif
883
884 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000885 return 0;
886}
887#endif
888
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000889int
890internal_fork(tcp)
891struct tcb *tcp;
892{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000893#ifdef LINUX
894 /* We do special magic with clone for any clone or fork. */
895 return internal_clone(tcp);
896#else
897
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000898 struct tcb *tcpchild;
899 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000900 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000901
902#ifdef SYS_vfork
Nate Sammonsccd8f211999-03-29 22:57:54 +0000903 if (tcp->scno == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000904 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000905 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000906 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000907 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000908 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000909#endif
910 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000911 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000912 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000913 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000914 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000915 if (setbpt(tcp) < 0)
916 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000917 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000918 else {
919 int bpt = tcp->flags & TCB_BPTSET;
920
921 if (!(tcp->flags & TCB_FOLLOWFORK))
922 return 0;
923 if (bpt)
924 clearbpt(tcp);
925
926 if (syserror(tcp))
927 return 0;
928
929 pid = tcp->u_rval;
930 if ((tcpchild = alloctcb(pid)) == NULL) {
931 fprintf(stderr, " [tcb table full]\n");
932 kill(pid, SIGKILL); /* XXX */
933 return 0;
934 }
935#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000936#ifdef HPPA
937 /* The child must have run before it can be attached. */
938 /* This must be a bug in the parisc kernel, but I havn't
939 * identified it yet. Seems to be an issue associated
940 * with attaching to a process (which sends it a signal)
941 * before that process has ever been scheduled. When
942 * debugging, I started seeing crashes in
943 * arch/parisc/kernel/signal.c:do_signal(), apparently
944 * caused by r8 getting corrupt over the dequeue_signal()
945 * call. Didn't make much sense though...
946 */
947 {
948 struct timeval tv;
949 tv.tv_sec = 0;
950 tv.tv_usec = 10000;
951 select(0, NULL, NULL, NULL, &tv);
952 }
953#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000954 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
955 perror("PTRACE_ATTACH");
956 fprintf(stderr, "Too late?\n");
957 droptcb(tcpchild);
958 return 0;
959 }
960#endif /* LINUX */
961#ifdef SUNOS4
962#ifdef oldway
963 /* The child must have run before it can be attached. */
964 {
965 struct timeval tv;
966 tv.tv_sec = 0;
967 tv.tv_usec = 10000;
968 select(0, NULL, NULL, NULL, &tv);
969 }
970 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
971 perror("PTRACE_ATTACH");
972 fprintf(stderr, "Too late?\n");
973 droptcb(tcpchild);
974 return 0;
975 }
976#else /* !oldway */
977 /* Try to catch the new process as soon as possible. */
978 {
979 int i;
980 for (i = 0; i < 1024; i++)
981 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
982 break;
983 if (i == 1024) {
984 perror("PTRACE_ATTACH");
985 fprintf(stderr, "Too late?\n");
986 droptcb(tcpchild);
987 return 0;
988 }
989 }
990#endif /* !oldway */
991#endif /* SUNOS4 */
992 tcpchild->flags |= TCB_ATTACHED;
993 /* Child has BPT too, must be removed on first occasion */
994 if (bpt) {
995 tcpchild->flags |= TCB_BPTSET;
996 tcpchild->baddr = tcp->baddr;
997 memcpy(tcpchild->inst, tcp->inst,
998 sizeof tcpchild->inst);
999 }
1000 newoutf(tcpchild);
1001 tcpchild->parent = tcp;
1002 tcp->nchildren++;
1003 if (!qflag)
1004 fprintf(stderr, "Process %d attached\n", pid);
1005 }
1006 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001007#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001008}
1009
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001010#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001011
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001012#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001013
1014int
1015sys_vfork(tcp)
1016struct tcb *tcp;
1017{
1018 if (exiting(tcp))
1019 return RVAL_UDECIMAL;
1020 return 0;
1021}
1022
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001023#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001024
1025#ifndef LINUX
1026
1027static char idstr[16];
1028
1029int
1030sys_getpid(tcp)
1031struct tcb *tcp;
1032{
1033 if (exiting(tcp)) {
1034 sprintf(idstr, "ppid %lu", getrval2(tcp));
1035 tcp->auxstr = idstr;
1036 return RVAL_STR;
1037 }
1038 return 0;
1039}
1040
1041int
1042sys_getuid(tcp)
1043struct tcb *tcp;
1044{
1045 if (exiting(tcp)) {
1046 sprintf(idstr, "euid %lu", getrval2(tcp));
1047 tcp->auxstr = idstr;
1048 return RVAL_STR;
1049 }
1050 return 0;
1051}
1052
1053int
1054sys_getgid(tcp)
1055struct tcb *tcp;
1056{
1057 if (exiting(tcp)) {
1058 sprintf(idstr, "egid %lu", getrval2(tcp));
1059 tcp->auxstr = idstr;
1060 return RVAL_STR;
1061 }
1062 return 0;
1063}
1064
1065#endif /* !LINUX */
1066
1067#ifdef LINUX
1068
1069int
1070sys_setuid(tcp)
1071struct tcb *tcp;
1072{
1073 if (entering(tcp)) {
1074 tprintf("%u", (uid_t) tcp->u_arg[0]);
1075 }
1076 return 0;
1077}
1078
1079int
1080sys_setgid(tcp)
1081struct tcb *tcp;
1082{
1083 if (entering(tcp)) {
1084 tprintf("%u", (gid_t) tcp->u_arg[0]);
1085 }
1086 return 0;
1087}
1088
1089int
1090sys_getresuid(tcp)
1091 struct tcb *tcp;
1092{
1093 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001094 __kernel_uid_t uid;
1095 if (syserror(tcp))
1096 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1097 tcp->u_arg[1], tcp->u_arg[2]);
1098 else {
1099 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1100 tprintf("%#lx, ", tcp->u_arg[0]);
1101 else
1102 tprintf("ruid %lu, ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001103 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1104 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001105 else
1106 tprintf("euid %lu, ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001107 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1108 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001109 else
1110 tprintf("suid %lu", (unsigned long) uid);
1111 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001112 }
1113 return 0;
1114}
1115
1116int
1117sys_getresgid(tcp)
1118struct tcb *tcp;
1119{
1120 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001121 __kernel_gid_t gid;
1122 if (syserror(tcp))
1123 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1124 tcp->u_arg[1], tcp->u_arg[2]);
1125 else {
1126 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1127 tprintf("%#lx, ", tcp->u_arg[0]);
1128 else
1129 tprintf("rgid %lu, ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001130 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1131 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001132 else
1133 tprintf("egid %lu, ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001134 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1135 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001136 else
1137 tprintf("sgid %lu", (unsigned long) gid);
1138 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001139 }
1140 return 0;
1141}
1142
1143#endif /* LINUX */
1144
1145int
1146sys_setreuid(tcp)
1147struct tcb *tcp;
1148{
1149 if (entering(tcp)) {
1150 tprintf("%lu, %lu",
1151 (unsigned long) (uid_t) tcp->u_arg[0],
1152 (unsigned long) (uid_t) tcp->u_arg[1]);
1153 }
1154 return 0;
1155}
1156
1157int
1158sys_setregid(tcp)
1159struct tcb *tcp;
1160{
1161 if (entering(tcp)) {
1162 tprintf("%lu, %lu",
1163 (unsigned long) (gid_t) tcp->u_arg[0],
1164 (unsigned long) (gid_t) tcp->u_arg[1]);
1165 }
1166 return 0;
1167}
1168
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001169#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001170int
1171sys_setresuid(tcp)
1172 struct tcb *tcp;
1173{
1174 if (entering(tcp)) {
1175 tprintf("ruid %u, euid %u, suid %u",
1176 (uid_t) tcp->u_arg[0],
1177 (uid_t) tcp->u_arg[1],
1178 (uid_t) tcp->u_arg[2]);
1179 }
1180 return 0;
1181}
1182int
1183sys_setresgid(tcp)
1184 struct tcb *tcp;
1185{
1186 if (entering(tcp)) {
1187 tprintf("rgid %u, egid %u, sgid %u",
1188 (uid_t) tcp->u_arg[0],
1189 (uid_t) tcp->u_arg[1],
1190 (uid_t) tcp->u_arg[2]);
1191 }
1192 return 0;
1193}
1194
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001195#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001196
1197int
1198sys_setgroups(tcp)
1199struct tcb *tcp;
1200{
1201 int i, len;
1202 GETGROUPS_T *gidset;
1203
1204 if (entering(tcp)) {
1205 len = tcp->u_arg[0];
1206 tprintf("%u, ", len);
1207 if (len <= 0) {
1208 tprintf("[]");
1209 return 0;
1210 }
1211 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1212 if (gidset == NULL) {
1213 fprintf(stderr, "sys_setgroups: out of memory\n");
1214 return -1;
1215 }
1216 if (!verbose(tcp))
1217 tprintf("%#lx", tcp->u_arg[1]);
1218 else if (umoven(tcp, tcp->u_arg[1],
1219 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1220 tprintf("[?]");
1221 else {
1222 tprintf("[");
1223 for (i = 0; i < len; i++)
1224 tprintf("%s%lu", i ? ", " : "",
1225 (unsigned long) gidset[i]);
1226 tprintf("]");
1227 }
1228 free((char *) gidset);
1229 }
1230 return 0;
1231}
1232
1233int
1234sys_getgroups(tcp)
1235struct tcb *tcp;
1236{
1237 int i, len;
1238 GETGROUPS_T *gidset;
1239
1240 if (entering(tcp)) {
1241 len = tcp->u_arg[0];
1242 tprintf("%u, ", len);
1243 } else {
1244 len = tcp->u_rval;
1245 if (len <= 0) {
1246 tprintf("[]");
1247 return 0;
1248 }
1249 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1250 if (gidset == NULL) {
1251 fprintf(stderr, "sys_getgroups: out of memory\n");
1252 return -1;
1253 }
1254 if (!tcp->u_arg[1])
1255 tprintf("NULL");
1256 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1257 tprintf("%#lx", tcp->u_arg[1]);
1258 else if (umoven(tcp, tcp->u_arg[1],
1259 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1260 tprintf("[?]");
1261 else {
1262 tprintf("[");
1263 for (i = 0; i < len; i++)
1264 tprintf("%s%lu", i ? ", " : "",
1265 (unsigned long) gidset[i]);
1266 tprintf("]");
1267 }
1268 free((char *)gidset);
1269 }
1270 return 0;
1271}
1272
1273int
1274sys_setpgrp(tcp)
1275struct tcb *tcp;
1276{
1277 if (entering(tcp)) {
1278#ifndef SVR4
1279 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1280#endif /* !SVR4 */
1281 }
1282 return 0;
1283}
1284
1285int
1286sys_getpgrp(tcp)
1287struct tcb *tcp;
1288{
1289 if (entering(tcp)) {
1290#ifndef SVR4
1291 tprintf("%lu", tcp->u_arg[0]);
1292#endif /* !SVR4 */
1293 }
1294 return 0;
1295}
1296
1297int
1298sys_getsid(tcp)
1299struct tcb *tcp;
1300{
1301 if (entering(tcp)) {
1302 tprintf("%lu", tcp->u_arg[0]);
1303 }
1304 return 0;
1305}
1306
1307int
1308sys_setsid(tcp)
1309struct tcb *tcp;
1310{
1311 return 0;
1312}
1313
1314int
1315sys_getpgid(tcp)
1316struct tcb *tcp;
1317{
1318 if (entering(tcp)) {
1319 tprintf("%lu", tcp->u_arg[0]);
1320 }
1321 return 0;
1322}
1323
1324int
1325sys_setpgid(tcp)
1326struct tcb *tcp;
1327{
1328 if (entering(tcp)) {
1329 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1330 }
1331 return 0;
1332}
1333
John Hughesc61eb3d2002-05-17 11:37:50 +00001334#if UNIXWARE >= 2
1335
1336#include <sys/privilege.h>
1337
1338
1339static struct xlat procpriv_cmds [] = {
1340 { SETPRV, "SETPRV" },
1341 { CLRPRV, "CLRPRV" },
1342 { PUTPRV, "PUTPRV" },
1343 { GETPRV, "GETPRV" },
1344 { CNTPRV, "CNTPRV" },
1345 { 0, NULL },
1346};
1347
1348
1349static struct xlat procpriv_priv [] = {
1350 { P_OWNER, "P_OWNER" },
1351 { P_AUDIT, "P_AUDIT" },
1352 { P_COMPAT, "P_COMPAT" },
1353 { P_DACREAD, "P_DACREAD" },
1354 { P_DACWRITE, "P_DACWRITE" },
1355 { P_DEV, "P_DEV" },
1356 { P_FILESYS, "P_FILESYS" },
1357 { P_MACREAD, "P_MACREAD" },
1358 { P_MACWRITE, "P_MACWRITE" },
1359 { P_MOUNT, "P_MOUNT" },
1360 { P_MULTIDIR, "P_MULTIDIR" },
1361 { P_SETPLEVEL, "P_SETPLEVEL" },
1362 { P_SETSPRIV, "P_SETSPRIV" },
1363 { P_SETUID, "P_SETUID" },
1364 { P_SYSOPS, "P_SYSOPS" },
1365 { P_SETUPRIV, "P_SETUPRIV" },
1366 { P_DRIVER, "P_DRIVER" },
1367 { P_RTIME, "P_RTIME" },
1368 { P_MACUPGRADE, "P_MACUPGRADE" },
1369 { P_FSYSRANGE, "P_FSYSRANGE" },
1370 { P_SETFLEVEL, "P_SETFLEVEL" },
1371 { P_AUDITWR, "P_AUDITWR" },
1372 { P_TSHAR, "P_TSHAR" },
1373 { P_PLOCK, "P_PLOCK" },
1374 { P_CORE, "P_CORE" },
1375 { P_LOADMOD, "P_LOADMOD" },
1376 { P_BIND, "P_BIND" },
1377 { P_ALLPRIVS, "P_ALLPRIVS" },
1378 { 0, NULL },
1379};
1380
1381
1382static struct xlat procpriv_type [] = {
1383 { PS_FIX, "PS_FIX" },
1384 { PS_INH, "PS_INH" },
1385 { PS_MAX, "PS_MAX" },
1386 { PS_WKG, "PS_WKG" },
1387 { 0, NULL },
1388};
1389
1390
1391static void
1392printpriv(tcp, addr, len, opt)
1393struct tcb *tcp;
1394long addr;
1395int len;
1396struct xlat *opt;
1397{
1398 priv_t buf [128];
1399 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1400 int dots = len > max;
1401 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001402
John Hughesc61eb3d2002-05-17 11:37:50 +00001403 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001404
John Hughesc61eb3d2002-05-17 11:37:50 +00001405 if (len <= 0 ||
1406 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1407 {
1408 tprintf ("%#lx", addr);
1409 return;
1410 }
1411
1412 tprintf ("[");
1413
1414 for (i = 0; i < len; ++i) {
1415 char *t, *p;
1416
1417 if (i) tprintf (", ");
1418
1419 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1420 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1421 {
1422 tprintf ("%s|%s", t, p);
1423 }
1424 else {
1425 tprintf ("%#lx", buf [i]);
1426 }
1427 }
1428
1429 if (dots) tprintf (" ...");
1430
1431 tprintf ("]");
1432}
1433
1434
1435int
1436sys_procpriv(tcp)
1437struct tcb *tcp;
1438{
1439 if (entering(tcp)) {
1440 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1441 switch (tcp->u_arg[0]) {
1442 case CNTPRV:
1443 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1444 break;
1445
1446 case GETPRV:
1447 break;
1448
1449 default:
1450 tprintf (", ");
1451 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1452 tprintf (", %ld", tcp->u_arg[2]);
1453 }
1454 }
1455 else if (tcp->u_arg[0] == GETPRV) {
1456 if (syserror (tcp)) {
1457 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1458 }
1459 else {
1460 tprintf (", ");
1461 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1462 tprintf (", %ld", tcp->u_arg[2]);
1463 }
1464 }
Roland McGrath5a223472002-12-15 23:58:26 +00001465
John Hughesc61eb3d2002-05-17 11:37:50 +00001466 return 0;
1467}
1468
1469#endif
1470
1471
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001472void
1473fake_execve(tcp, program, argv, envp)
1474struct tcb *tcp;
1475char *program;
1476char *argv[];
1477char *envp[];
1478{
1479 int i;
1480
1481#ifdef ARM
1482 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1483 return;
1484#else
1485 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1486 return;
1487#endif /* !ARM */
1488 printleader(tcp);
1489 tprintf("execve(");
1490 string_quote(program);
1491 tprintf(", [");
1492 for (i = 0; argv[i] != NULL; i++) {
1493 if (i != 0)
1494 tprintf(", ");
1495 string_quote(argv[i]);
1496 }
1497 for (i = 0; envp[i] != NULL; i++)
1498 ;
1499 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1500 tabto(acolumn);
1501 tprintf("= 0");
1502 printtrailer(tcp);
1503}
1504
1505static void
1506printargv(tcp, addr)
1507struct tcb *tcp;
1508long addr;
1509{
1510 char *cp;
1511 char *sep;
1512 int max = max_strlen / 2;
1513
1514 for (sep = ""; --max >= 0; sep = ", ") {
1515 if (!abbrev(tcp))
1516 max++;
1517 if (umove(tcp, addr, &cp) < 0) {
1518 tprintf("%#lx", addr);
1519 return;
1520 }
1521 if (cp == 0)
1522 break;
1523 tprintf(sep);
1524 printstr(tcp, (long) cp, -1);
1525 addr += sizeof(char *);
1526 }
1527 if (cp)
1528 tprintf(", ...");
1529}
1530
1531static void
1532printargc(fmt, tcp, addr)
1533char *fmt;
1534struct tcb *tcp;
1535long addr;
1536{
1537 int count;
1538 char *cp;
1539
1540 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1541 addr += sizeof(char *);
1542 }
1543 tprintf(fmt, count, count == 1 ? "" : "s");
1544}
1545
1546int
1547sys_execv(tcp)
1548struct tcb *tcp;
1549{
1550 if (entering(tcp)) {
1551 printpath(tcp, tcp->u_arg[0]);
1552 if (!verbose(tcp))
1553 tprintf(", %#lx", tcp->u_arg[1]);
1554#if 0
1555 else if (abbrev(tcp))
1556 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1557#endif
1558 else {
1559 tprintf(", [");
1560 printargv(tcp, tcp->u_arg[1]);
1561 tprintf("]");
1562 }
1563 }
1564 return 0;
1565}
1566
1567int
1568sys_execve(tcp)
1569struct tcb *tcp;
1570{
1571 if (entering(tcp)) {
1572 printpath(tcp, tcp->u_arg[0]);
1573 if (!verbose(tcp))
1574 tprintf(", %#lx", tcp->u_arg[1]);
1575#if 0
1576 else if (abbrev(tcp))
1577 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1578#endif
1579 else {
1580 tprintf(", [");
1581 printargv(tcp, tcp->u_arg[1]);
1582 tprintf("]");
1583 }
1584 if (!verbose(tcp))
1585 tprintf(", %#lx", tcp->u_arg[2]);
1586 else if (abbrev(tcp))
1587 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1588 else {
1589 tprintf(", [");
1590 printargv(tcp, tcp->u_arg[2]);
1591 tprintf("]");
1592 }
1593 }
Roland McGrathb4968be2003-01-20 09:04:33 +00001594#if defined LINUX && defined TCB_WAITEXECVE
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001595 tcp->flags |= TCB_WAITEXECVE;
Roland McGrathb4968be2003-01-20 09:04:33 +00001596#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001597 return 0;
1598}
1599
John Hughes4e36a812001-04-18 15:11:51 +00001600#if UNIXWARE > 2
1601
1602int sys_rexecve(tcp)
1603struct tcb *tcp;
1604{
1605 if (entering (tcp)) {
1606 sys_execve (tcp);
1607 tprintf (", %ld", tcp->u_arg[3]);
1608 }
1609 return 0;
1610}
1611
1612#endif
1613
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001614int
1615internal_exec(tcp)
1616struct tcb *tcp;
1617{
1618#ifdef SUNOS4
1619 if (exiting(tcp) && !syserror(tcp) && followfork)
1620 fixvfork(tcp);
1621#endif /* SUNOS4 */
1622 return 0;
1623}
1624
1625#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001626#ifndef __WNOTHREAD
1627#define __WNOTHREAD 0x20000000
1628#endif
1629#ifndef __WALL
1630#define __WALL 0x40000000
1631#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001632#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001633#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001634#endif
1635#endif /* LINUX */
1636
1637static struct xlat wait4_options[] = {
1638 { WNOHANG, "WNOHANG" },
1639#ifndef WSTOPPED
1640 { WUNTRACED, "WUNTRACED" },
1641#endif
1642#ifdef WEXITED
1643 { WEXITED, "WEXITED" },
1644#endif
1645#ifdef WTRAPPED
1646 { WTRAPPED, "WTRAPPED" },
1647#endif
1648#ifdef WSTOPPED
1649 { WSTOPPED, "WSTOPPED" },
1650#endif
1651#ifdef WCONTINUED
1652 { WCONTINUED, "WCONTINUED" },
1653#endif
1654#ifdef WNOWAIT
1655 { WNOWAIT, "WNOWAIT" },
1656#endif
1657#ifdef __WCLONE
1658 { __WCLONE, "__WCLONE" },
1659#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001660#ifdef __WALL
1661 { __WALL, "__WALL" },
1662#endif
1663#ifdef __WNOTHREAD
1664 { __WNOTHREAD, "__WNOTHREAD" },
1665#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001666 { 0, NULL },
1667};
1668
1669static int
1670printstatus(status)
1671int status;
1672{
1673 int exited = 0;
1674
1675 /*
1676 * Here is a tricky presentation problem. This solution
1677 * is still not entirely satisfactory but since there
1678 * are no wait status constructors it will have to do.
1679 */
1680 if (WIFSTOPPED(status))
1681 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001682 signame(WSTOPSIG(status)));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001683 else if WIFSIGNALED(status)
1684 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001685 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001686 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1687 else if WIFEXITED(status) {
1688 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1689 WEXITSTATUS(status));
1690 exited = 1;
1691 }
1692 else
1693 tprintf("[%#x]", status);
1694 return exited;
1695}
1696
1697static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001698printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001699struct tcb *tcp;
1700int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001701int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001702{
1703 int status;
1704 int exited = 0;
1705
1706 if (entering(tcp)) {
1707 tprintf("%ld, ", tcp->u_arg[0]);
1708 } else {
1709 /* status */
1710 if (!tcp->u_arg[1])
1711 tprintf("NULL");
1712 else if (syserror(tcp) || tcp->u_rval == 0)
1713 tprintf("%#lx", tcp->u_arg[1]);
1714 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1715 tprintf("[?]");
1716 else
1717 exited = printstatus(status);
1718 /* options */
1719 tprintf(", ");
1720 if (!printflags(wait4_options, tcp->u_arg[2]))
1721 tprintf("0");
1722 if (n == 4) {
1723 tprintf(", ");
1724 /* usage */
1725 if (!tcp->u_arg[3])
1726 tprintf("NULL");
1727#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001728 else if (tcp->u_rval > 0) {
1729#ifdef LINUX_64BIT
1730 if (bitness)
1731 printrusage32(tcp, tcp->u_arg[3]);
1732 else
1733#endif
1734 printrusage(tcp, tcp->u_arg[3]);
1735 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001736#endif /* LINUX */
1737#ifdef SUNOS4
1738 else if (tcp->u_rval > 0 && exited)
1739 printrusage(tcp, tcp->u_arg[3]);
1740#endif /* SUNOS4 */
1741 else
1742 tprintf("%#lx", tcp->u_arg[3]);
1743 }
1744 }
1745 return 0;
1746}
1747
1748int
1749internal_wait(tcp)
1750struct tcb *tcp;
1751{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001752 int got_kids;
1753
1754#ifdef TCB_CLONE_THREAD
1755 if (tcp->flags & TCB_CLONE_THREAD)
1756 /* The children we wait for are our parent's children. */
1757 got_kids = (tcp->parent->nchildren
1758 > tcp->parent->nclone_detached);
1759 else
1760 got_kids = (tcp->nchildren > tcp->nclone_detached);
1761#else
1762 got_kids = tcp->nchildren > 0;
1763#endif
1764
1765 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001766 /* There are children that this parent should block for.
1767 But ptrace made us the parent of the traced children
1768 and the real parent will get ECHILD from the wait call.
1769
1770 XXX If we attached with strace -f -p PID, then there
1771 may be untraced dead children the parent could be reaping
1772 now, but we make him block. */
1773
1774 /* ??? WTA: fix bug with hanging children */
1775
1776 if (!(tcp->u_arg[2] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00001777 /*
1778 * There are traced children. We'll make the parent
1779 * block to avoid a false ECHILD error due to our
1780 * ptrace having stolen the children. However,
1781 * we shouldn't block if there are zombies to reap.
1782 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1783 */
1784 if (tcp->nzombies > 0 &&
1785 (tcp->u_arg[0] == -1 ||
1786 pid2tcb(tcp->u_arg[0]) == NULL))
1787 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001788 tcp->flags |= TCB_SUSPENDED;
1789 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001790#ifdef TCB_CLONE_THREAD
1791 if (tcp->flags & TCB_CLONE_THREAD)
1792 tcp->parent->nclone_waiting++;
1793#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001794 }
1795 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001796 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001797 if (tcp->u_arg[2] & WNOHANG) {
1798 /* We must force a fake result of 0 instead of
1799 the ECHILD error. */
1800 extern int force_result();
1801 return force_result(tcp, 0, 0);
1802 }
1803 else
1804 fprintf(stderr,
1805 "internal_wait: should not have resumed %d\n",
1806 tcp->pid);
1807 }
Roland McGrath09623452003-05-23 02:27:13 +00001808 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
1809 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
1810 /*
1811 * We just reaped a child we don't know about,
1812 * presumably a zombie we already droptcb'd.
1813 */
1814 tcp->nzombies--;
1815 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001816 return 0;
1817}
1818
1819#ifdef SVR4
1820
1821int
1822sys_wait(tcp)
1823struct tcb *tcp;
1824{
1825 if (exiting(tcp)) {
1826 /* The library wrapper stuffs this into the user variable. */
1827 if (!syserror(tcp))
1828 printstatus(getrval2(tcp));
1829 }
1830 return 0;
1831}
1832
1833#endif /* SVR4 */
1834
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001835#ifdef FREEBSD
1836int
1837sys_wait(tcp)
1838struct tcb *tcp;
1839{
1840 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001841
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001842 if (exiting(tcp)) {
1843 if (!syserror(tcp)) {
1844 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1845 tprintf("%#lx", tcp->u_arg[0]);
1846 else
1847 printstatus(status);
1848 }
1849 }
1850 return 0;
1851}
1852#endif
1853
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001854int
1855sys_waitpid(tcp)
1856struct tcb *tcp;
1857{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001858 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001859}
1860
1861int
1862sys_wait4(tcp)
1863struct tcb *tcp;
1864{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001865 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001866}
1867
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001868#ifdef ALPHA
1869int
1870sys_osf_wait4(tcp)
1871struct tcb *tcp;
1872{
1873 return printwaitn(tcp, 4, 1);
1874}
1875#endif
1876
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001877#ifdef SVR4
1878
1879static struct xlat waitid_types[] = {
1880 { P_PID, "P_PID" },
1881 { P_PPID, "P_PPID" },
1882 { P_PGID, "P_PGID" },
1883 { P_SID, "P_SID" },
1884 { P_CID, "P_CID" },
1885 { P_UID, "P_UID" },
1886 { P_GID, "P_GID" },
1887 { P_ALL, "P_ALL" },
1888#ifdef P_LWPID
1889 { P_LWPID, "P_LWPID" },
1890#endif
1891 { 0, NULL },
1892};
1893
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001894int
1895sys_waitid(tcp)
1896struct tcb *tcp;
1897{
1898 siginfo_t si;
1899 int exited;
1900
1901 if (entering(tcp)) {
1902 printxval(waitid_types, tcp->u_arg[0], "P_???");
1903 tprintf(", %ld, ", tcp->u_arg[1]);
1904 if (tcp->nchildren > 0) {
1905 /* There are traced children */
1906 tcp->flags |= TCB_SUSPENDED;
1907 tcp->waitpid = tcp->u_arg[0];
1908 }
1909 }
1910 else {
1911 /* siginfo */
1912 exited = 0;
1913 if (!tcp->u_arg[2])
1914 tprintf("NULL");
1915 else if (syserror(tcp))
1916 tprintf("%#lx", tcp->u_arg[2]);
1917 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1918 tprintf("{???}");
1919 else
John Hughes58265892001-10-18 15:13:53 +00001920 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001921 /* options */
1922 tprintf(", ");
1923 if (!printflags(wait4_options, tcp->u_arg[3]))
1924 tprintf("0");
1925 }
1926 return 0;
1927}
1928
1929#endif /* SVR4 */
1930
1931int
1932sys_alarm(tcp)
1933struct tcb *tcp;
1934{
1935 if (entering(tcp))
1936 tprintf("%lu", tcp->u_arg[0]);
1937 return 0;
1938}
1939
1940int
1941sys_uname(tcp)
1942struct tcb *tcp;
1943{
1944 struct utsname uname;
1945
1946 if (exiting(tcp)) {
1947 if (syserror(tcp) || !verbose(tcp))
1948 tprintf("%#lx", tcp->u_arg[0]);
1949 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1950 tprintf("{...}");
1951 else if (!abbrev(tcp)) {
1952
1953 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1954 uname.sysname, uname.nodename);
1955 tprintf("release=\"%s\", version=\"%s\", ",
1956 uname.release, uname.version);
1957 tprintf("machine=\"%s\"", uname.machine);
1958#ifdef LINUX
1959#ifndef __GLIBC__
1960 tprintf(", domainname=\"%s\"", uname.domainname);
1961#endif /* __GLIBC__ */
1962#endif /* LINUX */
1963 tprintf("}");
1964 }
1965 else
1966 tprintf("{sys=\"%s\", node=\"%s\", ...}",
1967 uname.sysname, uname.nodename);
1968 }
1969 return 0;
1970}
1971
1972#ifndef SVR4
1973
1974static struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00001975#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001976 { PTRACE_TRACEME, "PTRACE_TRACEME" },
1977 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
1978 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
1979 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
1980 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
1981 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
1982 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
1983 { PTRACE_CONT, "PTRACE_CONT" },
1984 { PTRACE_KILL, "PTRACE_KILL" },
1985 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
1986 { PTRACE_ATTACH, "PTRACE_ATTACH" },
1987 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001988#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001989 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001990#endif
1991#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001992 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001993#endif
1994#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001995 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00001996#endif
1997#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001998 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00001999#endif
2000#ifdef PTRACE_GETFPXREGS
2001 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2002#endif
2003#ifdef PTRACE_SETFPXREGS
2004 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2005#endif
2006#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002007 { PTRACE_READDATA, "PTRACE_READDATA" },
2008 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2009 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2010 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2011 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2012 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2013#ifdef SPARC
2014 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2015 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2016#else /* !SPARC */
2017 { PTRACE_22, "PTRACE_PTRACE_22" },
2018 { PTRACE_23, "PTRACE_PTRACE_23" },
2019#endif /* !SPARC */
2020#endif /* SUNOS4 */
2021 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2022#ifdef SUNOS4
2023 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2024#ifdef I386
2025 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2026 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2027 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2028#else /* !I386 */
2029 { PTRACE_26, "PTRACE_26" },
2030 { PTRACE_27, "PTRACE_27" },
2031 { PTRACE_28, "PTRACE_28" },
2032#endif /* !I386 */
2033 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2034#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002035#else /* FREEBSD */
2036 { PT_TRACE_ME, "PT_TRACE_ME" },
2037 { PT_READ_I, "PT_READ_I" },
2038 { PT_READ_D, "PT_READ_D" },
2039 { PT_WRITE_I, "PT_WRITE_I" },
2040 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002041#ifdef PT_READ_U
2042 { PT_READ_U, "PT_READ_U" },
2043#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002044 { PT_CONTINUE, "PT_CONTINUE" },
2045 { PT_KILL, "PT_KILL" },
2046 { PT_STEP, "PT_STEP" },
2047 { PT_ATTACH, "PT_ATTACH" },
2048 { PT_DETACH, "PT_DETACH" },
2049 { PT_GETREGS, "PT_GETREGS" },
2050 { PT_SETREGS, "PT_SETREGS" },
2051 { PT_GETFPREGS, "PT_GETFPREGS" },
2052 { PT_SETFPREGS, "PT_SETFPREGS" },
2053 { PT_GETDBREGS, "PT_GETDBREGS" },
2054 { PT_SETDBREGS, "PT_SETDBREGS" },
2055#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002056 { 0, NULL },
2057};
2058
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002059#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002060#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2061static
2062#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2063struct xlat struct_user_offsets[] = {
2064#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002065#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002066 { PT_PSWMASK, "psw_mask" },
2067 { PT_PSWADDR, "psw_addr" },
2068 { PT_GPR0, "gpr0" },
2069 { PT_GPR1, "gpr1" },
2070 { PT_GPR2, "gpr2" },
2071 { PT_GPR3, "gpr3" },
2072 { PT_GPR4, "gpr4" },
2073 { PT_GPR5, "gpr5" },
2074 { PT_GPR6, "gpr6" },
2075 { PT_GPR7, "gpr7" },
2076 { PT_GPR8, "gpr8" },
2077 { PT_GPR9, "gpr9" },
2078 { PT_GPR10, "gpr10" },
2079 { PT_GPR11, "gpr11" },
2080 { PT_GPR12, "gpr12" },
2081 { PT_GPR13, "gpr13" },
2082 { PT_GPR14, "gpr14" },
2083 { PT_GPR15, "gpr15" },
2084 { PT_ACR0, "acr0" },
2085 { PT_ACR1, "acr1" },
2086 { PT_ACR2, "acr2" },
2087 { PT_ACR3, "acr3" },
2088 { PT_ACR4, "acr4" },
2089 { PT_ACR5, "acr5" },
2090 { PT_ACR6, "acr6" },
2091 { PT_ACR7, "acr7" },
2092 { PT_ACR8, "acr8" },
2093 { PT_ACR9, "acr9" },
2094 { PT_ACR10, "acr10" },
2095 { PT_ACR11, "acr11" },
2096 { PT_ACR12, "acr12" },
2097 { PT_ACR13, "acr13" },
2098 { PT_ACR14, "acr14" },
2099 { PT_ACR15, "acr15" },
2100 { PT_ORIGGPR2, "orig_gpr2" },
2101 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002102#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002103 { PT_FPR0_HI, "fpr0.hi" },
2104 { PT_FPR0_LO, "fpr0.lo" },
2105 { PT_FPR1_HI, "fpr1.hi" },
2106 { PT_FPR1_LO, "fpr1.lo" },
2107 { PT_FPR2_HI, "fpr2.hi" },
2108 { PT_FPR2_LO, "fpr2.lo" },
2109 { PT_FPR3_HI, "fpr3.hi" },
2110 { PT_FPR3_LO, "fpr3.lo" },
2111 { PT_FPR4_HI, "fpr4.hi" },
2112 { PT_FPR4_LO, "fpr4.lo" },
2113 { PT_FPR5_HI, "fpr5.hi" },
2114 { PT_FPR5_LO, "fpr5.lo" },
2115 { PT_FPR6_HI, "fpr6.hi" },
2116 { PT_FPR6_LO, "fpr6.lo" },
2117 { PT_FPR7_HI, "fpr7.hi" },
2118 { PT_FPR7_LO, "fpr7.lo" },
2119 { PT_FPR8_HI, "fpr8.hi" },
2120 { PT_FPR8_LO, "fpr8.lo" },
2121 { PT_FPR9_HI, "fpr9.hi" },
2122 { PT_FPR9_LO, "fpr9.lo" },
2123 { PT_FPR10_HI, "fpr10.hi" },
2124 { PT_FPR10_LO, "fpr10.lo" },
2125 { PT_FPR11_HI, "fpr11.hi" },
2126 { PT_FPR11_LO, "fpr11.lo" },
2127 { PT_FPR12_HI, "fpr12.hi" },
2128 { PT_FPR12_LO, "fpr12.lo" },
2129 { PT_FPR13_HI, "fpr13.hi" },
2130 { PT_FPR13_LO, "fpr13.lo" },
2131 { PT_FPR14_HI, "fpr14.hi" },
2132 { PT_FPR14_LO, "fpr14.lo" },
2133 { PT_FPR15_HI, "fpr15.hi" },
2134 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002135#endif
2136#if defined(S390X)
2137 { PT_FPR0, "fpr0" },
2138 { PT_FPR1, "fpr1" },
2139 { PT_FPR2, "fpr2" },
2140 { PT_FPR3, "fpr3" },
2141 { PT_FPR4, "fpr4" },
2142 { PT_FPR5, "fpr5" },
2143 { PT_FPR6, "fpr6" },
2144 { PT_FPR7, "fpr7" },
2145 { PT_FPR8, "fpr8" },
2146 { PT_FPR9, "fpr9" },
2147 { PT_FPR10, "fpr10" },
2148 { PT_FPR11, "fpr11" },
2149 { PT_FPR12, "fpr12" },
2150 { PT_FPR13, "fpr13" },
2151 { PT_FPR14, "fpr14" },
2152 { PT_FPR15, "fpr15" },
2153#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002154 { PT_CR_9, "cr9" },
2155 { PT_CR_10, "cr10" },
2156 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002157 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002158#endif
2159#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002160 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002161#elif defined(HPPA)
2162 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002163#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002164#ifndef PT_ORIG_R3
2165#define PT_ORIG_R3 34
2166#endif
Roland McGratheb285352003-01-14 09:59:00 +00002167#define REGSIZE (sizeof(unsigned long))
2168 { REGSIZE*PT_R0, "r0" },
2169 { REGSIZE*PT_R1, "r1" },
2170 { REGSIZE*PT_R2, "r2" },
2171 { REGSIZE*PT_R3, "r3" },
2172 { REGSIZE*PT_R4, "r4" },
2173 { REGSIZE*PT_R5, "r5" },
2174 { REGSIZE*PT_R6, "r6" },
2175 { REGSIZE*PT_R7, "r7" },
2176 { REGSIZE*PT_R8, "r8" },
2177 { REGSIZE*PT_R9, "r9" },
2178 { REGSIZE*PT_R10, "r10" },
2179 { REGSIZE*PT_R11, "r11" },
2180 { REGSIZE*PT_R12, "r12" },
2181 { REGSIZE*PT_R13, "r13" },
2182 { REGSIZE*PT_R14, "r14" },
2183 { REGSIZE*PT_R15, "r15" },
2184 { REGSIZE*PT_R16, "r16" },
2185 { REGSIZE*PT_R17, "r17" },
2186 { REGSIZE*PT_R18, "r18" },
2187 { REGSIZE*PT_R19, "r19" },
2188 { REGSIZE*PT_R20, "r20" },
2189 { REGSIZE*PT_R21, "r21" },
2190 { REGSIZE*PT_R22, "r22" },
2191 { REGSIZE*PT_R23, "r23" },
2192 { REGSIZE*PT_R24, "r24" },
2193 { REGSIZE*PT_R25, "r25" },
2194 { REGSIZE*PT_R26, "r26" },
2195 { REGSIZE*PT_R27, "r27" },
2196 { REGSIZE*PT_R28, "r28" },
2197 { REGSIZE*PT_R29, "r29" },
2198 { REGSIZE*PT_R30, "r30" },
2199 { REGSIZE*PT_R31, "r31" },
2200 { REGSIZE*PT_NIP, "NIP" },
2201 { REGSIZE*PT_MSR, "MSR" },
2202 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2203 { REGSIZE*PT_CTR, "CTR" },
2204 { REGSIZE*PT_LNK, "LNK" },
2205 { REGSIZE*PT_XER, "XER" },
2206 { REGSIZE*PT_CCR, "CCR" },
2207 { REGSIZE*PT_FPR0, "FPR0" },
2208#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002209#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002210#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002211 { 0, "r0" },
2212 { 1, "r1" },
2213 { 2, "r2" },
2214 { 3, "r3" },
2215 { 4, "r4" },
2216 { 5, "r5" },
2217 { 6, "r6" },
2218 { 7, "r7" },
2219 { 8, "r8" },
2220 { 9, "r9" },
2221 { 10, "r10" },
2222 { 11, "r11" },
2223 { 12, "r12" },
2224 { 13, "r13" },
2225 { 14, "r14" },
2226 { 15, "r15" },
2227 { 16, "r16" },
2228 { 17, "r17" },
2229 { 18, "r18" },
2230 { 19, "r19" },
2231 { 20, "r20" },
2232 { 21, "r21" },
2233 { 22, "r22" },
2234 { 23, "r23" },
2235 { 24, "r24" },
2236 { 25, "r25" },
2237 { 26, "r26" },
2238 { 27, "r27" },
2239 { 28, "r28" },
2240 { 29, "gp" },
2241 { 30, "fp" },
2242 { 31, "zero" },
2243 { 32, "fp0" },
2244 { 33, "fp" },
2245 { 34, "fp2" },
2246 { 35, "fp3" },
2247 { 36, "fp4" },
2248 { 37, "fp5" },
2249 { 38, "fp6" },
2250 { 39, "fp7" },
2251 { 40, "fp8" },
2252 { 41, "fp9" },
2253 { 42, "fp10" },
2254 { 43, "fp11" },
2255 { 44, "fp12" },
2256 { 45, "fp13" },
2257 { 46, "fp14" },
2258 { 47, "fp15" },
2259 { 48, "fp16" },
2260 { 49, "fp17" },
2261 { 50, "fp18" },
2262 { 51, "fp19" },
2263 { 52, "fp20" },
2264 { 53, "fp21" },
2265 { 54, "fp22" },
2266 { 55, "fp23" },
2267 { 56, "fp24" },
2268 { 57, "fp25" },
2269 { 58, "fp26" },
2270 { 59, "fp27" },
2271 { 60, "fp28" },
2272 { 61, "fp29" },
2273 { 62, "fp30" },
2274 { 63, "fp31" },
2275 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002276#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002277#ifdef IA64
2278 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2279 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2280 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2281 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2282 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2283 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2284 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2285 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2286 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2287 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2288 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2289 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2290 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2291 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2292 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2293 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2294 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2295 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2296 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2297 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2298 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2299 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2300 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2301 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2302 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2303 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2304 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2305 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2306 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2307 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2308 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2309 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2310 /* switch stack: */
2311 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2312 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2313 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2314 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2315 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2316 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2317 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2318 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2319 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2320 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002321 { PT_B0, "kb0" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002322 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2323 { PT_B4, "b4" }, { PT_B5, "b5" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002324 { PT_AR_PFS, "kar.pfs" },
2325 { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" },
2326 { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" },
2327 { PT_PR, "k.pr" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002328 /* pt_regs */
2329 { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002330 /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002331 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2332 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2333 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2334 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2335 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2336 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2337 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2338 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2339 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2340 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2341 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2342 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2343 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2344 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2345 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2346#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002347#ifdef I386
2348 { 4*EBX, "4*EBX" },
2349 { 4*ECX, "4*ECX" },
2350 { 4*EDX, "4*EDX" },
2351 { 4*ESI, "4*ESI" },
2352 { 4*EDI, "4*EDI" },
2353 { 4*EBP, "4*EBP" },
2354 { 4*EAX, "4*EAX" },
2355 { 4*DS, "4*DS" },
2356 { 4*ES, "4*ES" },
2357 { 4*FS, "4*FS" },
2358 { 4*GS, "4*GS" },
2359 { 4*ORIG_EAX, "4*ORIG_EAX" },
2360 { 4*EIP, "4*EIP" },
2361 { 4*CS, "4*CS" },
2362 { 4*EFL, "4*EFL" },
2363 { 4*UESP, "4*UESP" },
2364 { 4*SS, "4*SS" },
2365#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002366#ifdef X86_64
2367 { 8*RDI, "8*RDI" },
2368 { 8*RSI, "8*RSI" },
2369 { 8*RDX, "8*RDX" },
2370 { 8*R10, "8*R10" },
2371 { 8*R8, "8*R8" },
2372 { 8*R9, "8*R9" },
2373 { 8*RBX, "8*RBX" },
2374 { 8*RCX, "8*RCX" },
2375 { 8*RBP, "8*RBP" },
2376 { 8*RAX, "8*RAX" },
2377#if 0
2378 { 8*DS, "8*DS" },
2379 { 8*ES, "8*ES" },
2380 { 8*FS, "8*FS" },
2381 { 8*GS, "8*GS" },
2382#endif
2383 { 8*ORIG_RAX, "8*ORIG_EAX" },
2384 { 8*RIP, "8*RIP" },
2385 { 8*CS, "8*CS" },
2386 { 8*EFLAGS, "8*EFL" },
2387 { 8*RSP, "8*RSP" },
2388 { 8*SS, "8*SS" },
2389 { 8*R11, "8*R11" },
2390 { 8*R12, "8*R12" },
2391 { 8*R13, "8*R13" },
2392 { 8*R14, "8*R14" },
2393 { 8*R15, "8*R15" },
2394#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002395#ifdef M68K
2396 { 4*PT_D1, "4*PT_D1" },
2397 { 4*PT_D2, "4*PT_D2" },
2398 { 4*PT_D3, "4*PT_D3" },
2399 { 4*PT_D4, "4*PT_D4" },
2400 { 4*PT_D5, "4*PT_D5" },
2401 { 4*PT_D6, "4*PT_D6" },
2402 { 4*PT_D7, "4*PT_D7" },
2403 { 4*PT_A0, "4*PT_A0" },
2404 { 4*PT_A1, "4*PT_A1" },
2405 { 4*PT_A2, "4*PT_A2" },
2406 { 4*PT_A3, "4*PT_A3" },
2407 { 4*PT_A4, "4*PT_A4" },
2408 { 4*PT_A5, "4*PT_A5" },
2409 { 4*PT_A6, "4*PT_A6" },
2410 { 4*PT_D0, "4*PT_D0" },
2411 { 4*PT_USP, "4*PT_USP" },
2412 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2413 { 4*PT_SR, "4*PT_SR" },
2414 { 4*PT_PC, "4*PT_PC" },
2415#endif /* M68K */
2416#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002417#ifdef SH
2418 { 4*REG_REG0, "4*REG_REG0" },
2419 { 4*(REG_REG0+1), "4*REG_REG1" },
2420 { 4*(REG_REG0+2), "4*REG_REG2" },
2421 { 4*(REG_REG0+3), "4*REG_REG3" },
2422 { 4*(REG_REG0+4), "4*REG_REG4" },
2423 { 4*(REG_REG0+5), "4*REG_REG5" },
2424 { 4*(REG_REG0+6), "4*REG_REG6" },
2425 { 4*(REG_REG0+7), "4*REG_REG7" },
2426 { 4*(REG_REG0+8), "4*REG_REG8" },
2427 { 4*(REG_REG0+9), "4*REG_REG9" },
2428 { 4*(REG_REG0+10), "4*REG_REG10" },
2429 { 4*(REG_REG0+11), "4*REG_REG11" },
2430 { 4*(REG_REG0+12), "4*REG_REG12" },
2431 { 4*(REG_REG0+13), "4*REG_REG13" },
2432 { 4*(REG_REG0+14), "4*REG_REG14" },
2433 { 4*REG_REG15, "4*REG_REG15" },
2434 { 4*REG_PC, "4*REG_PC" },
2435 { 4*REG_PR, "4*REG_PR" },
2436 { 4*REG_SR, "4*REG_SR" },
2437 { 4*REG_GBR, "4*REG_GBR" },
2438 { 4*REG_MACH, "4*REG_MACH" },
2439 { 4*REG_MACL, "4*REG_MACL" },
2440 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2441 { 4*REG_FPUL, "4*REG_FPUL" },
2442 { 4*REG_FPREG0, "4*REG_FPREG0" },
2443 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2444 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2445 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2446 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2447 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2448 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2449 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2450 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2451 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2452 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2453 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2454 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2455 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2456 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2457 { 4*REG_FPREG15, "4*REG_FPREG15" },
2458 { 4*REG_XDREG0, "4*REG_XDREG0" },
2459 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2460 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2461 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2462 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2463 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2464 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2465 { 4*REG_XDREG14, "4*REG_XDREG14" },
2466 { 4*REG_FPSCR, "4*REG_FPSCR" },
2467#endif /* SH */
2468
Michal Ludvig10a88d02002-10-07 14:31:00 +00002469#if !defined(S390) && !defined(S390X) && !defined(MIPS)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002470 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002471#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002472#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002473 { uoff(i387), "offsetof(struct user, i387)" },
2474#else /* !I386 */
2475#ifdef M68K
2476 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2477#endif /* M68K */
2478#endif /* !I386 */
2479 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2480 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2481 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2482 { uoff(start_code), "offsetof(struct user, start_code)" },
2483 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2484 { uoff(signal), "offsetof(struct user, signal)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002485#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002486 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002487#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002488 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002489#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002490 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2491#endif
2492 { uoff(magic), "offsetof(struct user, magic)" },
2493 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002494#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002495 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2496#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002497#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002498#endif /* !ALPHA */
2499#endif /* !POWERPC/!SPARC */
2500#endif /* LINUX */
2501#ifdef SUNOS4
2502 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2503 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2504 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2505 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2506 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2507 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2508 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2509 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2510 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2511 { uoff(u_error), "offsetof(struct user, u_error)" },
2512 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2513 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2514 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2515 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2516 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2517 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2518 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2519 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2520 { uoff(u_code), "offsetof(struct user, u_code)" },
2521 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2522 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2523 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2524 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2525 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2526 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2527 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2528 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2529 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2530 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2531 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2532 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2533 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2534 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2535 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2536 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2537 { uoff(u_start), "offsetof(struct user, u_start)" },
2538 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2539 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2540 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2541 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2542 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2543 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2544 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2545 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2546 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2547#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002548#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002549 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002550#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002551 { 0, NULL },
2552};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002553#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002554
2555int
2556sys_ptrace(tcp)
2557struct tcb *tcp;
2558{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002559 struct xlat *x;
2560 long addr;
2561
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002562 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002563 printxval(ptrace_cmds, tcp->u_arg[0],
2564#ifndef FREEBSD
2565 "PTRACE_???"
2566#else
2567 "PT_???"
2568#endif
2569 );
2570 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002571 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002572#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002573 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2574 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2575 for (x = struct_user_offsets; x->str; x++) {
2576 if (x->val >= addr)
2577 break;
2578 }
2579 if (!x->str)
2580 tprintf("%#lx, ", addr);
2581 else if (x->val > addr && x != struct_user_offsets) {
2582 x--;
2583 tprintf("%s + %ld, ", x->str, addr - x->val);
2584 }
2585 else
2586 tprintf("%s, ", x->str);
2587 }
2588 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002589#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002590 tprintf("%#lx, ", tcp->u_arg[2]);
2591#ifdef LINUX
2592 switch (tcp->u_arg[0]) {
2593 case PTRACE_PEEKDATA:
2594 case PTRACE_PEEKTEXT:
2595 case PTRACE_PEEKUSER:
2596 break;
2597 case PTRACE_CONT:
2598 case PTRACE_SINGLESTEP:
2599 case PTRACE_SYSCALL:
2600 case PTRACE_DETACH:
2601 printsignal(tcp->u_arg[3]);
2602 break;
2603 default:
2604 tprintf("%#lx", tcp->u_arg[3]);
2605 break;
2606 }
2607 } else {
2608 switch (tcp->u_arg[0]) {
2609 case PTRACE_PEEKDATA:
2610 case PTRACE_PEEKTEXT:
2611 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00002612 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002613 break;
2614 }
2615 }
2616#endif /* LINUX */
2617#ifdef SUNOS4
2618 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2619 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2620 tprintf("%lu, ", tcp->u_arg[3]);
2621 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2622 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2623 tcp->u_arg[0] != PTRACE_READTEXT) {
2624 tprintf("%#lx", tcp->u_arg[3]);
2625 }
2626 } else {
2627 if (tcp->u_arg[0] == PTRACE_READDATA ||
2628 tcp->u_arg[0] == PTRACE_READTEXT) {
2629 tprintf("%lu, ", tcp->u_arg[3]);
2630 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2631 }
2632 }
2633#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002634#ifdef FREEBSD
2635 tprintf("%lu", tcp->u_arg[3]);
2636 }
2637#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002638 return 0;
2639}
2640
2641#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002642
2643#ifdef LINUX
2644static struct xlat futexops[] = {
2645 { FUTEX_WAIT, "FUTEX_WAIT" },
2646 { FUTEX_WAKE, "FUTEX_WAKE" },
2647 { FUTEX_FD, "FUTEX_FD" },
2648 { 0, NULL }
2649};
2650
2651int
2652sys_futex(tcp)
2653struct tcb *tcp;
2654{
2655 if (entering(tcp)) {
2656 tprintf("%p, ", (void *) tcp->u_arg[0]);
2657 printflags(futexops, tcp->u_arg[1]);
Roland McGrath8dfa04a2003-03-05 04:07:55 +00002658 tprintf(", %ld", tcp->u_arg[2]);
2659 if (tcp->u_arg[1] == FUTEX_WAIT) {
2660 tprintf(", ");
2661 printtv(tcp, tcp->u_arg[3]);
2662 }
Roland McGrath5a223472002-12-15 23:58:26 +00002663 }
2664 return 0;
2665}
2666
2667static void
2668print_affinitylist(list, len)
2669unsigned long *list;
2670unsigned int len;
2671{
2672 int first = 1;
2673 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00002674 while (len >= sizeof (unsigned long)) {
Roland McGrath5a223472002-12-15 23:58:26 +00002675 tprintf("%s %lx", first ? "" : ",", *list++);
2676 first = 0;
2677 len -= sizeof (unsigned long);
2678 }
2679 tprintf(" }");
2680}
2681
2682int
2683sys_sched_setaffinity(tcp)
2684struct tcb *tcp;
2685{
2686 if (entering(tcp)) {
2687 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2688 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2689 }
2690 return 0;
2691}
2692
2693int
2694sys_sched_getaffinity(tcp)
2695struct tcb *tcp;
2696{
2697 if (entering(tcp)) {
2698 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2699 } else {
2700 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);
2701 }
2702 return 0;
2703}
2704#endif