blob: bb33a2027cb4678ddfe175d48e59406bd3b6889f [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;
Roland McGrathe1e584b2003-06-02 19:18:58 +0000666#elif defined(SHMEDIA)
667 /* Top half of reg encodes the no. of args n as 0x1n.
668 Assume 0 args as kernel never actually checks... */
669 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
670 0x100000 | new) < 0)
671 return -1;
672 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000673#else
674#warning Do not know how to handle change_syscall for this architecture
675#endif /* architecture */
676#endif /* LINUX */
677 return -1;
678}
679
680int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000681setarg(tcp, argnum)
682 struct tcb *tcp;
683 int argnum;
684{
685#if defined (IA64)
686 {
687 unsigned long *bsp, *ap;
688
689 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
690 return -1;
691
692 ap = ia64_rse_skip_regs(bsp, argnum);
693 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000694 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000695 if (errno)
696 return -1;
697
698 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000699#elif defined(I386)
700 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000701 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000702 if (errno)
703 return -1;
704 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000705#elif defined(X86_64)
706 {
707 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
708 if (errno)
709 return -1;
710 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000711#elif defined(POWERPC)
712#ifndef PT_ORIG_R3
713#define PT_ORIG_R3 34
714#endif
715 {
716 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000717 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000718 tcp->u_arg[argnum]);
719 if (errno)
720 return -1;
721 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000722#elif defined(MIPS)
723 {
724 errno = 0;
725 if (argnum < 4)
726 ptrace(PTRACE_POKEUSER, tcp->pid,
727 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
728 else {
729 unsigned long *sp;
730
731 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
732 return -1;
733
734 ptrace(PTRACE_POKEDATA, tcp->pid,
735 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
736 }
737 if (errno)
738 return -1;
739 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000740#elif defined(S390) || defined(S390X)
741 {
742 if(argnum <= 5)
743 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000744 (char *) (argnum==0 ? PT_ORIGGPR2 :
745 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000746 tcp->u_arg[argnum]);
747 else
748 return -E2BIG;
749 if (errno)
750 return -1;
751 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000752#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000753# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000754#endif
755 return 0;
756}
757
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000758#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000759int
760internal_clone(tcp)
761struct tcb *tcp;
762{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000763 struct tcb *tcpchild;
764 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000765 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000766 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000767 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000768 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000769 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000770 if (setbpt(tcp) < 0)
771 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000772 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000773 int bpt = tcp->flags & TCB_BPTSET;
774
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000775 if (!(tcp->flags & TCB_FOLLOWFORK))
776 return 0;
777
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000778 if (syserror(tcp)) {
779 if (bpt)
780 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000781 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000782 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000783
784 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000785
786#ifdef CLONE_PTRACE /* See new setbpt code. */
787 tcpchild = pid2tcb(pid);
788 if (tcpchild != NULL) {
789 /* The child already reported its startup trap
790 before the parent reported its syscall return. */
791 if ((tcpchild->flags
792 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
793 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
794 fprintf(stderr, "\
795[preattached child %d of %d in weird state!]\n",
796 pid, tcp->pid);
797 }
798 else
799#endif
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000800 if ((tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000801 if (bpt)
802 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000803 fprintf(stderr, " [tcb table full]\n");
804 kill(pid, SIGKILL); /* XXX */
805 return 0;
806 }
807
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000808#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000809 /* Attach to the new child */
810 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000811 if (bpt)
812 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000813 perror("PTRACE_ATTACH");
814 fprintf(stderr, "Too late?\n");
815 droptcb(tcpchild);
816 return 0;
817 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000818#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000819
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000820 if (bpt)
821 clearbpt(tcp);
822
Ulrich Drepper90512f01999-12-24 07:22:25 +0000823 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000824 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000825 if (bpt) {
826 tcpchild->flags |= TCB_BPTSET;
827 tcpchild->baddr = tcp->baddr;
828 memcpy(tcpchild->inst, tcp->inst,
829 sizeof tcpchild->inst);
830 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000831 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000832 tcp->nchildren++;
833 if (tcpchild->flags & TCB_SUSPENDED) {
834 /* The child was born suspended, due to our having
835 forced CLONE_PTRACE. */
836 if (bpt)
837 clearbpt(tcpchild);
838
839 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
840 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
841 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
842 return -1;
843 }
844
845 if (!qflag)
846 fprintf(stderr, "\
847Process %u resumed (parent %d ready)\n",
848 pid, tcp->pid);
849 }
850 else {
851 newoutf(tcpchild);
852 if (!qflag)
853 fprintf(stderr, "Process %d attached\n", pid);
854 }
855
856#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000857 {
858 /*
859 * Save the flags used in this call,
860 * in case we point TCP to our parent below.
861 */
862 int call_flags = tcp->u_arg[ARG_FLAGS];
863 if ((tcp->flags & TCB_CLONE_THREAD) &&
864 tcp->parent != NULL) {
865 /* The parent in this clone is itself a
866 thread belonging to another process.
867 There is no meaning to the parentage
868 relationship of the new child with the
869 thread, only with the process. We
870 associate the new thread with our
871 parent. Since this is done for every
872 new thread, there will never be a
873 TCB_CLONE_THREAD process that has
874 children. */
875 --tcp->nchildren;
876 tcp = tcp->parent;
877 tcpchild->parent = tcp;
878 ++tcp->nchildren;
879 }
880 if (call_flags & CLONE_THREAD) {
881 tcpchild->flags |= TCB_CLONE_THREAD;
882 ++tcp->nclone_threads;
883 }
884 if (call_flags & CLONE_DETACHED) {
885 tcpchild->flags |= TCB_CLONE_DETACHED;
886 ++tcp->nclone_detached;
887 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000888 }
889#endif
890
891 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000892 return 0;
893}
894#endif
895
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000896int
897internal_fork(tcp)
898struct tcb *tcp;
899{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000900#ifdef LINUX
901 /* We do special magic with clone for any clone or fork. */
902 return internal_clone(tcp);
903#else
904
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000905 struct tcb *tcpchild;
906 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000907 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000908
909#ifdef SYS_vfork
Nate Sammonsccd8f211999-03-29 22:57:54 +0000910 if (tcp->scno == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000911 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000912 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000913 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000914 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000915 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000916#endif
917 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000918 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000919 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000920 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000921 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000922 if (setbpt(tcp) < 0)
923 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000924 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000925 else {
926 int bpt = tcp->flags & TCB_BPTSET;
927
928 if (!(tcp->flags & TCB_FOLLOWFORK))
929 return 0;
930 if (bpt)
931 clearbpt(tcp);
932
933 if (syserror(tcp))
934 return 0;
935
936 pid = tcp->u_rval;
937 if ((tcpchild = alloctcb(pid)) == NULL) {
938 fprintf(stderr, " [tcb table full]\n");
939 kill(pid, SIGKILL); /* XXX */
940 return 0;
941 }
942#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000943#ifdef HPPA
944 /* The child must have run before it can be attached. */
945 /* This must be a bug in the parisc kernel, but I havn't
946 * identified it yet. Seems to be an issue associated
947 * with attaching to a process (which sends it a signal)
948 * before that process has ever been scheduled. When
949 * debugging, I started seeing crashes in
950 * arch/parisc/kernel/signal.c:do_signal(), apparently
951 * caused by r8 getting corrupt over the dequeue_signal()
952 * call. Didn't make much sense though...
953 */
954 {
955 struct timeval tv;
956 tv.tv_sec = 0;
957 tv.tv_usec = 10000;
958 select(0, NULL, NULL, NULL, &tv);
959 }
960#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000961 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
962 perror("PTRACE_ATTACH");
963 fprintf(stderr, "Too late?\n");
964 droptcb(tcpchild);
965 return 0;
966 }
967#endif /* LINUX */
968#ifdef SUNOS4
969#ifdef oldway
970 /* The child must have run before it can be attached. */
971 {
972 struct timeval tv;
973 tv.tv_sec = 0;
974 tv.tv_usec = 10000;
975 select(0, NULL, NULL, NULL, &tv);
976 }
977 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
978 perror("PTRACE_ATTACH");
979 fprintf(stderr, "Too late?\n");
980 droptcb(tcpchild);
981 return 0;
982 }
983#else /* !oldway */
984 /* Try to catch the new process as soon as possible. */
985 {
986 int i;
987 for (i = 0; i < 1024; i++)
988 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
989 break;
990 if (i == 1024) {
991 perror("PTRACE_ATTACH");
992 fprintf(stderr, "Too late?\n");
993 droptcb(tcpchild);
994 return 0;
995 }
996 }
997#endif /* !oldway */
998#endif /* SUNOS4 */
999 tcpchild->flags |= TCB_ATTACHED;
1000 /* Child has BPT too, must be removed on first occasion */
1001 if (bpt) {
1002 tcpchild->flags |= TCB_BPTSET;
1003 tcpchild->baddr = tcp->baddr;
1004 memcpy(tcpchild->inst, tcp->inst,
1005 sizeof tcpchild->inst);
1006 }
1007 newoutf(tcpchild);
1008 tcpchild->parent = tcp;
1009 tcp->nchildren++;
1010 if (!qflag)
1011 fprintf(stderr, "Process %d attached\n", pid);
1012 }
1013 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001014#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001015}
1016
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001017#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001018
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001019#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001020
1021int
1022sys_vfork(tcp)
1023struct tcb *tcp;
1024{
1025 if (exiting(tcp))
1026 return RVAL_UDECIMAL;
1027 return 0;
1028}
1029
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001030#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001031
1032#ifndef LINUX
1033
1034static char idstr[16];
1035
1036int
1037sys_getpid(tcp)
1038struct tcb *tcp;
1039{
1040 if (exiting(tcp)) {
1041 sprintf(idstr, "ppid %lu", getrval2(tcp));
1042 tcp->auxstr = idstr;
1043 return RVAL_STR;
1044 }
1045 return 0;
1046}
1047
1048int
1049sys_getuid(tcp)
1050struct tcb *tcp;
1051{
1052 if (exiting(tcp)) {
1053 sprintf(idstr, "euid %lu", getrval2(tcp));
1054 tcp->auxstr = idstr;
1055 return RVAL_STR;
1056 }
1057 return 0;
1058}
1059
1060int
1061sys_getgid(tcp)
1062struct tcb *tcp;
1063{
1064 if (exiting(tcp)) {
1065 sprintf(idstr, "egid %lu", getrval2(tcp));
1066 tcp->auxstr = idstr;
1067 return RVAL_STR;
1068 }
1069 return 0;
1070}
1071
1072#endif /* !LINUX */
1073
1074#ifdef LINUX
1075
1076int
1077sys_setuid(tcp)
1078struct tcb *tcp;
1079{
1080 if (entering(tcp)) {
1081 tprintf("%u", (uid_t) tcp->u_arg[0]);
1082 }
1083 return 0;
1084}
1085
1086int
1087sys_setgid(tcp)
1088struct tcb *tcp;
1089{
1090 if (entering(tcp)) {
1091 tprintf("%u", (gid_t) tcp->u_arg[0]);
1092 }
1093 return 0;
1094}
1095
1096int
1097sys_getresuid(tcp)
1098 struct tcb *tcp;
1099{
1100 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001101 __kernel_uid_t uid;
1102 if (syserror(tcp))
1103 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1104 tcp->u_arg[1], tcp->u_arg[2]);
1105 else {
1106 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1107 tprintf("%#lx, ", tcp->u_arg[0]);
1108 else
1109 tprintf("ruid %lu, ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001110 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1111 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001112 else
1113 tprintf("euid %lu, ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001114 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1115 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001116 else
1117 tprintf("suid %lu", (unsigned long) uid);
1118 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001119 }
1120 return 0;
1121}
1122
1123int
1124sys_getresgid(tcp)
1125struct tcb *tcp;
1126{
1127 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001128 __kernel_gid_t gid;
1129 if (syserror(tcp))
1130 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1131 tcp->u_arg[1], tcp->u_arg[2]);
1132 else {
1133 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1134 tprintf("%#lx, ", tcp->u_arg[0]);
1135 else
1136 tprintf("rgid %lu, ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001137 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1138 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001139 else
1140 tprintf("egid %lu, ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001141 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1142 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001143 else
1144 tprintf("sgid %lu", (unsigned long) gid);
1145 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001146 }
1147 return 0;
1148}
1149
1150#endif /* LINUX */
1151
1152int
1153sys_setreuid(tcp)
1154struct tcb *tcp;
1155{
1156 if (entering(tcp)) {
1157 tprintf("%lu, %lu",
1158 (unsigned long) (uid_t) tcp->u_arg[0],
1159 (unsigned long) (uid_t) tcp->u_arg[1]);
1160 }
1161 return 0;
1162}
1163
1164int
1165sys_setregid(tcp)
1166struct tcb *tcp;
1167{
1168 if (entering(tcp)) {
1169 tprintf("%lu, %lu",
1170 (unsigned long) (gid_t) tcp->u_arg[0],
1171 (unsigned long) (gid_t) tcp->u_arg[1]);
1172 }
1173 return 0;
1174}
1175
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001176#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001177int
1178sys_setresuid(tcp)
1179 struct tcb *tcp;
1180{
1181 if (entering(tcp)) {
1182 tprintf("ruid %u, euid %u, suid %u",
1183 (uid_t) tcp->u_arg[0],
1184 (uid_t) tcp->u_arg[1],
1185 (uid_t) tcp->u_arg[2]);
1186 }
1187 return 0;
1188}
1189int
1190sys_setresgid(tcp)
1191 struct tcb *tcp;
1192{
1193 if (entering(tcp)) {
1194 tprintf("rgid %u, egid %u, sgid %u",
1195 (uid_t) tcp->u_arg[0],
1196 (uid_t) tcp->u_arg[1],
1197 (uid_t) tcp->u_arg[2]);
1198 }
1199 return 0;
1200}
1201
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001202#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001203
1204int
1205sys_setgroups(tcp)
1206struct tcb *tcp;
1207{
1208 int i, len;
1209 GETGROUPS_T *gidset;
1210
1211 if (entering(tcp)) {
1212 len = tcp->u_arg[0];
1213 tprintf("%u, ", len);
1214 if (len <= 0) {
1215 tprintf("[]");
1216 return 0;
1217 }
1218 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1219 if (gidset == NULL) {
1220 fprintf(stderr, "sys_setgroups: out of memory\n");
1221 return -1;
1222 }
1223 if (!verbose(tcp))
1224 tprintf("%#lx", tcp->u_arg[1]);
1225 else if (umoven(tcp, tcp->u_arg[1],
1226 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1227 tprintf("[?]");
1228 else {
1229 tprintf("[");
1230 for (i = 0; i < len; i++)
1231 tprintf("%s%lu", i ? ", " : "",
1232 (unsigned long) gidset[i]);
1233 tprintf("]");
1234 }
1235 free((char *) gidset);
1236 }
1237 return 0;
1238}
1239
1240int
1241sys_getgroups(tcp)
1242struct tcb *tcp;
1243{
1244 int i, len;
1245 GETGROUPS_T *gidset;
1246
1247 if (entering(tcp)) {
1248 len = tcp->u_arg[0];
1249 tprintf("%u, ", len);
1250 } else {
1251 len = tcp->u_rval;
1252 if (len <= 0) {
1253 tprintf("[]");
1254 return 0;
1255 }
1256 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1257 if (gidset == NULL) {
1258 fprintf(stderr, "sys_getgroups: out of memory\n");
1259 return -1;
1260 }
1261 if (!tcp->u_arg[1])
1262 tprintf("NULL");
1263 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1264 tprintf("%#lx", tcp->u_arg[1]);
1265 else if (umoven(tcp, tcp->u_arg[1],
1266 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1267 tprintf("[?]");
1268 else {
1269 tprintf("[");
1270 for (i = 0; i < len; i++)
1271 tprintf("%s%lu", i ? ", " : "",
1272 (unsigned long) gidset[i]);
1273 tprintf("]");
1274 }
1275 free((char *)gidset);
1276 }
1277 return 0;
1278}
1279
1280int
1281sys_setpgrp(tcp)
1282struct tcb *tcp;
1283{
1284 if (entering(tcp)) {
1285#ifndef SVR4
1286 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1287#endif /* !SVR4 */
1288 }
1289 return 0;
1290}
1291
1292int
1293sys_getpgrp(tcp)
1294struct tcb *tcp;
1295{
1296 if (entering(tcp)) {
1297#ifndef SVR4
1298 tprintf("%lu", tcp->u_arg[0]);
1299#endif /* !SVR4 */
1300 }
1301 return 0;
1302}
1303
1304int
1305sys_getsid(tcp)
1306struct tcb *tcp;
1307{
1308 if (entering(tcp)) {
1309 tprintf("%lu", tcp->u_arg[0]);
1310 }
1311 return 0;
1312}
1313
1314int
1315sys_setsid(tcp)
1316struct tcb *tcp;
1317{
1318 return 0;
1319}
1320
1321int
1322sys_getpgid(tcp)
1323struct tcb *tcp;
1324{
1325 if (entering(tcp)) {
1326 tprintf("%lu", tcp->u_arg[0]);
1327 }
1328 return 0;
1329}
1330
1331int
1332sys_setpgid(tcp)
1333struct tcb *tcp;
1334{
1335 if (entering(tcp)) {
1336 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1337 }
1338 return 0;
1339}
1340
John Hughesc61eb3d2002-05-17 11:37:50 +00001341#if UNIXWARE >= 2
1342
1343#include <sys/privilege.h>
1344
1345
1346static struct xlat procpriv_cmds [] = {
1347 { SETPRV, "SETPRV" },
1348 { CLRPRV, "CLRPRV" },
1349 { PUTPRV, "PUTPRV" },
1350 { GETPRV, "GETPRV" },
1351 { CNTPRV, "CNTPRV" },
1352 { 0, NULL },
1353};
1354
1355
1356static struct xlat procpriv_priv [] = {
1357 { P_OWNER, "P_OWNER" },
1358 { P_AUDIT, "P_AUDIT" },
1359 { P_COMPAT, "P_COMPAT" },
1360 { P_DACREAD, "P_DACREAD" },
1361 { P_DACWRITE, "P_DACWRITE" },
1362 { P_DEV, "P_DEV" },
1363 { P_FILESYS, "P_FILESYS" },
1364 { P_MACREAD, "P_MACREAD" },
1365 { P_MACWRITE, "P_MACWRITE" },
1366 { P_MOUNT, "P_MOUNT" },
1367 { P_MULTIDIR, "P_MULTIDIR" },
1368 { P_SETPLEVEL, "P_SETPLEVEL" },
1369 { P_SETSPRIV, "P_SETSPRIV" },
1370 { P_SETUID, "P_SETUID" },
1371 { P_SYSOPS, "P_SYSOPS" },
1372 { P_SETUPRIV, "P_SETUPRIV" },
1373 { P_DRIVER, "P_DRIVER" },
1374 { P_RTIME, "P_RTIME" },
1375 { P_MACUPGRADE, "P_MACUPGRADE" },
1376 { P_FSYSRANGE, "P_FSYSRANGE" },
1377 { P_SETFLEVEL, "P_SETFLEVEL" },
1378 { P_AUDITWR, "P_AUDITWR" },
1379 { P_TSHAR, "P_TSHAR" },
1380 { P_PLOCK, "P_PLOCK" },
1381 { P_CORE, "P_CORE" },
1382 { P_LOADMOD, "P_LOADMOD" },
1383 { P_BIND, "P_BIND" },
1384 { P_ALLPRIVS, "P_ALLPRIVS" },
1385 { 0, NULL },
1386};
1387
1388
1389static struct xlat procpriv_type [] = {
1390 { PS_FIX, "PS_FIX" },
1391 { PS_INH, "PS_INH" },
1392 { PS_MAX, "PS_MAX" },
1393 { PS_WKG, "PS_WKG" },
1394 { 0, NULL },
1395};
1396
1397
1398static void
1399printpriv(tcp, addr, len, opt)
1400struct tcb *tcp;
1401long addr;
1402int len;
1403struct xlat *opt;
1404{
1405 priv_t buf [128];
1406 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1407 int dots = len > max;
1408 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001409
John Hughesc61eb3d2002-05-17 11:37:50 +00001410 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001411
John Hughesc61eb3d2002-05-17 11:37:50 +00001412 if (len <= 0 ||
1413 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1414 {
1415 tprintf ("%#lx", addr);
1416 return;
1417 }
1418
1419 tprintf ("[");
1420
1421 for (i = 0; i < len; ++i) {
1422 char *t, *p;
1423
1424 if (i) tprintf (", ");
1425
1426 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1427 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1428 {
1429 tprintf ("%s|%s", t, p);
1430 }
1431 else {
1432 tprintf ("%#lx", buf [i]);
1433 }
1434 }
1435
1436 if (dots) tprintf (" ...");
1437
1438 tprintf ("]");
1439}
1440
1441
1442int
1443sys_procpriv(tcp)
1444struct tcb *tcp;
1445{
1446 if (entering(tcp)) {
1447 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1448 switch (tcp->u_arg[0]) {
1449 case CNTPRV:
1450 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1451 break;
1452
1453 case GETPRV:
1454 break;
1455
1456 default:
1457 tprintf (", ");
1458 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1459 tprintf (", %ld", tcp->u_arg[2]);
1460 }
1461 }
1462 else if (tcp->u_arg[0] == GETPRV) {
1463 if (syserror (tcp)) {
1464 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1465 }
1466 else {
1467 tprintf (", ");
1468 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1469 tprintf (", %ld", tcp->u_arg[2]);
1470 }
1471 }
Roland McGrath5a223472002-12-15 23:58:26 +00001472
John Hughesc61eb3d2002-05-17 11:37:50 +00001473 return 0;
1474}
1475
1476#endif
1477
1478
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001479void
1480fake_execve(tcp, program, argv, envp)
1481struct tcb *tcp;
1482char *program;
1483char *argv[];
1484char *envp[];
1485{
1486 int i;
1487
1488#ifdef ARM
1489 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1490 return;
1491#else
1492 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1493 return;
1494#endif /* !ARM */
1495 printleader(tcp);
1496 tprintf("execve(");
1497 string_quote(program);
1498 tprintf(", [");
1499 for (i = 0; argv[i] != NULL; i++) {
1500 if (i != 0)
1501 tprintf(", ");
1502 string_quote(argv[i]);
1503 }
1504 for (i = 0; envp[i] != NULL; i++)
1505 ;
1506 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1507 tabto(acolumn);
1508 tprintf("= 0");
1509 printtrailer(tcp);
1510}
1511
1512static void
1513printargv(tcp, addr)
1514struct tcb *tcp;
1515long addr;
1516{
1517 char *cp;
1518 char *sep;
1519 int max = max_strlen / 2;
1520
1521 for (sep = ""; --max >= 0; sep = ", ") {
1522 if (!abbrev(tcp))
1523 max++;
1524 if (umove(tcp, addr, &cp) < 0) {
1525 tprintf("%#lx", addr);
1526 return;
1527 }
1528 if (cp == 0)
1529 break;
1530 tprintf(sep);
1531 printstr(tcp, (long) cp, -1);
1532 addr += sizeof(char *);
1533 }
1534 if (cp)
1535 tprintf(", ...");
1536}
1537
1538static void
1539printargc(fmt, tcp, addr)
1540char *fmt;
1541struct tcb *tcp;
1542long addr;
1543{
1544 int count;
1545 char *cp;
1546
1547 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1548 addr += sizeof(char *);
1549 }
1550 tprintf(fmt, count, count == 1 ? "" : "s");
1551}
1552
1553int
1554sys_execv(tcp)
1555struct tcb *tcp;
1556{
1557 if (entering(tcp)) {
1558 printpath(tcp, tcp->u_arg[0]);
1559 if (!verbose(tcp))
1560 tprintf(", %#lx", tcp->u_arg[1]);
1561#if 0
1562 else if (abbrev(tcp))
1563 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1564#endif
1565 else {
1566 tprintf(", [");
1567 printargv(tcp, tcp->u_arg[1]);
1568 tprintf("]");
1569 }
1570 }
1571 return 0;
1572}
1573
1574int
1575sys_execve(tcp)
1576struct tcb *tcp;
1577{
1578 if (entering(tcp)) {
1579 printpath(tcp, tcp->u_arg[0]);
1580 if (!verbose(tcp))
1581 tprintf(", %#lx", tcp->u_arg[1]);
1582#if 0
1583 else if (abbrev(tcp))
1584 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1585#endif
1586 else {
1587 tprintf(", [");
1588 printargv(tcp, tcp->u_arg[1]);
1589 tprintf("]");
1590 }
1591 if (!verbose(tcp))
1592 tprintf(", %#lx", tcp->u_arg[2]);
1593 else if (abbrev(tcp))
1594 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1595 else {
1596 tprintf(", [");
1597 printargv(tcp, tcp->u_arg[2]);
1598 tprintf("]");
1599 }
1600 }
Roland McGrathb4968be2003-01-20 09:04:33 +00001601#if defined LINUX && defined TCB_WAITEXECVE
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001602 tcp->flags |= TCB_WAITEXECVE;
Roland McGrathb4968be2003-01-20 09:04:33 +00001603#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001604 return 0;
1605}
1606
John Hughes4e36a812001-04-18 15:11:51 +00001607#if UNIXWARE > 2
1608
1609int sys_rexecve(tcp)
1610struct tcb *tcp;
1611{
1612 if (entering (tcp)) {
1613 sys_execve (tcp);
1614 tprintf (", %ld", tcp->u_arg[3]);
1615 }
1616 return 0;
1617}
1618
1619#endif
1620
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001621int
1622internal_exec(tcp)
1623struct tcb *tcp;
1624{
1625#ifdef SUNOS4
1626 if (exiting(tcp) && !syserror(tcp) && followfork)
1627 fixvfork(tcp);
1628#endif /* SUNOS4 */
1629 return 0;
1630}
1631
1632#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001633#ifndef __WNOTHREAD
1634#define __WNOTHREAD 0x20000000
1635#endif
1636#ifndef __WALL
1637#define __WALL 0x40000000
1638#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001639#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001640#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001641#endif
1642#endif /* LINUX */
1643
1644static struct xlat wait4_options[] = {
1645 { WNOHANG, "WNOHANG" },
1646#ifndef WSTOPPED
1647 { WUNTRACED, "WUNTRACED" },
1648#endif
1649#ifdef WEXITED
1650 { WEXITED, "WEXITED" },
1651#endif
1652#ifdef WTRAPPED
1653 { WTRAPPED, "WTRAPPED" },
1654#endif
1655#ifdef WSTOPPED
1656 { WSTOPPED, "WSTOPPED" },
1657#endif
1658#ifdef WCONTINUED
1659 { WCONTINUED, "WCONTINUED" },
1660#endif
1661#ifdef WNOWAIT
1662 { WNOWAIT, "WNOWAIT" },
1663#endif
1664#ifdef __WCLONE
1665 { __WCLONE, "__WCLONE" },
1666#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001667#ifdef __WALL
1668 { __WALL, "__WALL" },
1669#endif
1670#ifdef __WNOTHREAD
1671 { __WNOTHREAD, "__WNOTHREAD" },
1672#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001673 { 0, NULL },
1674};
1675
1676static int
1677printstatus(status)
1678int status;
1679{
1680 int exited = 0;
1681
1682 /*
1683 * Here is a tricky presentation problem. This solution
1684 * is still not entirely satisfactory but since there
1685 * are no wait status constructors it will have to do.
1686 */
1687 if (WIFSTOPPED(status))
1688 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001689 signame(WSTOPSIG(status)));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001690 else if WIFSIGNALED(status)
1691 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001692 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001693 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1694 else if WIFEXITED(status) {
1695 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1696 WEXITSTATUS(status));
1697 exited = 1;
1698 }
1699 else
1700 tprintf("[%#x]", status);
1701 return exited;
1702}
1703
1704static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001705printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001706struct tcb *tcp;
1707int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001708int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001709{
1710 int status;
1711 int exited = 0;
1712
1713 if (entering(tcp)) {
1714 tprintf("%ld, ", tcp->u_arg[0]);
1715 } else {
1716 /* status */
1717 if (!tcp->u_arg[1])
1718 tprintf("NULL");
1719 else if (syserror(tcp) || tcp->u_rval == 0)
1720 tprintf("%#lx", tcp->u_arg[1]);
1721 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1722 tprintf("[?]");
1723 else
1724 exited = printstatus(status);
1725 /* options */
1726 tprintf(", ");
1727 if (!printflags(wait4_options, tcp->u_arg[2]))
1728 tprintf("0");
1729 if (n == 4) {
1730 tprintf(", ");
1731 /* usage */
1732 if (!tcp->u_arg[3])
1733 tprintf("NULL");
1734#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001735 else if (tcp->u_rval > 0) {
1736#ifdef LINUX_64BIT
1737 if (bitness)
1738 printrusage32(tcp, tcp->u_arg[3]);
1739 else
1740#endif
1741 printrusage(tcp, tcp->u_arg[3]);
1742 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001743#endif /* LINUX */
1744#ifdef SUNOS4
1745 else if (tcp->u_rval > 0 && exited)
1746 printrusage(tcp, tcp->u_arg[3]);
1747#endif /* SUNOS4 */
1748 else
1749 tprintf("%#lx", tcp->u_arg[3]);
1750 }
1751 }
1752 return 0;
1753}
1754
1755int
1756internal_wait(tcp)
1757struct tcb *tcp;
1758{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001759 int got_kids;
1760
1761#ifdef TCB_CLONE_THREAD
1762 if (tcp->flags & TCB_CLONE_THREAD)
1763 /* The children we wait for are our parent's children. */
1764 got_kids = (tcp->parent->nchildren
1765 > tcp->parent->nclone_detached);
1766 else
1767 got_kids = (tcp->nchildren > tcp->nclone_detached);
1768#else
1769 got_kids = tcp->nchildren > 0;
1770#endif
1771
1772 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001773 /* There are children that this parent should block for.
1774 But ptrace made us the parent of the traced children
1775 and the real parent will get ECHILD from the wait call.
1776
1777 XXX If we attached with strace -f -p PID, then there
1778 may be untraced dead children the parent could be reaping
1779 now, but we make him block. */
1780
1781 /* ??? WTA: fix bug with hanging children */
1782
1783 if (!(tcp->u_arg[2] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00001784 /*
1785 * There are traced children. We'll make the parent
1786 * block to avoid a false ECHILD error due to our
1787 * ptrace having stolen the children. However,
1788 * we shouldn't block if there are zombies to reap.
1789 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1790 */
1791 if (tcp->nzombies > 0 &&
1792 (tcp->u_arg[0] == -1 ||
1793 pid2tcb(tcp->u_arg[0]) == NULL))
1794 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001795 tcp->flags |= TCB_SUSPENDED;
1796 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001797#ifdef TCB_CLONE_THREAD
1798 if (tcp->flags & TCB_CLONE_THREAD)
1799 tcp->parent->nclone_waiting++;
1800#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001801 }
1802 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001803 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001804 if (tcp->u_arg[2] & WNOHANG) {
1805 /* We must force a fake result of 0 instead of
1806 the ECHILD error. */
1807 extern int force_result();
1808 return force_result(tcp, 0, 0);
1809 }
1810 else
1811 fprintf(stderr,
1812 "internal_wait: should not have resumed %d\n",
1813 tcp->pid);
1814 }
Roland McGrath09623452003-05-23 02:27:13 +00001815 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
1816 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
1817 /*
1818 * We just reaped a child we don't know about,
1819 * presumably a zombie we already droptcb'd.
1820 */
1821 tcp->nzombies--;
1822 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001823 return 0;
1824}
1825
1826#ifdef SVR4
1827
1828int
1829sys_wait(tcp)
1830struct tcb *tcp;
1831{
1832 if (exiting(tcp)) {
1833 /* The library wrapper stuffs this into the user variable. */
1834 if (!syserror(tcp))
1835 printstatus(getrval2(tcp));
1836 }
1837 return 0;
1838}
1839
1840#endif /* SVR4 */
1841
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001842#ifdef FREEBSD
1843int
1844sys_wait(tcp)
1845struct tcb *tcp;
1846{
1847 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001848
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001849 if (exiting(tcp)) {
1850 if (!syserror(tcp)) {
1851 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1852 tprintf("%#lx", tcp->u_arg[0]);
1853 else
1854 printstatus(status);
1855 }
1856 }
1857 return 0;
1858}
1859#endif
1860
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001861int
1862sys_waitpid(tcp)
1863struct tcb *tcp;
1864{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001865 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001866}
1867
1868int
1869sys_wait4(tcp)
1870struct tcb *tcp;
1871{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001872 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001873}
1874
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001875#ifdef ALPHA
1876int
1877sys_osf_wait4(tcp)
1878struct tcb *tcp;
1879{
1880 return printwaitn(tcp, 4, 1);
1881}
1882#endif
1883
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001884#ifdef SVR4
1885
1886static struct xlat waitid_types[] = {
1887 { P_PID, "P_PID" },
1888 { P_PPID, "P_PPID" },
1889 { P_PGID, "P_PGID" },
1890 { P_SID, "P_SID" },
1891 { P_CID, "P_CID" },
1892 { P_UID, "P_UID" },
1893 { P_GID, "P_GID" },
1894 { P_ALL, "P_ALL" },
1895#ifdef P_LWPID
1896 { P_LWPID, "P_LWPID" },
1897#endif
1898 { 0, NULL },
1899};
1900
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001901int
1902sys_waitid(tcp)
1903struct tcb *tcp;
1904{
1905 siginfo_t si;
1906 int exited;
1907
1908 if (entering(tcp)) {
1909 printxval(waitid_types, tcp->u_arg[0], "P_???");
1910 tprintf(", %ld, ", tcp->u_arg[1]);
1911 if (tcp->nchildren > 0) {
1912 /* There are traced children */
1913 tcp->flags |= TCB_SUSPENDED;
1914 tcp->waitpid = tcp->u_arg[0];
1915 }
1916 }
1917 else {
1918 /* siginfo */
1919 exited = 0;
1920 if (!tcp->u_arg[2])
1921 tprintf("NULL");
1922 else if (syserror(tcp))
1923 tprintf("%#lx", tcp->u_arg[2]);
1924 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1925 tprintf("{???}");
1926 else
John Hughes58265892001-10-18 15:13:53 +00001927 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001928 /* options */
1929 tprintf(", ");
1930 if (!printflags(wait4_options, tcp->u_arg[3]))
1931 tprintf("0");
1932 }
1933 return 0;
1934}
1935
1936#endif /* SVR4 */
1937
1938int
1939sys_alarm(tcp)
1940struct tcb *tcp;
1941{
1942 if (entering(tcp))
1943 tprintf("%lu", tcp->u_arg[0]);
1944 return 0;
1945}
1946
1947int
1948sys_uname(tcp)
1949struct tcb *tcp;
1950{
1951 struct utsname uname;
1952
1953 if (exiting(tcp)) {
1954 if (syserror(tcp) || !verbose(tcp))
1955 tprintf("%#lx", tcp->u_arg[0]);
1956 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1957 tprintf("{...}");
1958 else if (!abbrev(tcp)) {
1959
1960 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1961 uname.sysname, uname.nodename);
1962 tprintf("release=\"%s\", version=\"%s\", ",
1963 uname.release, uname.version);
1964 tprintf("machine=\"%s\"", uname.machine);
1965#ifdef LINUX
1966#ifndef __GLIBC__
1967 tprintf(", domainname=\"%s\"", uname.domainname);
1968#endif /* __GLIBC__ */
1969#endif /* LINUX */
1970 tprintf("}");
1971 }
1972 else
1973 tprintf("{sys=\"%s\", node=\"%s\", ...}",
1974 uname.sysname, uname.nodename);
1975 }
1976 return 0;
1977}
1978
1979#ifndef SVR4
1980
1981static struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00001982#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001983 { PTRACE_TRACEME, "PTRACE_TRACEME" },
1984 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
1985 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
1986 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
1987 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
1988 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
1989 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
1990 { PTRACE_CONT, "PTRACE_CONT" },
1991 { PTRACE_KILL, "PTRACE_KILL" },
1992 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
1993 { PTRACE_ATTACH, "PTRACE_ATTACH" },
1994 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001995#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001996 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001997#endif
1998#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001999 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002000#endif
2001#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002002 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002003#endif
2004#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002005 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002006#endif
2007#ifdef PTRACE_GETFPXREGS
2008 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2009#endif
2010#ifdef PTRACE_SETFPXREGS
2011 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2012#endif
2013#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002014 { PTRACE_READDATA, "PTRACE_READDATA" },
2015 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2016 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2017 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2018 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2019 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2020#ifdef SPARC
2021 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2022 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2023#else /* !SPARC */
2024 { PTRACE_22, "PTRACE_PTRACE_22" },
2025 { PTRACE_23, "PTRACE_PTRACE_23" },
2026#endif /* !SPARC */
2027#endif /* SUNOS4 */
2028 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2029#ifdef SUNOS4
2030 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2031#ifdef I386
2032 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2033 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2034 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2035#else /* !I386 */
2036 { PTRACE_26, "PTRACE_26" },
2037 { PTRACE_27, "PTRACE_27" },
2038 { PTRACE_28, "PTRACE_28" },
2039#endif /* !I386 */
2040 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2041#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002042#else /* FREEBSD */
2043 { PT_TRACE_ME, "PT_TRACE_ME" },
2044 { PT_READ_I, "PT_READ_I" },
2045 { PT_READ_D, "PT_READ_D" },
2046 { PT_WRITE_I, "PT_WRITE_I" },
2047 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002048#ifdef PT_READ_U
2049 { PT_READ_U, "PT_READ_U" },
2050#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002051 { PT_CONTINUE, "PT_CONTINUE" },
2052 { PT_KILL, "PT_KILL" },
2053 { PT_STEP, "PT_STEP" },
2054 { PT_ATTACH, "PT_ATTACH" },
2055 { PT_DETACH, "PT_DETACH" },
2056 { PT_GETREGS, "PT_GETREGS" },
2057 { PT_SETREGS, "PT_SETREGS" },
2058 { PT_GETFPREGS, "PT_GETFPREGS" },
2059 { PT_SETFPREGS, "PT_SETFPREGS" },
2060 { PT_GETDBREGS, "PT_GETDBREGS" },
2061 { PT_SETDBREGS, "PT_SETDBREGS" },
2062#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002063 { 0, NULL },
2064};
2065
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002066#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002067#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2068static
2069#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2070struct xlat struct_user_offsets[] = {
2071#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002072#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002073 { PT_PSWMASK, "psw_mask" },
2074 { PT_PSWADDR, "psw_addr" },
2075 { PT_GPR0, "gpr0" },
2076 { PT_GPR1, "gpr1" },
2077 { PT_GPR2, "gpr2" },
2078 { PT_GPR3, "gpr3" },
2079 { PT_GPR4, "gpr4" },
2080 { PT_GPR5, "gpr5" },
2081 { PT_GPR6, "gpr6" },
2082 { PT_GPR7, "gpr7" },
2083 { PT_GPR8, "gpr8" },
2084 { PT_GPR9, "gpr9" },
2085 { PT_GPR10, "gpr10" },
2086 { PT_GPR11, "gpr11" },
2087 { PT_GPR12, "gpr12" },
2088 { PT_GPR13, "gpr13" },
2089 { PT_GPR14, "gpr14" },
2090 { PT_GPR15, "gpr15" },
2091 { PT_ACR0, "acr0" },
2092 { PT_ACR1, "acr1" },
2093 { PT_ACR2, "acr2" },
2094 { PT_ACR3, "acr3" },
2095 { PT_ACR4, "acr4" },
2096 { PT_ACR5, "acr5" },
2097 { PT_ACR6, "acr6" },
2098 { PT_ACR7, "acr7" },
2099 { PT_ACR8, "acr8" },
2100 { PT_ACR9, "acr9" },
2101 { PT_ACR10, "acr10" },
2102 { PT_ACR11, "acr11" },
2103 { PT_ACR12, "acr12" },
2104 { PT_ACR13, "acr13" },
2105 { PT_ACR14, "acr14" },
2106 { PT_ACR15, "acr15" },
2107 { PT_ORIGGPR2, "orig_gpr2" },
2108 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002109#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002110 { PT_FPR0_HI, "fpr0.hi" },
2111 { PT_FPR0_LO, "fpr0.lo" },
2112 { PT_FPR1_HI, "fpr1.hi" },
2113 { PT_FPR1_LO, "fpr1.lo" },
2114 { PT_FPR2_HI, "fpr2.hi" },
2115 { PT_FPR2_LO, "fpr2.lo" },
2116 { PT_FPR3_HI, "fpr3.hi" },
2117 { PT_FPR3_LO, "fpr3.lo" },
2118 { PT_FPR4_HI, "fpr4.hi" },
2119 { PT_FPR4_LO, "fpr4.lo" },
2120 { PT_FPR5_HI, "fpr5.hi" },
2121 { PT_FPR5_LO, "fpr5.lo" },
2122 { PT_FPR6_HI, "fpr6.hi" },
2123 { PT_FPR6_LO, "fpr6.lo" },
2124 { PT_FPR7_HI, "fpr7.hi" },
2125 { PT_FPR7_LO, "fpr7.lo" },
2126 { PT_FPR8_HI, "fpr8.hi" },
2127 { PT_FPR8_LO, "fpr8.lo" },
2128 { PT_FPR9_HI, "fpr9.hi" },
2129 { PT_FPR9_LO, "fpr9.lo" },
2130 { PT_FPR10_HI, "fpr10.hi" },
2131 { PT_FPR10_LO, "fpr10.lo" },
2132 { PT_FPR11_HI, "fpr11.hi" },
2133 { PT_FPR11_LO, "fpr11.lo" },
2134 { PT_FPR12_HI, "fpr12.hi" },
2135 { PT_FPR12_LO, "fpr12.lo" },
2136 { PT_FPR13_HI, "fpr13.hi" },
2137 { PT_FPR13_LO, "fpr13.lo" },
2138 { PT_FPR14_HI, "fpr14.hi" },
2139 { PT_FPR14_LO, "fpr14.lo" },
2140 { PT_FPR15_HI, "fpr15.hi" },
2141 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002142#endif
2143#if defined(S390X)
2144 { PT_FPR0, "fpr0" },
2145 { PT_FPR1, "fpr1" },
2146 { PT_FPR2, "fpr2" },
2147 { PT_FPR3, "fpr3" },
2148 { PT_FPR4, "fpr4" },
2149 { PT_FPR5, "fpr5" },
2150 { PT_FPR6, "fpr6" },
2151 { PT_FPR7, "fpr7" },
2152 { PT_FPR8, "fpr8" },
2153 { PT_FPR9, "fpr9" },
2154 { PT_FPR10, "fpr10" },
2155 { PT_FPR11, "fpr11" },
2156 { PT_FPR12, "fpr12" },
2157 { PT_FPR13, "fpr13" },
2158 { PT_FPR14, "fpr14" },
2159 { PT_FPR15, "fpr15" },
2160#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002161 { PT_CR_9, "cr9" },
2162 { PT_CR_10, "cr10" },
2163 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002164 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002165#endif
2166#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002167 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002168#elif defined(HPPA)
2169 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002170#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002171#ifndef PT_ORIG_R3
2172#define PT_ORIG_R3 34
2173#endif
Roland McGratheb285352003-01-14 09:59:00 +00002174#define REGSIZE (sizeof(unsigned long))
2175 { REGSIZE*PT_R0, "r0" },
2176 { REGSIZE*PT_R1, "r1" },
2177 { REGSIZE*PT_R2, "r2" },
2178 { REGSIZE*PT_R3, "r3" },
2179 { REGSIZE*PT_R4, "r4" },
2180 { REGSIZE*PT_R5, "r5" },
2181 { REGSIZE*PT_R6, "r6" },
2182 { REGSIZE*PT_R7, "r7" },
2183 { REGSIZE*PT_R8, "r8" },
2184 { REGSIZE*PT_R9, "r9" },
2185 { REGSIZE*PT_R10, "r10" },
2186 { REGSIZE*PT_R11, "r11" },
2187 { REGSIZE*PT_R12, "r12" },
2188 { REGSIZE*PT_R13, "r13" },
2189 { REGSIZE*PT_R14, "r14" },
2190 { REGSIZE*PT_R15, "r15" },
2191 { REGSIZE*PT_R16, "r16" },
2192 { REGSIZE*PT_R17, "r17" },
2193 { REGSIZE*PT_R18, "r18" },
2194 { REGSIZE*PT_R19, "r19" },
2195 { REGSIZE*PT_R20, "r20" },
2196 { REGSIZE*PT_R21, "r21" },
2197 { REGSIZE*PT_R22, "r22" },
2198 { REGSIZE*PT_R23, "r23" },
2199 { REGSIZE*PT_R24, "r24" },
2200 { REGSIZE*PT_R25, "r25" },
2201 { REGSIZE*PT_R26, "r26" },
2202 { REGSIZE*PT_R27, "r27" },
2203 { REGSIZE*PT_R28, "r28" },
2204 { REGSIZE*PT_R29, "r29" },
2205 { REGSIZE*PT_R30, "r30" },
2206 { REGSIZE*PT_R31, "r31" },
2207 { REGSIZE*PT_NIP, "NIP" },
2208 { REGSIZE*PT_MSR, "MSR" },
2209 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2210 { REGSIZE*PT_CTR, "CTR" },
2211 { REGSIZE*PT_LNK, "LNK" },
2212 { REGSIZE*PT_XER, "XER" },
2213 { REGSIZE*PT_CCR, "CCR" },
2214 { REGSIZE*PT_FPR0, "FPR0" },
2215#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002216#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002217#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002218 { 0, "r0" },
2219 { 1, "r1" },
2220 { 2, "r2" },
2221 { 3, "r3" },
2222 { 4, "r4" },
2223 { 5, "r5" },
2224 { 6, "r6" },
2225 { 7, "r7" },
2226 { 8, "r8" },
2227 { 9, "r9" },
2228 { 10, "r10" },
2229 { 11, "r11" },
2230 { 12, "r12" },
2231 { 13, "r13" },
2232 { 14, "r14" },
2233 { 15, "r15" },
2234 { 16, "r16" },
2235 { 17, "r17" },
2236 { 18, "r18" },
2237 { 19, "r19" },
2238 { 20, "r20" },
2239 { 21, "r21" },
2240 { 22, "r22" },
2241 { 23, "r23" },
2242 { 24, "r24" },
2243 { 25, "r25" },
2244 { 26, "r26" },
2245 { 27, "r27" },
2246 { 28, "r28" },
2247 { 29, "gp" },
2248 { 30, "fp" },
2249 { 31, "zero" },
2250 { 32, "fp0" },
2251 { 33, "fp" },
2252 { 34, "fp2" },
2253 { 35, "fp3" },
2254 { 36, "fp4" },
2255 { 37, "fp5" },
2256 { 38, "fp6" },
2257 { 39, "fp7" },
2258 { 40, "fp8" },
2259 { 41, "fp9" },
2260 { 42, "fp10" },
2261 { 43, "fp11" },
2262 { 44, "fp12" },
2263 { 45, "fp13" },
2264 { 46, "fp14" },
2265 { 47, "fp15" },
2266 { 48, "fp16" },
2267 { 49, "fp17" },
2268 { 50, "fp18" },
2269 { 51, "fp19" },
2270 { 52, "fp20" },
2271 { 53, "fp21" },
2272 { 54, "fp22" },
2273 { 55, "fp23" },
2274 { 56, "fp24" },
2275 { 57, "fp25" },
2276 { 58, "fp26" },
2277 { 59, "fp27" },
2278 { 60, "fp28" },
2279 { 61, "fp29" },
2280 { 62, "fp30" },
2281 { 63, "fp31" },
2282 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002283#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002284#ifdef IA64
2285 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2286 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2287 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2288 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2289 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2290 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2291 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2292 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2293 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2294 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2295 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2296 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2297 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2298 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2299 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2300 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2301 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2302 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2303 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2304 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2305 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2306 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2307 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2308 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2309 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2310 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2311 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2312 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2313 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2314 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2315 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2316 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2317 /* switch stack: */
2318 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2319 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2320 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2321 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2322 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2323 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2324 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2325 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2326 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2327 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002328 { PT_B0, "kb0" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002329 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2330 { PT_B4, "b4" }, { PT_B5, "b5" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002331 { PT_AR_PFS, "kar.pfs" },
2332 { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" },
2333 { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" },
2334 { PT_PR, "k.pr" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002335 /* pt_regs */
2336 { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002337 /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002338 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2339 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2340 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2341 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2342 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2343 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2344 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2345 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2346 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2347 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2348 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2349 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2350 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2351 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2352 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2353#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002354#ifdef I386
2355 { 4*EBX, "4*EBX" },
2356 { 4*ECX, "4*ECX" },
2357 { 4*EDX, "4*EDX" },
2358 { 4*ESI, "4*ESI" },
2359 { 4*EDI, "4*EDI" },
2360 { 4*EBP, "4*EBP" },
2361 { 4*EAX, "4*EAX" },
2362 { 4*DS, "4*DS" },
2363 { 4*ES, "4*ES" },
2364 { 4*FS, "4*FS" },
2365 { 4*GS, "4*GS" },
2366 { 4*ORIG_EAX, "4*ORIG_EAX" },
2367 { 4*EIP, "4*EIP" },
2368 { 4*CS, "4*CS" },
2369 { 4*EFL, "4*EFL" },
2370 { 4*UESP, "4*UESP" },
2371 { 4*SS, "4*SS" },
2372#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002373#ifdef X86_64
2374 { 8*RDI, "8*RDI" },
2375 { 8*RSI, "8*RSI" },
2376 { 8*RDX, "8*RDX" },
2377 { 8*R10, "8*R10" },
2378 { 8*R8, "8*R8" },
2379 { 8*R9, "8*R9" },
2380 { 8*RBX, "8*RBX" },
2381 { 8*RCX, "8*RCX" },
2382 { 8*RBP, "8*RBP" },
2383 { 8*RAX, "8*RAX" },
2384#if 0
2385 { 8*DS, "8*DS" },
2386 { 8*ES, "8*ES" },
2387 { 8*FS, "8*FS" },
2388 { 8*GS, "8*GS" },
2389#endif
2390 { 8*ORIG_RAX, "8*ORIG_EAX" },
2391 { 8*RIP, "8*RIP" },
2392 { 8*CS, "8*CS" },
2393 { 8*EFLAGS, "8*EFL" },
2394 { 8*RSP, "8*RSP" },
2395 { 8*SS, "8*SS" },
2396 { 8*R11, "8*R11" },
2397 { 8*R12, "8*R12" },
2398 { 8*R13, "8*R13" },
2399 { 8*R14, "8*R14" },
2400 { 8*R15, "8*R15" },
2401#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002402#ifdef M68K
2403 { 4*PT_D1, "4*PT_D1" },
2404 { 4*PT_D2, "4*PT_D2" },
2405 { 4*PT_D3, "4*PT_D3" },
2406 { 4*PT_D4, "4*PT_D4" },
2407 { 4*PT_D5, "4*PT_D5" },
2408 { 4*PT_D6, "4*PT_D6" },
2409 { 4*PT_D7, "4*PT_D7" },
2410 { 4*PT_A0, "4*PT_A0" },
2411 { 4*PT_A1, "4*PT_A1" },
2412 { 4*PT_A2, "4*PT_A2" },
2413 { 4*PT_A3, "4*PT_A3" },
2414 { 4*PT_A4, "4*PT_A4" },
2415 { 4*PT_A5, "4*PT_A5" },
2416 { 4*PT_A6, "4*PT_A6" },
2417 { 4*PT_D0, "4*PT_D0" },
2418 { 4*PT_USP, "4*PT_USP" },
2419 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2420 { 4*PT_SR, "4*PT_SR" },
2421 { 4*PT_PC, "4*PT_PC" },
2422#endif /* M68K */
2423#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002424#ifdef SH
2425 { 4*REG_REG0, "4*REG_REG0" },
2426 { 4*(REG_REG0+1), "4*REG_REG1" },
2427 { 4*(REG_REG0+2), "4*REG_REG2" },
2428 { 4*(REG_REG0+3), "4*REG_REG3" },
2429 { 4*(REG_REG0+4), "4*REG_REG4" },
2430 { 4*(REG_REG0+5), "4*REG_REG5" },
2431 { 4*(REG_REG0+6), "4*REG_REG6" },
2432 { 4*(REG_REG0+7), "4*REG_REG7" },
2433 { 4*(REG_REG0+8), "4*REG_REG8" },
2434 { 4*(REG_REG0+9), "4*REG_REG9" },
2435 { 4*(REG_REG0+10), "4*REG_REG10" },
2436 { 4*(REG_REG0+11), "4*REG_REG11" },
2437 { 4*(REG_REG0+12), "4*REG_REG12" },
2438 { 4*(REG_REG0+13), "4*REG_REG13" },
2439 { 4*(REG_REG0+14), "4*REG_REG14" },
2440 { 4*REG_REG15, "4*REG_REG15" },
2441 { 4*REG_PC, "4*REG_PC" },
2442 { 4*REG_PR, "4*REG_PR" },
2443 { 4*REG_SR, "4*REG_SR" },
2444 { 4*REG_GBR, "4*REG_GBR" },
2445 { 4*REG_MACH, "4*REG_MACH" },
2446 { 4*REG_MACL, "4*REG_MACL" },
2447 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2448 { 4*REG_FPUL, "4*REG_FPUL" },
2449 { 4*REG_FPREG0, "4*REG_FPREG0" },
2450 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2451 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2452 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2453 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2454 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2455 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2456 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2457 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2458 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2459 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2460 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2461 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2462 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2463 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2464 { 4*REG_FPREG15, "4*REG_FPREG15" },
2465 { 4*REG_XDREG0, "4*REG_XDREG0" },
2466 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2467 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2468 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2469 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2470 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2471 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2472 { 4*REG_XDREG14, "4*REG_XDREG14" },
2473 { 4*REG_FPSCR, "4*REG_FPSCR" },
2474#endif /* SH */
Roland McGrathe1e584b2003-06-02 19:18:58 +00002475#ifdef SHMEDIA
2476 { 0, "PC(L)" },
2477 { 4, "PC(U)" },
2478 { 8, "SR(L)" },
2479 { 12, "SR(U)" },
2480 { 16, "syscall no.(L)" },
2481 { 20, "syscall_no.(U)" },
2482 { 24, "R0(L)" },
2483 { 28, "R0(U)" },
2484 { 32, "R1(L)" },
2485 { 36, "R1(U)" },
2486 { 40, "R2(L)" },
2487 { 44, "R2(U)" },
2488 { 48, "R3(L)" },
2489 { 52, "R3(U)" },
2490 { 56, "R4(L)" },
2491 { 60, "R4(U)" },
2492 { 64, "R5(L)" },
2493 { 68, "R5(U)" },
2494 { 72, "R6(L)" },
2495 { 76, "R6(U)" },
2496 { 80, "R7(L)" },
2497 { 84, "R7(U)" },
2498 { 88, "R8(L)" },
2499 { 92, "R8(U)" },
2500 { 96, "R9(L)" },
2501 { 100, "R9(U)" },
2502 { 104, "R10(L)" },
2503 { 108, "R10(U)" },
2504 { 112, "R11(L)" },
2505 { 116, "R11(U)" },
2506 { 120, "R12(L)" },
2507 { 124, "R12(U)" },
2508 { 128, "R13(L)" },
2509 { 132, "R13(U)" },
2510 { 136, "R14(L)" },
2511 { 140, "R14(U)" },
2512 { 144, "R15(L)" },
2513 { 148, "R15(U)" },
2514 { 152, "R16(L)" },
2515 { 156, "R16(U)" },
2516 { 160, "R17(L)" },
2517 { 164, "R17(U)" },
2518 { 168, "R18(L)" },
2519 { 172, "R18(U)" },
2520 { 176, "R19(L)" },
2521 { 180, "R19(U)" },
2522 { 184, "R20(L)" },
2523 { 188, "R20(U)" },
2524 { 192, "R21(L)" },
2525 { 196, "R21(U)" },
2526 { 200, "R22(L)" },
2527 { 204, "R22(U)" },
2528 { 208, "R23(L)" },
2529 { 212, "R23(U)" },
2530 { 216, "R24(L)" },
2531 { 220, "R24(U)" },
2532 { 224, "R25(L)" },
2533 { 228, "R25(U)" },
2534 { 232, "R26(L)" },
2535 { 236, "R26(U)" },
2536 { 240, "R27(L)" },
2537 { 244, "R27(U)" },
2538 { 248, "R28(L)" },
2539 { 252, "R28(U)" },
2540 { 256, "R29(L)" },
2541 { 260, "R29(U)" },
2542 { 264, "R30(L)" },
2543 { 268, "R30(U)" },
2544 { 272, "R31(L)" },
2545 { 276, "R31(U)" },
2546 { 280, "R32(L)" },
2547 { 284, "R32(U)" },
2548 { 288, "R33(L)" },
2549 { 292, "R33(U)" },
2550 { 296, "R34(L)" },
2551 { 300, "R34(U)" },
2552 { 304, "R35(L)" },
2553 { 308, "R35(U)" },
2554 { 312, "R36(L)" },
2555 { 316, "R36(U)" },
2556 { 320, "R37(L)" },
2557 { 324, "R37(U)" },
2558 { 328, "R38(L)" },
2559 { 332, "R38(U)" },
2560 { 336, "R39(L)" },
2561 { 340, "R39(U)" },
2562 { 344, "R40(L)" },
2563 { 348, "R40(U)" },
2564 { 352, "R41(L)" },
2565 { 356, "R41(U)" },
2566 { 360, "R42(L)" },
2567 { 364, "R42(U)" },
2568 { 368, "R43(L)" },
2569 { 372, "R43(U)" },
2570 { 376, "R44(L)" },
2571 { 380, "R44(U)" },
2572 { 384, "R45(L)" },
2573 { 388, "R45(U)" },
2574 { 392, "R46(L)" },
2575 { 396, "R46(U)" },
2576 { 400, "R47(L)" },
2577 { 404, "R47(U)" },
2578 { 408, "R48(L)" },
2579 { 412, "R48(U)" },
2580 { 416, "R49(L)" },
2581 { 420, "R49(U)" },
2582 { 424, "R50(L)" },
2583 { 428, "R50(U)" },
2584 { 432, "R51(L)" },
2585 { 436, "R51(U)" },
2586 { 440, "R52(L)" },
2587 { 444, "R52(U)" },
2588 { 448, "R53(L)" },
2589 { 452, "R53(U)" },
2590 { 456, "R54(L)" },
2591 { 460, "R54(U)" },
2592 { 464, "R55(L)" },
2593 { 468, "R55(U)" },
2594 { 472, "R56(L)" },
2595 { 476, "R56(U)" },
2596 { 480, "R57(L)" },
2597 { 484, "R57(U)" },
2598 { 488, "R58(L)" },
2599 { 492, "R58(U)" },
2600 { 496, "R59(L)" },
2601 { 500, "R59(U)" },
2602 { 504, "R60(L)" },
2603 { 508, "R60(U)" },
2604 { 512, "R61(L)" },
2605 { 516, "R61(U)" },
2606 { 520, "R62(L)" },
2607 { 524, "R62(U)" },
2608 { 528, "TR0(L)" },
2609 { 532, "TR0(U)" },
2610 { 536, "TR1(L)" },
2611 { 540, "TR1(U)" },
2612 { 544, "TR2(L)" },
2613 { 548, "TR2(U)" },
2614 { 552, "TR3(L)" },
2615 { 556, "TR3(U)" },
2616 { 560, "TR4(L)" },
2617 { 564, "TR4(U)" },
2618 { 568, "TR5(L)" },
2619 { 572, "TR5(U)" },
2620 { 576, "TR6(L)" },
2621 { 580, "TR6(U)" },
2622 { 584, "TR7(L)" },
2623 { 588, "TR7(U)" },
2624 /* This entry is in case pt_regs contains dregs (depends on
2625 the kernel build options). */
2626 { uoff(regs), "offsetof(struct user, regs)" },
2627 { uoff(fpu), "offsetof(struct user, fpu)" },
2628#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002629
Michal Ludvig10a88d02002-10-07 14:31:00 +00002630#if !defined(S390) && !defined(S390X) && !defined(MIPS)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002631 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002632#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002633#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002634 { uoff(i387), "offsetof(struct user, i387)" },
2635#else /* !I386 */
2636#ifdef M68K
2637 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2638#endif /* M68K */
2639#endif /* !I386 */
2640 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2641 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2642 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2643 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrathe1e584b2003-06-02 19:18:58 +00002644#ifdef SHMEDIA
2645 { uoff(start_data), "offsetof(struct user, start_data)" },
2646#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002647 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2648 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrathe1e584b2003-06-02 19:18:58 +00002649#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SHMEDIA)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002650 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002651#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002652 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002653#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002654 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2655#endif
2656 { uoff(magic), "offsetof(struct user, magic)" },
2657 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002658#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002659 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2660#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002661#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002662#endif /* !ALPHA */
2663#endif /* !POWERPC/!SPARC */
2664#endif /* LINUX */
2665#ifdef SUNOS4
2666 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2667 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2668 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2669 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2670 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2671 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2672 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2673 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2674 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2675 { uoff(u_error), "offsetof(struct user, u_error)" },
2676 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2677 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2678 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2679 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2680 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2681 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2682 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2683 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2684 { uoff(u_code), "offsetof(struct user, u_code)" },
2685 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2686 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2687 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2688 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2689 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2690 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2691 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2692 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2693 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2694 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2695 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2696 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2697 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2698 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2699 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2700 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2701 { uoff(u_start), "offsetof(struct user, u_start)" },
2702 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2703 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2704 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2705 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2706 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2707 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2708 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2709 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2710 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2711#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002712#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002713 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002714#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002715 { 0, NULL },
2716};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002717#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002718
2719int
2720sys_ptrace(tcp)
2721struct tcb *tcp;
2722{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002723 struct xlat *x;
2724 long addr;
2725
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002726 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002727 printxval(ptrace_cmds, tcp->u_arg[0],
2728#ifndef FREEBSD
2729 "PTRACE_???"
2730#else
2731 "PT_???"
2732#endif
2733 );
2734 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002735 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002736#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002737 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2738 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2739 for (x = struct_user_offsets; x->str; x++) {
2740 if (x->val >= addr)
2741 break;
2742 }
2743 if (!x->str)
2744 tprintf("%#lx, ", addr);
2745 else if (x->val > addr && x != struct_user_offsets) {
2746 x--;
2747 tprintf("%s + %ld, ", x->str, addr - x->val);
2748 }
2749 else
2750 tprintf("%s, ", x->str);
2751 }
2752 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002753#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002754 tprintf("%#lx, ", tcp->u_arg[2]);
2755#ifdef LINUX
2756 switch (tcp->u_arg[0]) {
2757 case PTRACE_PEEKDATA:
2758 case PTRACE_PEEKTEXT:
2759 case PTRACE_PEEKUSER:
2760 break;
2761 case PTRACE_CONT:
2762 case PTRACE_SINGLESTEP:
2763 case PTRACE_SYSCALL:
2764 case PTRACE_DETACH:
2765 printsignal(tcp->u_arg[3]);
2766 break;
2767 default:
2768 tprintf("%#lx", tcp->u_arg[3]);
2769 break;
2770 }
2771 } else {
2772 switch (tcp->u_arg[0]) {
2773 case PTRACE_PEEKDATA:
2774 case PTRACE_PEEKTEXT:
2775 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00002776 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002777 break;
2778 }
2779 }
2780#endif /* LINUX */
2781#ifdef SUNOS4
2782 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2783 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2784 tprintf("%lu, ", tcp->u_arg[3]);
2785 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2786 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2787 tcp->u_arg[0] != PTRACE_READTEXT) {
2788 tprintf("%#lx", tcp->u_arg[3]);
2789 }
2790 } else {
2791 if (tcp->u_arg[0] == PTRACE_READDATA ||
2792 tcp->u_arg[0] == PTRACE_READTEXT) {
2793 tprintf("%lu, ", tcp->u_arg[3]);
2794 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2795 }
2796 }
2797#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002798#ifdef FREEBSD
2799 tprintf("%lu", tcp->u_arg[3]);
2800 }
2801#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002802 return 0;
2803}
2804
2805#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002806
2807#ifdef LINUX
2808static struct xlat futexops[] = {
2809 { FUTEX_WAIT, "FUTEX_WAIT" },
2810 { FUTEX_WAKE, "FUTEX_WAKE" },
2811 { FUTEX_FD, "FUTEX_FD" },
2812 { 0, NULL }
2813};
2814
2815int
2816sys_futex(tcp)
2817struct tcb *tcp;
2818{
2819 if (entering(tcp)) {
2820 tprintf("%p, ", (void *) tcp->u_arg[0]);
2821 printflags(futexops, tcp->u_arg[1]);
Roland McGrath8dfa04a2003-03-05 04:07:55 +00002822 tprintf(", %ld", tcp->u_arg[2]);
2823 if (tcp->u_arg[1] == FUTEX_WAIT) {
2824 tprintf(", ");
2825 printtv(tcp, tcp->u_arg[3]);
2826 }
Roland McGrath5a223472002-12-15 23:58:26 +00002827 }
2828 return 0;
2829}
2830
2831static void
2832print_affinitylist(list, len)
2833unsigned long *list;
2834unsigned int len;
2835{
2836 int first = 1;
2837 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00002838 while (len >= sizeof (unsigned long)) {
Roland McGrath5a223472002-12-15 23:58:26 +00002839 tprintf("%s %lx", first ? "" : ",", *list++);
2840 first = 0;
2841 len -= sizeof (unsigned long);
2842 }
2843 tprintf(" }");
2844}
2845
2846int
2847sys_sched_setaffinity(tcp)
2848struct tcb *tcp;
2849{
2850 if (entering(tcp)) {
2851 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2852 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2853 }
2854 return 0;
2855}
2856
2857int
2858sys_sched_getaffinity(tcp)
2859struct tcb *tcp;
2860{
2861 if (entering(tcp)) {
2862 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2863 } else {
2864 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);
2865 }
2866 return 0;
2867}
2868#endif