blob: 9ae689ea36cafe91455180c136dbe39aa3f9137d [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
John Hughesae259332004-01-29 11:17:50 +0000614sys_rfork(tcp)
615struct tcb *tcp;
616{
617 if (entering(tcp)) {
618 tprintf ("%ld", tcp->u_arg[0]);
619 }
620 else {
621 return RVAL_UDECIMAL;
622 }
623 return 0;
624}
625
626int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000627change_syscall(tcp, new)
628struct tcb *tcp;
629int new;
630{
631#if defined(LINUX)
632#if defined(I386)
633 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000634 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000635 return -1;
636 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000637#elif defined(X86_64)
638 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000639 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000640 return -1;
641 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000642#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000643 if (ptrace(PTRACE_POKEUSER, tcp->pid,
644 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000645 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000646 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000647#elif defined(S390) || defined(S390X)
648 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
649 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
650 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000651 return 0;
652#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000653 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000654 return -1;
655 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000656#elif defined(SPARC)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000657 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000658 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
659 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000660 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000661 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
662 return -1;
663 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000664#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000665 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000666 return -1;
667 return 0;
668#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000669 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000670 return -1;
671 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000672#elif defined(IA64)
673 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
674 return -1;
675 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000676#elif defined(HPPA)
677 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
678 return -1;
679 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000680#elif defined(SH)
Roland McGrathac971c22003-03-31 01:03:33 +0000681 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
Wichert Akkermanccef6372002-05-01 16:39:22 +0000682 return -1;
683 return 0;
Roland McGrathf5a47772003-06-26 22:40:42 +0000684#elif defined(SH64)
Roland McGrathe1e584b2003-06-02 19:18:58 +0000685 /* Top half of reg encodes the no. of args n as 0x1n.
686 Assume 0 args as kernel never actually checks... */
687 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
688 0x100000 | new) < 0)
689 return -1;
690 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000691#else
692#warning Do not know how to handle change_syscall for this architecture
693#endif /* architecture */
694#endif /* LINUX */
695 return -1;
696}
697
698int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000699setarg(tcp, argnum)
700 struct tcb *tcp;
701 int argnum;
702{
703#if defined (IA64)
704 {
705 unsigned long *bsp, *ap;
706
707 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
708 return -1;
709
710 ap = ia64_rse_skip_regs(bsp, argnum);
711 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000712 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000713 if (errno)
714 return -1;
715
716 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000717#elif defined(I386)
718 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000719 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000720 if (errno)
721 return -1;
722 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000723#elif defined(X86_64)
724 {
725 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
726 if (errno)
727 return -1;
728 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000729#elif defined(POWERPC)
730#ifndef PT_ORIG_R3
731#define PT_ORIG_R3 34
732#endif
733 {
734 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000735 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000736 tcp->u_arg[argnum]);
737 if (errno)
738 return -1;
739 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000740#elif defined(MIPS)
741 {
742 errno = 0;
743 if (argnum < 4)
744 ptrace(PTRACE_POKEUSER, tcp->pid,
745 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
746 else {
747 unsigned long *sp;
748
749 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
750 return -1;
751
752 ptrace(PTRACE_POKEDATA, tcp->pid,
753 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
754 }
755 if (errno)
756 return -1;
757 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000758#elif defined(S390) || defined(S390X)
759 {
760 if(argnum <= 5)
761 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000762 (char *) (argnum==0 ? PT_ORIGGPR2 :
763 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000764 tcp->u_arg[argnum]);
765 else
766 return -E2BIG;
767 if (errno)
768 return -1;
769 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000770#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000771# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000772#endif
773 return 0;
774}
775
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000776#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000777int
778internal_clone(tcp)
779struct tcb *tcp;
780{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000781 struct tcb *tcpchild;
782 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000783 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000784 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000785 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000786 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000787 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000788 if (setbpt(tcp) < 0)
789 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000790 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000791 int bpt = tcp->flags & TCB_BPTSET;
792
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000793 if (!(tcp->flags & TCB_FOLLOWFORK))
794 return 0;
795
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000796 if (syserror(tcp)) {
797 if (bpt)
798 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000799 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000800 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000801
802 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000803
804#ifdef CLONE_PTRACE /* See new setbpt code. */
805 tcpchild = pid2tcb(pid);
806 if (tcpchild != NULL) {
807 /* The child already reported its startup trap
808 before the parent reported its syscall return. */
809 if ((tcpchild->flags
810 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
811 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
812 fprintf(stderr, "\
813[preattached child %d of %d in weird state!]\n",
814 pid, tcp->pid);
815 }
816 else
817#endif
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000818 if ((tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000819 if (bpt)
820 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000821 fprintf(stderr, " [tcb table full]\n");
822 kill(pid, SIGKILL); /* XXX */
823 return 0;
824 }
825
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000826#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000827 /* Attach to the new child */
828 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000829 if (bpt)
830 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000831 perror("PTRACE_ATTACH");
832 fprintf(stderr, "Too late?\n");
833 droptcb(tcpchild);
834 return 0;
835 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000836#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000837
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000838 if (bpt)
839 clearbpt(tcp);
840
Ulrich Drepper90512f01999-12-24 07:22:25 +0000841 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000842 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000843 if (bpt) {
844 tcpchild->flags |= TCB_BPTSET;
845 tcpchild->baddr = tcp->baddr;
846 memcpy(tcpchild->inst, tcp->inst,
847 sizeof tcpchild->inst);
848 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000849 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000850 tcp->nchildren++;
851 if (tcpchild->flags & TCB_SUSPENDED) {
852 /* The child was born suspended, due to our having
853 forced CLONE_PTRACE. */
854 if (bpt)
855 clearbpt(tcpchild);
856
857 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
858 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
859 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
860 return -1;
861 }
862
863 if (!qflag)
864 fprintf(stderr, "\
865Process %u resumed (parent %d ready)\n",
866 pid, tcp->pid);
867 }
868 else {
869 newoutf(tcpchild);
870 if (!qflag)
871 fprintf(stderr, "Process %d attached\n", pid);
872 }
873
874#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000875 {
876 /*
877 * Save the flags used in this call,
878 * in case we point TCP to our parent below.
879 */
880 int call_flags = tcp->u_arg[ARG_FLAGS];
881 if ((tcp->flags & TCB_CLONE_THREAD) &&
882 tcp->parent != NULL) {
883 /* The parent in this clone is itself a
884 thread belonging to another process.
885 There is no meaning to the parentage
886 relationship of the new child with the
887 thread, only with the process. We
888 associate the new thread with our
889 parent. Since this is done for every
890 new thread, there will never be a
891 TCB_CLONE_THREAD process that has
892 children. */
893 --tcp->nchildren;
894 tcp = tcp->parent;
895 tcpchild->parent = tcp;
896 ++tcp->nchildren;
897 }
898 if (call_flags & CLONE_THREAD) {
899 tcpchild->flags |= TCB_CLONE_THREAD;
900 ++tcp->nclone_threads;
901 }
902 if (call_flags & CLONE_DETACHED) {
903 tcpchild->flags |= TCB_CLONE_DETACHED;
904 ++tcp->nclone_detached;
905 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000906 }
907#endif
908
909 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000910 return 0;
911}
912#endif
913
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000914int
915internal_fork(tcp)
916struct tcb *tcp;
917{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000918#ifdef LINUX
919 /* We do special magic with clone for any clone or fork. */
920 return internal_clone(tcp);
921#else
922
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000923 struct tcb *tcpchild;
924 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000925 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000926
927#ifdef SYS_vfork
Nate Sammonsccd8f211999-03-29 22:57:54 +0000928 if (tcp->scno == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000929 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000930 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000931 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000932 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000933 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000934#endif
935 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000936 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000937 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000938 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000939 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000940 if (setbpt(tcp) < 0)
941 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000942 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000943 else {
944 int bpt = tcp->flags & TCB_BPTSET;
945
946 if (!(tcp->flags & TCB_FOLLOWFORK))
947 return 0;
948 if (bpt)
949 clearbpt(tcp);
950
951 if (syserror(tcp))
952 return 0;
953
954 pid = tcp->u_rval;
955 if ((tcpchild = alloctcb(pid)) == NULL) {
956 fprintf(stderr, " [tcb table full]\n");
957 kill(pid, SIGKILL); /* XXX */
958 return 0;
959 }
960#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000961#ifdef HPPA
962 /* The child must have run before it can be attached. */
963 /* This must be a bug in the parisc kernel, but I havn't
964 * identified it yet. Seems to be an issue associated
965 * with attaching to a process (which sends it a signal)
966 * before that process has ever been scheduled. When
967 * debugging, I started seeing crashes in
968 * arch/parisc/kernel/signal.c:do_signal(), apparently
969 * caused by r8 getting corrupt over the dequeue_signal()
970 * call. Didn't make much sense though...
971 */
972 {
973 struct timeval tv;
974 tv.tv_sec = 0;
975 tv.tv_usec = 10000;
976 select(0, NULL, NULL, NULL, &tv);
977 }
978#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000979 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
980 perror("PTRACE_ATTACH");
981 fprintf(stderr, "Too late?\n");
982 droptcb(tcpchild);
983 return 0;
984 }
985#endif /* LINUX */
986#ifdef SUNOS4
987#ifdef oldway
988 /* The child must have run before it can be attached. */
989 {
990 struct timeval tv;
991 tv.tv_sec = 0;
992 tv.tv_usec = 10000;
993 select(0, NULL, NULL, NULL, &tv);
994 }
995 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
996 perror("PTRACE_ATTACH");
997 fprintf(stderr, "Too late?\n");
998 droptcb(tcpchild);
999 return 0;
1000 }
1001#else /* !oldway */
1002 /* Try to catch the new process as soon as possible. */
1003 {
1004 int i;
1005 for (i = 0; i < 1024; i++)
1006 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1007 break;
1008 if (i == 1024) {
1009 perror("PTRACE_ATTACH");
1010 fprintf(stderr, "Too late?\n");
1011 droptcb(tcpchild);
1012 return 0;
1013 }
1014 }
1015#endif /* !oldway */
1016#endif /* SUNOS4 */
1017 tcpchild->flags |= TCB_ATTACHED;
1018 /* Child has BPT too, must be removed on first occasion */
1019 if (bpt) {
1020 tcpchild->flags |= TCB_BPTSET;
1021 tcpchild->baddr = tcp->baddr;
1022 memcpy(tcpchild->inst, tcp->inst,
1023 sizeof tcpchild->inst);
1024 }
1025 newoutf(tcpchild);
1026 tcpchild->parent = tcp;
1027 tcp->nchildren++;
1028 if (!qflag)
1029 fprintf(stderr, "Process %d attached\n", pid);
1030 }
1031 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001032#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001033}
1034
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001035#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001036
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001037#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001038
1039int
1040sys_vfork(tcp)
1041struct tcb *tcp;
1042{
1043 if (exiting(tcp))
1044 return RVAL_UDECIMAL;
1045 return 0;
1046}
1047
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001048#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001049
1050#ifndef LINUX
1051
1052static char idstr[16];
1053
1054int
1055sys_getpid(tcp)
1056struct tcb *tcp;
1057{
1058 if (exiting(tcp)) {
1059 sprintf(idstr, "ppid %lu", getrval2(tcp));
1060 tcp->auxstr = idstr;
1061 return RVAL_STR;
1062 }
1063 return 0;
1064}
1065
1066int
1067sys_getuid(tcp)
1068struct tcb *tcp;
1069{
1070 if (exiting(tcp)) {
1071 sprintf(idstr, "euid %lu", getrval2(tcp));
1072 tcp->auxstr = idstr;
1073 return RVAL_STR;
1074 }
1075 return 0;
1076}
1077
1078int
1079sys_getgid(tcp)
1080struct tcb *tcp;
1081{
1082 if (exiting(tcp)) {
1083 sprintf(idstr, "egid %lu", getrval2(tcp));
1084 tcp->auxstr = idstr;
1085 return RVAL_STR;
1086 }
1087 return 0;
1088}
1089
1090#endif /* !LINUX */
1091
1092#ifdef LINUX
1093
1094int
1095sys_setuid(tcp)
1096struct tcb *tcp;
1097{
1098 if (entering(tcp)) {
1099 tprintf("%u", (uid_t) tcp->u_arg[0]);
1100 }
1101 return 0;
1102}
1103
1104int
1105sys_setgid(tcp)
1106struct tcb *tcp;
1107{
1108 if (entering(tcp)) {
1109 tprintf("%u", (gid_t) tcp->u_arg[0]);
1110 }
1111 return 0;
1112}
1113
1114int
1115sys_getresuid(tcp)
1116 struct tcb *tcp;
1117{
1118 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001119 __kernel_uid_t uid;
1120 if (syserror(tcp))
1121 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1122 tcp->u_arg[1], tcp->u_arg[2]);
1123 else {
1124 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1125 tprintf("%#lx, ", tcp->u_arg[0]);
1126 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001127 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001128 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1129 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001130 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001131 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001132 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1133 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001134 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001135 tprintf("[%lu]", (unsigned long) uid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001136 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001137 }
1138 return 0;
1139}
1140
1141int
1142sys_getresgid(tcp)
1143struct tcb *tcp;
1144{
1145 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001146 __kernel_gid_t gid;
1147 if (syserror(tcp))
1148 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1149 tcp->u_arg[1], tcp->u_arg[2]);
1150 else {
1151 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1152 tprintf("%#lx, ", tcp->u_arg[0]);
1153 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001154 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001155 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1156 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001157 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001158 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001159 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1160 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001161 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001162 tprintf("[%lu]", (unsigned long) gid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001163 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001164 }
1165 return 0;
1166}
1167
1168#endif /* LINUX */
1169
1170int
1171sys_setreuid(tcp)
1172struct tcb *tcp;
1173{
1174 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001175 printuid("", tcp->u_arg[0]);
1176 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001177 }
1178 return 0;
1179}
1180
1181int
1182sys_setregid(tcp)
1183struct tcb *tcp;
1184{
1185 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001186 printuid("", tcp->u_arg[0]);
1187 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001188 }
1189 return 0;
1190}
1191
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001192#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001193int
1194sys_setresuid(tcp)
1195 struct tcb *tcp;
1196{
1197 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001198 printuid("", tcp->u_arg[0]);
1199 printuid(", ", tcp->u_arg[1]);
1200 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001201 }
1202 return 0;
1203}
1204int
1205sys_setresgid(tcp)
1206 struct tcb *tcp;
1207{
1208 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001209 printuid("", tcp->u_arg[0]);
1210 printuid(", ", tcp->u_arg[1]);
1211 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001212 }
1213 return 0;
1214}
1215
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001216#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001217
1218int
1219sys_setgroups(tcp)
1220struct tcb *tcp;
1221{
1222 int i, len;
1223 GETGROUPS_T *gidset;
1224
1225 if (entering(tcp)) {
1226 len = tcp->u_arg[0];
1227 tprintf("%u, ", len);
1228 if (len <= 0) {
1229 tprintf("[]");
1230 return 0;
1231 }
1232 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1233 if (gidset == NULL) {
1234 fprintf(stderr, "sys_setgroups: out of memory\n");
1235 return -1;
1236 }
1237 if (!verbose(tcp))
1238 tprintf("%#lx", tcp->u_arg[1]);
1239 else if (umoven(tcp, tcp->u_arg[1],
1240 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1241 tprintf("[?]");
1242 else {
1243 tprintf("[");
1244 for (i = 0; i < len; i++)
1245 tprintf("%s%lu", i ? ", " : "",
1246 (unsigned long) gidset[i]);
1247 tprintf("]");
1248 }
1249 free((char *) gidset);
1250 }
1251 return 0;
1252}
1253
1254int
1255sys_getgroups(tcp)
1256struct tcb *tcp;
1257{
1258 int i, len;
1259 GETGROUPS_T *gidset;
1260
1261 if (entering(tcp)) {
1262 len = tcp->u_arg[0];
1263 tprintf("%u, ", len);
1264 } else {
1265 len = tcp->u_rval;
1266 if (len <= 0) {
1267 tprintf("[]");
1268 return 0;
1269 }
1270 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1271 if (gidset == NULL) {
1272 fprintf(stderr, "sys_getgroups: out of memory\n");
1273 return -1;
1274 }
1275 if (!tcp->u_arg[1])
1276 tprintf("NULL");
1277 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1278 tprintf("%#lx", tcp->u_arg[1]);
1279 else if (umoven(tcp, tcp->u_arg[1],
1280 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1281 tprintf("[?]");
1282 else {
1283 tprintf("[");
1284 for (i = 0; i < len; i++)
1285 tprintf("%s%lu", i ? ", " : "",
1286 (unsigned long) gidset[i]);
1287 tprintf("]");
1288 }
1289 free((char *)gidset);
1290 }
1291 return 0;
1292}
1293
Roland McGrath83bd47a2003-11-13 22:32:26 +00001294#ifdef LINUX
1295int
1296sys_setgroups32(tcp)
1297struct tcb *tcp;
1298{
1299 int i, len;
1300 GETGROUPS32_T *gidset;
1301
1302 if (entering(tcp)) {
1303 len = tcp->u_arg[0];
1304 tprintf("%u, ", len);
1305 if (len <= 0) {
1306 tprintf("[]");
1307 return 0;
1308 }
1309 gidset = (GETGROUPS32_T *) malloc(len * sizeof(GETGROUPS32_T));
1310 if (gidset == NULL) {
1311 fprintf(stderr, "sys_setgroups32: out of memory\n");
1312 return -1;
1313 }
1314 if (!verbose(tcp))
1315 tprintf("%#lx", tcp->u_arg[1]);
1316 else if (umoven(tcp, tcp->u_arg[1],
1317 len * sizeof(GETGROUPS32_T), (char *) gidset) < 0)
1318 tprintf("[?]");
1319 else {
1320 tprintf("[");
1321 for (i = 0; i < len; i++)
1322 tprintf("%s%lu", i ? ", " : "",
1323 (unsigned long) gidset[i]);
1324 tprintf("]");
1325 }
1326 free((char *) gidset);
1327 }
1328 return 0;
1329}
1330
1331int
1332sys_getgroups32(tcp)
1333struct tcb *tcp;
1334{
1335 int i, len;
1336 GETGROUPS32_T *gidset;
1337
1338 if (entering(tcp)) {
1339 len = tcp->u_arg[0];
1340 tprintf("%u, ", len);
1341 } else {
1342 len = tcp->u_rval;
1343 if (len <= 0) {
1344 tprintf("[]");
1345 return 0;
1346 }
1347 gidset = (GETGROUPS32_T *) malloc(len * sizeof(GETGROUPS32_T));
1348 if (gidset == NULL) {
1349 fprintf(stderr, "sys_getgroups32: out of memory\n");
1350 return -1;
1351 }
1352 if (!tcp->u_arg[1])
1353 tprintf("NULL");
1354 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1355 tprintf("%#lx", tcp->u_arg[1]);
1356 else if (umoven(tcp, tcp->u_arg[1],
1357 len * sizeof(GETGROUPS32_T), (char *) gidset) < 0)
1358 tprintf("[?]");
1359 else {
1360 tprintf("[");
1361 for (i = 0; i < len; i++)
1362 tprintf("%s%lu", i ? ", " : "",
1363 (unsigned long) gidset[i]);
1364 tprintf("]");
1365 }
1366 free((char *)gidset);
1367 }
1368 return 0;
1369}
1370#endif /* LINUX */
1371
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001372int
1373sys_setpgrp(tcp)
1374struct tcb *tcp;
1375{
1376 if (entering(tcp)) {
1377#ifndef SVR4
1378 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1379#endif /* !SVR4 */
1380 }
1381 return 0;
1382}
1383
1384int
1385sys_getpgrp(tcp)
1386struct tcb *tcp;
1387{
1388 if (entering(tcp)) {
1389#ifndef SVR4
1390 tprintf("%lu", tcp->u_arg[0]);
1391#endif /* !SVR4 */
1392 }
1393 return 0;
1394}
1395
1396int
1397sys_getsid(tcp)
1398struct tcb *tcp;
1399{
1400 if (entering(tcp)) {
1401 tprintf("%lu", tcp->u_arg[0]);
1402 }
1403 return 0;
1404}
1405
1406int
1407sys_setsid(tcp)
1408struct tcb *tcp;
1409{
1410 return 0;
1411}
1412
1413int
1414sys_getpgid(tcp)
1415struct tcb *tcp;
1416{
1417 if (entering(tcp)) {
1418 tprintf("%lu", tcp->u_arg[0]);
1419 }
1420 return 0;
1421}
1422
1423int
1424sys_setpgid(tcp)
1425struct tcb *tcp;
1426{
1427 if (entering(tcp)) {
1428 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1429 }
1430 return 0;
1431}
1432
John Hughesc61eb3d2002-05-17 11:37:50 +00001433#if UNIXWARE >= 2
1434
1435#include <sys/privilege.h>
1436
1437
1438static struct xlat procpriv_cmds [] = {
1439 { SETPRV, "SETPRV" },
1440 { CLRPRV, "CLRPRV" },
1441 { PUTPRV, "PUTPRV" },
1442 { GETPRV, "GETPRV" },
1443 { CNTPRV, "CNTPRV" },
1444 { 0, NULL },
1445};
1446
1447
1448static struct xlat procpriv_priv [] = {
1449 { P_OWNER, "P_OWNER" },
1450 { P_AUDIT, "P_AUDIT" },
1451 { P_COMPAT, "P_COMPAT" },
1452 { P_DACREAD, "P_DACREAD" },
1453 { P_DACWRITE, "P_DACWRITE" },
1454 { P_DEV, "P_DEV" },
1455 { P_FILESYS, "P_FILESYS" },
1456 { P_MACREAD, "P_MACREAD" },
1457 { P_MACWRITE, "P_MACWRITE" },
1458 { P_MOUNT, "P_MOUNT" },
1459 { P_MULTIDIR, "P_MULTIDIR" },
1460 { P_SETPLEVEL, "P_SETPLEVEL" },
1461 { P_SETSPRIV, "P_SETSPRIV" },
1462 { P_SETUID, "P_SETUID" },
1463 { P_SYSOPS, "P_SYSOPS" },
1464 { P_SETUPRIV, "P_SETUPRIV" },
1465 { P_DRIVER, "P_DRIVER" },
1466 { P_RTIME, "P_RTIME" },
1467 { P_MACUPGRADE, "P_MACUPGRADE" },
1468 { P_FSYSRANGE, "P_FSYSRANGE" },
1469 { P_SETFLEVEL, "P_SETFLEVEL" },
1470 { P_AUDITWR, "P_AUDITWR" },
1471 { P_TSHAR, "P_TSHAR" },
1472 { P_PLOCK, "P_PLOCK" },
1473 { P_CORE, "P_CORE" },
1474 { P_LOADMOD, "P_LOADMOD" },
1475 { P_BIND, "P_BIND" },
1476 { P_ALLPRIVS, "P_ALLPRIVS" },
1477 { 0, NULL },
1478};
1479
1480
1481static struct xlat procpriv_type [] = {
1482 { PS_FIX, "PS_FIX" },
1483 { PS_INH, "PS_INH" },
1484 { PS_MAX, "PS_MAX" },
1485 { PS_WKG, "PS_WKG" },
1486 { 0, NULL },
1487};
1488
1489
1490static void
1491printpriv(tcp, addr, len, opt)
1492struct tcb *tcp;
1493long addr;
1494int len;
1495struct xlat *opt;
1496{
1497 priv_t buf [128];
1498 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1499 int dots = len > max;
1500 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001501
John Hughesc61eb3d2002-05-17 11:37:50 +00001502 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001503
John Hughesc61eb3d2002-05-17 11:37:50 +00001504 if (len <= 0 ||
1505 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1506 {
1507 tprintf ("%#lx", addr);
1508 return;
1509 }
1510
1511 tprintf ("[");
1512
1513 for (i = 0; i < len; ++i) {
1514 char *t, *p;
1515
1516 if (i) tprintf (", ");
1517
1518 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1519 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1520 {
1521 tprintf ("%s|%s", t, p);
1522 }
1523 else {
1524 tprintf ("%#lx", buf [i]);
1525 }
1526 }
1527
1528 if (dots) tprintf (" ...");
1529
1530 tprintf ("]");
1531}
1532
1533
1534int
1535sys_procpriv(tcp)
1536struct tcb *tcp;
1537{
1538 if (entering(tcp)) {
1539 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1540 switch (tcp->u_arg[0]) {
1541 case CNTPRV:
1542 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1543 break;
1544
1545 case GETPRV:
1546 break;
1547
1548 default:
1549 tprintf (", ");
1550 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1551 tprintf (", %ld", tcp->u_arg[2]);
1552 }
1553 }
1554 else if (tcp->u_arg[0] == GETPRV) {
1555 if (syserror (tcp)) {
1556 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1557 }
1558 else {
1559 tprintf (", ");
1560 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1561 tprintf (", %ld", tcp->u_arg[2]);
1562 }
1563 }
Roland McGrath5a223472002-12-15 23:58:26 +00001564
John Hughesc61eb3d2002-05-17 11:37:50 +00001565 return 0;
1566}
1567
1568#endif
1569
1570
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001571void
1572fake_execve(tcp, program, argv, envp)
1573struct tcb *tcp;
1574char *program;
1575char *argv[];
1576char *envp[];
1577{
1578 int i;
1579
1580#ifdef ARM
1581 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1582 return;
1583#else
1584 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1585 return;
1586#endif /* !ARM */
1587 printleader(tcp);
1588 tprintf("execve(");
1589 string_quote(program);
1590 tprintf(", [");
1591 for (i = 0; argv[i] != NULL; i++) {
1592 if (i != 0)
1593 tprintf(", ");
1594 string_quote(argv[i]);
1595 }
1596 for (i = 0; envp[i] != NULL; i++)
1597 ;
1598 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1599 tabto(acolumn);
1600 tprintf("= 0");
1601 printtrailer(tcp);
1602}
1603
1604static void
1605printargv(tcp, addr)
1606struct tcb *tcp;
1607long addr;
1608{
1609 char *cp;
1610 char *sep;
1611 int max = max_strlen / 2;
1612
1613 for (sep = ""; --max >= 0; sep = ", ") {
1614 if (!abbrev(tcp))
1615 max++;
1616 if (umove(tcp, addr, &cp) < 0) {
1617 tprintf("%#lx", addr);
1618 return;
1619 }
1620 if (cp == 0)
1621 break;
1622 tprintf(sep);
1623 printstr(tcp, (long) cp, -1);
1624 addr += sizeof(char *);
1625 }
1626 if (cp)
1627 tprintf(", ...");
1628}
1629
1630static void
1631printargc(fmt, tcp, addr)
1632char *fmt;
1633struct tcb *tcp;
1634long addr;
1635{
1636 int count;
1637 char *cp;
1638
1639 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1640 addr += sizeof(char *);
1641 }
1642 tprintf(fmt, count, count == 1 ? "" : "s");
1643}
1644
1645int
1646sys_execv(tcp)
1647struct tcb *tcp;
1648{
1649 if (entering(tcp)) {
1650 printpath(tcp, tcp->u_arg[0]);
1651 if (!verbose(tcp))
1652 tprintf(", %#lx", tcp->u_arg[1]);
1653#if 0
1654 else if (abbrev(tcp))
1655 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1656#endif
1657 else {
1658 tprintf(", [");
1659 printargv(tcp, tcp->u_arg[1]);
1660 tprintf("]");
1661 }
1662 }
1663 return 0;
1664}
1665
1666int
1667sys_execve(tcp)
1668struct tcb *tcp;
1669{
1670 if (entering(tcp)) {
1671 printpath(tcp, tcp->u_arg[0]);
1672 if (!verbose(tcp))
1673 tprintf(", %#lx", tcp->u_arg[1]);
1674#if 0
1675 else if (abbrev(tcp))
1676 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1677#endif
1678 else {
1679 tprintf(", [");
1680 printargv(tcp, tcp->u_arg[1]);
1681 tprintf("]");
1682 }
1683 if (!verbose(tcp))
1684 tprintf(", %#lx", tcp->u_arg[2]);
1685 else if (abbrev(tcp))
1686 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1687 else {
1688 tprintf(", [");
1689 printargv(tcp, tcp->u_arg[2]);
1690 tprintf("]");
1691 }
1692 }
Roland McGrathb4968be2003-01-20 09:04:33 +00001693#if defined LINUX && defined TCB_WAITEXECVE
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001694 tcp->flags |= TCB_WAITEXECVE;
Roland McGrathb4968be2003-01-20 09:04:33 +00001695#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001696 return 0;
1697}
1698
John Hughes4e36a812001-04-18 15:11:51 +00001699
1700int sys_rexecve(tcp)
1701struct tcb *tcp;
1702{
1703 if (entering (tcp)) {
1704 sys_execve (tcp);
1705 tprintf (", %ld", tcp->u_arg[3]);
1706 }
1707 return 0;
1708}
1709
John Hughes4e36a812001-04-18 15:11:51 +00001710
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001711int
1712internal_exec(tcp)
1713struct tcb *tcp;
1714{
1715#ifdef SUNOS4
1716 if (exiting(tcp) && !syserror(tcp) && followfork)
1717 fixvfork(tcp);
1718#endif /* SUNOS4 */
1719 return 0;
1720}
1721
1722#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001723#ifndef __WNOTHREAD
1724#define __WNOTHREAD 0x20000000
1725#endif
1726#ifndef __WALL
1727#define __WALL 0x40000000
1728#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001729#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001730#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001731#endif
1732#endif /* LINUX */
1733
1734static struct xlat wait4_options[] = {
1735 { WNOHANG, "WNOHANG" },
1736#ifndef WSTOPPED
1737 { WUNTRACED, "WUNTRACED" },
1738#endif
1739#ifdef WEXITED
1740 { WEXITED, "WEXITED" },
1741#endif
1742#ifdef WTRAPPED
1743 { WTRAPPED, "WTRAPPED" },
1744#endif
1745#ifdef WSTOPPED
1746 { WSTOPPED, "WSTOPPED" },
1747#endif
1748#ifdef WCONTINUED
1749 { WCONTINUED, "WCONTINUED" },
1750#endif
1751#ifdef WNOWAIT
1752 { WNOWAIT, "WNOWAIT" },
1753#endif
1754#ifdef __WCLONE
1755 { __WCLONE, "__WCLONE" },
1756#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001757#ifdef __WALL
1758 { __WALL, "__WALL" },
1759#endif
1760#ifdef __WNOTHREAD
1761 { __WNOTHREAD, "__WNOTHREAD" },
1762#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001763 { 0, NULL },
1764};
1765
1766static int
1767printstatus(status)
1768int status;
1769{
1770 int exited = 0;
1771
1772 /*
1773 * Here is a tricky presentation problem. This solution
1774 * is still not entirely satisfactory but since there
1775 * are no wait status constructors it will have to do.
1776 */
1777 if (WIFSTOPPED(status))
1778 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001779 signame(WSTOPSIG(status)));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001780 else if WIFSIGNALED(status)
1781 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001782 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001783 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1784 else if WIFEXITED(status) {
1785 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1786 WEXITSTATUS(status));
1787 exited = 1;
1788 }
1789 else
1790 tprintf("[%#x]", status);
1791 return exited;
1792}
1793
1794static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001795printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001796struct tcb *tcp;
1797int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001798int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001799{
1800 int status;
1801 int exited = 0;
1802
1803 if (entering(tcp)) {
1804 tprintf("%ld, ", tcp->u_arg[0]);
1805 } else {
1806 /* status */
1807 if (!tcp->u_arg[1])
1808 tprintf("NULL");
1809 else if (syserror(tcp) || tcp->u_rval == 0)
1810 tprintf("%#lx", tcp->u_arg[1]);
1811 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1812 tprintf("[?]");
1813 else
1814 exited = printstatus(status);
1815 /* options */
1816 tprintf(", ");
1817 if (!printflags(wait4_options, tcp->u_arg[2]))
1818 tprintf("0");
1819 if (n == 4) {
1820 tprintf(", ");
1821 /* usage */
1822 if (!tcp->u_arg[3])
1823 tprintf("NULL");
1824#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001825 else if (tcp->u_rval > 0) {
1826#ifdef LINUX_64BIT
1827 if (bitness)
1828 printrusage32(tcp, tcp->u_arg[3]);
1829 else
1830#endif
1831 printrusage(tcp, tcp->u_arg[3]);
1832 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001833#endif /* LINUX */
1834#ifdef SUNOS4
1835 else if (tcp->u_rval > 0 && exited)
1836 printrusage(tcp, tcp->u_arg[3]);
1837#endif /* SUNOS4 */
1838 else
1839 tprintf("%#lx", tcp->u_arg[3]);
1840 }
1841 }
1842 return 0;
1843}
1844
1845int
1846internal_wait(tcp)
1847struct tcb *tcp;
1848{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001849 int got_kids;
1850
1851#ifdef TCB_CLONE_THREAD
1852 if (tcp->flags & TCB_CLONE_THREAD)
1853 /* The children we wait for are our parent's children. */
1854 got_kids = (tcp->parent->nchildren
1855 > tcp->parent->nclone_detached);
1856 else
1857 got_kids = (tcp->nchildren > tcp->nclone_detached);
1858#else
1859 got_kids = tcp->nchildren > 0;
1860#endif
1861
1862 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001863 /* There are children that this parent should block for.
1864 But ptrace made us the parent of the traced children
1865 and the real parent will get ECHILD from the wait call.
1866
1867 XXX If we attached with strace -f -p PID, then there
1868 may be untraced dead children the parent could be reaping
1869 now, but we make him block. */
1870
1871 /* ??? WTA: fix bug with hanging children */
1872
1873 if (!(tcp->u_arg[2] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00001874 /*
1875 * There are traced children. We'll make the parent
1876 * block to avoid a false ECHILD error due to our
1877 * ptrace having stolen the children. However,
1878 * we shouldn't block if there are zombies to reap.
1879 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1880 */
Roland McGrathfccfb942003-10-01 21:59:44 +00001881 struct tcb *child = NULL;
Roland McGrath09623452003-05-23 02:27:13 +00001882 if (tcp->nzombies > 0 &&
1883 (tcp->u_arg[0] == -1 ||
Roland McGrathfccfb942003-10-01 21:59:44 +00001884 (child = pid2tcb(tcp->u_arg[0])) == NULL))
Roland McGrath09623452003-05-23 02:27:13 +00001885 return 0;
Roland McGrathfccfb942003-10-01 21:59:44 +00001886 if (tcp->u_arg[0] > 0) {
1887 /*
1888 * If the parent waits for a specified child
1889 * PID, then it must get ECHILD right away
1890 * if that PID is not one of its children.
1891 * Make sure that the requested PID matches
1892 * one of the parent's children that we are
1893 * tracing, and don't suspend it otherwise.
1894 */
1895 if (child == NULL)
1896 child = pid2tcb(tcp->u_arg[0]);
1897 if (child == NULL || child->parent != (
1898#ifdef TCB_CLONE_THREAD
1899 (tcp->flags & TCB_CLONE_THREAD)
1900 ? tcp->parent :
1901#endif
1902 tcp))
1903 return 0;
1904 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001905 tcp->flags |= TCB_SUSPENDED;
1906 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001907#ifdef TCB_CLONE_THREAD
1908 if (tcp->flags & TCB_CLONE_THREAD)
1909 tcp->parent->nclone_waiting++;
1910#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001911 }
1912 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001913 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001914 if (tcp->u_arg[2] & WNOHANG) {
1915 /* We must force a fake result of 0 instead of
1916 the ECHILD error. */
1917 extern int force_result();
1918 return force_result(tcp, 0, 0);
1919 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00001920 }
Roland McGrath09623452003-05-23 02:27:13 +00001921 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
1922 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
1923 /*
1924 * We just reaped a child we don't know about,
1925 * presumably a zombie we already droptcb'd.
1926 */
1927 tcp->nzombies--;
1928 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001929 return 0;
1930}
1931
1932#ifdef SVR4
1933
1934int
1935sys_wait(tcp)
1936struct tcb *tcp;
1937{
1938 if (exiting(tcp)) {
1939 /* The library wrapper stuffs this into the user variable. */
1940 if (!syserror(tcp))
1941 printstatus(getrval2(tcp));
1942 }
1943 return 0;
1944}
1945
1946#endif /* SVR4 */
1947
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001948#ifdef FREEBSD
1949int
1950sys_wait(tcp)
1951struct tcb *tcp;
1952{
1953 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001954
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001955 if (exiting(tcp)) {
1956 if (!syserror(tcp)) {
1957 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1958 tprintf("%#lx", tcp->u_arg[0]);
1959 else
1960 printstatus(status);
1961 }
1962 }
1963 return 0;
1964}
1965#endif
1966
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001967int
1968sys_waitpid(tcp)
1969struct tcb *tcp;
1970{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001971 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001972}
1973
1974int
1975sys_wait4(tcp)
1976struct tcb *tcp;
1977{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001978 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001979}
1980
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001981#ifdef ALPHA
1982int
1983sys_osf_wait4(tcp)
1984struct tcb *tcp;
1985{
1986 return printwaitn(tcp, 4, 1);
1987}
1988#endif
1989
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001990#ifdef SVR4
1991
1992static struct xlat waitid_types[] = {
1993 { P_PID, "P_PID" },
1994 { P_PPID, "P_PPID" },
1995 { P_PGID, "P_PGID" },
1996 { P_SID, "P_SID" },
1997 { P_CID, "P_CID" },
1998 { P_UID, "P_UID" },
1999 { P_GID, "P_GID" },
2000 { P_ALL, "P_ALL" },
2001#ifdef P_LWPID
2002 { P_LWPID, "P_LWPID" },
2003#endif
2004 { 0, NULL },
2005};
2006
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002007int
2008sys_waitid(tcp)
2009struct tcb *tcp;
2010{
2011 siginfo_t si;
2012 int exited;
2013
2014 if (entering(tcp)) {
2015 printxval(waitid_types, tcp->u_arg[0], "P_???");
2016 tprintf(", %ld, ", tcp->u_arg[1]);
2017 if (tcp->nchildren > 0) {
2018 /* There are traced children */
2019 tcp->flags |= TCB_SUSPENDED;
2020 tcp->waitpid = tcp->u_arg[0];
2021 }
2022 }
2023 else {
2024 /* siginfo */
2025 exited = 0;
2026 if (!tcp->u_arg[2])
2027 tprintf("NULL");
2028 else if (syserror(tcp))
2029 tprintf("%#lx", tcp->u_arg[2]);
2030 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2031 tprintf("{???}");
2032 else
John Hughes58265892001-10-18 15:13:53 +00002033 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002034 /* options */
2035 tprintf(", ");
2036 if (!printflags(wait4_options, tcp->u_arg[3]))
2037 tprintf("0");
2038 }
2039 return 0;
2040}
2041
2042#endif /* SVR4 */
2043
2044int
2045sys_alarm(tcp)
2046struct tcb *tcp;
2047{
2048 if (entering(tcp))
2049 tprintf("%lu", tcp->u_arg[0]);
2050 return 0;
2051}
2052
2053int
2054sys_uname(tcp)
2055struct tcb *tcp;
2056{
2057 struct utsname uname;
2058
2059 if (exiting(tcp)) {
2060 if (syserror(tcp) || !verbose(tcp))
2061 tprintf("%#lx", tcp->u_arg[0]);
2062 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2063 tprintf("{...}");
2064 else if (!abbrev(tcp)) {
2065
2066 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2067 uname.sysname, uname.nodename);
2068 tprintf("release=\"%s\", version=\"%s\", ",
2069 uname.release, uname.version);
2070 tprintf("machine=\"%s\"", uname.machine);
2071#ifdef LINUX
2072#ifndef __GLIBC__
2073 tprintf(", domainname=\"%s\"", uname.domainname);
2074#endif /* __GLIBC__ */
2075#endif /* LINUX */
2076 tprintf("}");
2077 }
2078 else
2079 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2080 uname.sysname, uname.nodename);
2081 }
2082 return 0;
2083}
2084
2085#ifndef SVR4
2086
2087static struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002088#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002089 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2090 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2091 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2092 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2093 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2094 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2095 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2096 { PTRACE_CONT, "PTRACE_CONT" },
2097 { PTRACE_KILL, "PTRACE_KILL" },
2098 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2099 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2100 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002101#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002102 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002103#endif
2104#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002105 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002106#endif
2107#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002108 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002109#endif
2110#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002111 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002112#endif
2113#ifdef PTRACE_GETFPXREGS
2114 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2115#endif
2116#ifdef PTRACE_SETFPXREGS
2117 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2118#endif
2119#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002120 { PTRACE_READDATA, "PTRACE_READDATA" },
2121 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2122 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2123 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2124 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2125 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2126#ifdef SPARC
2127 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2128 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2129#else /* !SPARC */
2130 { PTRACE_22, "PTRACE_PTRACE_22" },
2131 { PTRACE_23, "PTRACE_PTRACE_23" },
2132#endif /* !SPARC */
2133#endif /* SUNOS4 */
2134 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2135#ifdef SUNOS4
2136 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2137#ifdef I386
2138 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2139 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2140 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2141#else /* !I386 */
2142 { PTRACE_26, "PTRACE_26" },
2143 { PTRACE_27, "PTRACE_27" },
2144 { PTRACE_28, "PTRACE_28" },
2145#endif /* !I386 */
2146 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2147#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002148#else /* FREEBSD */
2149 { PT_TRACE_ME, "PT_TRACE_ME" },
2150 { PT_READ_I, "PT_READ_I" },
2151 { PT_READ_D, "PT_READ_D" },
2152 { PT_WRITE_I, "PT_WRITE_I" },
2153 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002154#ifdef PT_READ_U
2155 { PT_READ_U, "PT_READ_U" },
2156#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002157 { PT_CONTINUE, "PT_CONTINUE" },
2158 { PT_KILL, "PT_KILL" },
2159 { PT_STEP, "PT_STEP" },
2160 { PT_ATTACH, "PT_ATTACH" },
2161 { PT_DETACH, "PT_DETACH" },
2162 { PT_GETREGS, "PT_GETREGS" },
2163 { PT_SETREGS, "PT_SETREGS" },
2164 { PT_GETFPREGS, "PT_GETFPREGS" },
2165 { PT_SETFPREGS, "PT_SETFPREGS" },
2166 { PT_GETDBREGS, "PT_GETDBREGS" },
2167 { PT_SETDBREGS, "PT_SETDBREGS" },
2168#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002169 { 0, NULL },
2170};
2171
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002172#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002173#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2174static
2175#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2176struct xlat struct_user_offsets[] = {
2177#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002178#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002179 { PT_PSWMASK, "psw_mask" },
2180 { PT_PSWADDR, "psw_addr" },
2181 { PT_GPR0, "gpr0" },
2182 { PT_GPR1, "gpr1" },
2183 { PT_GPR2, "gpr2" },
2184 { PT_GPR3, "gpr3" },
2185 { PT_GPR4, "gpr4" },
2186 { PT_GPR5, "gpr5" },
2187 { PT_GPR6, "gpr6" },
2188 { PT_GPR7, "gpr7" },
2189 { PT_GPR8, "gpr8" },
2190 { PT_GPR9, "gpr9" },
2191 { PT_GPR10, "gpr10" },
2192 { PT_GPR11, "gpr11" },
2193 { PT_GPR12, "gpr12" },
2194 { PT_GPR13, "gpr13" },
2195 { PT_GPR14, "gpr14" },
2196 { PT_GPR15, "gpr15" },
2197 { PT_ACR0, "acr0" },
2198 { PT_ACR1, "acr1" },
2199 { PT_ACR2, "acr2" },
2200 { PT_ACR3, "acr3" },
2201 { PT_ACR4, "acr4" },
2202 { PT_ACR5, "acr5" },
2203 { PT_ACR6, "acr6" },
2204 { PT_ACR7, "acr7" },
2205 { PT_ACR8, "acr8" },
2206 { PT_ACR9, "acr9" },
2207 { PT_ACR10, "acr10" },
2208 { PT_ACR11, "acr11" },
2209 { PT_ACR12, "acr12" },
2210 { PT_ACR13, "acr13" },
2211 { PT_ACR14, "acr14" },
2212 { PT_ACR15, "acr15" },
2213 { PT_ORIGGPR2, "orig_gpr2" },
2214 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002215#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002216 { PT_FPR0_HI, "fpr0.hi" },
2217 { PT_FPR0_LO, "fpr0.lo" },
2218 { PT_FPR1_HI, "fpr1.hi" },
2219 { PT_FPR1_LO, "fpr1.lo" },
2220 { PT_FPR2_HI, "fpr2.hi" },
2221 { PT_FPR2_LO, "fpr2.lo" },
2222 { PT_FPR3_HI, "fpr3.hi" },
2223 { PT_FPR3_LO, "fpr3.lo" },
2224 { PT_FPR4_HI, "fpr4.hi" },
2225 { PT_FPR4_LO, "fpr4.lo" },
2226 { PT_FPR5_HI, "fpr5.hi" },
2227 { PT_FPR5_LO, "fpr5.lo" },
2228 { PT_FPR6_HI, "fpr6.hi" },
2229 { PT_FPR6_LO, "fpr6.lo" },
2230 { PT_FPR7_HI, "fpr7.hi" },
2231 { PT_FPR7_LO, "fpr7.lo" },
2232 { PT_FPR8_HI, "fpr8.hi" },
2233 { PT_FPR8_LO, "fpr8.lo" },
2234 { PT_FPR9_HI, "fpr9.hi" },
2235 { PT_FPR9_LO, "fpr9.lo" },
2236 { PT_FPR10_HI, "fpr10.hi" },
2237 { PT_FPR10_LO, "fpr10.lo" },
2238 { PT_FPR11_HI, "fpr11.hi" },
2239 { PT_FPR11_LO, "fpr11.lo" },
2240 { PT_FPR12_HI, "fpr12.hi" },
2241 { PT_FPR12_LO, "fpr12.lo" },
2242 { PT_FPR13_HI, "fpr13.hi" },
2243 { PT_FPR13_LO, "fpr13.lo" },
2244 { PT_FPR14_HI, "fpr14.hi" },
2245 { PT_FPR14_LO, "fpr14.lo" },
2246 { PT_FPR15_HI, "fpr15.hi" },
2247 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002248#endif
2249#if defined(S390X)
2250 { PT_FPR0, "fpr0" },
2251 { PT_FPR1, "fpr1" },
2252 { PT_FPR2, "fpr2" },
2253 { PT_FPR3, "fpr3" },
2254 { PT_FPR4, "fpr4" },
2255 { PT_FPR5, "fpr5" },
2256 { PT_FPR6, "fpr6" },
2257 { PT_FPR7, "fpr7" },
2258 { PT_FPR8, "fpr8" },
2259 { PT_FPR9, "fpr9" },
2260 { PT_FPR10, "fpr10" },
2261 { PT_FPR11, "fpr11" },
2262 { PT_FPR12, "fpr12" },
2263 { PT_FPR13, "fpr13" },
2264 { PT_FPR14, "fpr14" },
2265 { PT_FPR15, "fpr15" },
2266#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002267 { PT_CR_9, "cr9" },
2268 { PT_CR_10, "cr10" },
2269 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002270 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002271#endif
2272#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002273 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002274#elif defined(HPPA)
2275 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002276#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002277#ifndef PT_ORIG_R3
2278#define PT_ORIG_R3 34
2279#endif
Roland McGratheb285352003-01-14 09:59:00 +00002280#define REGSIZE (sizeof(unsigned long))
2281 { REGSIZE*PT_R0, "r0" },
2282 { REGSIZE*PT_R1, "r1" },
2283 { REGSIZE*PT_R2, "r2" },
2284 { REGSIZE*PT_R3, "r3" },
2285 { REGSIZE*PT_R4, "r4" },
2286 { REGSIZE*PT_R5, "r5" },
2287 { REGSIZE*PT_R6, "r6" },
2288 { REGSIZE*PT_R7, "r7" },
2289 { REGSIZE*PT_R8, "r8" },
2290 { REGSIZE*PT_R9, "r9" },
2291 { REGSIZE*PT_R10, "r10" },
2292 { REGSIZE*PT_R11, "r11" },
2293 { REGSIZE*PT_R12, "r12" },
2294 { REGSIZE*PT_R13, "r13" },
2295 { REGSIZE*PT_R14, "r14" },
2296 { REGSIZE*PT_R15, "r15" },
2297 { REGSIZE*PT_R16, "r16" },
2298 { REGSIZE*PT_R17, "r17" },
2299 { REGSIZE*PT_R18, "r18" },
2300 { REGSIZE*PT_R19, "r19" },
2301 { REGSIZE*PT_R20, "r20" },
2302 { REGSIZE*PT_R21, "r21" },
2303 { REGSIZE*PT_R22, "r22" },
2304 { REGSIZE*PT_R23, "r23" },
2305 { REGSIZE*PT_R24, "r24" },
2306 { REGSIZE*PT_R25, "r25" },
2307 { REGSIZE*PT_R26, "r26" },
2308 { REGSIZE*PT_R27, "r27" },
2309 { REGSIZE*PT_R28, "r28" },
2310 { REGSIZE*PT_R29, "r29" },
2311 { REGSIZE*PT_R30, "r30" },
2312 { REGSIZE*PT_R31, "r31" },
2313 { REGSIZE*PT_NIP, "NIP" },
2314 { REGSIZE*PT_MSR, "MSR" },
2315 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2316 { REGSIZE*PT_CTR, "CTR" },
2317 { REGSIZE*PT_LNK, "LNK" },
2318 { REGSIZE*PT_XER, "XER" },
2319 { REGSIZE*PT_CCR, "CCR" },
2320 { REGSIZE*PT_FPR0, "FPR0" },
2321#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002322#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002323#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002324 { 0, "r0" },
2325 { 1, "r1" },
2326 { 2, "r2" },
2327 { 3, "r3" },
2328 { 4, "r4" },
2329 { 5, "r5" },
2330 { 6, "r6" },
2331 { 7, "r7" },
2332 { 8, "r8" },
2333 { 9, "r9" },
2334 { 10, "r10" },
2335 { 11, "r11" },
2336 { 12, "r12" },
2337 { 13, "r13" },
2338 { 14, "r14" },
2339 { 15, "r15" },
2340 { 16, "r16" },
2341 { 17, "r17" },
2342 { 18, "r18" },
2343 { 19, "r19" },
2344 { 20, "r20" },
2345 { 21, "r21" },
2346 { 22, "r22" },
2347 { 23, "r23" },
2348 { 24, "r24" },
2349 { 25, "r25" },
2350 { 26, "r26" },
2351 { 27, "r27" },
2352 { 28, "r28" },
2353 { 29, "gp" },
2354 { 30, "fp" },
2355 { 31, "zero" },
2356 { 32, "fp0" },
2357 { 33, "fp" },
2358 { 34, "fp2" },
2359 { 35, "fp3" },
2360 { 36, "fp4" },
2361 { 37, "fp5" },
2362 { 38, "fp6" },
2363 { 39, "fp7" },
2364 { 40, "fp8" },
2365 { 41, "fp9" },
2366 { 42, "fp10" },
2367 { 43, "fp11" },
2368 { 44, "fp12" },
2369 { 45, "fp13" },
2370 { 46, "fp14" },
2371 { 47, "fp15" },
2372 { 48, "fp16" },
2373 { 49, "fp17" },
2374 { 50, "fp18" },
2375 { 51, "fp19" },
2376 { 52, "fp20" },
2377 { 53, "fp21" },
2378 { 54, "fp22" },
2379 { 55, "fp23" },
2380 { 56, "fp24" },
2381 { 57, "fp25" },
2382 { 58, "fp26" },
2383 { 59, "fp27" },
2384 { 60, "fp28" },
2385 { 61, "fp29" },
2386 { 62, "fp30" },
2387 { 63, "fp31" },
2388 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002389#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002390#ifdef IA64
2391 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2392 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2393 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2394 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2395 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2396 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2397 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2398 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2399 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2400 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2401 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2402 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2403 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2404 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2405 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2406 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2407 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2408 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2409 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2410 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2411 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2412 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2413 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2414 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2415 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2416 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2417 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2418 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2419 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2420 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2421 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2422 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2423 /* switch stack: */
2424 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2425 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2426 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2427 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2428 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2429 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2430 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2431 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2432 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2433 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002434 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2435 { PT_B4, "b4" }, { PT_B5, "b5" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002436 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002437 /* pt_regs */
Roland McGrathca4e10c2004-01-13 10:13:20 +00002438 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2439 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002440 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2441 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2442 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2443 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2444 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2445 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2446 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2447 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2448 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2449 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2450 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2451 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2452 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2453 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2454 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002455 { PT_AR_CSD, "ar.csd" }, { PT_AR_SSD, "ar.ssd" },
2456 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002457#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002458#ifdef I386
2459 { 4*EBX, "4*EBX" },
2460 { 4*ECX, "4*ECX" },
2461 { 4*EDX, "4*EDX" },
2462 { 4*ESI, "4*ESI" },
2463 { 4*EDI, "4*EDI" },
2464 { 4*EBP, "4*EBP" },
2465 { 4*EAX, "4*EAX" },
2466 { 4*DS, "4*DS" },
2467 { 4*ES, "4*ES" },
2468 { 4*FS, "4*FS" },
2469 { 4*GS, "4*GS" },
2470 { 4*ORIG_EAX, "4*ORIG_EAX" },
2471 { 4*EIP, "4*EIP" },
2472 { 4*CS, "4*CS" },
2473 { 4*EFL, "4*EFL" },
2474 { 4*UESP, "4*UESP" },
2475 { 4*SS, "4*SS" },
2476#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002477#ifdef X86_64
2478 { 8*RDI, "8*RDI" },
2479 { 8*RSI, "8*RSI" },
2480 { 8*RDX, "8*RDX" },
2481 { 8*R10, "8*R10" },
2482 { 8*R8, "8*R8" },
2483 { 8*R9, "8*R9" },
2484 { 8*RBX, "8*RBX" },
2485 { 8*RCX, "8*RCX" },
2486 { 8*RBP, "8*RBP" },
2487 { 8*RAX, "8*RAX" },
2488#if 0
2489 { 8*DS, "8*DS" },
2490 { 8*ES, "8*ES" },
2491 { 8*FS, "8*FS" },
2492 { 8*GS, "8*GS" },
2493#endif
2494 { 8*ORIG_RAX, "8*ORIG_EAX" },
2495 { 8*RIP, "8*RIP" },
2496 { 8*CS, "8*CS" },
2497 { 8*EFLAGS, "8*EFL" },
2498 { 8*RSP, "8*RSP" },
2499 { 8*SS, "8*SS" },
2500 { 8*R11, "8*R11" },
2501 { 8*R12, "8*R12" },
2502 { 8*R13, "8*R13" },
2503 { 8*R14, "8*R14" },
2504 { 8*R15, "8*R15" },
2505#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002506#ifdef M68K
2507 { 4*PT_D1, "4*PT_D1" },
2508 { 4*PT_D2, "4*PT_D2" },
2509 { 4*PT_D3, "4*PT_D3" },
2510 { 4*PT_D4, "4*PT_D4" },
2511 { 4*PT_D5, "4*PT_D5" },
2512 { 4*PT_D6, "4*PT_D6" },
2513 { 4*PT_D7, "4*PT_D7" },
2514 { 4*PT_A0, "4*PT_A0" },
2515 { 4*PT_A1, "4*PT_A1" },
2516 { 4*PT_A2, "4*PT_A2" },
2517 { 4*PT_A3, "4*PT_A3" },
2518 { 4*PT_A4, "4*PT_A4" },
2519 { 4*PT_A5, "4*PT_A5" },
2520 { 4*PT_A6, "4*PT_A6" },
2521 { 4*PT_D0, "4*PT_D0" },
2522 { 4*PT_USP, "4*PT_USP" },
2523 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2524 { 4*PT_SR, "4*PT_SR" },
2525 { 4*PT_PC, "4*PT_PC" },
2526#endif /* M68K */
2527#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002528#ifdef SH
2529 { 4*REG_REG0, "4*REG_REG0" },
2530 { 4*(REG_REG0+1), "4*REG_REG1" },
2531 { 4*(REG_REG0+2), "4*REG_REG2" },
2532 { 4*(REG_REG0+3), "4*REG_REG3" },
2533 { 4*(REG_REG0+4), "4*REG_REG4" },
2534 { 4*(REG_REG0+5), "4*REG_REG5" },
2535 { 4*(REG_REG0+6), "4*REG_REG6" },
2536 { 4*(REG_REG0+7), "4*REG_REG7" },
2537 { 4*(REG_REG0+8), "4*REG_REG8" },
2538 { 4*(REG_REG0+9), "4*REG_REG9" },
2539 { 4*(REG_REG0+10), "4*REG_REG10" },
2540 { 4*(REG_REG0+11), "4*REG_REG11" },
2541 { 4*(REG_REG0+12), "4*REG_REG12" },
2542 { 4*(REG_REG0+13), "4*REG_REG13" },
2543 { 4*(REG_REG0+14), "4*REG_REG14" },
2544 { 4*REG_REG15, "4*REG_REG15" },
2545 { 4*REG_PC, "4*REG_PC" },
2546 { 4*REG_PR, "4*REG_PR" },
2547 { 4*REG_SR, "4*REG_SR" },
2548 { 4*REG_GBR, "4*REG_GBR" },
2549 { 4*REG_MACH, "4*REG_MACH" },
2550 { 4*REG_MACL, "4*REG_MACL" },
2551 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2552 { 4*REG_FPUL, "4*REG_FPUL" },
2553 { 4*REG_FPREG0, "4*REG_FPREG0" },
2554 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2555 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2556 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2557 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2558 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2559 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2560 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2561 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2562 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2563 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2564 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2565 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2566 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2567 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2568 { 4*REG_FPREG15, "4*REG_FPREG15" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002569#ifdef REG_XDREG0
Wichert Akkermanccef6372002-05-01 16:39:22 +00002570 { 4*REG_XDREG0, "4*REG_XDREG0" },
2571 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2572 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2573 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2574 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2575 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2576 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2577 { 4*REG_XDREG14, "4*REG_XDREG14" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002578#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002579 { 4*REG_FPSCR, "4*REG_FPSCR" },
2580#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002581#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002582 { 0, "PC(L)" },
2583 { 4, "PC(U)" },
2584 { 8, "SR(L)" },
2585 { 12, "SR(U)" },
2586 { 16, "syscall no.(L)" },
2587 { 20, "syscall_no.(U)" },
2588 { 24, "R0(L)" },
2589 { 28, "R0(U)" },
2590 { 32, "R1(L)" },
2591 { 36, "R1(U)" },
2592 { 40, "R2(L)" },
2593 { 44, "R2(U)" },
2594 { 48, "R3(L)" },
2595 { 52, "R3(U)" },
2596 { 56, "R4(L)" },
2597 { 60, "R4(U)" },
2598 { 64, "R5(L)" },
2599 { 68, "R5(U)" },
2600 { 72, "R6(L)" },
2601 { 76, "R6(U)" },
2602 { 80, "R7(L)" },
2603 { 84, "R7(U)" },
2604 { 88, "R8(L)" },
2605 { 92, "R8(U)" },
2606 { 96, "R9(L)" },
2607 { 100, "R9(U)" },
2608 { 104, "R10(L)" },
2609 { 108, "R10(U)" },
2610 { 112, "R11(L)" },
2611 { 116, "R11(U)" },
2612 { 120, "R12(L)" },
2613 { 124, "R12(U)" },
2614 { 128, "R13(L)" },
2615 { 132, "R13(U)" },
2616 { 136, "R14(L)" },
2617 { 140, "R14(U)" },
2618 { 144, "R15(L)" },
2619 { 148, "R15(U)" },
2620 { 152, "R16(L)" },
2621 { 156, "R16(U)" },
2622 { 160, "R17(L)" },
2623 { 164, "R17(U)" },
2624 { 168, "R18(L)" },
2625 { 172, "R18(U)" },
2626 { 176, "R19(L)" },
2627 { 180, "R19(U)" },
2628 { 184, "R20(L)" },
2629 { 188, "R20(U)" },
2630 { 192, "R21(L)" },
2631 { 196, "R21(U)" },
2632 { 200, "R22(L)" },
2633 { 204, "R22(U)" },
2634 { 208, "R23(L)" },
2635 { 212, "R23(U)" },
2636 { 216, "R24(L)" },
2637 { 220, "R24(U)" },
2638 { 224, "R25(L)" },
2639 { 228, "R25(U)" },
2640 { 232, "R26(L)" },
2641 { 236, "R26(U)" },
2642 { 240, "R27(L)" },
2643 { 244, "R27(U)" },
2644 { 248, "R28(L)" },
2645 { 252, "R28(U)" },
2646 { 256, "R29(L)" },
2647 { 260, "R29(U)" },
2648 { 264, "R30(L)" },
2649 { 268, "R30(U)" },
2650 { 272, "R31(L)" },
2651 { 276, "R31(U)" },
2652 { 280, "R32(L)" },
2653 { 284, "R32(U)" },
2654 { 288, "R33(L)" },
2655 { 292, "R33(U)" },
2656 { 296, "R34(L)" },
2657 { 300, "R34(U)" },
2658 { 304, "R35(L)" },
2659 { 308, "R35(U)" },
2660 { 312, "R36(L)" },
2661 { 316, "R36(U)" },
2662 { 320, "R37(L)" },
2663 { 324, "R37(U)" },
2664 { 328, "R38(L)" },
2665 { 332, "R38(U)" },
2666 { 336, "R39(L)" },
2667 { 340, "R39(U)" },
2668 { 344, "R40(L)" },
2669 { 348, "R40(U)" },
2670 { 352, "R41(L)" },
2671 { 356, "R41(U)" },
2672 { 360, "R42(L)" },
2673 { 364, "R42(U)" },
2674 { 368, "R43(L)" },
2675 { 372, "R43(U)" },
2676 { 376, "R44(L)" },
2677 { 380, "R44(U)" },
2678 { 384, "R45(L)" },
2679 { 388, "R45(U)" },
2680 { 392, "R46(L)" },
2681 { 396, "R46(U)" },
2682 { 400, "R47(L)" },
2683 { 404, "R47(U)" },
2684 { 408, "R48(L)" },
2685 { 412, "R48(U)" },
2686 { 416, "R49(L)" },
2687 { 420, "R49(U)" },
2688 { 424, "R50(L)" },
2689 { 428, "R50(U)" },
2690 { 432, "R51(L)" },
2691 { 436, "R51(U)" },
2692 { 440, "R52(L)" },
2693 { 444, "R52(U)" },
2694 { 448, "R53(L)" },
2695 { 452, "R53(U)" },
2696 { 456, "R54(L)" },
2697 { 460, "R54(U)" },
2698 { 464, "R55(L)" },
2699 { 468, "R55(U)" },
2700 { 472, "R56(L)" },
2701 { 476, "R56(U)" },
2702 { 480, "R57(L)" },
2703 { 484, "R57(U)" },
2704 { 488, "R58(L)" },
2705 { 492, "R58(U)" },
2706 { 496, "R59(L)" },
2707 { 500, "R59(U)" },
2708 { 504, "R60(L)" },
2709 { 508, "R60(U)" },
2710 { 512, "R61(L)" },
2711 { 516, "R61(U)" },
2712 { 520, "R62(L)" },
2713 { 524, "R62(U)" },
2714 { 528, "TR0(L)" },
2715 { 532, "TR0(U)" },
2716 { 536, "TR1(L)" },
2717 { 540, "TR1(U)" },
2718 { 544, "TR2(L)" },
2719 { 548, "TR2(U)" },
2720 { 552, "TR3(L)" },
2721 { 556, "TR3(U)" },
2722 { 560, "TR4(L)" },
2723 { 564, "TR4(U)" },
2724 { 568, "TR5(L)" },
2725 { 572, "TR5(U)" },
2726 { 576, "TR6(L)" },
2727 { 580, "TR6(U)" },
2728 { 584, "TR7(L)" },
2729 { 588, "TR7(U)" },
2730 /* This entry is in case pt_regs contains dregs (depends on
2731 the kernel build options). */
2732 { uoff(regs), "offsetof(struct user, regs)" },
2733 { uoff(fpu), "offsetof(struct user, fpu)" },
2734#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002735#ifdef ARM
2736 { uoff(regs.ARM_r0), "r0" },
2737 { uoff(regs.ARM_r1), "r1" },
2738 { uoff(regs.ARM_r2), "r2" },
2739 { uoff(regs.ARM_r3), "r3" },
2740 { uoff(regs.ARM_r4), "r4" },
2741 { uoff(regs.ARM_r5), "r5" },
2742 { uoff(regs.ARM_r6), "r6" },
2743 { uoff(regs.ARM_r7), "r7" },
2744 { uoff(regs.ARM_r8), "r8" },
2745 { uoff(regs.ARM_r9), "r9" },
2746 { uoff(regs.ARM_r10), "r10" },
2747 { uoff(regs.ARM_fp), "fp" },
2748 { uoff(regs.ARM_ip), "ip" },
2749 { uoff(regs.ARM_sp), "sp" },
2750 { uoff(regs.ARM_lr), "lr" },
2751 { uoff(regs.ARM_pc), "pc" },
2752 { uoff(regs.ARM_cpsr), "cpsr" },
2753#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002754
Michal Ludvig10a88d02002-10-07 14:31:00 +00002755#if !defined(S390) && !defined(S390X) && !defined(MIPS)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002756 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002757#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002758#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002759 { uoff(i387), "offsetof(struct user, i387)" },
2760#else /* !I386 */
2761#ifdef M68K
2762 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2763#endif /* M68K */
2764#endif /* !I386 */
2765 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2766 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2767 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2768 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrathf5a47772003-06-26 22:40:42 +00002769#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002770 { uoff(start_data), "offsetof(struct user, start_data)" },
2771#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002772 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2773 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrathf5a47772003-06-26 22:40:42 +00002774#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002775 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002776#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002777 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002778#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002779 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2780#endif
2781 { uoff(magic), "offsetof(struct user, magic)" },
2782 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002783#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002784 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2785#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002786#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002787#endif /* !ALPHA */
2788#endif /* !POWERPC/!SPARC */
2789#endif /* LINUX */
2790#ifdef SUNOS4
2791 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2792 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2793 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2794 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2795 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2796 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2797 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2798 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2799 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2800 { uoff(u_error), "offsetof(struct user, u_error)" },
2801 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2802 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2803 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2804 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2805 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2806 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2807 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2808 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2809 { uoff(u_code), "offsetof(struct user, u_code)" },
2810 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2811 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2812 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2813 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2814 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2815 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2816 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2817 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2818 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2819 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2820 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2821 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2822 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2823 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2824 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2825 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2826 { uoff(u_start), "offsetof(struct user, u_start)" },
2827 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2828 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2829 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2830 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2831 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2832 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2833 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2834 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2835 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2836#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002837#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002838 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002839#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002840 { 0, NULL },
2841};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002842#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002843
2844int
2845sys_ptrace(tcp)
2846struct tcb *tcp;
2847{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002848 struct xlat *x;
2849 long addr;
2850
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002851 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002852 printxval(ptrace_cmds, tcp->u_arg[0],
2853#ifndef FREEBSD
2854 "PTRACE_???"
2855#else
2856 "PT_???"
2857#endif
2858 );
2859 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002860 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002861#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002862 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2863 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2864 for (x = struct_user_offsets; x->str; x++) {
2865 if (x->val >= addr)
2866 break;
2867 }
2868 if (!x->str)
2869 tprintf("%#lx, ", addr);
2870 else if (x->val > addr && x != struct_user_offsets) {
2871 x--;
2872 tprintf("%s + %ld, ", x->str, addr - x->val);
2873 }
2874 else
2875 tprintf("%s, ", x->str);
2876 }
2877 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002878#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002879 tprintf("%#lx, ", tcp->u_arg[2]);
2880#ifdef LINUX
2881 switch (tcp->u_arg[0]) {
2882 case PTRACE_PEEKDATA:
2883 case PTRACE_PEEKTEXT:
2884 case PTRACE_PEEKUSER:
2885 break;
2886 case PTRACE_CONT:
2887 case PTRACE_SINGLESTEP:
2888 case PTRACE_SYSCALL:
2889 case PTRACE_DETACH:
2890 printsignal(tcp->u_arg[3]);
2891 break;
2892 default:
2893 tprintf("%#lx", tcp->u_arg[3]);
2894 break;
2895 }
2896 } else {
2897 switch (tcp->u_arg[0]) {
2898 case PTRACE_PEEKDATA:
2899 case PTRACE_PEEKTEXT:
2900 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00002901 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002902 break;
2903 }
2904 }
2905#endif /* LINUX */
2906#ifdef SUNOS4
2907 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2908 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2909 tprintf("%lu, ", tcp->u_arg[3]);
2910 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2911 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2912 tcp->u_arg[0] != PTRACE_READTEXT) {
2913 tprintf("%#lx", tcp->u_arg[3]);
2914 }
2915 } else {
2916 if (tcp->u_arg[0] == PTRACE_READDATA ||
2917 tcp->u_arg[0] == PTRACE_READTEXT) {
2918 tprintf("%lu, ", tcp->u_arg[3]);
2919 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2920 }
2921 }
2922#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002923#ifdef FREEBSD
2924 tprintf("%lu", tcp->u_arg[3]);
2925 }
2926#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002927 return 0;
2928}
2929
2930#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002931
2932#ifdef LINUX
2933static struct xlat futexops[] = {
2934 { FUTEX_WAIT, "FUTEX_WAIT" },
2935 { FUTEX_WAKE, "FUTEX_WAKE" },
2936 { FUTEX_FD, "FUTEX_FD" },
Roland McGrath88812d62003-06-26 22:27:23 +00002937 { FUTEX_REQUEUE,"FUTEX_REQUEUE" },
Roland McGrath5a223472002-12-15 23:58:26 +00002938 { 0, NULL }
2939};
2940
2941int
2942sys_futex(tcp)
2943struct tcb *tcp;
2944{
2945 if (entering(tcp)) {
2946 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00002947 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00002948 tprintf(", %ld", tcp->u_arg[2]);
2949 if (tcp->u_arg[1] == FUTEX_WAIT) {
2950 tprintf(", ");
2951 printtv(tcp, tcp->u_arg[3]);
Roland McGrath88812d62003-06-26 22:27:23 +00002952 } else if (tcp->u_arg[1] == FUTEX_REQUEUE)
2953 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath5a223472002-12-15 23:58:26 +00002954 }
2955 return 0;
2956}
2957
2958static void
2959print_affinitylist(list, len)
2960unsigned long *list;
2961unsigned int len;
2962{
2963 int first = 1;
2964 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00002965 while (len >= sizeof (unsigned long)) {
Roland McGrath5a223472002-12-15 23:58:26 +00002966 tprintf("%s %lx", first ? "" : ",", *list++);
2967 first = 0;
2968 len -= sizeof (unsigned long);
2969 }
2970 tprintf(" }");
2971}
2972
2973int
2974sys_sched_setaffinity(tcp)
2975struct tcb *tcp;
2976{
2977 if (entering(tcp)) {
2978 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2979 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2980 }
2981 return 0;
2982}
2983
2984int
2985sys_sched_getaffinity(tcp)
2986struct tcb *tcp;
2987{
2988 if (entering(tcp)) {
2989 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2990 } else {
2991 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);
2992 }
2993 return 0;
2994}
2995#endif