blob: 231820faddee6f8a0968dad2f6c9a23a9c4977a9 [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
Roland McGrath88812d62003-06-26 22:27:23 +0000101# ifndef FUTEX_REQUEUE
102# define FUTEX_REQUEUE 3
103# endif
Roland McGrath5a223472002-12-15 23:58:26 +0000104#endif
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000105
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000106#ifdef LINUX
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000107#include <asm/posix_types.h>
108#undef GETGROUPS_T
109#define GETGROUPS_T __kernel_gid_t
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000110#endif /* LINUX */
111
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000112#if defined(LINUX) && defined(IA64)
113# include <asm/ptrace_offsets.h>
114# include <asm/rse.h>
115#endif
116
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000117#ifdef HAVE_PRCTL
118#include <sys/prctl.h>
119#endif
120
121#ifndef WCOREDUMP
122#define WCOREDUMP(status) ((status) & 0200)
123#endif
124
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000125/* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000126#if defined(HAVE_PRCTL)
127static struct xlat prctl_options[] = {
128#ifdef PR_MAXPROCS
129 { PR_MAXPROCS, "PR_MAXPROCS" },
130#endif
131#ifdef PR_ISBLOCKED
132 { PR_ISBLOCKED, "PR_ISBLOCKED" },
133#endif
134#ifdef PR_SETSTACKSIZE
135 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
136#endif
137#ifdef PR_GETSTACKSIZE
138 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
139#endif
140#ifdef PR_MAXPPROCS
141 { PR_MAXPPROCS, "PR_MAXPPROCS" },
142#endif
143#ifdef PR_UNBLKONEXEC
144 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
145#endif
146#ifdef PR_ATOMICSIM
147 { PR_ATOMICSIM, "PR_ATOMICSIM" },
148#endif
149#ifdef PR_SETEXITSIG
150 { PR_SETEXITSIG, "PR_SETEXITSIG" },
151#endif
152#ifdef PR_RESIDENT
153 { PR_RESIDENT, "PR_RESIDENT" },
154#endif
155#ifdef PR_ATTACHADDR
156 { PR_ATTACHADDR, "PR_ATTACHADDR" },
157#endif
158#ifdef PR_DETACHADDR
159 { PR_DETACHADDR, "PR_DETACHADDR" },
160#endif
161#ifdef PR_TERMCHILD
162 { PR_TERMCHILD, "PR_TERMCHILD" },
163#endif
164#ifdef PR_GETSHMASK
165 { PR_GETSHMASK, "PR_GETSHMASK" },
166#endif
167#ifdef PR_GETNSHARE
168 { PR_GETNSHARE, "PR_GETNSHARE" },
169#endif
170#if defined(PR_SET_PDEATHSIG)
171 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
172#endif
Wichert Akkerman8829a551999-06-11 13:18:40 +0000173#ifdef PR_COREPID
174 { PR_COREPID, "PR_COREPID" },
175#endif
176#ifdef PR_ATTACHADDRPERM
177 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
178#endif
179#ifdef PR_PTHREADEXIT
180 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
181#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000182#ifdef PR_SET_PDEATHSIG
183 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
184#endif
185#ifdef PR_GET_PDEATHSIG
186 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
187#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000188#ifdef PR_GET_UNALIGN
189 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
190#endif
191#ifdef PR_SET_UNALIGN
192 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
193#endif
194#ifdef PR_GET_KEEPCAPS
195 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" },
196#endif
197#ifdef PR_SET_KEEPCAPS
198 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" },
199#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000200 { 0, NULL },
201};
202
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000203
204const char *
205unalignctl_string (unsigned int ctl)
206{
207 static char buf[16];
208
209 switch (ctl) {
210#ifdef PR_UNALIGN_NOPRINT
211 case PR_UNALIGN_NOPRINT:
212 return "NOPRINT";
213#endif
214#ifdef PR_UNALIGN_SIGBUS
215 case PR_UNALIGN_SIGBUS:
216 return "SIGBUS";
217#endif
218 default:
219 break;
220 }
221 sprintf(buf, "%x", ctl);
222 return buf;
223}
224
225
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000226int
227sys_prctl(tcp)
228struct tcb *tcp;
229{
230 int i;
231
232 if (entering(tcp)) {
233 printxval(prctl_options, tcp->u_arg[0], "PR_???");
234 switch (tcp->u_arg[0]) {
235#ifdef PR_GETNSHARE
236 case PR_GETNSHARE:
237 break;
238#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000239#ifdef PR_SET_DEATHSIG
240 case PR_GET_PDEATHSIG:
241 break;
242#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000243#ifdef PR_SET_UNALIGN
244 case PR_SET_UNALIGN:
245 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
246 break;
247#endif
248#ifdef PR_GET_UNALIGN
249 case PR_GET_UNALIGN:
250 tprintf(", %#lx", tcp->u_arg[1]);
251 break;
252#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000253 default:
254 for (i = 1; i < tcp->u_nargs; i++)
255 tprintf(", %#lx", tcp->u_arg[i]);
256 break;
257 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000258 } else {
259 switch (tcp->u_arg[0]) {
260#ifdef PR_GET_PDEATHSIG
261 case PR_GET_PDEATHSIG:
262 for (i=1; i<tcp->u_nargs; i++)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000263 tprintf(", %#lx", tcp->u_arg[i]);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000264 break;
265#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000266#ifdef PR_SET_UNALIGN
267 case PR_SET_UNALIGN:
268 break;
269#endif
270#ifdef PR_GET_UNALIGN
271 case PR_GET_UNALIGN:
272 {
273 int ctl;
274
275 umove(tcp, tcp->u_arg[1], &ctl);
276 tcp->auxstr = unalignctl_string(ctl);
277 return RVAL_STR;
278 }
279#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000280 default:
281 break;
282 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000283 }
284 return 0;
285}
286
287#endif /* HAVE_PRCTL */
288
289int
290sys_gethostid(tcp)
291struct tcb *tcp;
292{
293 if (exiting(tcp))
294 return RVAL_HEX;
295 return 0;
296}
297
298int
299sys_sethostname(tcp)
300struct tcb *tcp;
301{
302 if (entering(tcp)) {
303 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
304 tprintf(", %lu", tcp->u_arg[1]);
305 }
306 return 0;
307}
308
309int
310sys_gethostname(tcp)
311struct tcb *tcp;
312{
313 if (exiting(tcp)) {
314 if (syserror(tcp))
315 tprintf("%#lx", tcp->u_arg[0]);
316 else
317 printpath(tcp, tcp->u_arg[0]);
318 tprintf(", %lu", tcp->u_arg[1]);
319 }
320 return 0;
321}
322
323int
324sys_setdomainname(tcp)
325struct tcb *tcp;
326{
327 if (entering(tcp)) {
328 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
329 tprintf(", %lu", tcp->u_arg[1]);
330 }
331 return 0;
332}
333
Wichert Akkerman5daa0281999-03-15 19:49:42 +0000334#if !defined(LINUX)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000335
336int
337sys_getdomainname(tcp)
338struct tcb *tcp;
339{
340 if (exiting(tcp)) {
341 if (syserror(tcp))
342 tprintf("%#lx", tcp->u_arg[0]);
343 else
344 printpath(tcp, tcp->u_arg[0]);
345 tprintf(", %lu", tcp->u_arg[1]);
346 }
347 return 0;
348}
349#endif /* !LINUX */
350
351int
352sys_exit(tcp)
353struct tcb *tcp;
354{
355 if (exiting(tcp)) {
356 fprintf(stderr, "_exit returned!\n");
357 return -1;
358 }
359 /* special case: we stop tracing this process, finish line now */
360 tprintf("%ld) ", tcp->u_arg[0]);
361 tabto(acolumn);
362 tprintf("= ?");
363 printtrailer(tcp);
364 return 0;
365}
366
367int
368internal_exit(tcp)
369struct tcb *tcp;
370{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000371 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000372 tcp->flags |= TCB_EXITING;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000373#ifdef __NR_exit_group
374 if (tcp->scno == __NR_exit_group)
375 tcp->flags |= TCB_GROUP_EXITING;
376#endif
377 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000378 return 0;
379}
380
Roland McGrathee9d4352002-12-18 04:16:10 +0000381/* TCP is creating a child we want to follow.
382 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
383 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
384static int
385fork_tcb(struct tcb *tcp)
386{
387 if (nprocs == tcbtabsize) {
388 /* Allocate some more TCBs and expand the table.
389 We don't want to relocate the TCBs because our
390 callers have pointers and it would be a pain.
391 So tcbtab is a table of pointers. Since we never
392 free the TCBs, we allocate a single chunk of many. */
393 struct tcb **newtab = (struct tcb **)
394 realloc(tcbtab, 2 * tcbtabsize * sizeof tcbtab[0]);
395 struct tcb *newtcbs = (struct tcb *) calloc(tcbtabsize,
396 sizeof *newtcbs);
397 int i;
398 if (newtab == NULL || newtcbs == NULL) {
399 if (newtab != NULL)
400 free(newtab);
401 tcp->flags &= ~TCB_FOLLOWFORK;
402 fprintf(stderr, "sys_fork: tcb table full\n");
403 return 1;
404 }
405 for (i = tcbtabsize; i < 2 * tcbtabsize; ++i)
406 newtab[i] = &newtcbs[i - tcbtabsize];
407 tcbtabsize *= 2;
408 tcbtab = newtab;
409 }
410
411 tcp->flags |= TCB_FOLLOWFORK;
412 return 0;
413}
414
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000415#ifdef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000416
417int
418sys_fork(tcp)
419struct tcb *tcp;
420{
421 if (exiting(tcp)) {
422 if (getrval2(tcp)) {
423 tcp->auxstr = "child process";
424 return RVAL_UDECIMAL | RVAL_STR;
425 }
426 }
427 return 0;
428}
429
John Hughes4e36a812001-04-18 15:11:51 +0000430#if UNIXWARE > 2
431
432int
433sys_rfork(tcp)
434struct tcb *tcp;
435{
436 if (entering(tcp)) {
437 tprintf ("%ld", tcp->u_arg[0]);
438 }
439 else {
440 if (getrval2(tcp)) {
441 tcp->auxstr = "child process";
442 return RVAL_UDECIMAL | RVAL_STR;
443 }
444 }
445 return 0;
446}
447
448#endif
449
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000450int
451internal_fork(tcp)
452struct tcb *tcp;
453{
454 struct tcb *tcpchild;
455
456 if (exiting(tcp)) {
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000457#ifdef SYS_rfork
458 if (tcp->scno == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
459 return 0;
460#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000461 if (getrval2(tcp))
462 return 0;
463 if (!followfork)
464 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000465 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000466 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000467 if (syserror(tcp))
468 return 0;
469 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
470 fprintf(stderr, "sys_fork: tcb table full\n");
471 return 0;
472 }
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000473 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000474 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000475 }
476 return 0;
477}
478
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000479#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000480
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000481#ifdef LINUX
482
483/* defines copied from linux/sched.h since we can't include that
484 * ourselves (it conflicts with *lots* of libc includes)
485 */
486#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
487#define CLONE_VM 0x00000100 /* set if VM shared between processes */
488#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
489#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
490#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000491#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000492#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
493#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
494#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000495#define CLONE_THREAD 0x00010000 /* Same thread group? */
496#define CLONE_NEWNS 0x00020000 /* New namespace group? */
497#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
498#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
499#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
500#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
501#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
502#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
503#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000504
505static struct xlat clone_flags[] = {
506 { CLONE_VM, "CLONE_VM" },
507 { CLONE_FS, "CLONE_FS" },
508 { CLONE_FILES, "CLONE_FILES" },
509 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000510 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000511 { CLONE_PTRACE, "CLONE_PTRACE" },
512 { CLONE_VFORK, "CLONE_VFORK" },
513 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000514 { CLONE_THREAD, "CLONE_THREAD" },
515 { CLONE_NEWNS, "CLONE_NEWNS" },
516 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
517 { CLONE_SETTLS, "CLONE_SETTLS" },
518 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
519 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
520 { CLONE_DETACHED, "CLONE_DETACHED" },
521 { CLONE_UNTRACED, "CLONE_UNTRACED" },
522 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000523 { 0, NULL },
524};
525
Roland McGrath909875b2002-12-22 03:34:36 +0000526# ifdef I386
527# include <asm/ldt.h>
528extern void print_ldt_entry();
529# endif
530
Roland McGrath9677b3a2003-03-12 09:54:36 +0000531# if defined IA64
532# define ARG_FLAGS 0
533# define ARG_STACK 1
534# define ARG_STACKSIZE (tcp->scno == SYS_clone2 ? 2 : -1)
Roland McGrathc03981d2003-03-14 10:32:36 +0000535# define ARG_PTID (tcp->scno == SYS_clone2 ? 3 : 2)
536# define ARG_CTID (tcp->scno == SYS_clone2 ? 4 : 3)
537# define ARG_TLS (tcp->scno == SYS_clone2 ? 5 : 4)
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000538# elif defined S390 || defined S390X
Roland McGrath9677b3a2003-03-12 09:54:36 +0000539# define ARG_STACK 0
540# define ARG_FLAGS 1
541# define ARG_PTID 2
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000542# define ARG_CTID 3
543# define ARG_TLS 4
Roland McGrath9c555e72003-07-09 09:47:59 +0000544# elif defined X86_64 || defined ALPHA
Roland McGrath361aac52003-03-18 07:43:42 +0000545# define ARG_FLAGS 0
546# define ARG_STACK 1
547# define ARG_PTID 2
548# define ARG_CTID 3
549# define ARG_TLS 4
Roland McGrath9677b3a2003-03-12 09:54:36 +0000550# else
551# define ARG_FLAGS 0
552# define ARG_STACK 1
553# define ARG_PTID 2
554# define ARG_TLS 3
555# define ARG_CTID 4
556# endif
557
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000558int
559sys_clone(tcp)
560struct tcb *tcp;
561{
562 if (exiting(tcp)) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000563 unsigned long flags = tcp->u_arg[ARG_FLAGS];
564 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
565# ifdef ARG_STACKSIZE
566 if (ARG_STACKSIZE != -1)
567 tprintf("stack_size=%#lx, ",
568 tcp->u_arg[ARG_STACKSIZE]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000569# endif
Roland McGrath9677b3a2003-03-12 09:54:36 +0000570 tprintf("flags=");
Roland McGrath984154d2003-05-23 01:08:42 +0000571 if (printflags(clone_flags, flags &~ CSIGNAL) == 0)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000572 tprintf("0");
Roland McGrath984154d2003-05-23 01:08:42 +0000573 if ((flags & CSIGNAL) != 0)
574 tprintf("|%s", signame(flags & CSIGNAL));
Roland McGrathb4968be2003-01-20 09:04:33 +0000575 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
Roland McGrath9677b3a2003-03-12 09:54:36 +0000576 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
Roland McGrath909875b2002-12-22 03:34:36 +0000577 return 0;
Roland McGrath6f67a982003-03-21 07:33:15 +0000578 if (flags & CLONE_PARENT_SETTID)
579 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000580 if (flags & CLONE_SETTLS) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000581# ifdef I386
Roland McGrath909875b2002-12-22 03:34:36 +0000582 struct modify_ldt_ldt_s copy;
Roland McGrath9677b3a2003-03-12 09:54:36 +0000583 if (umove(tcp, tcp->u_arg[ARG_TLS], &copy) != -1) {
Roland McGrath909875b2002-12-22 03:34:36 +0000584 tprintf(", {entry_number:%d, ",
585 copy.entry_number);
586 if (!verbose(tcp))
587 tprintf("...}");
588 else
589 print_ldt_entry(&copy);
590 }
591 else
Roland McGrath9677b3a2003-03-12 09:54:36 +0000592# endif
Roland McGrath43f2c842003-03-12 09:58:14 +0000593 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
Roland McGrath909875b2002-12-22 03:34:36 +0000594 }
Roland McGrath9677b3a2003-03-12 09:54:36 +0000595 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
596 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000597 }
598 return 0;
599}
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000600#endif
601
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000602int
603sys_fork(tcp)
604struct tcb *tcp;
605{
606 if (exiting(tcp))
607 return RVAL_UDECIMAL;
608 return 0;
609}
610
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000611int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000612change_syscall(tcp, new)
613struct tcb *tcp;
614int new;
615{
616#if defined(LINUX)
617#if defined(I386)
618 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000619 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000620 return -1;
621 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000622#elif defined(X86_64)
623 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000624 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000625 return -1;
626 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000627#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000628 if (ptrace(PTRACE_POKEUSER, tcp->pid,
629 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000630 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000631 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000632#elif defined(S390) || defined(S390X)
633 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
634 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
635 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000636 return 0;
637#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000638 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000639 return -1;
640 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000641#elif defined(SPARC)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000642 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000643 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
644 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000645 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000646 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
647 return -1;
648 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000649#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000650 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000651 return -1;
652 return 0;
653#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000654 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000655 return -1;
656 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000657#elif defined(IA64)
658 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
659 return -1;
660 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000661#elif defined(HPPA)
662 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
663 return -1;
664 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000665#elif defined(SH)
Roland McGrathac971c22003-03-31 01:03:33 +0000666 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
Wichert Akkermanccef6372002-05-01 16:39:22 +0000667 return -1;
668 return 0;
Roland McGrathf5a47772003-06-26 22:40:42 +0000669#elif defined(SH64)
Roland McGrathe1e584b2003-06-02 19:18:58 +0000670 /* Top half of reg encodes the no. of args n as 0x1n.
671 Assume 0 args as kernel never actually checks... */
672 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
673 0x100000 | new) < 0)
674 return -1;
675 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000676#else
677#warning Do not know how to handle change_syscall for this architecture
678#endif /* architecture */
679#endif /* LINUX */
680 return -1;
681}
682
683int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000684setarg(tcp, argnum)
685 struct tcb *tcp;
686 int argnum;
687{
688#if defined (IA64)
689 {
690 unsigned long *bsp, *ap;
691
692 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
693 return -1;
694
695 ap = ia64_rse_skip_regs(bsp, argnum);
696 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000697 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000698 if (errno)
699 return -1;
700
701 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000702#elif defined(I386)
703 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000704 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000705 if (errno)
706 return -1;
707 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000708#elif defined(X86_64)
709 {
710 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
711 if (errno)
712 return -1;
713 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000714#elif defined(POWERPC)
715#ifndef PT_ORIG_R3
716#define PT_ORIG_R3 34
717#endif
718 {
719 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000720 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000721 tcp->u_arg[argnum]);
722 if (errno)
723 return -1;
724 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000725#elif defined(MIPS)
726 {
727 errno = 0;
728 if (argnum < 4)
729 ptrace(PTRACE_POKEUSER, tcp->pid,
730 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
731 else {
732 unsigned long *sp;
733
734 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
735 return -1;
736
737 ptrace(PTRACE_POKEDATA, tcp->pid,
738 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
739 }
740 if (errno)
741 return -1;
742 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000743#elif defined(S390) || defined(S390X)
744 {
745 if(argnum <= 5)
746 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000747 (char *) (argnum==0 ? PT_ORIGGPR2 :
748 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000749 tcp->u_arg[argnum]);
750 else
751 return -E2BIG;
752 if (errno)
753 return -1;
754 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000755#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000756# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000757#endif
758 return 0;
759}
760
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000761#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000762int
763internal_clone(tcp)
764struct tcb *tcp;
765{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000766 struct tcb *tcpchild;
767 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000768 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000769 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000770 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000771 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000772 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000773 if (setbpt(tcp) < 0)
774 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000775 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000776 int bpt = tcp->flags & TCB_BPTSET;
777
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000778 if (!(tcp->flags & TCB_FOLLOWFORK))
779 return 0;
780
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000781 if (syserror(tcp)) {
782 if (bpt)
783 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000784 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000785 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000786
787 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000788
789#ifdef CLONE_PTRACE /* See new setbpt code. */
790 tcpchild = pid2tcb(pid);
791 if (tcpchild != NULL) {
792 /* The child already reported its startup trap
793 before the parent reported its syscall return. */
794 if ((tcpchild->flags
795 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
796 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
797 fprintf(stderr, "\
798[preattached child %d of %d in weird state!]\n",
799 pid, tcp->pid);
800 }
801 else
802#endif
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000803 if ((tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000804 if (bpt)
805 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000806 fprintf(stderr, " [tcb table full]\n");
807 kill(pid, SIGKILL); /* XXX */
808 return 0;
809 }
810
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000811#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000812 /* Attach to the new child */
813 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000814 if (bpt)
815 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000816 perror("PTRACE_ATTACH");
817 fprintf(stderr, "Too late?\n");
818 droptcb(tcpchild);
819 return 0;
820 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000821#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000822
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000823 if (bpt)
824 clearbpt(tcp);
825
Ulrich Drepper90512f01999-12-24 07:22:25 +0000826 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000827 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000828 if (bpt) {
829 tcpchild->flags |= TCB_BPTSET;
830 tcpchild->baddr = tcp->baddr;
831 memcpy(tcpchild->inst, tcp->inst,
832 sizeof tcpchild->inst);
833 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000834 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000835 tcp->nchildren++;
836 if (tcpchild->flags & TCB_SUSPENDED) {
837 /* The child was born suspended, due to our having
838 forced CLONE_PTRACE. */
839 if (bpt)
840 clearbpt(tcpchild);
841
842 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
843 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
844 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
845 return -1;
846 }
847
848 if (!qflag)
849 fprintf(stderr, "\
850Process %u resumed (parent %d ready)\n",
851 pid, tcp->pid);
852 }
853 else {
854 newoutf(tcpchild);
855 if (!qflag)
856 fprintf(stderr, "Process %d attached\n", pid);
857 }
858
859#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000860 {
861 /*
862 * Save the flags used in this call,
863 * in case we point TCP to our parent below.
864 */
865 int call_flags = tcp->u_arg[ARG_FLAGS];
866 if ((tcp->flags & TCB_CLONE_THREAD) &&
867 tcp->parent != NULL) {
868 /* The parent in this clone is itself a
869 thread belonging to another process.
870 There is no meaning to the parentage
871 relationship of the new child with the
872 thread, only with the process. We
873 associate the new thread with our
874 parent. Since this is done for every
875 new thread, there will never be a
876 TCB_CLONE_THREAD process that has
877 children. */
878 --tcp->nchildren;
879 tcp = tcp->parent;
880 tcpchild->parent = tcp;
881 ++tcp->nchildren;
882 }
883 if (call_flags & CLONE_THREAD) {
884 tcpchild->flags |= TCB_CLONE_THREAD;
885 ++tcp->nclone_threads;
886 }
887 if (call_flags & CLONE_DETACHED) {
888 tcpchild->flags |= TCB_CLONE_DETACHED;
889 ++tcp->nclone_detached;
890 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000891 }
892#endif
893
894 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000895 return 0;
896}
897#endif
898
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000899int
900internal_fork(tcp)
901struct tcb *tcp;
902{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000903#ifdef LINUX
904 /* We do special magic with clone for any clone or fork. */
905 return internal_clone(tcp);
906#else
907
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000908 struct tcb *tcpchild;
909 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000910 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000911
912#ifdef SYS_vfork
Nate Sammonsccd8f211999-03-29 22:57:54 +0000913 if (tcp->scno == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000914 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000915 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000916 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000917 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000918 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000919#endif
920 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000921 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000922 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000923 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000924 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000925 if (setbpt(tcp) < 0)
926 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000927 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000928 else {
929 int bpt = tcp->flags & TCB_BPTSET;
930
931 if (!(tcp->flags & TCB_FOLLOWFORK))
932 return 0;
933 if (bpt)
934 clearbpt(tcp);
935
936 if (syserror(tcp))
937 return 0;
938
939 pid = tcp->u_rval;
940 if ((tcpchild = alloctcb(pid)) == NULL) {
941 fprintf(stderr, " [tcb table full]\n");
942 kill(pid, SIGKILL); /* XXX */
943 return 0;
944 }
945#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000946#ifdef HPPA
947 /* The child must have run before it can be attached. */
948 /* This must be a bug in the parisc kernel, but I havn't
949 * identified it yet. Seems to be an issue associated
950 * with attaching to a process (which sends it a signal)
951 * before that process has ever been scheduled. When
952 * debugging, I started seeing crashes in
953 * arch/parisc/kernel/signal.c:do_signal(), apparently
954 * caused by r8 getting corrupt over the dequeue_signal()
955 * call. Didn't make much sense though...
956 */
957 {
958 struct timeval tv;
959 tv.tv_sec = 0;
960 tv.tv_usec = 10000;
961 select(0, NULL, NULL, NULL, &tv);
962 }
963#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000964 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
965 perror("PTRACE_ATTACH");
966 fprintf(stderr, "Too late?\n");
967 droptcb(tcpchild);
968 return 0;
969 }
970#endif /* LINUX */
971#ifdef SUNOS4
972#ifdef oldway
973 /* The child must have run before it can be attached. */
974 {
975 struct timeval tv;
976 tv.tv_sec = 0;
977 tv.tv_usec = 10000;
978 select(0, NULL, NULL, NULL, &tv);
979 }
980 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
981 perror("PTRACE_ATTACH");
982 fprintf(stderr, "Too late?\n");
983 droptcb(tcpchild);
984 return 0;
985 }
986#else /* !oldway */
987 /* Try to catch the new process as soon as possible. */
988 {
989 int i;
990 for (i = 0; i < 1024; i++)
991 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
992 break;
993 if (i == 1024) {
994 perror("PTRACE_ATTACH");
995 fprintf(stderr, "Too late?\n");
996 droptcb(tcpchild);
997 return 0;
998 }
999 }
1000#endif /* !oldway */
1001#endif /* SUNOS4 */
1002 tcpchild->flags |= TCB_ATTACHED;
1003 /* Child has BPT too, must be removed on first occasion */
1004 if (bpt) {
1005 tcpchild->flags |= TCB_BPTSET;
1006 tcpchild->baddr = tcp->baddr;
1007 memcpy(tcpchild->inst, tcp->inst,
1008 sizeof tcpchild->inst);
1009 }
1010 newoutf(tcpchild);
1011 tcpchild->parent = tcp;
1012 tcp->nchildren++;
1013 if (!qflag)
1014 fprintf(stderr, "Process %d attached\n", pid);
1015 }
1016 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001017#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001018}
1019
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001020#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001021
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001022#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001023
1024int
1025sys_vfork(tcp)
1026struct tcb *tcp;
1027{
1028 if (exiting(tcp))
1029 return RVAL_UDECIMAL;
1030 return 0;
1031}
1032
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001033#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001034
1035#ifndef LINUX
1036
1037static char idstr[16];
1038
1039int
1040sys_getpid(tcp)
1041struct tcb *tcp;
1042{
1043 if (exiting(tcp)) {
1044 sprintf(idstr, "ppid %lu", getrval2(tcp));
1045 tcp->auxstr = idstr;
1046 return RVAL_STR;
1047 }
1048 return 0;
1049}
1050
1051int
1052sys_getuid(tcp)
1053struct tcb *tcp;
1054{
1055 if (exiting(tcp)) {
1056 sprintf(idstr, "euid %lu", getrval2(tcp));
1057 tcp->auxstr = idstr;
1058 return RVAL_STR;
1059 }
1060 return 0;
1061}
1062
1063int
1064sys_getgid(tcp)
1065struct tcb *tcp;
1066{
1067 if (exiting(tcp)) {
1068 sprintf(idstr, "egid %lu", getrval2(tcp));
1069 tcp->auxstr = idstr;
1070 return RVAL_STR;
1071 }
1072 return 0;
1073}
1074
1075#endif /* !LINUX */
1076
1077#ifdef LINUX
1078
1079int
1080sys_setuid(tcp)
1081struct tcb *tcp;
1082{
1083 if (entering(tcp)) {
1084 tprintf("%u", (uid_t) tcp->u_arg[0]);
1085 }
1086 return 0;
1087}
1088
1089int
1090sys_setgid(tcp)
1091struct tcb *tcp;
1092{
1093 if (entering(tcp)) {
1094 tprintf("%u", (gid_t) tcp->u_arg[0]);
1095 }
1096 return 0;
1097}
1098
1099int
1100sys_getresuid(tcp)
1101 struct tcb *tcp;
1102{
1103 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001104 __kernel_uid_t uid;
1105 if (syserror(tcp))
1106 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1107 tcp->u_arg[1], tcp->u_arg[2]);
1108 else {
1109 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1110 tprintf("%#lx, ", tcp->u_arg[0]);
1111 else
1112 tprintf("ruid %lu, ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001113 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1114 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001115 else
1116 tprintf("euid %lu, ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001117 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1118 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001119 else
1120 tprintf("suid %lu", (unsigned long) uid);
1121 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001122 }
1123 return 0;
1124}
1125
1126int
1127sys_getresgid(tcp)
1128struct tcb *tcp;
1129{
1130 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001131 __kernel_gid_t gid;
1132 if (syserror(tcp))
1133 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1134 tcp->u_arg[1], tcp->u_arg[2]);
1135 else {
1136 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1137 tprintf("%#lx, ", tcp->u_arg[0]);
1138 else
1139 tprintf("rgid %lu, ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001140 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1141 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001142 else
1143 tprintf("egid %lu, ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001144 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1145 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001146 else
1147 tprintf("sgid %lu", (unsigned long) gid);
1148 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001149 }
1150 return 0;
1151}
1152
1153#endif /* LINUX */
1154
1155int
1156sys_setreuid(tcp)
1157struct tcb *tcp;
1158{
1159 if (entering(tcp)) {
1160 tprintf("%lu, %lu",
1161 (unsigned long) (uid_t) tcp->u_arg[0],
1162 (unsigned long) (uid_t) tcp->u_arg[1]);
1163 }
1164 return 0;
1165}
1166
1167int
1168sys_setregid(tcp)
1169struct tcb *tcp;
1170{
1171 if (entering(tcp)) {
1172 tprintf("%lu, %lu",
1173 (unsigned long) (gid_t) tcp->u_arg[0],
1174 (unsigned long) (gid_t) tcp->u_arg[1]);
1175 }
1176 return 0;
1177}
1178
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001179#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001180int
1181sys_setresuid(tcp)
1182 struct tcb *tcp;
1183{
1184 if (entering(tcp)) {
1185 tprintf("ruid %u, euid %u, suid %u",
1186 (uid_t) tcp->u_arg[0],
1187 (uid_t) tcp->u_arg[1],
1188 (uid_t) tcp->u_arg[2]);
1189 }
1190 return 0;
1191}
1192int
1193sys_setresgid(tcp)
1194 struct tcb *tcp;
1195{
1196 if (entering(tcp)) {
1197 tprintf("rgid %u, egid %u, sgid %u",
1198 (uid_t) tcp->u_arg[0],
1199 (uid_t) tcp->u_arg[1],
1200 (uid_t) tcp->u_arg[2]);
1201 }
1202 return 0;
1203}
1204
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001205#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001206
1207int
1208sys_setgroups(tcp)
1209struct tcb *tcp;
1210{
1211 int i, len;
1212 GETGROUPS_T *gidset;
1213
1214 if (entering(tcp)) {
1215 len = tcp->u_arg[0];
1216 tprintf("%u, ", len);
1217 if (len <= 0) {
1218 tprintf("[]");
1219 return 0;
1220 }
1221 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1222 if (gidset == NULL) {
1223 fprintf(stderr, "sys_setgroups: out of memory\n");
1224 return -1;
1225 }
1226 if (!verbose(tcp))
1227 tprintf("%#lx", tcp->u_arg[1]);
1228 else if (umoven(tcp, tcp->u_arg[1],
1229 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1230 tprintf("[?]");
1231 else {
1232 tprintf("[");
1233 for (i = 0; i < len; i++)
1234 tprintf("%s%lu", i ? ", " : "",
1235 (unsigned long) gidset[i]);
1236 tprintf("]");
1237 }
1238 free((char *) gidset);
1239 }
1240 return 0;
1241}
1242
1243int
1244sys_getgroups(tcp)
1245struct tcb *tcp;
1246{
1247 int i, len;
1248 GETGROUPS_T *gidset;
1249
1250 if (entering(tcp)) {
1251 len = tcp->u_arg[0];
1252 tprintf("%u, ", len);
1253 } else {
1254 len = tcp->u_rval;
1255 if (len <= 0) {
1256 tprintf("[]");
1257 return 0;
1258 }
1259 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1260 if (gidset == NULL) {
1261 fprintf(stderr, "sys_getgroups: out of memory\n");
1262 return -1;
1263 }
1264 if (!tcp->u_arg[1])
1265 tprintf("NULL");
1266 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1267 tprintf("%#lx", tcp->u_arg[1]);
1268 else if (umoven(tcp, tcp->u_arg[1],
1269 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1270 tprintf("[?]");
1271 else {
1272 tprintf("[");
1273 for (i = 0; i < len; i++)
1274 tprintf("%s%lu", i ? ", " : "",
1275 (unsigned long) gidset[i]);
1276 tprintf("]");
1277 }
1278 free((char *)gidset);
1279 }
1280 return 0;
1281}
1282
1283int
1284sys_setpgrp(tcp)
1285struct tcb *tcp;
1286{
1287 if (entering(tcp)) {
1288#ifndef SVR4
1289 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1290#endif /* !SVR4 */
1291 }
1292 return 0;
1293}
1294
1295int
1296sys_getpgrp(tcp)
1297struct tcb *tcp;
1298{
1299 if (entering(tcp)) {
1300#ifndef SVR4
1301 tprintf("%lu", tcp->u_arg[0]);
1302#endif /* !SVR4 */
1303 }
1304 return 0;
1305}
1306
1307int
1308sys_getsid(tcp)
1309struct tcb *tcp;
1310{
1311 if (entering(tcp)) {
1312 tprintf("%lu", tcp->u_arg[0]);
1313 }
1314 return 0;
1315}
1316
1317int
1318sys_setsid(tcp)
1319struct tcb *tcp;
1320{
1321 return 0;
1322}
1323
1324int
1325sys_getpgid(tcp)
1326struct tcb *tcp;
1327{
1328 if (entering(tcp)) {
1329 tprintf("%lu", tcp->u_arg[0]);
1330 }
1331 return 0;
1332}
1333
1334int
1335sys_setpgid(tcp)
1336struct tcb *tcp;
1337{
1338 if (entering(tcp)) {
1339 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1340 }
1341 return 0;
1342}
1343
John Hughesc61eb3d2002-05-17 11:37:50 +00001344#if UNIXWARE >= 2
1345
1346#include <sys/privilege.h>
1347
1348
1349static struct xlat procpriv_cmds [] = {
1350 { SETPRV, "SETPRV" },
1351 { CLRPRV, "CLRPRV" },
1352 { PUTPRV, "PUTPRV" },
1353 { GETPRV, "GETPRV" },
1354 { CNTPRV, "CNTPRV" },
1355 { 0, NULL },
1356};
1357
1358
1359static struct xlat procpriv_priv [] = {
1360 { P_OWNER, "P_OWNER" },
1361 { P_AUDIT, "P_AUDIT" },
1362 { P_COMPAT, "P_COMPAT" },
1363 { P_DACREAD, "P_DACREAD" },
1364 { P_DACWRITE, "P_DACWRITE" },
1365 { P_DEV, "P_DEV" },
1366 { P_FILESYS, "P_FILESYS" },
1367 { P_MACREAD, "P_MACREAD" },
1368 { P_MACWRITE, "P_MACWRITE" },
1369 { P_MOUNT, "P_MOUNT" },
1370 { P_MULTIDIR, "P_MULTIDIR" },
1371 { P_SETPLEVEL, "P_SETPLEVEL" },
1372 { P_SETSPRIV, "P_SETSPRIV" },
1373 { P_SETUID, "P_SETUID" },
1374 { P_SYSOPS, "P_SYSOPS" },
1375 { P_SETUPRIV, "P_SETUPRIV" },
1376 { P_DRIVER, "P_DRIVER" },
1377 { P_RTIME, "P_RTIME" },
1378 { P_MACUPGRADE, "P_MACUPGRADE" },
1379 { P_FSYSRANGE, "P_FSYSRANGE" },
1380 { P_SETFLEVEL, "P_SETFLEVEL" },
1381 { P_AUDITWR, "P_AUDITWR" },
1382 { P_TSHAR, "P_TSHAR" },
1383 { P_PLOCK, "P_PLOCK" },
1384 { P_CORE, "P_CORE" },
1385 { P_LOADMOD, "P_LOADMOD" },
1386 { P_BIND, "P_BIND" },
1387 { P_ALLPRIVS, "P_ALLPRIVS" },
1388 { 0, NULL },
1389};
1390
1391
1392static struct xlat procpriv_type [] = {
1393 { PS_FIX, "PS_FIX" },
1394 { PS_INH, "PS_INH" },
1395 { PS_MAX, "PS_MAX" },
1396 { PS_WKG, "PS_WKG" },
1397 { 0, NULL },
1398};
1399
1400
1401static void
1402printpriv(tcp, addr, len, opt)
1403struct tcb *tcp;
1404long addr;
1405int len;
1406struct xlat *opt;
1407{
1408 priv_t buf [128];
1409 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1410 int dots = len > max;
1411 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001412
John Hughesc61eb3d2002-05-17 11:37:50 +00001413 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001414
John Hughesc61eb3d2002-05-17 11:37:50 +00001415 if (len <= 0 ||
1416 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1417 {
1418 tprintf ("%#lx", addr);
1419 return;
1420 }
1421
1422 tprintf ("[");
1423
1424 for (i = 0; i < len; ++i) {
1425 char *t, *p;
1426
1427 if (i) tprintf (", ");
1428
1429 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1430 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1431 {
1432 tprintf ("%s|%s", t, p);
1433 }
1434 else {
1435 tprintf ("%#lx", buf [i]);
1436 }
1437 }
1438
1439 if (dots) tprintf (" ...");
1440
1441 tprintf ("]");
1442}
1443
1444
1445int
1446sys_procpriv(tcp)
1447struct tcb *tcp;
1448{
1449 if (entering(tcp)) {
1450 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1451 switch (tcp->u_arg[0]) {
1452 case CNTPRV:
1453 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1454 break;
1455
1456 case GETPRV:
1457 break;
1458
1459 default:
1460 tprintf (", ");
1461 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1462 tprintf (", %ld", tcp->u_arg[2]);
1463 }
1464 }
1465 else if (tcp->u_arg[0] == GETPRV) {
1466 if (syserror (tcp)) {
1467 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1468 }
1469 else {
1470 tprintf (", ");
1471 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1472 tprintf (", %ld", tcp->u_arg[2]);
1473 }
1474 }
Roland McGrath5a223472002-12-15 23:58:26 +00001475
John Hughesc61eb3d2002-05-17 11:37:50 +00001476 return 0;
1477}
1478
1479#endif
1480
1481
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001482void
1483fake_execve(tcp, program, argv, envp)
1484struct tcb *tcp;
1485char *program;
1486char *argv[];
1487char *envp[];
1488{
1489 int i;
1490
1491#ifdef ARM
1492 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1493 return;
1494#else
1495 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1496 return;
1497#endif /* !ARM */
1498 printleader(tcp);
1499 tprintf("execve(");
1500 string_quote(program);
1501 tprintf(", [");
1502 for (i = 0; argv[i] != NULL; i++) {
1503 if (i != 0)
1504 tprintf(", ");
1505 string_quote(argv[i]);
1506 }
1507 for (i = 0; envp[i] != NULL; i++)
1508 ;
1509 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1510 tabto(acolumn);
1511 tprintf("= 0");
1512 printtrailer(tcp);
1513}
1514
1515static void
1516printargv(tcp, addr)
1517struct tcb *tcp;
1518long addr;
1519{
1520 char *cp;
1521 char *sep;
1522 int max = max_strlen / 2;
1523
1524 for (sep = ""; --max >= 0; sep = ", ") {
1525 if (!abbrev(tcp))
1526 max++;
1527 if (umove(tcp, addr, &cp) < 0) {
1528 tprintf("%#lx", addr);
1529 return;
1530 }
1531 if (cp == 0)
1532 break;
1533 tprintf(sep);
1534 printstr(tcp, (long) cp, -1);
1535 addr += sizeof(char *);
1536 }
1537 if (cp)
1538 tprintf(", ...");
1539}
1540
1541static void
1542printargc(fmt, tcp, addr)
1543char *fmt;
1544struct tcb *tcp;
1545long addr;
1546{
1547 int count;
1548 char *cp;
1549
1550 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1551 addr += sizeof(char *);
1552 }
1553 tprintf(fmt, count, count == 1 ? "" : "s");
1554}
1555
1556int
1557sys_execv(tcp)
1558struct tcb *tcp;
1559{
1560 if (entering(tcp)) {
1561 printpath(tcp, tcp->u_arg[0]);
1562 if (!verbose(tcp))
1563 tprintf(", %#lx", tcp->u_arg[1]);
1564#if 0
1565 else if (abbrev(tcp))
1566 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1567#endif
1568 else {
1569 tprintf(", [");
1570 printargv(tcp, tcp->u_arg[1]);
1571 tprintf("]");
1572 }
1573 }
1574 return 0;
1575}
1576
1577int
1578sys_execve(tcp)
1579struct tcb *tcp;
1580{
1581 if (entering(tcp)) {
1582 printpath(tcp, tcp->u_arg[0]);
1583 if (!verbose(tcp))
1584 tprintf(", %#lx", tcp->u_arg[1]);
1585#if 0
1586 else if (abbrev(tcp))
1587 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1588#endif
1589 else {
1590 tprintf(", [");
1591 printargv(tcp, tcp->u_arg[1]);
1592 tprintf("]");
1593 }
1594 if (!verbose(tcp))
1595 tprintf(", %#lx", tcp->u_arg[2]);
1596 else if (abbrev(tcp))
1597 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1598 else {
1599 tprintf(", [");
1600 printargv(tcp, tcp->u_arg[2]);
1601 tprintf("]");
1602 }
1603 }
Roland McGrathb4968be2003-01-20 09:04:33 +00001604#if defined LINUX && defined TCB_WAITEXECVE
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001605 tcp->flags |= TCB_WAITEXECVE;
Roland McGrathb4968be2003-01-20 09:04:33 +00001606#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001607 return 0;
1608}
1609
John Hughes4e36a812001-04-18 15:11:51 +00001610#if UNIXWARE > 2
1611
1612int sys_rexecve(tcp)
1613struct tcb *tcp;
1614{
1615 if (entering (tcp)) {
1616 sys_execve (tcp);
1617 tprintf (", %ld", tcp->u_arg[3]);
1618 }
1619 return 0;
1620}
1621
1622#endif
1623
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001624int
1625internal_exec(tcp)
1626struct tcb *tcp;
1627{
1628#ifdef SUNOS4
1629 if (exiting(tcp) && !syserror(tcp) && followfork)
1630 fixvfork(tcp);
1631#endif /* SUNOS4 */
1632 return 0;
1633}
1634
1635#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001636#ifndef __WNOTHREAD
1637#define __WNOTHREAD 0x20000000
1638#endif
1639#ifndef __WALL
1640#define __WALL 0x40000000
1641#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001642#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001643#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001644#endif
1645#endif /* LINUX */
1646
1647static struct xlat wait4_options[] = {
1648 { WNOHANG, "WNOHANG" },
1649#ifndef WSTOPPED
1650 { WUNTRACED, "WUNTRACED" },
1651#endif
1652#ifdef WEXITED
1653 { WEXITED, "WEXITED" },
1654#endif
1655#ifdef WTRAPPED
1656 { WTRAPPED, "WTRAPPED" },
1657#endif
1658#ifdef WSTOPPED
1659 { WSTOPPED, "WSTOPPED" },
1660#endif
1661#ifdef WCONTINUED
1662 { WCONTINUED, "WCONTINUED" },
1663#endif
1664#ifdef WNOWAIT
1665 { WNOWAIT, "WNOWAIT" },
1666#endif
1667#ifdef __WCLONE
1668 { __WCLONE, "__WCLONE" },
1669#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001670#ifdef __WALL
1671 { __WALL, "__WALL" },
1672#endif
1673#ifdef __WNOTHREAD
1674 { __WNOTHREAD, "__WNOTHREAD" },
1675#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001676 { 0, NULL },
1677};
1678
1679static int
1680printstatus(status)
1681int status;
1682{
1683 int exited = 0;
1684
1685 /*
1686 * Here is a tricky presentation problem. This solution
1687 * is still not entirely satisfactory but since there
1688 * are no wait status constructors it will have to do.
1689 */
1690 if (WIFSTOPPED(status))
1691 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001692 signame(WSTOPSIG(status)));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001693 else if WIFSIGNALED(status)
1694 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001695 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001696 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1697 else if WIFEXITED(status) {
1698 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1699 WEXITSTATUS(status));
1700 exited = 1;
1701 }
1702 else
1703 tprintf("[%#x]", status);
1704 return exited;
1705}
1706
1707static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001708printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001709struct tcb *tcp;
1710int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001711int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001712{
1713 int status;
1714 int exited = 0;
1715
1716 if (entering(tcp)) {
1717 tprintf("%ld, ", tcp->u_arg[0]);
1718 } else {
1719 /* status */
1720 if (!tcp->u_arg[1])
1721 tprintf("NULL");
1722 else if (syserror(tcp) || tcp->u_rval == 0)
1723 tprintf("%#lx", tcp->u_arg[1]);
1724 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1725 tprintf("[?]");
1726 else
1727 exited = printstatus(status);
1728 /* options */
1729 tprintf(", ");
1730 if (!printflags(wait4_options, tcp->u_arg[2]))
1731 tprintf("0");
1732 if (n == 4) {
1733 tprintf(", ");
1734 /* usage */
1735 if (!tcp->u_arg[3])
1736 tprintf("NULL");
1737#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001738 else if (tcp->u_rval > 0) {
1739#ifdef LINUX_64BIT
1740 if (bitness)
1741 printrusage32(tcp, tcp->u_arg[3]);
1742 else
1743#endif
1744 printrusage(tcp, tcp->u_arg[3]);
1745 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001746#endif /* LINUX */
1747#ifdef SUNOS4
1748 else if (tcp->u_rval > 0 && exited)
1749 printrusage(tcp, tcp->u_arg[3]);
1750#endif /* SUNOS4 */
1751 else
1752 tprintf("%#lx", tcp->u_arg[3]);
1753 }
1754 }
1755 return 0;
1756}
1757
1758int
1759internal_wait(tcp)
1760struct tcb *tcp;
1761{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001762 int got_kids;
1763
1764#ifdef TCB_CLONE_THREAD
1765 if (tcp->flags & TCB_CLONE_THREAD)
1766 /* The children we wait for are our parent's children. */
1767 got_kids = (tcp->parent->nchildren
1768 > tcp->parent->nclone_detached);
1769 else
1770 got_kids = (tcp->nchildren > tcp->nclone_detached);
1771#else
1772 got_kids = tcp->nchildren > 0;
1773#endif
1774
1775 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001776 /* There are children that this parent should block for.
1777 But ptrace made us the parent of the traced children
1778 and the real parent will get ECHILD from the wait call.
1779
1780 XXX If we attached with strace -f -p PID, then there
1781 may be untraced dead children the parent could be reaping
1782 now, but we make him block. */
1783
1784 /* ??? WTA: fix bug with hanging children */
1785
1786 if (!(tcp->u_arg[2] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00001787 /*
1788 * There are traced children. We'll make the parent
1789 * block to avoid a false ECHILD error due to our
1790 * ptrace having stolen the children. However,
1791 * we shouldn't block if there are zombies to reap.
1792 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1793 */
1794 if (tcp->nzombies > 0 &&
1795 (tcp->u_arg[0] == -1 ||
1796 pid2tcb(tcp->u_arg[0]) == NULL))
1797 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001798 tcp->flags |= TCB_SUSPENDED;
1799 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001800#ifdef TCB_CLONE_THREAD
1801 if (tcp->flags & TCB_CLONE_THREAD)
1802 tcp->parent->nclone_waiting++;
1803#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001804 }
1805 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001806 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001807 if (tcp->u_arg[2] & WNOHANG) {
1808 /* We must force a fake result of 0 instead of
1809 the ECHILD error. */
1810 extern int force_result();
1811 return force_result(tcp, 0, 0);
1812 }
1813 else
1814 fprintf(stderr,
1815 "internal_wait: should not have resumed %d\n",
1816 tcp->pid);
1817 }
Roland McGrath09623452003-05-23 02:27:13 +00001818 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
1819 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
1820 /*
1821 * We just reaped a child we don't know about,
1822 * presumably a zombie we already droptcb'd.
1823 */
1824 tcp->nzombies--;
1825 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001826 return 0;
1827}
1828
1829#ifdef SVR4
1830
1831int
1832sys_wait(tcp)
1833struct tcb *tcp;
1834{
1835 if (exiting(tcp)) {
1836 /* The library wrapper stuffs this into the user variable. */
1837 if (!syserror(tcp))
1838 printstatus(getrval2(tcp));
1839 }
1840 return 0;
1841}
1842
1843#endif /* SVR4 */
1844
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001845#ifdef FREEBSD
1846int
1847sys_wait(tcp)
1848struct tcb *tcp;
1849{
1850 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001851
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001852 if (exiting(tcp)) {
1853 if (!syserror(tcp)) {
1854 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1855 tprintf("%#lx", tcp->u_arg[0]);
1856 else
1857 printstatus(status);
1858 }
1859 }
1860 return 0;
1861}
1862#endif
1863
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001864int
1865sys_waitpid(tcp)
1866struct tcb *tcp;
1867{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001868 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001869}
1870
1871int
1872sys_wait4(tcp)
1873struct tcb *tcp;
1874{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001875 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001876}
1877
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001878#ifdef ALPHA
1879int
1880sys_osf_wait4(tcp)
1881struct tcb *tcp;
1882{
1883 return printwaitn(tcp, 4, 1);
1884}
1885#endif
1886
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001887#ifdef SVR4
1888
1889static struct xlat waitid_types[] = {
1890 { P_PID, "P_PID" },
1891 { P_PPID, "P_PPID" },
1892 { P_PGID, "P_PGID" },
1893 { P_SID, "P_SID" },
1894 { P_CID, "P_CID" },
1895 { P_UID, "P_UID" },
1896 { P_GID, "P_GID" },
1897 { P_ALL, "P_ALL" },
1898#ifdef P_LWPID
1899 { P_LWPID, "P_LWPID" },
1900#endif
1901 { 0, NULL },
1902};
1903
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001904int
1905sys_waitid(tcp)
1906struct tcb *tcp;
1907{
1908 siginfo_t si;
1909 int exited;
1910
1911 if (entering(tcp)) {
1912 printxval(waitid_types, tcp->u_arg[0], "P_???");
1913 tprintf(", %ld, ", tcp->u_arg[1]);
1914 if (tcp->nchildren > 0) {
1915 /* There are traced children */
1916 tcp->flags |= TCB_SUSPENDED;
1917 tcp->waitpid = tcp->u_arg[0];
1918 }
1919 }
1920 else {
1921 /* siginfo */
1922 exited = 0;
1923 if (!tcp->u_arg[2])
1924 tprintf("NULL");
1925 else if (syserror(tcp))
1926 tprintf("%#lx", tcp->u_arg[2]);
1927 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1928 tprintf("{???}");
1929 else
John Hughes58265892001-10-18 15:13:53 +00001930 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001931 /* options */
1932 tprintf(", ");
1933 if (!printflags(wait4_options, tcp->u_arg[3]))
1934 tprintf("0");
1935 }
1936 return 0;
1937}
1938
1939#endif /* SVR4 */
1940
1941int
1942sys_alarm(tcp)
1943struct tcb *tcp;
1944{
1945 if (entering(tcp))
1946 tprintf("%lu", tcp->u_arg[0]);
1947 return 0;
1948}
1949
1950int
1951sys_uname(tcp)
1952struct tcb *tcp;
1953{
1954 struct utsname uname;
1955
1956 if (exiting(tcp)) {
1957 if (syserror(tcp) || !verbose(tcp))
1958 tprintf("%#lx", tcp->u_arg[0]);
1959 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1960 tprintf("{...}");
1961 else if (!abbrev(tcp)) {
1962
1963 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1964 uname.sysname, uname.nodename);
1965 tprintf("release=\"%s\", version=\"%s\", ",
1966 uname.release, uname.version);
1967 tprintf("machine=\"%s\"", uname.machine);
1968#ifdef LINUX
1969#ifndef __GLIBC__
1970 tprintf(", domainname=\"%s\"", uname.domainname);
1971#endif /* __GLIBC__ */
1972#endif /* LINUX */
1973 tprintf("}");
1974 }
1975 else
1976 tprintf("{sys=\"%s\", node=\"%s\", ...}",
1977 uname.sysname, uname.nodename);
1978 }
1979 return 0;
1980}
1981
1982#ifndef SVR4
1983
1984static struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00001985#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001986 { PTRACE_TRACEME, "PTRACE_TRACEME" },
1987 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
1988 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
1989 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
1990 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
1991 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
1992 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
1993 { PTRACE_CONT, "PTRACE_CONT" },
1994 { PTRACE_KILL, "PTRACE_KILL" },
1995 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
1996 { PTRACE_ATTACH, "PTRACE_ATTACH" },
1997 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001998#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001999 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002000#endif
2001#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002002 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002003#endif
2004#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002005 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002006#endif
2007#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002008 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002009#endif
2010#ifdef PTRACE_GETFPXREGS
2011 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2012#endif
2013#ifdef PTRACE_SETFPXREGS
2014 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2015#endif
2016#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002017 { PTRACE_READDATA, "PTRACE_READDATA" },
2018 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2019 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2020 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2021 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2022 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2023#ifdef SPARC
2024 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2025 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2026#else /* !SPARC */
2027 { PTRACE_22, "PTRACE_PTRACE_22" },
2028 { PTRACE_23, "PTRACE_PTRACE_23" },
2029#endif /* !SPARC */
2030#endif /* SUNOS4 */
2031 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2032#ifdef SUNOS4
2033 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2034#ifdef I386
2035 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2036 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2037 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2038#else /* !I386 */
2039 { PTRACE_26, "PTRACE_26" },
2040 { PTRACE_27, "PTRACE_27" },
2041 { PTRACE_28, "PTRACE_28" },
2042#endif /* !I386 */
2043 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2044#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002045#else /* FREEBSD */
2046 { PT_TRACE_ME, "PT_TRACE_ME" },
2047 { PT_READ_I, "PT_READ_I" },
2048 { PT_READ_D, "PT_READ_D" },
2049 { PT_WRITE_I, "PT_WRITE_I" },
2050 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002051#ifdef PT_READ_U
2052 { PT_READ_U, "PT_READ_U" },
2053#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002054 { PT_CONTINUE, "PT_CONTINUE" },
2055 { PT_KILL, "PT_KILL" },
2056 { PT_STEP, "PT_STEP" },
2057 { PT_ATTACH, "PT_ATTACH" },
2058 { PT_DETACH, "PT_DETACH" },
2059 { PT_GETREGS, "PT_GETREGS" },
2060 { PT_SETREGS, "PT_SETREGS" },
2061 { PT_GETFPREGS, "PT_GETFPREGS" },
2062 { PT_SETFPREGS, "PT_SETFPREGS" },
2063 { PT_GETDBREGS, "PT_GETDBREGS" },
2064 { PT_SETDBREGS, "PT_SETDBREGS" },
2065#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002066 { 0, NULL },
2067};
2068
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002069#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002070#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2071static
2072#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2073struct xlat struct_user_offsets[] = {
2074#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002075#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002076 { PT_PSWMASK, "psw_mask" },
2077 { PT_PSWADDR, "psw_addr" },
2078 { PT_GPR0, "gpr0" },
2079 { PT_GPR1, "gpr1" },
2080 { PT_GPR2, "gpr2" },
2081 { PT_GPR3, "gpr3" },
2082 { PT_GPR4, "gpr4" },
2083 { PT_GPR5, "gpr5" },
2084 { PT_GPR6, "gpr6" },
2085 { PT_GPR7, "gpr7" },
2086 { PT_GPR8, "gpr8" },
2087 { PT_GPR9, "gpr9" },
2088 { PT_GPR10, "gpr10" },
2089 { PT_GPR11, "gpr11" },
2090 { PT_GPR12, "gpr12" },
2091 { PT_GPR13, "gpr13" },
2092 { PT_GPR14, "gpr14" },
2093 { PT_GPR15, "gpr15" },
2094 { PT_ACR0, "acr0" },
2095 { PT_ACR1, "acr1" },
2096 { PT_ACR2, "acr2" },
2097 { PT_ACR3, "acr3" },
2098 { PT_ACR4, "acr4" },
2099 { PT_ACR5, "acr5" },
2100 { PT_ACR6, "acr6" },
2101 { PT_ACR7, "acr7" },
2102 { PT_ACR8, "acr8" },
2103 { PT_ACR9, "acr9" },
2104 { PT_ACR10, "acr10" },
2105 { PT_ACR11, "acr11" },
2106 { PT_ACR12, "acr12" },
2107 { PT_ACR13, "acr13" },
2108 { PT_ACR14, "acr14" },
2109 { PT_ACR15, "acr15" },
2110 { PT_ORIGGPR2, "orig_gpr2" },
2111 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002112#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002113 { PT_FPR0_HI, "fpr0.hi" },
2114 { PT_FPR0_LO, "fpr0.lo" },
2115 { PT_FPR1_HI, "fpr1.hi" },
2116 { PT_FPR1_LO, "fpr1.lo" },
2117 { PT_FPR2_HI, "fpr2.hi" },
2118 { PT_FPR2_LO, "fpr2.lo" },
2119 { PT_FPR3_HI, "fpr3.hi" },
2120 { PT_FPR3_LO, "fpr3.lo" },
2121 { PT_FPR4_HI, "fpr4.hi" },
2122 { PT_FPR4_LO, "fpr4.lo" },
2123 { PT_FPR5_HI, "fpr5.hi" },
2124 { PT_FPR5_LO, "fpr5.lo" },
2125 { PT_FPR6_HI, "fpr6.hi" },
2126 { PT_FPR6_LO, "fpr6.lo" },
2127 { PT_FPR7_HI, "fpr7.hi" },
2128 { PT_FPR7_LO, "fpr7.lo" },
2129 { PT_FPR8_HI, "fpr8.hi" },
2130 { PT_FPR8_LO, "fpr8.lo" },
2131 { PT_FPR9_HI, "fpr9.hi" },
2132 { PT_FPR9_LO, "fpr9.lo" },
2133 { PT_FPR10_HI, "fpr10.hi" },
2134 { PT_FPR10_LO, "fpr10.lo" },
2135 { PT_FPR11_HI, "fpr11.hi" },
2136 { PT_FPR11_LO, "fpr11.lo" },
2137 { PT_FPR12_HI, "fpr12.hi" },
2138 { PT_FPR12_LO, "fpr12.lo" },
2139 { PT_FPR13_HI, "fpr13.hi" },
2140 { PT_FPR13_LO, "fpr13.lo" },
2141 { PT_FPR14_HI, "fpr14.hi" },
2142 { PT_FPR14_LO, "fpr14.lo" },
2143 { PT_FPR15_HI, "fpr15.hi" },
2144 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002145#endif
2146#if defined(S390X)
2147 { PT_FPR0, "fpr0" },
2148 { PT_FPR1, "fpr1" },
2149 { PT_FPR2, "fpr2" },
2150 { PT_FPR3, "fpr3" },
2151 { PT_FPR4, "fpr4" },
2152 { PT_FPR5, "fpr5" },
2153 { PT_FPR6, "fpr6" },
2154 { PT_FPR7, "fpr7" },
2155 { PT_FPR8, "fpr8" },
2156 { PT_FPR9, "fpr9" },
2157 { PT_FPR10, "fpr10" },
2158 { PT_FPR11, "fpr11" },
2159 { PT_FPR12, "fpr12" },
2160 { PT_FPR13, "fpr13" },
2161 { PT_FPR14, "fpr14" },
2162 { PT_FPR15, "fpr15" },
2163#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002164 { PT_CR_9, "cr9" },
2165 { PT_CR_10, "cr10" },
2166 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002167 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002168#endif
2169#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002170 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002171#elif defined(HPPA)
2172 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002173#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002174#ifndef PT_ORIG_R3
2175#define PT_ORIG_R3 34
2176#endif
Roland McGratheb285352003-01-14 09:59:00 +00002177#define REGSIZE (sizeof(unsigned long))
2178 { REGSIZE*PT_R0, "r0" },
2179 { REGSIZE*PT_R1, "r1" },
2180 { REGSIZE*PT_R2, "r2" },
2181 { REGSIZE*PT_R3, "r3" },
2182 { REGSIZE*PT_R4, "r4" },
2183 { REGSIZE*PT_R5, "r5" },
2184 { REGSIZE*PT_R6, "r6" },
2185 { REGSIZE*PT_R7, "r7" },
2186 { REGSIZE*PT_R8, "r8" },
2187 { REGSIZE*PT_R9, "r9" },
2188 { REGSIZE*PT_R10, "r10" },
2189 { REGSIZE*PT_R11, "r11" },
2190 { REGSIZE*PT_R12, "r12" },
2191 { REGSIZE*PT_R13, "r13" },
2192 { REGSIZE*PT_R14, "r14" },
2193 { REGSIZE*PT_R15, "r15" },
2194 { REGSIZE*PT_R16, "r16" },
2195 { REGSIZE*PT_R17, "r17" },
2196 { REGSIZE*PT_R18, "r18" },
2197 { REGSIZE*PT_R19, "r19" },
2198 { REGSIZE*PT_R20, "r20" },
2199 { REGSIZE*PT_R21, "r21" },
2200 { REGSIZE*PT_R22, "r22" },
2201 { REGSIZE*PT_R23, "r23" },
2202 { REGSIZE*PT_R24, "r24" },
2203 { REGSIZE*PT_R25, "r25" },
2204 { REGSIZE*PT_R26, "r26" },
2205 { REGSIZE*PT_R27, "r27" },
2206 { REGSIZE*PT_R28, "r28" },
2207 { REGSIZE*PT_R29, "r29" },
2208 { REGSIZE*PT_R30, "r30" },
2209 { REGSIZE*PT_R31, "r31" },
2210 { REGSIZE*PT_NIP, "NIP" },
2211 { REGSIZE*PT_MSR, "MSR" },
2212 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2213 { REGSIZE*PT_CTR, "CTR" },
2214 { REGSIZE*PT_LNK, "LNK" },
2215 { REGSIZE*PT_XER, "XER" },
2216 { REGSIZE*PT_CCR, "CCR" },
2217 { REGSIZE*PT_FPR0, "FPR0" },
2218#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002219#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002220#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002221 { 0, "r0" },
2222 { 1, "r1" },
2223 { 2, "r2" },
2224 { 3, "r3" },
2225 { 4, "r4" },
2226 { 5, "r5" },
2227 { 6, "r6" },
2228 { 7, "r7" },
2229 { 8, "r8" },
2230 { 9, "r9" },
2231 { 10, "r10" },
2232 { 11, "r11" },
2233 { 12, "r12" },
2234 { 13, "r13" },
2235 { 14, "r14" },
2236 { 15, "r15" },
2237 { 16, "r16" },
2238 { 17, "r17" },
2239 { 18, "r18" },
2240 { 19, "r19" },
2241 { 20, "r20" },
2242 { 21, "r21" },
2243 { 22, "r22" },
2244 { 23, "r23" },
2245 { 24, "r24" },
2246 { 25, "r25" },
2247 { 26, "r26" },
2248 { 27, "r27" },
2249 { 28, "r28" },
2250 { 29, "gp" },
2251 { 30, "fp" },
2252 { 31, "zero" },
2253 { 32, "fp0" },
2254 { 33, "fp" },
2255 { 34, "fp2" },
2256 { 35, "fp3" },
2257 { 36, "fp4" },
2258 { 37, "fp5" },
2259 { 38, "fp6" },
2260 { 39, "fp7" },
2261 { 40, "fp8" },
2262 { 41, "fp9" },
2263 { 42, "fp10" },
2264 { 43, "fp11" },
2265 { 44, "fp12" },
2266 { 45, "fp13" },
2267 { 46, "fp14" },
2268 { 47, "fp15" },
2269 { 48, "fp16" },
2270 { 49, "fp17" },
2271 { 50, "fp18" },
2272 { 51, "fp19" },
2273 { 52, "fp20" },
2274 { 53, "fp21" },
2275 { 54, "fp22" },
2276 { 55, "fp23" },
2277 { 56, "fp24" },
2278 { 57, "fp25" },
2279 { 58, "fp26" },
2280 { 59, "fp27" },
2281 { 60, "fp28" },
2282 { 61, "fp29" },
2283 { 62, "fp30" },
2284 { 63, "fp31" },
2285 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002286#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002287#ifdef IA64
2288 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2289 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2290 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2291 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2292 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2293 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2294 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2295 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2296 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2297 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2298 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2299 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2300 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2301 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2302 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2303 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2304 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2305 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2306 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2307 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2308 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2309 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2310 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2311 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2312 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2313 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2314 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2315 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2316 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2317 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2318 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2319 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2320 /* switch stack: */
2321 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2322 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2323 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2324 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2325 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2326 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2327 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2328 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2329 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2330 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002331 { PT_B0, "kb0" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002332 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2333 { PT_B4, "b4" }, { PT_B5, "b5" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002334 { PT_AR_PFS, "kar.pfs" },
2335 { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" },
2336 { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" },
2337 { PT_PR, "k.pr" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002338 /* pt_regs */
2339 { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002340 /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002341 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2342 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2343 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2344 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2345 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2346 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2347 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2348 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2349 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2350 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2351 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2352 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2353 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2354 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2355 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2356#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002357#ifdef I386
2358 { 4*EBX, "4*EBX" },
2359 { 4*ECX, "4*ECX" },
2360 { 4*EDX, "4*EDX" },
2361 { 4*ESI, "4*ESI" },
2362 { 4*EDI, "4*EDI" },
2363 { 4*EBP, "4*EBP" },
2364 { 4*EAX, "4*EAX" },
2365 { 4*DS, "4*DS" },
2366 { 4*ES, "4*ES" },
2367 { 4*FS, "4*FS" },
2368 { 4*GS, "4*GS" },
2369 { 4*ORIG_EAX, "4*ORIG_EAX" },
2370 { 4*EIP, "4*EIP" },
2371 { 4*CS, "4*CS" },
2372 { 4*EFL, "4*EFL" },
2373 { 4*UESP, "4*UESP" },
2374 { 4*SS, "4*SS" },
2375#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002376#ifdef X86_64
2377 { 8*RDI, "8*RDI" },
2378 { 8*RSI, "8*RSI" },
2379 { 8*RDX, "8*RDX" },
2380 { 8*R10, "8*R10" },
2381 { 8*R8, "8*R8" },
2382 { 8*R9, "8*R9" },
2383 { 8*RBX, "8*RBX" },
2384 { 8*RCX, "8*RCX" },
2385 { 8*RBP, "8*RBP" },
2386 { 8*RAX, "8*RAX" },
2387#if 0
2388 { 8*DS, "8*DS" },
2389 { 8*ES, "8*ES" },
2390 { 8*FS, "8*FS" },
2391 { 8*GS, "8*GS" },
2392#endif
2393 { 8*ORIG_RAX, "8*ORIG_EAX" },
2394 { 8*RIP, "8*RIP" },
2395 { 8*CS, "8*CS" },
2396 { 8*EFLAGS, "8*EFL" },
2397 { 8*RSP, "8*RSP" },
2398 { 8*SS, "8*SS" },
2399 { 8*R11, "8*R11" },
2400 { 8*R12, "8*R12" },
2401 { 8*R13, "8*R13" },
2402 { 8*R14, "8*R14" },
2403 { 8*R15, "8*R15" },
2404#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002405#ifdef M68K
2406 { 4*PT_D1, "4*PT_D1" },
2407 { 4*PT_D2, "4*PT_D2" },
2408 { 4*PT_D3, "4*PT_D3" },
2409 { 4*PT_D4, "4*PT_D4" },
2410 { 4*PT_D5, "4*PT_D5" },
2411 { 4*PT_D6, "4*PT_D6" },
2412 { 4*PT_D7, "4*PT_D7" },
2413 { 4*PT_A0, "4*PT_A0" },
2414 { 4*PT_A1, "4*PT_A1" },
2415 { 4*PT_A2, "4*PT_A2" },
2416 { 4*PT_A3, "4*PT_A3" },
2417 { 4*PT_A4, "4*PT_A4" },
2418 { 4*PT_A5, "4*PT_A5" },
2419 { 4*PT_A6, "4*PT_A6" },
2420 { 4*PT_D0, "4*PT_D0" },
2421 { 4*PT_USP, "4*PT_USP" },
2422 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2423 { 4*PT_SR, "4*PT_SR" },
2424 { 4*PT_PC, "4*PT_PC" },
2425#endif /* M68K */
2426#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002427#ifdef SH
2428 { 4*REG_REG0, "4*REG_REG0" },
2429 { 4*(REG_REG0+1), "4*REG_REG1" },
2430 { 4*(REG_REG0+2), "4*REG_REG2" },
2431 { 4*(REG_REG0+3), "4*REG_REG3" },
2432 { 4*(REG_REG0+4), "4*REG_REG4" },
2433 { 4*(REG_REG0+5), "4*REG_REG5" },
2434 { 4*(REG_REG0+6), "4*REG_REG6" },
2435 { 4*(REG_REG0+7), "4*REG_REG7" },
2436 { 4*(REG_REG0+8), "4*REG_REG8" },
2437 { 4*(REG_REG0+9), "4*REG_REG9" },
2438 { 4*(REG_REG0+10), "4*REG_REG10" },
2439 { 4*(REG_REG0+11), "4*REG_REG11" },
2440 { 4*(REG_REG0+12), "4*REG_REG12" },
2441 { 4*(REG_REG0+13), "4*REG_REG13" },
2442 { 4*(REG_REG0+14), "4*REG_REG14" },
2443 { 4*REG_REG15, "4*REG_REG15" },
2444 { 4*REG_PC, "4*REG_PC" },
2445 { 4*REG_PR, "4*REG_PR" },
2446 { 4*REG_SR, "4*REG_SR" },
2447 { 4*REG_GBR, "4*REG_GBR" },
2448 { 4*REG_MACH, "4*REG_MACH" },
2449 { 4*REG_MACL, "4*REG_MACL" },
2450 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2451 { 4*REG_FPUL, "4*REG_FPUL" },
2452 { 4*REG_FPREG0, "4*REG_FPREG0" },
2453 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2454 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2455 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2456 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2457 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2458 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2459 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2460 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2461 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2462 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2463 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2464 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2465 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2466 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2467 { 4*REG_FPREG15, "4*REG_FPREG15" },
2468 { 4*REG_XDREG0, "4*REG_XDREG0" },
2469 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2470 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2471 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2472 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2473 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2474 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2475 { 4*REG_XDREG14, "4*REG_XDREG14" },
2476 { 4*REG_FPSCR, "4*REG_FPSCR" },
2477#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002478#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002479 { 0, "PC(L)" },
2480 { 4, "PC(U)" },
2481 { 8, "SR(L)" },
2482 { 12, "SR(U)" },
2483 { 16, "syscall no.(L)" },
2484 { 20, "syscall_no.(U)" },
2485 { 24, "R0(L)" },
2486 { 28, "R0(U)" },
2487 { 32, "R1(L)" },
2488 { 36, "R1(U)" },
2489 { 40, "R2(L)" },
2490 { 44, "R2(U)" },
2491 { 48, "R3(L)" },
2492 { 52, "R3(U)" },
2493 { 56, "R4(L)" },
2494 { 60, "R4(U)" },
2495 { 64, "R5(L)" },
2496 { 68, "R5(U)" },
2497 { 72, "R6(L)" },
2498 { 76, "R6(U)" },
2499 { 80, "R7(L)" },
2500 { 84, "R7(U)" },
2501 { 88, "R8(L)" },
2502 { 92, "R8(U)" },
2503 { 96, "R9(L)" },
2504 { 100, "R9(U)" },
2505 { 104, "R10(L)" },
2506 { 108, "R10(U)" },
2507 { 112, "R11(L)" },
2508 { 116, "R11(U)" },
2509 { 120, "R12(L)" },
2510 { 124, "R12(U)" },
2511 { 128, "R13(L)" },
2512 { 132, "R13(U)" },
2513 { 136, "R14(L)" },
2514 { 140, "R14(U)" },
2515 { 144, "R15(L)" },
2516 { 148, "R15(U)" },
2517 { 152, "R16(L)" },
2518 { 156, "R16(U)" },
2519 { 160, "R17(L)" },
2520 { 164, "R17(U)" },
2521 { 168, "R18(L)" },
2522 { 172, "R18(U)" },
2523 { 176, "R19(L)" },
2524 { 180, "R19(U)" },
2525 { 184, "R20(L)" },
2526 { 188, "R20(U)" },
2527 { 192, "R21(L)" },
2528 { 196, "R21(U)" },
2529 { 200, "R22(L)" },
2530 { 204, "R22(U)" },
2531 { 208, "R23(L)" },
2532 { 212, "R23(U)" },
2533 { 216, "R24(L)" },
2534 { 220, "R24(U)" },
2535 { 224, "R25(L)" },
2536 { 228, "R25(U)" },
2537 { 232, "R26(L)" },
2538 { 236, "R26(U)" },
2539 { 240, "R27(L)" },
2540 { 244, "R27(U)" },
2541 { 248, "R28(L)" },
2542 { 252, "R28(U)" },
2543 { 256, "R29(L)" },
2544 { 260, "R29(U)" },
2545 { 264, "R30(L)" },
2546 { 268, "R30(U)" },
2547 { 272, "R31(L)" },
2548 { 276, "R31(U)" },
2549 { 280, "R32(L)" },
2550 { 284, "R32(U)" },
2551 { 288, "R33(L)" },
2552 { 292, "R33(U)" },
2553 { 296, "R34(L)" },
2554 { 300, "R34(U)" },
2555 { 304, "R35(L)" },
2556 { 308, "R35(U)" },
2557 { 312, "R36(L)" },
2558 { 316, "R36(U)" },
2559 { 320, "R37(L)" },
2560 { 324, "R37(U)" },
2561 { 328, "R38(L)" },
2562 { 332, "R38(U)" },
2563 { 336, "R39(L)" },
2564 { 340, "R39(U)" },
2565 { 344, "R40(L)" },
2566 { 348, "R40(U)" },
2567 { 352, "R41(L)" },
2568 { 356, "R41(U)" },
2569 { 360, "R42(L)" },
2570 { 364, "R42(U)" },
2571 { 368, "R43(L)" },
2572 { 372, "R43(U)" },
2573 { 376, "R44(L)" },
2574 { 380, "R44(U)" },
2575 { 384, "R45(L)" },
2576 { 388, "R45(U)" },
2577 { 392, "R46(L)" },
2578 { 396, "R46(U)" },
2579 { 400, "R47(L)" },
2580 { 404, "R47(U)" },
2581 { 408, "R48(L)" },
2582 { 412, "R48(U)" },
2583 { 416, "R49(L)" },
2584 { 420, "R49(U)" },
2585 { 424, "R50(L)" },
2586 { 428, "R50(U)" },
2587 { 432, "R51(L)" },
2588 { 436, "R51(U)" },
2589 { 440, "R52(L)" },
2590 { 444, "R52(U)" },
2591 { 448, "R53(L)" },
2592 { 452, "R53(U)" },
2593 { 456, "R54(L)" },
2594 { 460, "R54(U)" },
2595 { 464, "R55(L)" },
2596 { 468, "R55(U)" },
2597 { 472, "R56(L)" },
2598 { 476, "R56(U)" },
2599 { 480, "R57(L)" },
2600 { 484, "R57(U)" },
2601 { 488, "R58(L)" },
2602 { 492, "R58(U)" },
2603 { 496, "R59(L)" },
2604 { 500, "R59(U)" },
2605 { 504, "R60(L)" },
2606 { 508, "R60(U)" },
2607 { 512, "R61(L)" },
2608 { 516, "R61(U)" },
2609 { 520, "R62(L)" },
2610 { 524, "R62(U)" },
2611 { 528, "TR0(L)" },
2612 { 532, "TR0(U)" },
2613 { 536, "TR1(L)" },
2614 { 540, "TR1(U)" },
2615 { 544, "TR2(L)" },
2616 { 548, "TR2(U)" },
2617 { 552, "TR3(L)" },
2618 { 556, "TR3(U)" },
2619 { 560, "TR4(L)" },
2620 { 564, "TR4(U)" },
2621 { 568, "TR5(L)" },
2622 { 572, "TR5(U)" },
2623 { 576, "TR6(L)" },
2624 { 580, "TR6(U)" },
2625 { 584, "TR7(L)" },
2626 { 588, "TR7(U)" },
2627 /* This entry is in case pt_regs contains dregs (depends on
2628 the kernel build options). */
2629 { uoff(regs), "offsetof(struct user, regs)" },
2630 { uoff(fpu), "offsetof(struct user, fpu)" },
2631#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002632#ifdef ARM
2633 { uoff(regs.ARM_r0), "r0" },
2634 { uoff(regs.ARM_r1), "r1" },
2635 { uoff(regs.ARM_r2), "r2" },
2636 { uoff(regs.ARM_r3), "r3" },
2637 { uoff(regs.ARM_r4), "r4" },
2638 { uoff(regs.ARM_r5), "r5" },
2639 { uoff(regs.ARM_r6), "r6" },
2640 { uoff(regs.ARM_r7), "r7" },
2641 { uoff(regs.ARM_r8), "r8" },
2642 { uoff(regs.ARM_r9), "r9" },
2643 { uoff(regs.ARM_r10), "r10" },
2644 { uoff(regs.ARM_fp), "fp" },
2645 { uoff(regs.ARM_ip), "ip" },
2646 { uoff(regs.ARM_sp), "sp" },
2647 { uoff(regs.ARM_lr), "lr" },
2648 { uoff(regs.ARM_pc), "pc" },
2649 { uoff(regs.ARM_cpsr), "cpsr" },
2650#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002651
Michal Ludvig10a88d02002-10-07 14:31:00 +00002652#if !defined(S390) && !defined(S390X) && !defined(MIPS)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002653 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002654#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002655#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002656 { uoff(i387), "offsetof(struct user, i387)" },
2657#else /* !I386 */
2658#ifdef M68K
2659 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2660#endif /* M68K */
2661#endif /* !I386 */
2662 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2663 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2664 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2665 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrathf5a47772003-06-26 22:40:42 +00002666#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002667 { uoff(start_data), "offsetof(struct user, start_data)" },
2668#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002669 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2670 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrathf5a47772003-06-26 22:40:42 +00002671#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002672 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002673#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002674 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002675#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002676 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2677#endif
2678 { uoff(magic), "offsetof(struct user, magic)" },
2679 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002680#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002681 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2682#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002683#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002684#endif /* !ALPHA */
2685#endif /* !POWERPC/!SPARC */
2686#endif /* LINUX */
2687#ifdef SUNOS4
2688 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2689 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2690 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2691 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2692 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2693 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2694 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2695 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2696 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2697 { uoff(u_error), "offsetof(struct user, u_error)" },
2698 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2699 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2700 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2701 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2702 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2703 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2704 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2705 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2706 { uoff(u_code), "offsetof(struct user, u_code)" },
2707 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2708 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2709 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2710 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2711 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2712 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2713 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2714 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2715 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2716 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2717 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2718 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2719 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2720 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2721 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2722 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2723 { uoff(u_start), "offsetof(struct user, u_start)" },
2724 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2725 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2726 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2727 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2728 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2729 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2730 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2731 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2732 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2733#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002734#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002735 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002736#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002737 { 0, NULL },
2738};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002739#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002740
2741int
2742sys_ptrace(tcp)
2743struct tcb *tcp;
2744{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002745 struct xlat *x;
2746 long addr;
2747
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002748 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002749 printxval(ptrace_cmds, tcp->u_arg[0],
2750#ifndef FREEBSD
2751 "PTRACE_???"
2752#else
2753 "PT_???"
2754#endif
2755 );
2756 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002757 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002758#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002759 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2760 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2761 for (x = struct_user_offsets; x->str; x++) {
2762 if (x->val >= addr)
2763 break;
2764 }
2765 if (!x->str)
2766 tprintf("%#lx, ", addr);
2767 else if (x->val > addr && x != struct_user_offsets) {
2768 x--;
2769 tprintf("%s + %ld, ", x->str, addr - x->val);
2770 }
2771 else
2772 tprintf("%s, ", x->str);
2773 }
2774 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002775#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002776 tprintf("%#lx, ", tcp->u_arg[2]);
2777#ifdef LINUX
2778 switch (tcp->u_arg[0]) {
2779 case PTRACE_PEEKDATA:
2780 case PTRACE_PEEKTEXT:
2781 case PTRACE_PEEKUSER:
2782 break;
2783 case PTRACE_CONT:
2784 case PTRACE_SINGLESTEP:
2785 case PTRACE_SYSCALL:
2786 case PTRACE_DETACH:
2787 printsignal(tcp->u_arg[3]);
2788 break;
2789 default:
2790 tprintf("%#lx", tcp->u_arg[3]);
2791 break;
2792 }
2793 } else {
2794 switch (tcp->u_arg[0]) {
2795 case PTRACE_PEEKDATA:
2796 case PTRACE_PEEKTEXT:
2797 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00002798 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002799 break;
2800 }
2801 }
2802#endif /* LINUX */
2803#ifdef SUNOS4
2804 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2805 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2806 tprintf("%lu, ", tcp->u_arg[3]);
2807 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2808 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2809 tcp->u_arg[0] != PTRACE_READTEXT) {
2810 tprintf("%#lx", tcp->u_arg[3]);
2811 }
2812 } else {
2813 if (tcp->u_arg[0] == PTRACE_READDATA ||
2814 tcp->u_arg[0] == PTRACE_READTEXT) {
2815 tprintf("%lu, ", tcp->u_arg[3]);
2816 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2817 }
2818 }
2819#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002820#ifdef FREEBSD
2821 tprintf("%lu", tcp->u_arg[3]);
2822 }
2823#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002824 return 0;
2825}
2826
2827#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002828
2829#ifdef LINUX
2830static struct xlat futexops[] = {
2831 { FUTEX_WAIT, "FUTEX_WAIT" },
2832 { FUTEX_WAKE, "FUTEX_WAKE" },
2833 { FUTEX_FD, "FUTEX_FD" },
Roland McGrath88812d62003-06-26 22:27:23 +00002834 { FUTEX_REQUEUE,"FUTEX_REQUEUE" },
Roland McGrath5a223472002-12-15 23:58:26 +00002835 { 0, NULL }
2836};
2837
2838int
2839sys_futex(tcp)
2840struct tcb *tcp;
2841{
2842 if (entering(tcp)) {
2843 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00002844 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00002845 tprintf(", %ld", tcp->u_arg[2]);
2846 if (tcp->u_arg[1] == FUTEX_WAIT) {
2847 tprintf(", ");
2848 printtv(tcp, tcp->u_arg[3]);
Roland McGrath88812d62003-06-26 22:27:23 +00002849 } else if (tcp->u_arg[1] == FUTEX_REQUEUE)
2850 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath5a223472002-12-15 23:58:26 +00002851 }
2852 return 0;
2853}
2854
2855static void
2856print_affinitylist(list, len)
2857unsigned long *list;
2858unsigned int len;
2859{
2860 int first = 1;
2861 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00002862 while (len >= sizeof (unsigned long)) {
Roland McGrath5a223472002-12-15 23:58:26 +00002863 tprintf("%s %lx", first ? "" : ",", *list++);
2864 first = 0;
2865 len -= sizeof (unsigned long);
2866 }
2867 tprintf(" }");
2868}
2869
2870int
2871sys_sched_setaffinity(tcp)
2872struct tcb *tcp;
2873{
2874 if (entering(tcp)) {
2875 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2876 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2877 }
2878 return 0;
2879}
2880
2881int
2882sys_sched_getaffinity(tcp)
2883struct tcb *tcp;
2884{
2885 if (entering(tcp)) {
2886 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2887 } else {
2888 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);
2889 }
2890 return 0;
2891}
2892#endif