blob: 3b6a3577fe0e3faab0618b5799f71ab58e28ee08 [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
Roland McGrath83bd47a2003-11-13 22:32:26 +0000110#undef GETGROUPS32_T
111#define GETGROUPS32_T __kernel_gid32_t
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000112#endif /* LINUX */
113
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000114#if defined(LINUX) && defined(IA64)
115# include <asm/ptrace_offsets.h>
116# include <asm/rse.h>
117#endif
118
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000119#ifdef HAVE_PRCTL
120#include <sys/prctl.h>
121#endif
122
123#ifndef WCOREDUMP
124#define WCOREDUMP(status) ((status) & 0200)
125#endif
126
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000127/* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000128#if defined(HAVE_PRCTL)
129static struct xlat prctl_options[] = {
130#ifdef PR_MAXPROCS
131 { PR_MAXPROCS, "PR_MAXPROCS" },
132#endif
133#ifdef PR_ISBLOCKED
134 { PR_ISBLOCKED, "PR_ISBLOCKED" },
135#endif
136#ifdef PR_SETSTACKSIZE
137 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
138#endif
139#ifdef PR_GETSTACKSIZE
140 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
141#endif
142#ifdef PR_MAXPPROCS
143 { PR_MAXPPROCS, "PR_MAXPPROCS" },
144#endif
145#ifdef PR_UNBLKONEXEC
146 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
147#endif
148#ifdef PR_ATOMICSIM
149 { PR_ATOMICSIM, "PR_ATOMICSIM" },
150#endif
151#ifdef PR_SETEXITSIG
152 { PR_SETEXITSIG, "PR_SETEXITSIG" },
153#endif
154#ifdef PR_RESIDENT
155 { PR_RESIDENT, "PR_RESIDENT" },
156#endif
157#ifdef PR_ATTACHADDR
158 { PR_ATTACHADDR, "PR_ATTACHADDR" },
159#endif
160#ifdef PR_DETACHADDR
161 { PR_DETACHADDR, "PR_DETACHADDR" },
162#endif
163#ifdef PR_TERMCHILD
164 { PR_TERMCHILD, "PR_TERMCHILD" },
165#endif
166#ifdef PR_GETSHMASK
167 { PR_GETSHMASK, "PR_GETSHMASK" },
168#endif
169#ifdef PR_GETNSHARE
170 { PR_GETNSHARE, "PR_GETNSHARE" },
171#endif
172#if defined(PR_SET_PDEATHSIG)
173 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
174#endif
Wichert Akkerman8829a551999-06-11 13:18:40 +0000175#ifdef PR_COREPID
176 { PR_COREPID, "PR_COREPID" },
177#endif
178#ifdef PR_ATTACHADDRPERM
179 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
180#endif
181#ifdef PR_PTHREADEXIT
182 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
183#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000184#ifdef PR_SET_PDEATHSIG
185 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
186#endif
187#ifdef PR_GET_PDEATHSIG
188 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
189#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000190#ifdef PR_GET_UNALIGN
191 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
192#endif
193#ifdef PR_SET_UNALIGN
194 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
195#endif
196#ifdef PR_GET_KEEPCAPS
197 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" },
198#endif
199#ifdef PR_SET_KEEPCAPS
200 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" },
201#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000202 { 0, NULL },
203};
204
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000205
206const char *
207unalignctl_string (unsigned int ctl)
208{
209 static char buf[16];
210
211 switch (ctl) {
212#ifdef PR_UNALIGN_NOPRINT
213 case PR_UNALIGN_NOPRINT:
214 return "NOPRINT";
215#endif
216#ifdef PR_UNALIGN_SIGBUS
217 case PR_UNALIGN_SIGBUS:
218 return "SIGBUS";
219#endif
220 default:
221 break;
222 }
223 sprintf(buf, "%x", ctl);
224 return buf;
225}
226
227
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000228int
229sys_prctl(tcp)
230struct tcb *tcp;
231{
232 int i;
233
234 if (entering(tcp)) {
235 printxval(prctl_options, tcp->u_arg[0], "PR_???");
236 switch (tcp->u_arg[0]) {
237#ifdef PR_GETNSHARE
238 case PR_GETNSHARE:
239 break;
240#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000241#ifdef PR_SET_DEATHSIG
242 case PR_GET_PDEATHSIG:
243 break;
244#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000245#ifdef PR_SET_UNALIGN
246 case PR_SET_UNALIGN:
247 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
248 break;
249#endif
250#ifdef PR_GET_UNALIGN
251 case PR_GET_UNALIGN:
252 tprintf(", %#lx", tcp->u_arg[1]);
253 break;
254#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000255 default:
256 for (i = 1; i < tcp->u_nargs; i++)
257 tprintf(", %#lx", tcp->u_arg[i]);
258 break;
259 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000260 } else {
261 switch (tcp->u_arg[0]) {
262#ifdef PR_GET_PDEATHSIG
263 case PR_GET_PDEATHSIG:
264 for (i=1; i<tcp->u_nargs; i++)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000265 tprintf(", %#lx", tcp->u_arg[i]);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000266 break;
267#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000268#ifdef PR_SET_UNALIGN
269 case PR_SET_UNALIGN:
270 break;
271#endif
272#ifdef PR_GET_UNALIGN
273 case PR_GET_UNALIGN:
274 {
275 int ctl;
276
277 umove(tcp, tcp->u_arg[1], &ctl);
278 tcp->auxstr = unalignctl_string(ctl);
279 return RVAL_STR;
280 }
281#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000282 default:
283 break;
284 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000285 }
286 return 0;
287}
288
289#endif /* HAVE_PRCTL */
290
291int
292sys_gethostid(tcp)
293struct tcb *tcp;
294{
295 if (exiting(tcp))
296 return RVAL_HEX;
297 return 0;
298}
299
300int
301sys_sethostname(tcp)
302struct tcb *tcp;
303{
304 if (entering(tcp)) {
305 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
306 tprintf(", %lu", tcp->u_arg[1]);
307 }
308 return 0;
309}
310
311int
312sys_gethostname(tcp)
313struct tcb *tcp;
314{
315 if (exiting(tcp)) {
316 if (syserror(tcp))
317 tprintf("%#lx", tcp->u_arg[0]);
318 else
319 printpath(tcp, tcp->u_arg[0]);
320 tprintf(", %lu", tcp->u_arg[1]);
321 }
322 return 0;
323}
324
325int
326sys_setdomainname(tcp)
327struct tcb *tcp;
328{
329 if (entering(tcp)) {
330 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
331 tprintf(", %lu", tcp->u_arg[1]);
332 }
333 return 0;
334}
335
Wichert Akkerman5daa0281999-03-15 19:49:42 +0000336#if !defined(LINUX)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000337
338int
339sys_getdomainname(tcp)
340struct tcb *tcp;
341{
342 if (exiting(tcp)) {
343 if (syserror(tcp))
344 tprintf("%#lx", tcp->u_arg[0]);
345 else
346 printpath(tcp, tcp->u_arg[0]);
347 tprintf(", %lu", tcp->u_arg[1]);
348 }
349 return 0;
350}
351#endif /* !LINUX */
352
353int
354sys_exit(tcp)
355struct tcb *tcp;
356{
357 if (exiting(tcp)) {
358 fprintf(stderr, "_exit returned!\n");
359 return -1;
360 }
361 /* special case: we stop tracing this process, finish line now */
362 tprintf("%ld) ", tcp->u_arg[0]);
363 tabto(acolumn);
364 tprintf("= ?");
365 printtrailer(tcp);
366 return 0;
367}
368
369int
370internal_exit(tcp)
371struct tcb *tcp;
372{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000373 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000374 tcp->flags |= TCB_EXITING;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000375#ifdef __NR_exit_group
376 if (tcp->scno == __NR_exit_group)
377 tcp->flags |= TCB_GROUP_EXITING;
378#endif
379 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000380 return 0;
381}
382
Roland McGrathee9d4352002-12-18 04:16:10 +0000383/* TCP is creating a child we want to follow.
384 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
385 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
386static int
387fork_tcb(struct tcb *tcp)
388{
389 if (nprocs == tcbtabsize) {
390 /* Allocate some more TCBs and expand the table.
391 We don't want to relocate the TCBs because our
392 callers have pointers and it would be a pain.
393 So tcbtab is a table of pointers. Since we never
394 free the TCBs, we allocate a single chunk of many. */
395 struct tcb **newtab = (struct tcb **)
396 realloc(tcbtab, 2 * tcbtabsize * sizeof tcbtab[0]);
397 struct tcb *newtcbs = (struct tcb *) calloc(tcbtabsize,
398 sizeof *newtcbs);
399 int i;
400 if (newtab == NULL || newtcbs == NULL) {
401 if (newtab != NULL)
402 free(newtab);
403 tcp->flags &= ~TCB_FOLLOWFORK;
404 fprintf(stderr, "sys_fork: tcb table full\n");
405 return 1;
406 }
407 for (i = tcbtabsize; i < 2 * tcbtabsize; ++i)
408 newtab[i] = &newtcbs[i - tcbtabsize];
409 tcbtabsize *= 2;
410 tcbtab = newtab;
411 }
412
413 tcp->flags |= TCB_FOLLOWFORK;
414 return 0;
415}
416
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000417#ifdef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000418
419int
420sys_fork(tcp)
421struct tcb *tcp;
422{
423 if (exiting(tcp)) {
424 if (getrval2(tcp)) {
425 tcp->auxstr = "child process";
426 return RVAL_UDECIMAL | RVAL_STR;
427 }
428 }
429 return 0;
430}
431
John Hughes4e36a812001-04-18 15:11:51 +0000432#if UNIXWARE > 2
433
434int
435sys_rfork(tcp)
436struct tcb *tcp;
437{
438 if (entering(tcp)) {
439 tprintf ("%ld", tcp->u_arg[0]);
440 }
441 else {
442 if (getrval2(tcp)) {
443 tcp->auxstr = "child process";
444 return RVAL_UDECIMAL | RVAL_STR;
445 }
446 }
447 return 0;
448}
449
450#endif
451
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000452int
453internal_fork(tcp)
454struct tcb *tcp;
455{
456 struct tcb *tcpchild;
457
458 if (exiting(tcp)) {
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000459#ifdef SYS_rfork
460 if (tcp->scno == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
461 return 0;
462#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000463 if (getrval2(tcp))
464 return 0;
465 if (!followfork)
466 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000467 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000468 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000469 if (syserror(tcp))
470 return 0;
471 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
472 fprintf(stderr, "sys_fork: tcb table full\n");
473 return 0;
474 }
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000475 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000476 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000477 }
478 return 0;
479}
480
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000481#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000482
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000483#ifdef LINUX
484
485/* defines copied from linux/sched.h since we can't include that
486 * ourselves (it conflicts with *lots* of libc includes)
487 */
488#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
489#define CLONE_VM 0x00000100 /* set if VM shared between processes */
490#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
491#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
492#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000493#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000494#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
495#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
496#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000497#define CLONE_THREAD 0x00010000 /* Same thread group? */
498#define CLONE_NEWNS 0x00020000 /* New namespace group? */
499#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
500#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
501#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
502#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
503#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
504#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
505#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000506
507static struct xlat clone_flags[] = {
508 { CLONE_VM, "CLONE_VM" },
509 { CLONE_FS, "CLONE_FS" },
510 { CLONE_FILES, "CLONE_FILES" },
511 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000512 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000513 { CLONE_PTRACE, "CLONE_PTRACE" },
514 { CLONE_VFORK, "CLONE_VFORK" },
515 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000516 { CLONE_THREAD, "CLONE_THREAD" },
517 { CLONE_NEWNS, "CLONE_NEWNS" },
518 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
519 { CLONE_SETTLS, "CLONE_SETTLS" },
520 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
521 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
522 { CLONE_DETACHED, "CLONE_DETACHED" },
523 { CLONE_UNTRACED, "CLONE_UNTRACED" },
524 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000525 { 0, NULL },
526};
527
Roland McGrath909875b2002-12-22 03:34:36 +0000528# ifdef I386
529# include <asm/ldt.h>
530extern void print_ldt_entry();
531# endif
532
Roland McGrath9677b3a2003-03-12 09:54:36 +0000533# if defined IA64
534# define ARG_FLAGS 0
535# define ARG_STACK 1
536# define ARG_STACKSIZE (tcp->scno == SYS_clone2 ? 2 : -1)
Roland McGrathc03981d2003-03-14 10:32:36 +0000537# define ARG_PTID (tcp->scno == SYS_clone2 ? 3 : 2)
538# define ARG_CTID (tcp->scno == SYS_clone2 ? 4 : 3)
539# define ARG_TLS (tcp->scno == SYS_clone2 ? 5 : 4)
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000540# elif defined S390 || defined S390X
Roland McGrath9677b3a2003-03-12 09:54:36 +0000541# define ARG_STACK 0
542# define ARG_FLAGS 1
543# define ARG_PTID 2
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000544# define ARG_CTID 3
545# define ARG_TLS 4
Roland McGrath9c555e72003-07-09 09:47:59 +0000546# elif defined X86_64 || defined ALPHA
Roland McGrath361aac52003-03-18 07:43:42 +0000547# define ARG_FLAGS 0
548# define ARG_STACK 1
549# define ARG_PTID 2
550# define ARG_CTID 3
551# define ARG_TLS 4
Roland McGrath9677b3a2003-03-12 09:54:36 +0000552# else
553# define ARG_FLAGS 0
554# define ARG_STACK 1
555# define ARG_PTID 2
556# define ARG_TLS 3
557# define ARG_CTID 4
558# endif
559
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000560int
561sys_clone(tcp)
562struct tcb *tcp;
563{
564 if (exiting(tcp)) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000565 unsigned long flags = tcp->u_arg[ARG_FLAGS];
566 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
567# ifdef ARG_STACKSIZE
568 if (ARG_STACKSIZE != -1)
569 tprintf("stack_size=%#lx, ",
570 tcp->u_arg[ARG_STACKSIZE]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000571# endif
Roland McGrath9677b3a2003-03-12 09:54:36 +0000572 tprintf("flags=");
Roland McGrath984154d2003-05-23 01:08:42 +0000573 if (printflags(clone_flags, flags &~ CSIGNAL) == 0)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000574 tprintf("0");
Roland McGrath984154d2003-05-23 01:08:42 +0000575 if ((flags & CSIGNAL) != 0)
576 tprintf("|%s", signame(flags & CSIGNAL));
Roland McGrathb4968be2003-01-20 09:04:33 +0000577 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
Roland McGrath9677b3a2003-03-12 09:54:36 +0000578 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
Roland McGrath909875b2002-12-22 03:34:36 +0000579 return 0;
Roland McGrath6f67a982003-03-21 07:33:15 +0000580 if (flags & CLONE_PARENT_SETTID)
581 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000582 if (flags & CLONE_SETTLS) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000583# ifdef I386
Roland McGrath909875b2002-12-22 03:34:36 +0000584 struct modify_ldt_ldt_s copy;
Roland McGrath9677b3a2003-03-12 09:54:36 +0000585 if (umove(tcp, tcp->u_arg[ARG_TLS], &copy) != -1) {
Roland McGrath909875b2002-12-22 03:34:36 +0000586 tprintf(", {entry_number:%d, ",
587 copy.entry_number);
588 if (!verbose(tcp))
589 tprintf("...}");
590 else
591 print_ldt_entry(&copy);
592 }
593 else
Roland McGrath9677b3a2003-03-12 09:54:36 +0000594# endif
Roland McGrath43f2c842003-03-12 09:58:14 +0000595 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
Roland McGrath909875b2002-12-22 03:34:36 +0000596 }
Roland McGrath9677b3a2003-03-12 09:54:36 +0000597 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
598 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000599 }
600 return 0;
601}
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000602#endif
603
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000604int
605sys_fork(tcp)
606struct tcb *tcp;
607{
608 if (exiting(tcp))
609 return RVAL_UDECIMAL;
610 return 0;
611}
612
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000613int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000614change_syscall(tcp, new)
615struct tcb *tcp;
616int new;
617{
618#if defined(LINUX)
619#if defined(I386)
620 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000621 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000622 return -1;
623 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000624#elif defined(X86_64)
625 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000626 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000627 return -1;
628 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000629#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000630 if (ptrace(PTRACE_POKEUSER, tcp->pid,
631 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000632 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000633 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000634#elif defined(S390) || defined(S390X)
635 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
636 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
637 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000638 return 0;
639#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000640 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000641 return -1;
642 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000643#elif defined(SPARC)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000644 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000645 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
646 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000647 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000648 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
649 return -1;
650 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000651#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000652 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000653 return -1;
654 return 0;
655#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000656 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000657 return -1;
658 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000659#elif defined(IA64)
660 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
661 return -1;
662 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000663#elif defined(HPPA)
664 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
665 return -1;
666 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000667#elif defined(SH)
Roland McGrathac971c22003-03-31 01:03:33 +0000668 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
Wichert Akkermanccef6372002-05-01 16:39:22 +0000669 return -1;
670 return 0;
Roland McGrathf5a47772003-06-26 22:40:42 +0000671#elif defined(SH64)
Roland McGrathe1e584b2003-06-02 19:18:58 +0000672 /* Top half of reg encodes the no. of args n as 0x1n.
673 Assume 0 args as kernel never actually checks... */
674 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
675 0x100000 | new) < 0)
676 return -1;
677 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000678#else
679#warning Do not know how to handle change_syscall for this architecture
680#endif /* architecture */
681#endif /* LINUX */
682 return -1;
683}
684
685int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000686setarg(tcp, argnum)
687 struct tcb *tcp;
688 int argnum;
689{
690#if defined (IA64)
691 {
692 unsigned long *bsp, *ap;
693
694 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
695 return -1;
696
697 ap = ia64_rse_skip_regs(bsp, argnum);
698 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000699 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000700 if (errno)
701 return -1;
702
703 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000704#elif defined(I386)
705 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000706 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000707 if (errno)
708 return -1;
709 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000710#elif defined(X86_64)
711 {
712 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
713 if (errno)
714 return -1;
715 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000716#elif defined(POWERPC)
717#ifndef PT_ORIG_R3
718#define PT_ORIG_R3 34
719#endif
720 {
721 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000722 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000723 tcp->u_arg[argnum]);
724 if (errno)
725 return -1;
726 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000727#elif defined(MIPS)
728 {
729 errno = 0;
730 if (argnum < 4)
731 ptrace(PTRACE_POKEUSER, tcp->pid,
732 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
733 else {
734 unsigned long *sp;
735
736 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
737 return -1;
738
739 ptrace(PTRACE_POKEDATA, tcp->pid,
740 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
741 }
742 if (errno)
743 return -1;
744 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000745#elif defined(S390) || defined(S390X)
746 {
747 if(argnum <= 5)
748 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000749 (char *) (argnum==0 ? PT_ORIGGPR2 :
750 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000751 tcp->u_arg[argnum]);
752 else
753 return -E2BIG;
754 if (errno)
755 return -1;
756 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000757#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000758# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000759#endif
760 return 0;
761}
762
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000763#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000764int
765internal_clone(tcp)
766struct tcb *tcp;
767{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000768 struct tcb *tcpchild;
769 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000770 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000771 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000772 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000773 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000774 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000775 if (setbpt(tcp) < 0)
776 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000777 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000778 int bpt = tcp->flags & TCB_BPTSET;
779
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000780 if (!(tcp->flags & TCB_FOLLOWFORK))
781 return 0;
782
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000783 if (syserror(tcp)) {
784 if (bpt)
785 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000786 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000787 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000788
789 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000790
791#ifdef CLONE_PTRACE /* See new setbpt code. */
792 tcpchild = pid2tcb(pid);
793 if (tcpchild != NULL) {
794 /* The child already reported its startup trap
795 before the parent reported its syscall return. */
796 if ((tcpchild->flags
797 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
798 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
799 fprintf(stderr, "\
800[preattached child %d of %d in weird state!]\n",
801 pid, tcp->pid);
802 }
803 else
804#endif
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000805 if ((tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000806 if (bpt)
807 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000808 fprintf(stderr, " [tcb table full]\n");
809 kill(pid, SIGKILL); /* XXX */
810 return 0;
811 }
812
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000813#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000814 /* Attach to the new child */
815 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000816 if (bpt)
817 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000818 perror("PTRACE_ATTACH");
819 fprintf(stderr, "Too late?\n");
820 droptcb(tcpchild);
821 return 0;
822 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000823#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000824
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000825 if (bpt)
826 clearbpt(tcp);
827
Ulrich Drepper90512f01999-12-24 07:22:25 +0000828 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000829 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000830 if (bpt) {
831 tcpchild->flags |= TCB_BPTSET;
832 tcpchild->baddr = tcp->baddr;
833 memcpy(tcpchild->inst, tcp->inst,
834 sizeof tcpchild->inst);
835 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000836 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000837 tcp->nchildren++;
838 if (tcpchild->flags & TCB_SUSPENDED) {
839 /* The child was born suspended, due to our having
840 forced CLONE_PTRACE. */
841 if (bpt)
842 clearbpt(tcpchild);
843
844 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
845 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
846 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
847 return -1;
848 }
849
850 if (!qflag)
851 fprintf(stderr, "\
852Process %u resumed (parent %d ready)\n",
853 pid, tcp->pid);
854 }
855 else {
856 newoutf(tcpchild);
857 if (!qflag)
858 fprintf(stderr, "Process %d attached\n", pid);
859 }
860
861#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000862 {
863 /*
864 * Save the flags used in this call,
865 * in case we point TCP to our parent below.
866 */
867 int call_flags = tcp->u_arg[ARG_FLAGS];
868 if ((tcp->flags & TCB_CLONE_THREAD) &&
869 tcp->parent != NULL) {
870 /* The parent in this clone is itself a
871 thread belonging to another process.
872 There is no meaning to the parentage
873 relationship of the new child with the
874 thread, only with the process. We
875 associate the new thread with our
876 parent. Since this is done for every
877 new thread, there will never be a
878 TCB_CLONE_THREAD process that has
879 children. */
880 --tcp->nchildren;
881 tcp = tcp->parent;
882 tcpchild->parent = tcp;
883 ++tcp->nchildren;
884 }
885 if (call_flags & CLONE_THREAD) {
886 tcpchild->flags |= TCB_CLONE_THREAD;
887 ++tcp->nclone_threads;
888 }
889 if (call_flags & CLONE_DETACHED) {
890 tcpchild->flags |= TCB_CLONE_DETACHED;
891 ++tcp->nclone_detached;
892 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000893 }
894#endif
895
896 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000897 return 0;
898}
899#endif
900
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000901int
902internal_fork(tcp)
903struct tcb *tcp;
904{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000905#ifdef LINUX
906 /* We do special magic with clone for any clone or fork. */
907 return internal_clone(tcp);
908#else
909
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000910 struct tcb *tcpchild;
911 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000912 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000913
914#ifdef SYS_vfork
Nate Sammonsccd8f211999-03-29 22:57:54 +0000915 if (tcp->scno == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000916 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000917 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000918 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000919 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000920 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000921#endif
922 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000923 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000924 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000925 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000926 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000927 if (setbpt(tcp) < 0)
928 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000929 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000930 else {
931 int bpt = tcp->flags & TCB_BPTSET;
932
933 if (!(tcp->flags & TCB_FOLLOWFORK))
934 return 0;
935 if (bpt)
936 clearbpt(tcp);
937
938 if (syserror(tcp))
939 return 0;
940
941 pid = tcp->u_rval;
942 if ((tcpchild = alloctcb(pid)) == NULL) {
943 fprintf(stderr, " [tcb table full]\n");
944 kill(pid, SIGKILL); /* XXX */
945 return 0;
946 }
947#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000948#ifdef HPPA
949 /* The child must have run before it can be attached. */
950 /* This must be a bug in the parisc kernel, but I havn't
951 * identified it yet. Seems to be an issue associated
952 * with attaching to a process (which sends it a signal)
953 * before that process has ever been scheduled. When
954 * debugging, I started seeing crashes in
955 * arch/parisc/kernel/signal.c:do_signal(), apparently
956 * caused by r8 getting corrupt over the dequeue_signal()
957 * call. Didn't make much sense though...
958 */
959 {
960 struct timeval tv;
961 tv.tv_sec = 0;
962 tv.tv_usec = 10000;
963 select(0, NULL, NULL, NULL, &tv);
964 }
965#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000966 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
967 perror("PTRACE_ATTACH");
968 fprintf(stderr, "Too late?\n");
969 droptcb(tcpchild);
970 return 0;
971 }
972#endif /* LINUX */
973#ifdef SUNOS4
974#ifdef oldway
975 /* The child must have run before it can be attached. */
976 {
977 struct timeval tv;
978 tv.tv_sec = 0;
979 tv.tv_usec = 10000;
980 select(0, NULL, NULL, NULL, &tv);
981 }
982 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
983 perror("PTRACE_ATTACH");
984 fprintf(stderr, "Too late?\n");
985 droptcb(tcpchild);
986 return 0;
987 }
988#else /* !oldway */
989 /* Try to catch the new process as soon as possible. */
990 {
991 int i;
992 for (i = 0; i < 1024; i++)
993 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
994 break;
995 if (i == 1024) {
996 perror("PTRACE_ATTACH");
997 fprintf(stderr, "Too late?\n");
998 droptcb(tcpchild);
999 return 0;
1000 }
1001 }
1002#endif /* !oldway */
1003#endif /* SUNOS4 */
1004 tcpchild->flags |= TCB_ATTACHED;
1005 /* Child has BPT too, must be removed on first occasion */
1006 if (bpt) {
1007 tcpchild->flags |= TCB_BPTSET;
1008 tcpchild->baddr = tcp->baddr;
1009 memcpy(tcpchild->inst, tcp->inst,
1010 sizeof tcpchild->inst);
1011 }
1012 newoutf(tcpchild);
1013 tcpchild->parent = tcp;
1014 tcp->nchildren++;
1015 if (!qflag)
1016 fprintf(stderr, "Process %d attached\n", pid);
1017 }
1018 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001019#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001020}
1021
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001022#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001023
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001024#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001025
1026int
1027sys_vfork(tcp)
1028struct tcb *tcp;
1029{
1030 if (exiting(tcp))
1031 return RVAL_UDECIMAL;
1032 return 0;
1033}
1034
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001035#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001036
1037#ifndef LINUX
1038
1039static char idstr[16];
1040
1041int
1042sys_getpid(tcp)
1043struct tcb *tcp;
1044{
1045 if (exiting(tcp)) {
1046 sprintf(idstr, "ppid %lu", getrval2(tcp));
1047 tcp->auxstr = idstr;
1048 return RVAL_STR;
1049 }
1050 return 0;
1051}
1052
1053int
1054sys_getuid(tcp)
1055struct tcb *tcp;
1056{
1057 if (exiting(tcp)) {
1058 sprintf(idstr, "euid %lu", getrval2(tcp));
1059 tcp->auxstr = idstr;
1060 return RVAL_STR;
1061 }
1062 return 0;
1063}
1064
1065int
1066sys_getgid(tcp)
1067struct tcb *tcp;
1068{
1069 if (exiting(tcp)) {
1070 sprintf(idstr, "egid %lu", getrval2(tcp));
1071 tcp->auxstr = idstr;
1072 return RVAL_STR;
1073 }
1074 return 0;
1075}
1076
1077#endif /* !LINUX */
1078
1079#ifdef LINUX
1080
1081int
1082sys_setuid(tcp)
1083struct tcb *tcp;
1084{
1085 if (entering(tcp)) {
1086 tprintf("%u", (uid_t) tcp->u_arg[0]);
1087 }
1088 return 0;
1089}
1090
1091int
1092sys_setgid(tcp)
1093struct tcb *tcp;
1094{
1095 if (entering(tcp)) {
1096 tprintf("%u", (gid_t) tcp->u_arg[0]);
1097 }
1098 return 0;
1099}
1100
1101int
1102sys_getresuid(tcp)
1103 struct tcb *tcp;
1104{
1105 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001106 __kernel_uid_t uid;
1107 if (syserror(tcp))
1108 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1109 tcp->u_arg[1], tcp->u_arg[2]);
1110 else {
1111 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1112 tprintf("%#lx, ", tcp->u_arg[0]);
1113 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001114 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001115 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1116 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001117 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001118 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001119 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1120 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001121 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001122 tprintf("[%lu]", (unsigned long) uid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001123 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001124 }
1125 return 0;
1126}
1127
1128int
1129sys_getresgid(tcp)
1130struct tcb *tcp;
1131{
1132 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001133 __kernel_gid_t gid;
1134 if (syserror(tcp))
1135 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1136 tcp->u_arg[1], tcp->u_arg[2]);
1137 else {
1138 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1139 tprintf("%#lx, ", tcp->u_arg[0]);
1140 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001141 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001142 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1143 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001144 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001145 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001146 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1147 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001148 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001149 tprintf("[%lu]", (unsigned long) gid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001150 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001151 }
1152 return 0;
1153}
1154
1155#endif /* LINUX */
1156
1157int
1158sys_setreuid(tcp)
1159struct tcb *tcp;
1160{
1161 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001162 printuid("", tcp->u_arg[0]);
1163 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001164 }
1165 return 0;
1166}
1167
1168int
1169sys_setregid(tcp)
1170struct tcb *tcp;
1171{
1172 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001173 printuid("", tcp->u_arg[0]);
1174 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001175 }
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)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001185 printuid("", tcp->u_arg[0]);
1186 printuid(", ", tcp->u_arg[1]);
1187 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001188 }
1189 return 0;
1190}
1191int
1192sys_setresgid(tcp)
1193 struct tcb *tcp;
1194{
1195 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001196 printuid("", tcp->u_arg[0]);
1197 printuid(", ", tcp->u_arg[1]);
1198 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001199 }
1200 return 0;
1201}
1202
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001203#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001204
1205int
1206sys_setgroups(tcp)
1207struct tcb *tcp;
1208{
1209 int i, len;
1210 GETGROUPS_T *gidset;
1211
1212 if (entering(tcp)) {
1213 len = tcp->u_arg[0];
1214 tprintf("%u, ", len);
1215 if (len <= 0) {
1216 tprintf("[]");
1217 return 0;
1218 }
1219 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1220 if (gidset == NULL) {
1221 fprintf(stderr, "sys_setgroups: out of memory\n");
1222 return -1;
1223 }
1224 if (!verbose(tcp))
1225 tprintf("%#lx", tcp->u_arg[1]);
1226 else if (umoven(tcp, tcp->u_arg[1],
1227 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1228 tprintf("[?]");
1229 else {
1230 tprintf("[");
1231 for (i = 0; i < len; i++)
1232 tprintf("%s%lu", i ? ", " : "",
1233 (unsigned long) gidset[i]);
1234 tprintf("]");
1235 }
1236 free((char *) gidset);
1237 }
1238 return 0;
1239}
1240
1241int
1242sys_getgroups(tcp)
1243struct tcb *tcp;
1244{
1245 int i, len;
1246 GETGROUPS_T *gidset;
1247
1248 if (entering(tcp)) {
1249 len = tcp->u_arg[0];
1250 tprintf("%u, ", len);
1251 } else {
1252 len = tcp->u_rval;
1253 if (len <= 0) {
1254 tprintf("[]");
1255 return 0;
1256 }
1257 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1258 if (gidset == NULL) {
1259 fprintf(stderr, "sys_getgroups: out of memory\n");
1260 return -1;
1261 }
1262 if (!tcp->u_arg[1])
1263 tprintf("NULL");
1264 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1265 tprintf("%#lx", tcp->u_arg[1]);
1266 else if (umoven(tcp, tcp->u_arg[1],
1267 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1268 tprintf("[?]");
1269 else {
1270 tprintf("[");
1271 for (i = 0; i < len; i++)
1272 tprintf("%s%lu", i ? ", " : "",
1273 (unsigned long) gidset[i]);
1274 tprintf("]");
1275 }
1276 free((char *)gidset);
1277 }
1278 return 0;
1279}
1280
Roland McGrath83bd47a2003-11-13 22:32:26 +00001281#ifdef LINUX
1282int
1283sys_setgroups32(tcp)
1284struct tcb *tcp;
1285{
1286 int i, len;
1287 GETGROUPS32_T *gidset;
1288
1289 if (entering(tcp)) {
1290 len = tcp->u_arg[0];
1291 tprintf("%u, ", len);
1292 if (len <= 0) {
1293 tprintf("[]");
1294 return 0;
1295 }
1296 gidset = (GETGROUPS32_T *) malloc(len * sizeof(GETGROUPS32_T));
1297 if (gidset == NULL) {
1298 fprintf(stderr, "sys_setgroups32: out of memory\n");
1299 return -1;
1300 }
1301 if (!verbose(tcp))
1302 tprintf("%#lx", tcp->u_arg[1]);
1303 else if (umoven(tcp, tcp->u_arg[1],
1304 len * sizeof(GETGROUPS32_T), (char *) gidset) < 0)
1305 tprintf("[?]");
1306 else {
1307 tprintf("[");
1308 for (i = 0; i < len; i++)
1309 tprintf("%s%lu", i ? ", " : "",
1310 (unsigned long) gidset[i]);
1311 tprintf("]");
1312 }
1313 free((char *) gidset);
1314 }
1315 return 0;
1316}
1317
1318int
1319sys_getgroups32(tcp)
1320struct tcb *tcp;
1321{
1322 int i, len;
1323 GETGROUPS32_T *gidset;
1324
1325 if (entering(tcp)) {
1326 len = tcp->u_arg[0];
1327 tprintf("%u, ", len);
1328 } else {
1329 len = tcp->u_rval;
1330 if (len <= 0) {
1331 tprintf("[]");
1332 return 0;
1333 }
1334 gidset = (GETGROUPS32_T *) malloc(len * sizeof(GETGROUPS32_T));
1335 if (gidset == NULL) {
1336 fprintf(stderr, "sys_getgroups32: out of memory\n");
1337 return -1;
1338 }
1339 if (!tcp->u_arg[1])
1340 tprintf("NULL");
1341 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1342 tprintf("%#lx", tcp->u_arg[1]);
1343 else if (umoven(tcp, tcp->u_arg[1],
1344 len * sizeof(GETGROUPS32_T), (char *) gidset) < 0)
1345 tprintf("[?]");
1346 else {
1347 tprintf("[");
1348 for (i = 0; i < len; i++)
1349 tprintf("%s%lu", i ? ", " : "",
1350 (unsigned long) gidset[i]);
1351 tprintf("]");
1352 }
1353 free((char *)gidset);
1354 }
1355 return 0;
1356}
1357#endif /* LINUX */
1358
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001359int
1360sys_setpgrp(tcp)
1361struct tcb *tcp;
1362{
1363 if (entering(tcp)) {
1364#ifndef SVR4
1365 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1366#endif /* !SVR4 */
1367 }
1368 return 0;
1369}
1370
1371int
1372sys_getpgrp(tcp)
1373struct tcb *tcp;
1374{
1375 if (entering(tcp)) {
1376#ifndef SVR4
1377 tprintf("%lu", tcp->u_arg[0]);
1378#endif /* !SVR4 */
1379 }
1380 return 0;
1381}
1382
1383int
1384sys_getsid(tcp)
1385struct tcb *tcp;
1386{
1387 if (entering(tcp)) {
1388 tprintf("%lu", tcp->u_arg[0]);
1389 }
1390 return 0;
1391}
1392
1393int
1394sys_setsid(tcp)
1395struct tcb *tcp;
1396{
1397 return 0;
1398}
1399
1400int
1401sys_getpgid(tcp)
1402struct tcb *tcp;
1403{
1404 if (entering(tcp)) {
1405 tprintf("%lu", tcp->u_arg[0]);
1406 }
1407 return 0;
1408}
1409
1410int
1411sys_setpgid(tcp)
1412struct tcb *tcp;
1413{
1414 if (entering(tcp)) {
1415 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1416 }
1417 return 0;
1418}
1419
John Hughesc61eb3d2002-05-17 11:37:50 +00001420#if UNIXWARE >= 2
1421
1422#include <sys/privilege.h>
1423
1424
1425static struct xlat procpriv_cmds [] = {
1426 { SETPRV, "SETPRV" },
1427 { CLRPRV, "CLRPRV" },
1428 { PUTPRV, "PUTPRV" },
1429 { GETPRV, "GETPRV" },
1430 { CNTPRV, "CNTPRV" },
1431 { 0, NULL },
1432};
1433
1434
1435static struct xlat procpriv_priv [] = {
1436 { P_OWNER, "P_OWNER" },
1437 { P_AUDIT, "P_AUDIT" },
1438 { P_COMPAT, "P_COMPAT" },
1439 { P_DACREAD, "P_DACREAD" },
1440 { P_DACWRITE, "P_DACWRITE" },
1441 { P_DEV, "P_DEV" },
1442 { P_FILESYS, "P_FILESYS" },
1443 { P_MACREAD, "P_MACREAD" },
1444 { P_MACWRITE, "P_MACWRITE" },
1445 { P_MOUNT, "P_MOUNT" },
1446 { P_MULTIDIR, "P_MULTIDIR" },
1447 { P_SETPLEVEL, "P_SETPLEVEL" },
1448 { P_SETSPRIV, "P_SETSPRIV" },
1449 { P_SETUID, "P_SETUID" },
1450 { P_SYSOPS, "P_SYSOPS" },
1451 { P_SETUPRIV, "P_SETUPRIV" },
1452 { P_DRIVER, "P_DRIVER" },
1453 { P_RTIME, "P_RTIME" },
1454 { P_MACUPGRADE, "P_MACUPGRADE" },
1455 { P_FSYSRANGE, "P_FSYSRANGE" },
1456 { P_SETFLEVEL, "P_SETFLEVEL" },
1457 { P_AUDITWR, "P_AUDITWR" },
1458 { P_TSHAR, "P_TSHAR" },
1459 { P_PLOCK, "P_PLOCK" },
1460 { P_CORE, "P_CORE" },
1461 { P_LOADMOD, "P_LOADMOD" },
1462 { P_BIND, "P_BIND" },
1463 { P_ALLPRIVS, "P_ALLPRIVS" },
1464 { 0, NULL },
1465};
1466
1467
1468static struct xlat procpriv_type [] = {
1469 { PS_FIX, "PS_FIX" },
1470 { PS_INH, "PS_INH" },
1471 { PS_MAX, "PS_MAX" },
1472 { PS_WKG, "PS_WKG" },
1473 { 0, NULL },
1474};
1475
1476
1477static void
1478printpriv(tcp, addr, len, opt)
1479struct tcb *tcp;
1480long addr;
1481int len;
1482struct xlat *opt;
1483{
1484 priv_t buf [128];
1485 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1486 int dots = len > max;
1487 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001488
John Hughesc61eb3d2002-05-17 11:37:50 +00001489 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001490
John Hughesc61eb3d2002-05-17 11:37:50 +00001491 if (len <= 0 ||
1492 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1493 {
1494 tprintf ("%#lx", addr);
1495 return;
1496 }
1497
1498 tprintf ("[");
1499
1500 for (i = 0; i < len; ++i) {
1501 char *t, *p;
1502
1503 if (i) tprintf (", ");
1504
1505 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1506 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1507 {
1508 tprintf ("%s|%s", t, p);
1509 }
1510 else {
1511 tprintf ("%#lx", buf [i]);
1512 }
1513 }
1514
1515 if (dots) tprintf (" ...");
1516
1517 tprintf ("]");
1518}
1519
1520
1521int
1522sys_procpriv(tcp)
1523struct tcb *tcp;
1524{
1525 if (entering(tcp)) {
1526 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1527 switch (tcp->u_arg[0]) {
1528 case CNTPRV:
1529 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1530 break;
1531
1532 case GETPRV:
1533 break;
1534
1535 default:
1536 tprintf (", ");
1537 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1538 tprintf (", %ld", tcp->u_arg[2]);
1539 }
1540 }
1541 else if (tcp->u_arg[0] == GETPRV) {
1542 if (syserror (tcp)) {
1543 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1544 }
1545 else {
1546 tprintf (", ");
1547 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1548 tprintf (", %ld", tcp->u_arg[2]);
1549 }
1550 }
Roland McGrath5a223472002-12-15 23:58:26 +00001551
John Hughesc61eb3d2002-05-17 11:37:50 +00001552 return 0;
1553}
1554
1555#endif
1556
1557
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001558void
1559fake_execve(tcp, program, argv, envp)
1560struct tcb *tcp;
1561char *program;
1562char *argv[];
1563char *envp[];
1564{
1565 int i;
1566
1567#ifdef ARM
1568 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1569 return;
1570#else
1571 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1572 return;
1573#endif /* !ARM */
1574 printleader(tcp);
1575 tprintf("execve(");
1576 string_quote(program);
1577 tprintf(", [");
1578 for (i = 0; argv[i] != NULL; i++) {
1579 if (i != 0)
1580 tprintf(", ");
1581 string_quote(argv[i]);
1582 }
1583 for (i = 0; envp[i] != NULL; i++)
1584 ;
1585 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1586 tabto(acolumn);
1587 tprintf("= 0");
1588 printtrailer(tcp);
1589}
1590
1591static void
1592printargv(tcp, addr)
1593struct tcb *tcp;
1594long addr;
1595{
1596 char *cp;
1597 char *sep;
1598 int max = max_strlen / 2;
1599
1600 for (sep = ""; --max >= 0; sep = ", ") {
1601 if (!abbrev(tcp))
1602 max++;
1603 if (umove(tcp, addr, &cp) < 0) {
1604 tprintf("%#lx", addr);
1605 return;
1606 }
1607 if (cp == 0)
1608 break;
1609 tprintf(sep);
1610 printstr(tcp, (long) cp, -1);
1611 addr += sizeof(char *);
1612 }
1613 if (cp)
1614 tprintf(", ...");
1615}
1616
1617static void
1618printargc(fmt, tcp, addr)
1619char *fmt;
1620struct tcb *tcp;
1621long addr;
1622{
1623 int count;
1624 char *cp;
1625
1626 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1627 addr += sizeof(char *);
1628 }
1629 tprintf(fmt, count, count == 1 ? "" : "s");
1630}
1631
1632int
1633sys_execv(tcp)
1634struct tcb *tcp;
1635{
1636 if (entering(tcp)) {
1637 printpath(tcp, tcp->u_arg[0]);
1638 if (!verbose(tcp))
1639 tprintf(", %#lx", tcp->u_arg[1]);
1640#if 0
1641 else if (abbrev(tcp))
1642 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1643#endif
1644 else {
1645 tprintf(", [");
1646 printargv(tcp, tcp->u_arg[1]);
1647 tprintf("]");
1648 }
1649 }
1650 return 0;
1651}
1652
1653int
1654sys_execve(tcp)
1655struct tcb *tcp;
1656{
1657 if (entering(tcp)) {
1658 printpath(tcp, tcp->u_arg[0]);
1659 if (!verbose(tcp))
1660 tprintf(", %#lx", tcp->u_arg[1]);
1661#if 0
1662 else if (abbrev(tcp))
1663 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1664#endif
1665 else {
1666 tprintf(", [");
1667 printargv(tcp, tcp->u_arg[1]);
1668 tprintf("]");
1669 }
1670 if (!verbose(tcp))
1671 tprintf(", %#lx", tcp->u_arg[2]);
1672 else if (abbrev(tcp))
1673 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1674 else {
1675 tprintf(", [");
1676 printargv(tcp, tcp->u_arg[2]);
1677 tprintf("]");
1678 }
1679 }
Roland McGrathb4968be2003-01-20 09:04:33 +00001680#if defined LINUX && defined TCB_WAITEXECVE
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001681 tcp->flags |= TCB_WAITEXECVE;
Roland McGrathb4968be2003-01-20 09:04:33 +00001682#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001683 return 0;
1684}
1685
John Hughes4e36a812001-04-18 15:11:51 +00001686#if UNIXWARE > 2
1687
1688int sys_rexecve(tcp)
1689struct tcb *tcp;
1690{
1691 if (entering (tcp)) {
1692 sys_execve (tcp);
1693 tprintf (", %ld", tcp->u_arg[3]);
1694 }
1695 return 0;
1696}
1697
1698#endif
1699
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001700int
1701internal_exec(tcp)
1702struct tcb *tcp;
1703{
1704#ifdef SUNOS4
1705 if (exiting(tcp) && !syserror(tcp) && followfork)
1706 fixvfork(tcp);
1707#endif /* SUNOS4 */
1708 return 0;
1709}
1710
1711#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001712#ifndef __WNOTHREAD
1713#define __WNOTHREAD 0x20000000
1714#endif
1715#ifndef __WALL
1716#define __WALL 0x40000000
1717#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001718#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001719#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001720#endif
1721#endif /* LINUX */
1722
1723static struct xlat wait4_options[] = {
1724 { WNOHANG, "WNOHANG" },
1725#ifndef WSTOPPED
1726 { WUNTRACED, "WUNTRACED" },
1727#endif
1728#ifdef WEXITED
1729 { WEXITED, "WEXITED" },
1730#endif
1731#ifdef WTRAPPED
1732 { WTRAPPED, "WTRAPPED" },
1733#endif
1734#ifdef WSTOPPED
1735 { WSTOPPED, "WSTOPPED" },
1736#endif
1737#ifdef WCONTINUED
1738 { WCONTINUED, "WCONTINUED" },
1739#endif
1740#ifdef WNOWAIT
1741 { WNOWAIT, "WNOWAIT" },
1742#endif
1743#ifdef __WCLONE
1744 { __WCLONE, "__WCLONE" },
1745#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001746#ifdef __WALL
1747 { __WALL, "__WALL" },
1748#endif
1749#ifdef __WNOTHREAD
1750 { __WNOTHREAD, "__WNOTHREAD" },
1751#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001752 { 0, NULL },
1753};
1754
1755static int
1756printstatus(status)
1757int status;
1758{
1759 int exited = 0;
1760
1761 /*
1762 * Here is a tricky presentation problem. This solution
1763 * is still not entirely satisfactory but since there
1764 * are no wait status constructors it will have to do.
1765 */
1766 if (WIFSTOPPED(status))
1767 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001768 signame(WSTOPSIG(status)));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001769 else if WIFSIGNALED(status)
1770 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001771 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001772 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1773 else if WIFEXITED(status) {
1774 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1775 WEXITSTATUS(status));
1776 exited = 1;
1777 }
1778 else
1779 tprintf("[%#x]", status);
1780 return exited;
1781}
1782
1783static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001784printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001785struct tcb *tcp;
1786int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001787int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001788{
1789 int status;
1790 int exited = 0;
1791
1792 if (entering(tcp)) {
1793 tprintf("%ld, ", tcp->u_arg[0]);
1794 } else {
1795 /* status */
1796 if (!tcp->u_arg[1])
1797 tprintf("NULL");
1798 else if (syserror(tcp) || tcp->u_rval == 0)
1799 tprintf("%#lx", tcp->u_arg[1]);
1800 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1801 tprintf("[?]");
1802 else
1803 exited = printstatus(status);
1804 /* options */
1805 tprintf(", ");
1806 if (!printflags(wait4_options, tcp->u_arg[2]))
1807 tprintf("0");
1808 if (n == 4) {
1809 tprintf(", ");
1810 /* usage */
1811 if (!tcp->u_arg[3])
1812 tprintf("NULL");
1813#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001814 else if (tcp->u_rval > 0) {
1815#ifdef LINUX_64BIT
1816 if (bitness)
1817 printrusage32(tcp, tcp->u_arg[3]);
1818 else
1819#endif
1820 printrusage(tcp, tcp->u_arg[3]);
1821 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001822#endif /* LINUX */
1823#ifdef SUNOS4
1824 else if (tcp->u_rval > 0 && exited)
1825 printrusage(tcp, tcp->u_arg[3]);
1826#endif /* SUNOS4 */
1827 else
1828 tprintf("%#lx", tcp->u_arg[3]);
1829 }
1830 }
1831 return 0;
1832}
1833
1834int
1835internal_wait(tcp)
1836struct tcb *tcp;
1837{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001838 int got_kids;
1839
1840#ifdef TCB_CLONE_THREAD
1841 if (tcp->flags & TCB_CLONE_THREAD)
1842 /* The children we wait for are our parent's children. */
1843 got_kids = (tcp->parent->nchildren
1844 > tcp->parent->nclone_detached);
1845 else
1846 got_kids = (tcp->nchildren > tcp->nclone_detached);
1847#else
1848 got_kids = tcp->nchildren > 0;
1849#endif
1850
1851 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001852 /* There are children that this parent should block for.
1853 But ptrace made us the parent of the traced children
1854 and the real parent will get ECHILD from the wait call.
1855
1856 XXX If we attached with strace -f -p PID, then there
1857 may be untraced dead children the parent could be reaping
1858 now, but we make him block. */
1859
1860 /* ??? WTA: fix bug with hanging children */
1861
1862 if (!(tcp->u_arg[2] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00001863 /*
1864 * There are traced children. We'll make the parent
1865 * block to avoid a false ECHILD error due to our
1866 * ptrace having stolen the children. However,
1867 * we shouldn't block if there are zombies to reap.
1868 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1869 */
Roland McGrathfccfb942003-10-01 21:59:44 +00001870 struct tcb *child = NULL;
Roland McGrath09623452003-05-23 02:27:13 +00001871 if (tcp->nzombies > 0 &&
1872 (tcp->u_arg[0] == -1 ||
Roland McGrathfccfb942003-10-01 21:59:44 +00001873 (child = pid2tcb(tcp->u_arg[0])) == NULL))
Roland McGrath09623452003-05-23 02:27:13 +00001874 return 0;
Roland McGrathfccfb942003-10-01 21:59:44 +00001875 if (tcp->u_arg[0] > 0) {
1876 /*
1877 * If the parent waits for a specified child
1878 * PID, then it must get ECHILD right away
1879 * if that PID is not one of its children.
1880 * Make sure that the requested PID matches
1881 * one of the parent's children that we are
1882 * tracing, and don't suspend it otherwise.
1883 */
1884 if (child == NULL)
1885 child = pid2tcb(tcp->u_arg[0]);
1886 if (child == NULL || child->parent != (
1887#ifdef TCB_CLONE_THREAD
1888 (tcp->flags & TCB_CLONE_THREAD)
1889 ? tcp->parent :
1890#endif
1891 tcp))
1892 return 0;
1893 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001894 tcp->flags |= TCB_SUSPENDED;
1895 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001896#ifdef TCB_CLONE_THREAD
1897 if (tcp->flags & TCB_CLONE_THREAD)
1898 tcp->parent->nclone_waiting++;
1899#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001900 }
1901 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001902 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001903 if (tcp->u_arg[2] & WNOHANG) {
1904 /* We must force a fake result of 0 instead of
1905 the ECHILD error. */
1906 extern int force_result();
1907 return force_result(tcp, 0, 0);
1908 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00001909 }
Roland McGrath09623452003-05-23 02:27:13 +00001910 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
1911 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
1912 /*
1913 * We just reaped a child we don't know about,
1914 * presumably a zombie we already droptcb'd.
1915 */
1916 tcp->nzombies--;
1917 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001918 return 0;
1919}
1920
1921#ifdef SVR4
1922
1923int
1924sys_wait(tcp)
1925struct tcb *tcp;
1926{
1927 if (exiting(tcp)) {
1928 /* The library wrapper stuffs this into the user variable. */
1929 if (!syserror(tcp))
1930 printstatus(getrval2(tcp));
1931 }
1932 return 0;
1933}
1934
1935#endif /* SVR4 */
1936
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001937#ifdef FREEBSD
1938int
1939sys_wait(tcp)
1940struct tcb *tcp;
1941{
1942 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001943
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001944 if (exiting(tcp)) {
1945 if (!syserror(tcp)) {
1946 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1947 tprintf("%#lx", tcp->u_arg[0]);
1948 else
1949 printstatus(status);
1950 }
1951 }
1952 return 0;
1953}
1954#endif
1955
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001956int
1957sys_waitpid(tcp)
1958struct tcb *tcp;
1959{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001960 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001961}
1962
1963int
1964sys_wait4(tcp)
1965struct tcb *tcp;
1966{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001967 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001968}
1969
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001970#ifdef ALPHA
1971int
1972sys_osf_wait4(tcp)
1973struct tcb *tcp;
1974{
1975 return printwaitn(tcp, 4, 1);
1976}
1977#endif
1978
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001979#ifdef SVR4
1980
1981static struct xlat waitid_types[] = {
1982 { P_PID, "P_PID" },
1983 { P_PPID, "P_PPID" },
1984 { P_PGID, "P_PGID" },
1985 { P_SID, "P_SID" },
1986 { P_CID, "P_CID" },
1987 { P_UID, "P_UID" },
1988 { P_GID, "P_GID" },
1989 { P_ALL, "P_ALL" },
1990#ifdef P_LWPID
1991 { P_LWPID, "P_LWPID" },
1992#endif
1993 { 0, NULL },
1994};
1995
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001996int
1997sys_waitid(tcp)
1998struct tcb *tcp;
1999{
2000 siginfo_t si;
2001 int exited;
2002
2003 if (entering(tcp)) {
2004 printxval(waitid_types, tcp->u_arg[0], "P_???");
2005 tprintf(", %ld, ", tcp->u_arg[1]);
2006 if (tcp->nchildren > 0) {
2007 /* There are traced children */
2008 tcp->flags |= TCB_SUSPENDED;
2009 tcp->waitpid = tcp->u_arg[0];
2010 }
2011 }
2012 else {
2013 /* siginfo */
2014 exited = 0;
2015 if (!tcp->u_arg[2])
2016 tprintf("NULL");
2017 else if (syserror(tcp))
2018 tprintf("%#lx", tcp->u_arg[2]);
2019 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2020 tprintf("{???}");
2021 else
John Hughes58265892001-10-18 15:13:53 +00002022 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002023 /* options */
2024 tprintf(", ");
2025 if (!printflags(wait4_options, tcp->u_arg[3]))
2026 tprintf("0");
2027 }
2028 return 0;
2029}
2030
2031#endif /* SVR4 */
2032
2033int
2034sys_alarm(tcp)
2035struct tcb *tcp;
2036{
2037 if (entering(tcp))
2038 tprintf("%lu", tcp->u_arg[0]);
2039 return 0;
2040}
2041
2042int
2043sys_uname(tcp)
2044struct tcb *tcp;
2045{
2046 struct utsname uname;
2047
2048 if (exiting(tcp)) {
2049 if (syserror(tcp) || !verbose(tcp))
2050 tprintf("%#lx", tcp->u_arg[0]);
2051 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2052 tprintf("{...}");
2053 else if (!abbrev(tcp)) {
2054
2055 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2056 uname.sysname, uname.nodename);
2057 tprintf("release=\"%s\", version=\"%s\", ",
2058 uname.release, uname.version);
2059 tprintf("machine=\"%s\"", uname.machine);
2060#ifdef LINUX
2061#ifndef __GLIBC__
2062 tprintf(", domainname=\"%s\"", uname.domainname);
2063#endif /* __GLIBC__ */
2064#endif /* LINUX */
2065 tprintf("}");
2066 }
2067 else
2068 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2069 uname.sysname, uname.nodename);
2070 }
2071 return 0;
2072}
2073
2074#ifndef SVR4
2075
2076static struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002077#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002078 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2079 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2080 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2081 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2082 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2083 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2084 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2085 { PTRACE_CONT, "PTRACE_CONT" },
2086 { PTRACE_KILL, "PTRACE_KILL" },
2087 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2088 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2089 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002090#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002091 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002092#endif
2093#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002094 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002095#endif
2096#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002097 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002098#endif
2099#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002100 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002101#endif
2102#ifdef PTRACE_GETFPXREGS
2103 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2104#endif
2105#ifdef PTRACE_SETFPXREGS
2106 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2107#endif
2108#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002109 { PTRACE_READDATA, "PTRACE_READDATA" },
2110 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2111 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2112 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2113 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2114 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2115#ifdef SPARC
2116 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2117 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2118#else /* !SPARC */
2119 { PTRACE_22, "PTRACE_PTRACE_22" },
2120 { PTRACE_23, "PTRACE_PTRACE_23" },
2121#endif /* !SPARC */
2122#endif /* SUNOS4 */
2123 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2124#ifdef SUNOS4
2125 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2126#ifdef I386
2127 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2128 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2129 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2130#else /* !I386 */
2131 { PTRACE_26, "PTRACE_26" },
2132 { PTRACE_27, "PTRACE_27" },
2133 { PTRACE_28, "PTRACE_28" },
2134#endif /* !I386 */
2135 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2136#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002137#else /* FREEBSD */
2138 { PT_TRACE_ME, "PT_TRACE_ME" },
2139 { PT_READ_I, "PT_READ_I" },
2140 { PT_READ_D, "PT_READ_D" },
2141 { PT_WRITE_I, "PT_WRITE_I" },
2142 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002143#ifdef PT_READ_U
2144 { PT_READ_U, "PT_READ_U" },
2145#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002146 { PT_CONTINUE, "PT_CONTINUE" },
2147 { PT_KILL, "PT_KILL" },
2148 { PT_STEP, "PT_STEP" },
2149 { PT_ATTACH, "PT_ATTACH" },
2150 { PT_DETACH, "PT_DETACH" },
2151 { PT_GETREGS, "PT_GETREGS" },
2152 { PT_SETREGS, "PT_SETREGS" },
2153 { PT_GETFPREGS, "PT_GETFPREGS" },
2154 { PT_SETFPREGS, "PT_SETFPREGS" },
2155 { PT_GETDBREGS, "PT_GETDBREGS" },
2156 { PT_SETDBREGS, "PT_SETDBREGS" },
2157#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002158 { 0, NULL },
2159};
2160
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002161#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002162#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2163static
2164#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2165struct xlat struct_user_offsets[] = {
2166#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002167#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002168 { PT_PSWMASK, "psw_mask" },
2169 { PT_PSWADDR, "psw_addr" },
2170 { PT_GPR0, "gpr0" },
2171 { PT_GPR1, "gpr1" },
2172 { PT_GPR2, "gpr2" },
2173 { PT_GPR3, "gpr3" },
2174 { PT_GPR4, "gpr4" },
2175 { PT_GPR5, "gpr5" },
2176 { PT_GPR6, "gpr6" },
2177 { PT_GPR7, "gpr7" },
2178 { PT_GPR8, "gpr8" },
2179 { PT_GPR9, "gpr9" },
2180 { PT_GPR10, "gpr10" },
2181 { PT_GPR11, "gpr11" },
2182 { PT_GPR12, "gpr12" },
2183 { PT_GPR13, "gpr13" },
2184 { PT_GPR14, "gpr14" },
2185 { PT_GPR15, "gpr15" },
2186 { PT_ACR0, "acr0" },
2187 { PT_ACR1, "acr1" },
2188 { PT_ACR2, "acr2" },
2189 { PT_ACR3, "acr3" },
2190 { PT_ACR4, "acr4" },
2191 { PT_ACR5, "acr5" },
2192 { PT_ACR6, "acr6" },
2193 { PT_ACR7, "acr7" },
2194 { PT_ACR8, "acr8" },
2195 { PT_ACR9, "acr9" },
2196 { PT_ACR10, "acr10" },
2197 { PT_ACR11, "acr11" },
2198 { PT_ACR12, "acr12" },
2199 { PT_ACR13, "acr13" },
2200 { PT_ACR14, "acr14" },
2201 { PT_ACR15, "acr15" },
2202 { PT_ORIGGPR2, "orig_gpr2" },
2203 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002204#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002205 { PT_FPR0_HI, "fpr0.hi" },
2206 { PT_FPR0_LO, "fpr0.lo" },
2207 { PT_FPR1_HI, "fpr1.hi" },
2208 { PT_FPR1_LO, "fpr1.lo" },
2209 { PT_FPR2_HI, "fpr2.hi" },
2210 { PT_FPR2_LO, "fpr2.lo" },
2211 { PT_FPR3_HI, "fpr3.hi" },
2212 { PT_FPR3_LO, "fpr3.lo" },
2213 { PT_FPR4_HI, "fpr4.hi" },
2214 { PT_FPR4_LO, "fpr4.lo" },
2215 { PT_FPR5_HI, "fpr5.hi" },
2216 { PT_FPR5_LO, "fpr5.lo" },
2217 { PT_FPR6_HI, "fpr6.hi" },
2218 { PT_FPR6_LO, "fpr6.lo" },
2219 { PT_FPR7_HI, "fpr7.hi" },
2220 { PT_FPR7_LO, "fpr7.lo" },
2221 { PT_FPR8_HI, "fpr8.hi" },
2222 { PT_FPR8_LO, "fpr8.lo" },
2223 { PT_FPR9_HI, "fpr9.hi" },
2224 { PT_FPR9_LO, "fpr9.lo" },
2225 { PT_FPR10_HI, "fpr10.hi" },
2226 { PT_FPR10_LO, "fpr10.lo" },
2227 { PT_FPR11_HI, "fpr11.hi" },
2228 { PT_FPR11_LO, "fpr11.lo" },
2229 { PT_FPR12_HI, "fpr12.hi" },
2230 { PT_FPR12_LO, "fpr12.lo" },
2231 { PT_FPR13_HI, "fpr13.hi" },
2232 { PT_FPR13_LO, "fpr13.lo" },
2233 { PT_FPR14_HI, "fpr14.hi" },
2234 { PT_FPR14_LO, "fpr14.lo" },
2235 { PT_FPR15_HI, "fpr15.hi" },
2236 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002237#endif
2238#if defined(S390X)
2239 { PT_FPR0, "fpr0" },
2240 { PT_FPR1, "fpr1" },
2241 { PT_FPR2, "fpr2" },
2242 { PT_FPR3, "fpr3" },
2243 { PT_FPR4, "fpr4" },
2244 { PT_FPR5, "fpr5" },
2245 { PT_FPR6, "fpr6" },
2246 { PT_FPR7, "fpr7" },
2247 { PT_FPR8, "fpr8" },
2248 { PT_FPR9, "fpr9" },
2249 { PT_FPR10, "fpr10" },
2250 { PT_FPR11, "fpr11" },
2251 { PT_FPR12, "fpr12" },
2252 { PT_FPR13, "fpr13" },
2253 { PT_FPR14, "fpr14" },
2254 { PT_FPR15, "fpr15" },
2255#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002256 { PT_CR_9, "cr9" },
2257 { PT_CR_10, "cr10" },
2258 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002259 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002260#endif
2261#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002262 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002263#elif defined(HPPA)
2264 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002265#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002266#ifndef PT_ORIG_R3
2267#define PT_ORIG_R3 34
2268#endif
Roland McGratheb285352003-01-14 09:59:00 +00002269#define REGSIZE (sizeof(unsigned long))
2270 { REGSIZE*PT_R0, "r0" },
2271 { REGSIZE*PT_R1, "r1" },
2272 { REGSIZE*PT_R2, "r2" },
2273 { REGSIZE*PT_R3, "r3" },
2274 { REGSIZE*PT_R4, "r4" },
2275 { REGSIZE*PT_R5, "r5" },
2276 { REGSIZE*PT_R6, "r6" },
2277 { REGSIZE*PT_R7, "r7" },
2278 { REGSIZE*PT_R8, "r8" },
2279 { REGSIZE*PT_R9, "r9" },
2280 { REGSIZE*PT_R10, "r10" },
2281 { REGSIZE*PT_R11, "r11" },
2282 { REGSIZE*PT_R12, "r12" },
2283 { REGSIZE*PT_R13, "r13" },
2284 { REGSIZE*PT_R14, "r14" },
2285 { REGSIZE*PT_R15, "r15" },
2286 { REGSIZE*PT_R16, "r16" },
2287 { REGSIZE*PT_R17, "r17" },
2288 { REGSIZE*PT_R18, "r18" },
2289 { REGSIZE*PT_R19, "r19" },
2290 { REGSIZE*PT_R20, "r20" },
2291 { REGSIZE*PT_R21, "r21" },
2292 { REGSIZE*PT_R22, "r22" },
2293 { REGSIZE*PT_R23, "r23" },
2294 { REGSIZE*PT_R24, "r24" },
2295 { REGSIZE*PT_R25, "r25" },
2296 { REGSIZE*PT_R26, "r26" },
2297 { REGSIZE*PT_R27, "r27" },
2298 { REGSIZE*PT_R28, "r28" },
2299 { REGSIZE*PT_R29, "r29" },
2300 { REGSIZE*PT_R30, "r30" },
2301 { REGSIZE*PT_R31, "r31" },
2302 { REGSIZE*PT_NIP, "NIP" },
2303 { REGSIZE*PT_MSR, "MSR" },
2304 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2305 { REGSIZE*PT_CTR, "CTR" },
2306 { REGSIZE*PT_LNK, "LNK" },
2307 { REGSIZE*PT_XER, "XER" },
2308 { REGSIZE*PT_CCR, "CCR" },
2309 { REGSIZE*PT_FPR0, "FPR0" },
2310#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002311#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002312#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002313 { 0, "r0" },
2314 { 1, "r1" },
2315 { 2, "r2" },
2316 { 3, "r3" },
2317 { 4, "r4" },
2318 { 5, "r5" },
2319 { 6, "r6" },
2320 { 7, "r7" },
2321 { 8, "r8" },
2322 { 9, "r9" },
2323 { 10, "r10" },
2324 { 11, "r11" },
2325 { 12, "r12" },
2326 { 13, "r13" },
2327 { 14, "r14" },
2328 { 15, "r15" },
2329 { 16, "r16" },
2330 { 17, "r17" },
2331 { 18, "r18" },
2332 { 19, "r19" },
2333 { 20, "r20" },
2334 { 21, "r21" },
2335 { 22, "r22" },
2336 { 23, "r23" },
2337 { 24, "r24" },
2338 { 25, "r25" },
2339 { 26, "r26" },
2340 { 27, "r27" },
2341 { 28, "r28" },
2342 { 29, "gp" },
2343 { 30, "fp" },
2344 { 31, "zero" },
2345 { 32, "fp0" },
2346 { 33, "fp" },
2347 { 34, "fp2" },
2348 { 35, "fp3" },
2349 { 36, "fp4" },
2350 { 37, "fp5" },
2351 { 38, "fp6" },
2352 { 39, "fp7" },
2353 { 40, "fp8" },
2354 { 41, "fp9" },
2355 { 42, "fp10" },
2356 { 43, "fp11" },
2357 { 44, "fp12" },
2358 { 45, "fp13" },
2359 { 46, "fp14" },
2360 { 47, "fp15" },
2361 { 48, "fp16" },
2362 { 49, "fp17" },
2363 { 50, "fp18" },
2364 { 51, "fp19" },
2365 { 52, "fp20" },
2366 { 53, "fp21" },
2367 { 54, "fp22" },
2368 { 55, "fp23" },
2369 { 56, "fp24" },
2370 { 57, "fp25" },
2371 { 58, "fp26" },
2372 { 59, "fp27" },
2373 { 60, "fp28" },
2374 { 61, "fp29" },
2375 { 62, "fp30" },
2376 { 63, "fp31" },
2377 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002378#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002379#ifdef IA64
2380 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2381 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2382 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2383 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2384 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2385 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2386 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2387 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2388 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2389 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2390 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2391 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2392 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2393 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2394 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2395 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2396 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2397 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2398 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2399 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2400 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2401 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2402 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2403 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2404 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2405 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2406 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2407 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2408 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2409 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2410 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2411 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2412 /* switch stack: */
2413 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2414 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2415 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2416 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2417 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2418 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2419 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2420 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2421 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2422 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002423 { PT_B0, "kb0" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002424 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2425 { PT_B4, "b4" }, { PT_B5, "b5" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002426 { PT_AR_PFS, "kar.pfs" },
2427 { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" },
2428 { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" },
2429 { PT_PR, "k.pr" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002430 /* pt_regs */
2431 { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002432 /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002433 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2434 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2435 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2436 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2437 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2438 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2439 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2440 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2441 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2442 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2443 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2444 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2445 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2446 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2447 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2448#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002449#ifdef I386
2450 { 4*EBX, "4*EBX" },
2451 { 4*ECX, "4*ECX" },
2452 { 4*EDX, "4*EDX" },
2453 { 4*ESI, "4*ESI" },
2454 { 4*EDI, "4*EDI" },
2455 { 4*EBP, "4*EBP" },
2456 { 4*EAX, "4*EAX" },
2457 { 4*DS, "4*DS" },
2458 { 4*ES, "4*ES" },
2459 { 4*FS, "4*FS" },
2460 { 4*GS, "4*GS" },
2461 { 4*ORIG_EAX, "4*ORIG_EAX" },
2462 { 4*EIP, "4*EIP" },
2463 { 4*CS, "4*CS" },
2464 { 4*EFL, "4*EFL" },
2465 { 4*UESP, "4*UESP" },
2466 { 4*SS, "4*SS" },
2467#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002468#ifdef X86_64
2469 { 8*RDI, "8*RDI" },
2470 { 8*RSI, "8*RSI" },
2471 { 8*RDX, "8*RDX" },
2472 { 8*R10, "8*R10" },
2473 { 8*R8, "8*R8" },
2474 { 8*R9, "8*R9" },
2475 { 8*RBX, "8*RBX" },
2476 { 8*RCX, "8*RCX" },
2477 { 8*RBP, "8*RBP" },
2478 { 8*RAX, "8*RAX" },
2479#if 0
2480 { 8*DS, "8*DS" },
2481 { 8*ES, "8*ES" },
2482 { 8*FS, "8*FS" },
2483 { 8*GS, "8*GS" },
2484#endif
2485 { 8*ORIG_RAX, "8*ORIG_EAX" },
2486 { 8*RIP, "8*RIP" },
2487 { 8*CS, "8*CS" },
2488 { 8*EFLAGS, "8*EFL" },
2489 { 8*RSP, "8*RSP" },
2490 { 8*SS, "8*SS" },
2491 { 8*R11, "8*R11" },
2492 { 8*R12, "8*R12" },
2493 { 8*R13, "8*R13" },
2494 { 8*R14, "8*R14" },
2495 { 8*R15, "8*R15" },
2496#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002497#ifdef M68K
2498 { 4*PT_D1, "4*PT_D1" },
2499 { 4*PT_D2, "4*PT_D2" },
2500 { 4*PT_D3, "4*PT_D3" },
2501 { 4*PT_D4, "4*PT_D4" },
2502 { 4*PT_D5, "4*PT_D5" },
2503 { 4*PT_D6, "4*PT_D6" },
2504 { 4*PT_D7, "4*PT_D7" },
2505 { 4*PT_A0, "4*PT_A0" },
2506 { 4*PT_A1, "4*PT_A1" },
2507 { 4*PT_A2, "4*PT_A2" },
2508 { 4*PT_A3, "4*PT_A3" },
2509 { 4*PT_A4, "4*PT_A4" },
2510 { 4*PT_A5, "4*PT_A5" },
2511 { 4*PT_A6, "4*PT_A6" },
2512 { 4*PT_D0, "4*PT_D0" },
2513 { 4*PT_USP, "4*PT_USP" },
2514 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2515 { 4*PT_SR, "4*PT_SR" },
2516 { 4*PT_PC, "4*PT_PC" },
2517#endif /* M68K */
2518#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002519#ifdef SH
2520 { 4*REG_REG0, "4*REG_REG0" },
2521 { 4*(REG_REG0+1), "4*REG_REG1" },
2522 { 4*(REG_REG0+2), "4*REG_REG2" },
2523 { 4*(REG_REG0+3), "4*REG_REG3" },
2524 { 4*(REG_REG0+4), "4*REG_REG4" },
2525 { 4*(REG_REG0+5), "4*REG_REG5" },
2526 { 4*(REG_REG0+6), "4*REG_REG6" },
2527 { 4*(REG_REG0+7), "4*REG_REG7" },
2528 { 4*(REG_REG0+8), "4*REG_REG8" },
2529 { 4*(REG_REG0+9), "4*REG_REG9" },
2530 { 4*(REG_REG0+10), "4*REG_REG10" },
2531 { 4*(REG_REG0+11), "4*REG_REG11" },
2532 { 4*(REG_REG0+12), "4*REG_REG12" },
2533 { 4*(REG_REG0+13), "4*REG_REG13" },
2534 { 4*(REG_REG0+14), "4*REG_REG14" },
2535 { 4*REG_REG15, "4*REG_REG15" },
2536 { 4*REG_PC, "4*REG_PC" },
2537 { 4*REG_PR, "4*REG_PR" },
2538 { 4*REG_SR, "4*REG_SR" },
2539 { 4*REG_GBR, "4*REG_GBR" },
2540 { 4*REG_MACH, "4*REG_MACH" },
2541 { 4*REG_MACL, "4*REG_MACL" },
2542 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2543 { 4*REG_FPUL, "4*REG_FPUL" },
2544 { 4*REG_FPREG0, "4*REG_FPREG0" },
2545 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2546 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2547 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2548 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2549 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2550 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2551 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2552 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2553 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2554 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2555 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2556 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2557 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2558 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2559 { 4*REG_FPREG15, "4*REG_FPREG15" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002560#ifdef REG_XDREG0
Wichert Akkermanccef6372002-05-01 16:39:22 +00002561 { 4*REG_XDREG0, "4*REG_XDREG0" },
2562 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2563 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2564 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2565 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2566 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2567 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2568 { 4*REG_XDREG14, "4*REG_XDREG14" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002569#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002570 { 4*REG_FPSCR, "4*REG_FPSCR" },
2571#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002572#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002573 { 0, "PC(L)" },
2574 { 4, "PC(U)" },
2575 { 8, "SR(L)" },
2576 { 12, "SR(U)" },
2577 { 16, "syscall no.(L)" },
2578 { 20, "syscall_no.(U)" },
2579 { 24, "R0(L)" },
2580 { 28, "R0(U)" },
2581 { 32, "R1(L)" },
2582 { 36, "R1(U)" },
2583 { 40, "R2(L)" },
2584 { 44, "R2(U)" },
2585 { 48, "R3(L)" },
2586 { 52, "R3(U)" },
2587 { 56, "R4(L)" },
2588 { 60, "R4(U)" },
2589 { 64, "R5(L)" },
2590 { 68, "R5(U)" },
2591 { 72, "R6(L)" },
2592 { 76, "R6(U)" },
2593 { 80, "R7(L)" },
2594 { 84, "R7(U)" },
2595 { 88, "R8(L)" },
2596 { 92, "R8(U)" },
2597 { 96, "R9(L)" },
2598 { 100, "R9(U)" },
2599 { 104, "R10(L)" },
2600 { 108, "R10(U)" },
2601 { 112, "R11(L)" },
2602 { 116, "R11(U)" },
2603 { 120, "R12(L)" },
2604 { 124, "R12(U)" },
2605 { 128, "R13(L)" },
2606 { 132, "R13(U)" },
2607 { 136, "R14(L)" },
2608 { 140, "R14(U)" },
2609 { 144, "R15(L)" },
2610 { 148, "R15(U)" },
2611 { 152, "R16(L)" },
2612 { 156, "R16(U)" },
2613 { 160, "R17(L)" },
2614 { 164, "R17(U)" },
2615 { 168, "R18(L)" },
2616 { 172, "R18(U)" },
2617 { 176, "R19(L)" },
2618 { 180, "R19(U)" },
2619 { 184, "R20(L)" },
2620 { 188, "R20(U)" },
2621 { 192, "R21(L)" },
2622 { 196, "R21(U)" },
2623 { 200, "R22(L)" },
2624 { 204, "R22(U)" },
2625 { 208, "R23(L)" },
2626 { 212, "R23(U)" },
2627 { 216, "R24(L)" },
2628 { 220, "R24(U)" },
2629 { 224, "R25(L)" },
2630 { 228, "R25(U)" },
2631 { 232, "R26(L)" },
2632 { 236, "R26(U)" },
2633 { 240, "R27(L)" },
2634 { 244, "R27(U)" },
2635 { 248, "R28(L)" },
2636 { 252, "R28(U)" },
2637 { 256, "R29(L)" },
2638 { 260, "R29(U)" },
2639 { 264, "R30(L)" },
2640 { 268, "R30(U)" },
2641 { 272, "R31(L)" },
2642 { 276, "R31(U)" },
2643 { 280, "R32(L)" },
2644 { 284, "R32(U)" },
2645 { 288, "R33(L)" },
2646 { 292, "R33(U)" },
2647 { 296, "R34(L)" },
2648 { 300, "R34(U)" },
2649 { 304, "R35(L)" },
2650 { 308, "R35(U)" },
2651 { 312, "R36(L)" },
2652 { 316, "R36(U)" },
2653 { 320, "R37(L)" },
2654 { 324, "R37(U)" },
2655 { 328, "R38(L)" },
2656 { 332, "R38(U)" },
2657 { 336, "R39(L)" },
2658 { 340, "R39(U)" },
2659 { 344, "R40(L)" },
2660 { 348, "R40(U)" },
2661 { 352, "R41(L)" },
2662 { 356, "R41(U)" },
2663 { 360, "R42(L)" },
2664 { 364, "R42(U)" },
2665 { 368, "R43(L)" },
2666 { 372, "R43(U)" },
2667 { 376, "R44(L)" },
2668 { 380, "R44(U)" },
2669 { 384, "R45(L)" },
2670 { 388, "R45(U)" },
2671 { 392, "R46(L)" },
2672 { 396, "R46(U)" },
2673 { 400, "R47(L)" },
2674 { 404, "R47(U)" },
2675 { 408, "R48(L)" },
2676 { 412, "R48(U)" },
2677 { 416, "R49(L)" },
2678 { 420, "R49(U)" },
2679 { 424, "R50(L)" },
2680 { 428, "R50(U)" },
2681 { 432, "R51(L)" },
2682 { 436, "R51(U)" },
2683 { 440, "R52(L)" },
2684 { 444, "R52(U)" },
2685 { 448, "R53(L)" },
2686 { 452, "R53(U)" },
2687 { 456, "R54(L)" },
2688 { 460, "R54(U)" },
2689 { 464, "R55(L)" },
2690 { 468, "R55(U)" },
2691 { 472, "R56(L)" },
2692 { 476, "R56(U)" },
2693 { 480, "R57(L)" },
2694 { 484, "R57(U)" },
2695 { 488, "R58(L)" },
2696 { 492, "R58(U)" },
2697 { 496, "R59(L)" },
2698 { 500, "R59(U)" },
2699 { 504, "R60(L)" },
2700 { 508, "R60(U)" },
2701 { 512, "R61(L)" },
2702 { 516, "R61(U)" },
2703 { 520, "R62(L)" },
2704 { 524, "R62(U)" },
2705 { 528, "TR0(L)" },
2706 { 532, "TR0(U)" },
2707 { 536, "TR1(L)" },
2708 { 540, "TR1(U)" },
2709 { 544, "TR2(L)" },
2710 { 548, "TR2(U)" },
2711 { 552, "TR3(L)" },
2712 { 556, "TR3(U)" },
2713 { 560, "TR4(L)" },
2714 { 564, "TR4(U)" },
2715 { 568, "TR5(L)" },
2716 { 572, "TR5(U)" },
2717 { 576, "TR6(L)" },
2718 { 580, "TR6(U)" },
2719 { 584, "TR7(L)" },
2720 { 588, "TR7(U)" },
2721 /* This entry is in case pt_regs contains dregs (depends on
2722 the kernel build options). */
2723 { uoff(regs), "offsetof(struct user, regs)" },
2724 { uoff(fpu), "offsetof(struct user, fpu)" },
2725#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002726#ifdef ARM
2727 { uoff(regs.ARM_r0), "r0" },
2728 { uoff(regs.ARM_r1), "r1" },
2729 { uoff(regs.ARM_r2), "r2" },
2730 { uoff(regs.ARM_r3), "r3" },
2731 { uoff(regs.ARM_r4), "r4" },
2732 { uoff(regs.ARM_r5), "r5" },
2733 { uoff(regs.ARM_r6), "r6" },
2734 { uoff(regs.ARM_r7), "r7" },
2735 { uoff(regs.ARM_r8), "r8" },
2736 { uoff(regs.ARM_r9), "r9" },
2737 { uoff(regs.ARM_r10), "r10" },
2738 { uoff(regs.ARM_fp), "fp" },
2739 { uoff(regs.ARM_ip), "ip" },
2740 { uoff(regs.ARM_sp), "sp" },
2741 { uoff(regs.ARM_lr), "lr" },
2742 { uoff(regs.ARM_pc), "pc" },
2743 { uoff(regs.ARM_cpsr), "cpsr" },
2744#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002745
Michal Ludvig10a88d02002-10-07 14:31:00 +00002746#if !defined(S390) && !defined(S390X) && !defined(MIPS)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002747 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002748#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002749#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002750 { uoff(i387), "offsetof(struct user, i387)" },
2751#else /* !I386 */
2752#ifdef M68K
2753 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2754#endif /* M68K */
2755#endif /* !I386 */
2756 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2757 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2758 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2759 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrathf5a47772003-06-26 22:40:42 +00002760#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002761 { uoff(start_data), "offsetof(struct user, start_data)" },
2762#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002763 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2764 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrathf5a47772003-06-26 22:40:42 +00002765#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002766 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002767#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002768 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002769#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002770 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2771#endif
2772 { uoff(magic), "offsetof(struct user, magic)" },
2773 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002774#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002775 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2776#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002777#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002778#endif /* !ALPHA */
2779#endif /* !POWERPC/!SPARC */
2780#endif /* LINUX */
2781#ifdef SUNOS4
2782 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2783 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2784 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2785 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2786 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2787 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2788 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2789 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2790 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2791 { uoff(u_error), "offsetof(struct user, u_error)" },
2792 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2793 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2794 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2795 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2796 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2797 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2798 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2799 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2800 { uoff(u_code), "offsetof(struct user, u_code)" },
2801 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2802 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2803 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2804 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2805 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2806 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2807 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2808 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2809 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2810 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2811 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2812 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2813 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2814 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2815 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2816 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2817 { uoff(u_start), "offsetof(struct user, u_start)" },
2818 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2819 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2820 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2821 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2822 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2823 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2824 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2825 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2826 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2827#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002828#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002829 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002830#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002831 { 0, NULL },
2832};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002833#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002834
2835int
2836sys_ptrace(tcp)
2837struct tcb *tcp;
2838{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002839 struct xlat *x;
2840 long addr;
2841
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002842 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002843 printxval(ptrace_cmds, tcp->u_arg[0],
2844#ifndef FREEBSD
2845 "PTRACE_???"
2846#else
2847 "PT_???"
2848#endif
2849 );
2850 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002851 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002852#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002853 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2854 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2855 for (x = struct_user_offsets; x->str; x++) {
2856 if (x->val >= addr)
2857 break;
2858 }
2859 if (!x->str)
2860 tprintf("%#lx, ", addr);
2861 else if (x->val > addr && x != struct_user_offsets) {
2862 x--;
2863 tprintf("%s + %ld, ", x->str, addr - x->val);
2864 }
2865 else
2866 tprintf("%s, ", x->str);
2867 }
2868 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002869#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002870 tprintf("%#lx, ", tcp->u_arg[2]);
2871#ifdef LINUX
2872 switch (tcp->u_arg[0]) {
2873 case PTRACE_PEEKDATA:
2874 case PTRACE_PEEKTEXT:
2875 case PTRACE_PEEKUSER:
2876 break;
2877 case PTRACE_CONT:
2878 case PTRACE_SINGLESTEP:
2879 case PTRACE_SYSCALL:
2880 case PTRACE_DETACH:
2881 printsignal(tcp->u_arg[3]);
2882 break;
2883 default:
2884 tprintf("%#lx", tcp->u_arg[3]);
2885 break;
2886 }
2887 } else {
2888 switch (tcp->u_arg[0]) {
2889 case PTRACE_PEEKDATA:
2890 case PTRACE_PEEKTEXT:
2891 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00002892 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002893 break;
2894 }
2895 }
2896#endif /* LINUX */
2897#ifdef SUNOS4
2898 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2899 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2900 tprintf("%lu, ", tcp->u_arg[3]);
2901 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2902 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2903 tcp->u_arg[0] != PTRACE_READTEXT) {
2904 tprintf("%#lx", tcp->u_arg[3]);
2905 }
2906 } else {
2907 if (tcp->u_arg[0] == PTRACE_READDATA ||
2908 tcp->u_arg[0] == PTRACE_READTEXT) {
2909 tprintf("%lu, ", tcp->u_arg[3]);
2910 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2911 }
2912 }
2913#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002914#ifdef FREEBSD
2915 tprintf("%lu", tcp->u_arg[3]);
2916 }
2917#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002918 return 0;
2919}
2920
2921#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002922
2923#ifdef LINUX
2924static struct xlat futexops[] = {
2925 { FUTEX_WAIT, "FUTEX_WAIT" },
2926 { FUTEX_WAKE, "FUTEX_WAKE" },
2927 { FUTEX_FD, "FUTEX_FD" },
Roland McGrath88812d62003-06-26 22:27:23 +00002928 { FUTEX_REQUEUE,"FUTEX_REQUEUE" },
Roland McGrath5a223472002-12-15 23:58:26 +00002929 { 0, NULL }
2930};
2931
2932int
2933sys_futex(tcp)
2934struct tcb *tcp;
2935{
2936 if (entering(tcp)) {
2937 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00002938 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00002939 tprintf(", %ld", tcp->u_arg[2]);
2940 if (tcp->u_arg[1] == FUTEX_WAIT) {
2941 tprintf(", ");
2942 printtv(tcp, tcp->u_arg[3]);
Roland McGrath88812d62003-06-26 22:27:23 +00002943 } else if (tcp->u_arg[1] == FUTEX_REQUEUE)
2944 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath5a223472002-12-15 23:58:26 +00002945 }
2946 return 0;
2947}
2948
2949static void
2950print_affinitylist(list, len)
2951unsigned long *list;
2952unsigned int len;
2953{
2954 int first = 1;
2955 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00002956 while (len >= sizeof (unsigned long)) {
Roland McGrath5a223472002-12-15 23:58:26 +00002957 tprintf("%s %lx", first ? "" : ",", *list++);
2958 first = 0;
2959 len -= sizeof (unsigned long);
2960 }
2961 tprintf(" }");
2962}
2963
2964int
2965sys_sched_setaffinity(tcp)
2966struct tcb *tcp;
2967{
2968 if (entering(tcp)) {
2969 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2970 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2971 }
2972 return 0;
2973}
2974
2975int
2976sys_sched_getaffinity(tcp)
2977struct tcb *tcp;
2978{
2979 if (entering(tcp)) {
2980 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2981 } else {
2982 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);
2983 }
2984 return 0;
2985}
2986#endif