blob: 1839463c69035840d14ffffe2ec2daed1b36af42 [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
Roland McGrath08267b82004-02-20 22:56:43 +0000376# ifdef IA64
377 if (ia32) {
378 if (tcp->scno == 252)
379 tcp->flags |= TCB_GROUP_EXITING;
380 } else
381# endif
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000382 if (tcp->scno == __NR_exit_group)
383 tcp->flags |= TCB_GROUP_EXITING;
384#endif
385 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000386 return 0;
387}
388
Roland McGrathee9d4352002-12-18 04:16:10 +0000389/* TCP is creating a child we want to follow.
390 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
391 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
392static int
393fork_tcb(struct tcb *tcp)
394{
395 if (nprocs == tcbtabsize) {
396 /* Allocate some more TCBs and expand the table.
397 We don't want to relocate the TCBs because our
398 callers have pointers and it would be a pain.
399 So tcbtab is a table of pointers. Since we never
400 free the TCBs, we allocate a single chunk of many. */
401 struct tcb **newtab = (struct tcb **)
402 realloc(tcbtab, 2 * tcbtabsize * sizeof tcbtab[0]);
403 struct tcb *newtcbs = (struct tcb *) calloc(tcbtabsize,
404 sizeof *newtcbs);
405 int i;
406 if (newtab == NULL || newtcbs == NULL) {
407 if (newtab != NULL)
408 free(newtab);
409 tcp->flags &= ~TCB_FOLLOWFORK;
410 fprintf(stderr, "sys_fork: tcb table full\n");
411 return 1;
412 }
413 for (i = tcbtabsize; i < 2 * tcbtabsize; ++i)
414 newtab[i] = &newtcbs[i - tcbtabsize];
415 tcbtabsize *= 2;
416 tcbtab = newtab;
417 }
418
419 tcp->flags |= TCB_FOLLOWFORK;
420 return 0;
421}
422
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000423#ifdef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000424
425int
426sys_fork(tcp)
427struct tcb *tcp;
428{
429 if (exiting(tcp)) {
430 if (getrval2(tcp)) {
431 tcp->auxstr = "child process";
432 return RVAL_UDECIMAL | RVAL_STR;
433 }
434 }
435 return 0;
436}
437
John Hughes4e36a812001-04-18 15:11:51 +0000438#if UNIXWARE > 2
439
440int
441sys_rfork(tcp)
442struct tcb *tcp;
443{
444 if (entering(tcp)) {
445 tprintf ("%ld", tcp->u_arg[0]);
446 }
447 else {
448 if (getrval2(tcp)) {
449 tcp->auxstr = "child process";
450 return RVAL_UDECIMAL | RVAL_STR;
451 }
452 }
453 return 0;
454}
455
456#endif
457
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000458int
459internal_fork(tcp)
460struct tcb *tcp;
461{
462 struct tcb *tcpchild;
463
464 if (exiting(tcp)) {
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000465#ifdef SYS_rfork
466 if (tcp->scno == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
467 return 0;
468#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000469 if (getrval2(tcp))
470 return 0;
471 if (!followfork)
472 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000473 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000474 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000475 if (syserror(tcp))
476 return 0;
477 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
478 fprintf(stderr, "sys_fork: tcb table full\n");
479 return 0;
480 }
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000481 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000482 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000483 }
484 return 0;
485}
486
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000487#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000488
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000489#ifdef LINUX
490
491/* defines copied from linux/sched.h since we can't include that
492 * ourselves (it conflicts with *lots* of libc includes)
493 */
494#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
495#define CLONE_VM 0x00000100 /* set if VM shared between processes */
496#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
497#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
498#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000499#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000500#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
501#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
502#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000503#define CLONE_THREAD 0x00010000 /* Same thread group? */
504#define CLONE_NEWNS 0x00020000 /* New namespace group? */
505#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
506#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
507#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
508#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
509#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
510#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
511#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000512
513static struct xlat clone_flags[] = {
514 { CLONE_VM, "CLONE_VM" },
515 { CLONE_FS, "CLONE_FS" },
516 { CLONE_FILES, "CLONE_FILES" },
517 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000518 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000519 { CLONE_PTRACE, "CLONE_PTRACE" },
520 { CLONE_VFORK, "CLONE_VFORK" },
521 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000522 { CLONE_THREAD, "CLONE_THREAD" },
523 { CLONE_NEWNS, "CLONE_NEWNS" },
524 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
525 { CLONE_SETTLS, "CLONE_SETTLS" },
526 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
527 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
528 { CLONE_DETACHED, "CLONE_DETACHED" },
529 { CLONE_UNTRACED, "CLONE_UNTRACED" },
530 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000531 { 0, NULL },
532};
533
Roland McGrath909875b2002-12-22 03:34:36 +0000534# ifdef I386
535# include <asm/ldt.h>
536extern void print_ldt_entry();
537# endif
538
Roland McGrath9677b3a2003-03-12 09:54:36 +0000539# if defined IA64
540# define ARG_FLAGS 0
541# define ARG_STACK 1
542# define ARG_STACKSIZE (tcp->scno == SYS_clone2 ? 2 : -1)
Roland McGrathc03981d2003-03-14 10:32:36 +0000543# define ARG_PTID (tcp->scno == SYS_clone2 ? 3 : 2)
544# define ARG_CTID (tcp->scno == SYS_clone2 ? 4 : 3)
545# define ARG_TLS (tcp->scno == SYS_clone2 ? 5 : 4)
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000546# elif defined S390 || defined S390X
Roland McGrath9677b3a2003-03-12 09:54:36 +0000547# define ARG_STACK 0
548# define ARG_FLAGS 1
549# define ARG_PTID 2
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000550# define ARG_CTID 3
551# define ARG_TLS 4
Roland McGrath9c555e72003-07-09 09:47:59 +0000552# elif defined X86_64 || defined ALPHA
Roland McGrath361aac52003-03-18 07:43:42 +0000553# define ARG_FLAGS 0
554# define ARG_STACK 1
555# define ARG_PTID 2
556# define ARG_CTID 3
557# define ARG_TLS 4
Roland McGrath9677b3a2003-03-12 09:54:36 +0000558# else
559# define ARG_FLAGS 0
560# define ARG_STACK 1
561# define ARG_PTID 2
562# define ARG_TLS 3
563# define ARG_CTID 4
564# endif
565
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000566int
567sys_clone(tcp)
568struct tcb *tcp;
569{
570 if (exiting(tcp)) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000571 unsigned long flags = tcp->u_arg[ARG_FLAGS];
572 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
573# ifdef ARG_STACKSIZE
574 if (ARG_STACKSIZE != -1)
575 tprintf("stack_size=%#lx, ",
576 tcp->u_arg[ARG_STACKSIZE]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000577# endif
Roland McGrath9677b3a2003-03-12 09:54:36 +0000578 tprintf("flags=");
Roland McGrath984154d2003-05-23 01:08:42 +0000579 if (printflags(clone_flags, flags &~ CSIGNAL) == 0)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000580 tprintf("0");
Roland McGrath984154d2003-05-23 01:08:42 +0000581 if ((flags & CSIGNAL) != 0)
582 tprintf("|%s", signame(flags & CSIGNAL));
Roland McGrathb4968be2003-01-20 09:04:33 +0000583 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
Roland McGrath9677b3a2003-03-12 09:54:36 +0000584 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
Roland McGrath909875b2002-12-22 03:34:36 +0000585 return 0;
Roland McGrath6f67a982003-03-21 07:33:15 +0000586 if (flags & CLONE_PARENT_SETTID)
587 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000588 if (flags & CLONE_SETTLS) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000589# ifdef I386
Roland McGrath909875b2002-12-22 03:34:36 +0000590 struct modify_ldt_ldt_s copy;
Roland McGrath9677b3a2003-03-12 09:54:36 +0000591 if (umove(tcp, tcp->u_arg[ARG_TLS], &copy) != -1) {
Roland McGrath909875b2002-12-22 03:34:36 +0000592 tprintf(", {entry_number:%d, ",
593 copy.entry_number);
594 if (!verbose(tcp))
595 tprintf("...}");
596 else
597 print_ldt_entry(&copy);
598 }
599 else
Roland McGrath9677b3a2003-03-12 09:54:36 +0000600# endif
Roland McGrath43f2c842003-03-12 09:58:14 +0000601 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
Roland McGrath909875b2002-12-22 03:34:36 +0000602 }
Roland McGrath9677b3a2003-03-12 09:54:36 +0000603 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
604 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000605 }
606 return 0;
607}
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000608#endif
609
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000610int
611sys_fork(tcp)
612struct tcb *tcp;
613{
614 if (exiting(tcp))
615 return RVAL_UDECIMAL;
616 return 0;
617}
618
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000619int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000620change_syscall(tcp, new)
621struct tcb *tcp;
622int new;
623{
624#if defined(LINUX)
625#if defined(I386)
626 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000627 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000628 return -1;
629 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000630#elif defined(X86_64)
631 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000632 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000633 return -1;
634 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000635#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000636 if (ptrace(PTRACE_POKEUSER, tcp->pid,
637 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000638 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000639 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000640#elif defined(S390) || defined(S390X)
641 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
642 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
643 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000644 return 0;
645#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000646 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000647 return -1;
648 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000649#elif defined(SPARC)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000650 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000651 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
652 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000653 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000654 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
655 return -1;
656 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000657#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000658 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000659 return -1;
660 return 0;
661#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000662 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000663 return -1;
664 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000665#elif defined(IA64)
Roland McGrath08267b82004-02-20 22:56:43 +0000666 if (ia32) {
667 switch (new) {
668 case 2: break; /* x86 SYS_fork */
669 case SYS_clone: new = 120; break;
670 default:
671 fprintf(stderr, "%s: unexpected syscall %d\n",
672 __FUNCTION__, new);
673 return -1;
674 }
675 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
676 return -1;
677 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000678 return -1;
679 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000680#elif defined(HPPA)
681 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
682 return -1;
683 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000684#elif defined(SH)
Roland McGrathac971c22003-03-31 01:03:33 +0000685 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
Wichert Akkermanccef6372002-05-01 16:39:22 +0000686 return -1;
687 return 0;
Roland McGrathf5a47772003-06-26 22:40:42 +0000688#elif defined(SH64)
Roland McGrathe1e584b2003-06-02 19:18:58 +0000689 /* Top half of reg encodes the no. of args n as 0x1n.
690 Assume 0 args as kernel never actually checks... */
691 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
692 0x100000 | new) < 0)
693 return -1;
694 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000695#else
696#warning Do not know how to handle change_syscall for this architecture
697#endif /* architecture */
698#endif /* LINUX */
699 return -1;
700}
701
702int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000703setarg(tcp, argnum)
704 struct tcb *tcp;
705 int argnum;
706{
707#if defined (IA64)
708 {
709 unsigned long *bsp, *ap;
710
711 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
712 return -1;
713
714 ap = ia64_rse_skip_regs(bsp, argnum);
715 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000716 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000717 if (errno)
718 return -1;
719
720 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000721#elif defined(I386)
722 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000723 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000724 if (errno)
725 return -1;
726 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000727#elif defined(X86_64)
728 {
729 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
730 if (errno)
731 return -1;
732 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000733#elif defined(POWERPC)
734#ifndef PT_ORIG_R3
735#define PT_ORIG_R3 34
736#endif
737 {
738 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000739 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000740 tcp->u_arg[argnum]);
741 if (errno)
742 return -1;
743 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000744#elif defined(MIPS)
745 {
746 errno = 0;
747 if (argnum < 4)
748 ptrace(PTRACE_POKEUSER, tcp->pid,
749 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
750 else {
751 unsigned long *sp;
752
753 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
754 return -1;
755
756 ptrace(PTRACE_POKEDATA, tcp->pid,
757 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
758 }
759 if (errno)
760 return -1;
761 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000762#elif defined(S390) || defined(S390X)
763 {
764 if(argnum <= 5)
765 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000766 (char *) (argnum==0 ? PT_ORIGGPR2 :
767 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000768 tcp->u_arg[argnum]);
769 else
770 return -E2BIG;
771 if (errno)
772 return -1;
773 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000774#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000775# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000776#endif
777 return 0;
778}
779
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000780#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000781int
782internal_clone(tcp)
783struct tcb *tcp;
784{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000785 struct tcb *tcpchild;
786 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000787 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000788 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000789 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000790 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000791 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000792 if (setbpt(tcp) < 0)
793 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000794 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000795 int bpt = tcp->flags & TCB_BPTSET;
796
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000797 if (!(tcp->flags & TCB_FOLLOWFORK))
798 return 0;
799
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000800 if (syserror(tcp)) {
801 if (bpt)
802 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000803 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000804 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000805
806 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000807
808#ifdef CLONE_PTRACE /* See new setbpt code. */
809 tcpchild = pid2tcb(pid);
810 if (tcpchild != NULL) {
811 /* The child already reported its startup trap
812 before the parent reported its syscall return. */
813 if ((tcpchild->flags
814 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
815 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
816 fprintf(stderr, "\
817[preattached child %d of %d in weird state!]\n",
818 pid, tcp->pid);
819 }
820 else
821#endif
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000822 if ((tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000823 if (bpt)
824 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000825 fprintf(stderr, " [tcb table full]\n");
826 kill(pid, SIGKILL); /* XXX */
827 return 0;
828 }
829
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000830#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000831 /* Attach to the new child */
832 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000833 if (bpt)
834 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000835 perror("PTRACE_ATTACH");
836 fprintf(stderr, "Too late?\n");
837 droptcb(tcpchild);
838 return 0;
839 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000840#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000841
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000842 if (bpt)
843 clearbpt(tcp);
844
Ulrich Drepper90512f01999-12-24 07:22:25 +0000845 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000846 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000847 if (bpt) {
848 tcpchild->flags |= TCB_BPTSET;
849 tcpchild->baddr = tcp->baddr;
850 memcpy(tcpchild->inst, tcp->inst,
851 sizeof tcpchild->inst);
852 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000853 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000854 tcp->nchildren++;
855 if (tcpchild->flags & TCB_SUSPENDED) {
856 /* The child was born suspended, due to our having
857 forced CLONE_PTRACE. */
858 if (bpt)
859 clearbpt(tcpchild);
860
861 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
862 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
863 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
864 return -1;
865 }
866
867 if (!qflag)
868 fprintf(stderr, "\
869Process %u resumed (parent %d ready)\n",
870 pid, tcp->pid);
871 }
872 else {
873 newoutf(tcpchild);
874 if (!qflag)
875 fprintf(stderr, "Process %d attached\n", pid);
876 }
877
878#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000879 {
880 /*
881 * Save the flags used in this call,
882 * in case we point TCP to our parent below.
883 */
884 int call_flags = tcp->u_arg[ARG_FLAGS];
885 if ((tcp->flags & TCB_CLONE_THREAD) &&
886 tcp->parent != NULL) {
887 /* The parent in this clone is itself a
888 thread belonging to another process.
889 There is no meaning to the parentage
890 relationship of the new child with the
891 thread, only with the process. We
892 associate the new thread with our
893 parent. Since this is done for every
894 new thread, there will never be a
895 TCB_CLONE_THREAD process that has
896 children. */
897 --tcp->nchildren;
898 tcp = tcp->parent;
899 tcpchild->parent = tcp;
900 ++tcp->nchildren;
901 }
902 if (call_flags & CLONE_THREAD) {
903 tcpchild->flags |= TCB_CLONE_THREAD;
904 ++tcp->nclone_threads;
905 }
906 if (call_flags & CLONE_DETACHED) {
907 tcpchild->flags |= TCB_CLONE_DETACHED;
908 ++tcp->nclone_detached;
909 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000910 }
911#endif
912
913 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000914 return 0;
915}
916#endif
917
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000918int
919internal_fork(tcp)
920struct tcb *tcp;
921{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000922#ifdef LINUX
923 /* We do special magic with clone for any clone or fork. */
924 return internal_clone(tcp);
925#else
926
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000927 struct tcb *tcpchild;
928 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000929 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000930
931#ifdef SYS_vfork
Nate Sammonsccd8f211999-03-29 22:57:54 +0000932 if (tcp->scno == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000933 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000934 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000935 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000936 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000937 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000938#endif
939 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000940 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000941 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000942 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000943 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000944 if (setbpt(tcp) < 0)
945 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000946 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000947 else {
948 int bpt = tcp->flags & TCB_BPTSET;
949
950 if (!(tcp->flags & TCB_FOLLOWFORK))
951 return 0;
952 if (bpt)
953 clearbpt(tcp);
954
955 if (syserror(tcp))
956 return 0;
957
958 pid = tcp->u_rval;
959 if ((tcpchild = alloctcb(pid)) == NULL) {
960 fprintf(stderr, " [tcb table full]\n");
961 kill(pid, SIGKILL); /* XXX */
962 return 0;
963 }
964#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000965#ifdef HPPA
966 /* The child must have run before it can be attached. */
967 /* This must be a bug in the parisc kernel, but I havn't
968 * identified it yet. Seems to be an issue associated
969 * with attaching to a process (which sends it a signal)
970 * before that process has ever been scheduled. When
971 * debugging, I started seeing crashes in
972 * arch/parisc/kernel/signal.c:do_signal(), apparently
973 * caused by r8 getting corrupt over the dequeue_signal()
974 * call. Didn't make much sense though...
975 */
976 {
977 struct timeval tv;
978 tv.tv_sec = 0;
979 tv.tv_usec = 10000;
980 select(0, NULL, NULL, NULL, &tv);
981 }
982#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000983 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
984 perror("PTRACE_ATTACH");
985 fprintf(stderr, "Too late?\n");
986 droptcb(tcpchild);
987 return 0;
988 }
989#endif /* LINUX */
990#ifdef SUNOS4
991#ifdef oldway
992 /* The child must have run before it can be attached. */
993 {
994 struct timeval tv;
995 tv.tv_sec = 0;
996 tv.tv_usec = 10000;
997 select(0, NULL, NULL, NULL, &tv);
998 }
999 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1000 perror("PTRACE_ATTACH");
1001 fprintf(stderr, "Too late?\n");
1002 droptcb(tcpchild);
1003 return 0;
1004 }
1005#else /* !oldway */
1006 /* Try to catch the new process as soon as possible. */
1007 {
1008 int i;
1009 for (i = 0; i < 1024; i++)
1010 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1011 break;
1012 if (i == 1024) {
1013 perror("PTRACE_ATTACH");
1014 fprintf(stderr, "Too late?\n");
1015 droptcb(tcpchild);
1016 return 0;
1017 }
1018 }
1019#endif /* !oldway */
1020#endif /* SUNOS4 */
1021 tcpchild->flags |= TCB_ATTACHED;
1022 /* Child has BPT too, must be removed on first occasion */
1023 if (bpt) {
1024 tcpchild->flags |= TCB_BPTSET;
1025 tcpchild->baddr = tcp->baddr;
1026 memcpy(tcpchild->inst, tcp->inst,
1027 sizeof tcpchild->inst);
1028 }
1029 newoutf(tcpchild);
1030 tcpchild->parent = tcp;
1031 tcp->nchildren++;
1032 if (!qflag)
1033 fprintf(stderr, "Process %d attached\n", pid);
1034 }
1035 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001036#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001037}
1038
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001039#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001040
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001041#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001042
1043int
1044sys_vfork(tcp)
1045struct tcb *tcp;
1046{
1047 if (exiting(tcp))
1048 return RVAL_UDECIMAL;
1049 return 0;
1050}
1051
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001052#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001053
1054#ifndef LINUX
1055
1056static char idstr[16];
1057
1058int
1059sys_getpid(tcp)
1060struct tcb *tcp;
1061{
1062 if (exiting(tcp)) {
1063 sprintf(idstr, "ppid %lu", getrval2(tcp));
1064 tcp->auxstr = idstr;
1065 return RVAL_STR;
1066 }
1067 return 0;
1068}
1069
1070int
1071sys_getuid(tcp)
1072struct tcb *tcp;
1073{
1074 if (exiting(tcp)) {
1075 sprintf(idstr, "euid %lu", getrval2(tcp));
1076 tcp->auxstr = idstr;
1077 return RVAL_STR;
1078 }
1079 return 0;
1080}
1081
1082int
1083sys_getgid(tcp)
1084struct tcb *tcp;
1085{
1086 if (exiting(tcp)) {
1087 sprintf(idstr, "egid %lu", getrval2(tcp));
1088 tcp->auxstr = idstr;
1089 return RVAL_STR;
1090 }
1091 return 0;
1092}
1093
1094#endif /* !LINUX */
1095
1096#ifdef LINUX
1097
1098int
1099sys_setuid(tcp)
1100struct tcb *tcp;
1101{
1102 if (entering(tcp)) {
1103 tprintf("%u", (uid_t) tcp->u_arg[0]);
1104 }
1105 return 0;
1106}
1107
1108int
1109sys_setgid(tcp)
1110struct tcb *tcp;
1111{
1112 if (entering(tcp)) {
1113 tprintf("%u", (gid_t) tcp->u_arg[0]);
1114 }
1115 return 0;
1116}
1117
1118int
1119sys_getresuid(tcp)
1120 struct tcb *tcp;
1121{
1122 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001123 __kernel_uid_t uid;
1124 if (syserror(tcp))
1125 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1126 tcp->u_arg[1], tcp->u_arg[2]);
1127 else {
1128 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1129 tprintf("%#lx, ", tcp->u_arg[0]);
1130 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[1], &uid) < 0)
1133 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001134 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001135 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001136 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1137 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001138 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001139 tprintf("[%lu]", (unsigned long) uid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001140 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001141 }
1142 return 0;
1143}
1144
1145int
1146sys_getresgid(tcp)
1147struct tcb *tcp;
1148{
1149 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001150 __kernel_gid_t gid;
1151 if (syserror(tcp))
1152 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1153 tcp->u_arg[1], tcp->u_arg[2]);
1154 else {
1155 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1156 tprintf("%#lx, ", tcp->u_arg[0]);
1157 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[1], &gid) < 0)
1160 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001161 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001162 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001163 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1164 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001165 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001166 tprintf("[%lu]", (unsigned long) gid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001167 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001168 }
1169 return 0;
1170}
1171
1172#endif /* LINUX */
1173
1174int
1175sys_setreuid(tcp)
1176struct tcb *tcp;
1177{
1178 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001179 printuid("", tcp->u_arg[0]);
1180 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001181 }
1182 return 0;
1183}
1184
1185int
1186sys_setregid(tcp)
1187struct tcb *tcp;
1188{
1189 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001190 printuid("", tcp->u_arg[0]);
1191 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001192 }
1193 return 0;
1194}
1195
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001196#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001197int
1198sys_setresuid(tcp)
1199 struct tcb *tcp;
1200{
1201 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001202 printuid("", tcp->u_arg[0]);
1203 printuid(", ", tcp->u_arg[1]);
1204 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001205 }
1206 return 0;
1207}
1208int
1209sys_setresgid(tcp)
1210 struct tcb *tcp;
1211{
1212 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001213 printuid("", tcp->u_arg[0]);
1214 printuid(", ", tcp->u_arg[1]);
1215 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001216 }
1217 return 0;
1218}
1219
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001220#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001221
1222int
1223sys_setgroups(tcp)
1224struct tcb *tcp;
1225{
1226 int i, len;
1227 GETGROUPS_T *gidset;
1228
1229 if (entering(tcp)) {
1230 len = tcp->u_arg[0];
1231 tprintf("%u, ", len);
1232 if (len <= 0) {
1233 tprintf("[]");
1234 return 0;
1235 }
1236 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1237 if (gidset == NULL) {
1238 fprintf(stderr, "sys_setgroups: out of memory\n");
1239 return -1;
1240 }
1241 if (!verbose(tcp))
1242 tprintf("%#lx", tcp->u_arg[1]);
1243 else if (umoven(tcp, tcp->u_arg[1],
1244 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1245 tprintf("[?]");
1246 else {
1247 tprintf("[");
1248 for (i = 0; i < len; i++)
1249 tprintf("%s%lu", i ? ", " : "",
1250 (unsigned long) gidset[i]);
1251 tprintf("]");
1252 }
1253 free((char *) gidset);
1254 }
1255 return 0;
1256}
1257
1258int
1259sys_getgroups(tcp)
1260struct tcb *tcp;
1261{
1262 int i, len;
1263 GETGROUPS_T *gidset;
1264
1265 if (entering(tcp)) {
1266 len = tcp->u_arg[0];
1267 tprintf("%u, ", len);
1268 } else {
1269 len = tcp->u_rval;
1270 if (len <= 0) {
1271 tprintf("[]");
1272 return 0;
1273 }
1274 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1275 if (gidset == NULL) {
1276 fprintf(stderr, "sys_getgroups: out of memory\n");
1277 return -1;
1278 }
1279 if (!tcp->u_arg[1])
1280 tprintf("NULL");
1281 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1282 tprintf("%#lx", tcp->u_arg[1]);
1283 else if (umoven(tcp, tcp->u_arg[1],
1284 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1285 tprintf("[?]");
1286 else {
1287 tprintf("[");
1288 for (i = 0; i < len; i++)
1289 tprintf("%s%lu", i ? ", " : "",
1290 (unsigned long) gidset[i]);
1291 tprintf("]");
1292 }
1293 free((char *)gidset);
1294 }
1295 return 0;
1296}
1297
Roland McGrath83bd47a2003-11-13 22:32:26 +00001298#ifdef LINUX
1299int
1300sys_setgroups32(tcp)
1301struct tcb *tcp;
1302{
1303 int i, len;
1304 GETGROUPS32_T *gidset;
1305
1306 if (entering(tcp)) {
1307 len = tcp->u_arg[0];
1308 tprintf("%u, ", len);
1309 if (len <= 0) {
1310 tprintf("[]");
1311 return 0;
1312 }
1313 gidset = (GETGROUPS32_T *) malloc(len * sizeof(GETGROUPS32_T));
1314 if (gidset == NULL) {
1315 fprintf(stderr, "sys_setgroups32: out of memory\n");
1316 return -1;
1317 }
1318 if (!verbose(tcp))
1319 tprintf("%#lx", tcp->u_arg[1]);
1320 else if (umoven(tcp, tcp->u_arg[1],
1321 len * sizeof(GETGROUPS32_T), (char *) gidset) < 0)
1322 tprintf("[?]");
1323 else {
1324 tprintf("[");
1325 for (i = 0; i < len; i++)
1326 tprintf("%s%lu", i ? ", " : "",
1327 (unsigned long) gidset[i]);
1328 tprintf("]");
1329 }
1330 free((char *) gidset);
1331 }
1332 return 0;
1333}
1334
1335int
1336sys_getgroups32(tcp)
1337struct tcb *tcp;
1338{
1339 int i, len;
1340 GETGROUPS32_T *gidset;
1341
1342 if (entering(tcp)) {
1343 len = tcp->u_arg[0];
1344 tprintf("%u, ", len);
1345 } else {
1346 len = tcp->u_rval;
1347 if (len <= 0) {
1348 tprintf("[]");
1349 return 0;
1350 }
1351 gidset = (GETGROUPS32_T *) malloc(len * sizeof(GETGROUPS32_T));
1352 if (gidset == NULL) {
1353 fprintf(stderr, "sys_getgroups32: out of memory\n");
1354 return -1;
1355 }
1356 if (!tcp->u_arg[1])
1357 tprintf("NULL");
1358 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1359 tprintf("%#lx", tcp->u_arg[1]);
1360 else if (umoven(tcp, tcp->u_arg[1],
1361 len * sizeof(GETGROUPS32_T), (char *) gidset) < 0)
1362 tprintf("[?]");
1363 else {
1364 tprintf("[");
1365 for (i = 0; i < len; i++)
1366 tprintf("%s%lu", i ? ", " : "",
1367 (unsigned long) gidset[i]);
1368 tprintf("]");
1369 }
1370 free((char *)gidset);
1371 }
1372 return 0;
1373}
1374#endif /* LINUX */
1375
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001376int
1377sys_setpgrp(tcp)
1378struct tcb *tcp;
1379{
1380 if (entering(tcp)) {
1381#ifndef SVR4
1382 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1383#endif /* !SVR4 */
1384 }
1385 return 0;
1386}
1387
1388int
1389sys_getpgrp(tcp)
1390struct tcb *tcp;
1391{
1392 if (entering(tcp)) {
1393#ifndef SVR4
1394 tprintf("%lu", tcp->u_arg[0]);
1395#endif /* !SVR4 */
1396 }
1397 return 0;
1398}
1399
1400int
1401sys_getsid(tcp)
1402struct tcb *tcp;
1403{
1404 if (entering(tcp)) {
1405 tprintf("%lu", tcp->u_arg[0]);
1406 }
1407 return 0;
1408}
1409
1410int
1411sys_setsid(tcp)
1412struct tcb *tcp;
1413{
1414 return 0;
1415}
1416
1417int
1418sys_getpgid(tcp)
1419struct tcb *tcp;
1420{
1421 if (entering(tcp)) {
1422 tprintf("%lu", tcp->u_arg[0]);
1423 }
1424 return 0;
1425}
1426
1427int
1428sys_setpgid(tcp)
1429struct tcb *tcp;
1430{
1431 if (entering(tcp)) {
1432 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1433 }
1434 return 0;
1435}
1436
John Hughesc61eb3d2002-05-17 11:37:50 +00001437#if UNIXWARE >= 2
1438
1439#include <sys/privilege.h>
1440
1441
1442static struct xlat procpriv_cmds [] = {
1443 { SETPRV, "SETPRV" },
1444 { CLRPRV, "CLRPRV" },
1445 { PUTPRV, "PUTPRV" },
1446 { GETPRV, "GETPRV" },
1447 { CNTPRV, "CNTPRV" },
1448 { 0, NULL },
1449};
1450
1451
1452static struct xlat procpriv_priv [] = {
1453 { P_OWNER, "P_OWNER" },
1454 { P_AUDIT, "P_AUDIT" },
1455 { P_COMPAT, "P_COMPAT" },
1456 { P_DACREAD, "P_DACREAD" },
1457 { P_DACWRITE, "P_DACWRITE" },
1458 { P_DEV, "P_DEV" },
1459 { P_FILESYS, "P_FILESYS" },
1460 { P_MACREAD, "P_MACREAD" },
1461 { P_MACWRITE, "P_MACWRITE" },
1462 { P_MOUNT, "P_MOUNT" },
1463 { P_MULTIDIR, "P_MULTIDIR" },
1464 { P_SETPLEVEL, "P_SETPLEVEL" },
1465 { P_SETSPRIV, "P_SETSPRIV" },
1466 { P_SETUID, "P_SETUID" },
1467 { P_SYSOPS, "P_SYSOPS" },
1468 { P_SETUPRIV, "P_SETUPRIV" },
1469 { P_DRIVER, "P_DRIVER" },
1470 { P_RTIME, "P_RTIME" },
1471 { P_MACUPGRADE, "P_MACUPGRADE" },
1472 { P_FSYSRANGE, "P_FSYSRANGE" },
1473 { P_SETFLEVEL, "P_SETFLEVEL" },
1474 { P_AUDITWR, "P_AUDITWR" },
1475 { P_TSHAR, "P_TSHAR" },
1476 { P_PLOCK, "P_PLOCK" },
1477 { P_CORE, "P_CORE" },
1478 { P_LOADMOD, "P_LOADMOD" },
1479 { P_BIND, "P_BIND" },
1480 { P_ALLPRIVS, "P_ALLPRIVS" },
1481 { 0, NULL },
1482};
1483
1484
1485static struct xlat procpriv_type [] = {
1486 { PS_FIX, "PS_FIX" },
1487 { PS_INH, "PS_INH" },
1488 { PS_MAX, "PS_MAX" },
1489 { PS_WKG, "PS_WKG" },
1490 { 0, NULL },
1491};
1492
1493
1494static void
1495printpriv(tcp, addr, len, opt)
1496struct tcb *tcp;
1497long addr;
1498int len;
1499struct xlat *opt;
1500{
1501 priv_t buf [128];
1502 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1503 int dots = len > max;
1504 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001505
John Hughesc61eb3d2002-05-17 11:37:50 +00001506 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001507
John Hughesc61eb3d2002-05-17 11:37:50 +00001508 if (len <= 0 ||
1509 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1510 {
1511 tprintf ("%#lx", addr);
1512 return;
1513 }
1514
1515 tprintf ("[");
1516
1517 for (i = 0; i < len; ++i) {
1518 char *t, *p;
1519
1520 if (i) tprintf (", ");
1521
1522 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1523 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1524 {
1525 tprintf ("%s|%s", t, p);
1526 }
1527 else {
1528 tprintf ("%#lx", buf [i]);
1529 }
1530 }
1531
1532 if (dots) tprintf (" ...");
1533
1534 tprintf ("]");
1535}
1536
1537
1538int
1539sys_procpriv(tcp)
1540struct tcb *tcp;
1541{
1542 if (entering(tcp)) {
1543 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1544 switch (tcp->u_arg[0]) {
1545 case CNTPRV:
1546 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1547 break;
1548
1549 case GETPRV:
1550 break;
1551
1552 default:
1553 tprintf (", ");
1554 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1555 tprintf (", %ld", tcp->u_arg[2]);
1556 }
1557 }
1558 else if (tcp->u_arg[0] == GETPRV) {
1559 if (syserror (tcp)) {
1560 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1561 }
1562 else {
1563 tprintf (", ");
1564 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1565 tprintf (", %ld", tcp->u_arg[2]);
1566 }
1567 }
Roland McGrath5a223472002-12-15 23:58:26 +00001568
John Hughesc61eb3d2002-05-17 11:37:50 +00001569 return 0;
1570}
1571
1572#endif
1573
1574
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001575void
1576fake_execve(tcp, program, argv, envp)
1577struct tcb *tcp;
1578char *program;
1579char *argv[];
1580char *envp[];
1581{
1582 int i;
1583
1584#ifdef ARM
1585 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1586 return;
1587#else
1588 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1589 return;
1590#endif /* !ARM */
1591 printleader(tcp);
1592 tprintf("execve(");
1593 string_quote(program);
1594 tprintf(", [");
1595 for (i = 0; argv[i] != NULL; i++) {
1596 if (i != 0)
1597 tprintf(", ");
1598 string_quote(argv[i]);
1599 }
1600 for (i = 0; envp[i] != NULL; i++)
1601 ;
1602 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1603 tabto(acolumn);
1604 tprintf("= 0");
1605 printtrailer(tcp);
1606}
1607
1608static void
1609printargv(tcp, addr)
1610struct tcb *tcp;
1611long addr;
1612{
1613 char *cp;
1614 char *sep;
1615 int max = max_strlen / 2;
1616
1617 for (sep = ""; --max >= 0; sep = ", ") {
1618 if (!abbrev(tcp))
1619 max++;
1620 if (umove(tcp, addr, &cp) < 0) {
1621 tprintf("%#lx", addr);
1622 return;
1623 }
1624 if (cp == 0)
1625 break;
1626 tprintf(sep);
1627 printstr(tcp, (long) cp, -1);
1628 addr += sizeof(char *);
1629 }
1630 if (cp)
1631 tprintf(", ...");
1632}
1633
1634static void
1635printargc(fmt, tcp, addr)
1636char *fmt;
1637struct tcb *tcp;
1638long addr;
1639{
1640 int count;
1641 char *cp;
1642
1643 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1644 addr += sizeof(char *);
1645 }
1646 tprintf(fmt, count, count == 1 ? "" : "s");
1647}
1648
1649int
1650sys_execv(tcp)
1651struct tcb *tcp;
1652{
1653 if (entering(tcp)) {
1654 printpath(tcp, tcp->u_arg[0]);
1655 if (!verbose(tcp))
1656 tprintf(", %#lx", tcp->u_arg[1]);
1657#if 0
1658 else if (abbrev(tcp))
1659 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1660#endif
1661 else {
1662 tprintf(", [");
1663 printargv(tcp, tcp->u_arg[1]);
1664 tprintf("]");
1665 }
1666 }
1667 return 0;
1668}
1669
1670int
1671sys_execve(tcp)
1672struct tcb *tcp;
1673{
1674 if (entering(tcp)) {
1675 printpath(tcp, tcp->u_arg[0]);
1676 if (!verbose(tcp))
1677 tprintf(", %#lx", tcp->u_arg[1]);
1678#if 0
1679 else if (abbrev(tcp))
1680 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1681#endif
1682 else {
1683 tprintf(", [");
1684 printargv(tcp, tcp->u_arg[1]);
1685 tprintf("]");
1686 }
1687 if (!verbose(tcp))
1688 tprintf(", %#lx", tcp->u_arg[2]);
1689 else if (abbrev(tcp))
1690 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1691 else {
1692 tprintf(", [");
1693 printargv(tcp, tcp->u_arg[2]);
1694 tprintf("]");
1695 }
1696 }
Roland McGrathb4968be2003-01-20 09:04:33 +00001697#if defined LINUX && defined TCB_WAITEXECVE
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001698 tcp->flags |= TCB_WAITEXECVE;
Roland McGrathb4968be2003-01-20 09:04:33 +00001699#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001700 return 0;
1701}
1702
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001703#if UNIXWARE > 2
John Hughes4e36a812001-04-18 15:11:51 +00001704
1705int sys_rexecve(tcp)
1706struct tcb *tcp;
1707{
1708 if (entering (tcp)) {
1709 sys_execve (tcp);
1710 tprintf (", %ld", tcp->u_arg[3]);
1711 }
1712 return 0;
1713}
1714
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001715#endif
John Hughes4e36a812001-04-18 15:11:51 +00001716
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001717int
1718internal_exec(tcp)
1719struct tcb *tcp;
1720{
1721#ifdef SUNOS4
1722 if (exiting(tcp) && !syserror(tcp) && followfork)
1723 fixvfork(tcp);
1724#endif /* SUNOS4 */
1725 return 0;
1726}
1727
1728#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001729#ifndef __WNOTHREAD
1730#define __WNOTHREAD 0x20000000
1731#endif
1732#ifndef __WALL
1733#define __WALL 0x40000000
1734#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001735#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001736#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001737#endif
1738#endif /* LINUX */
1739
1740static struct xlat wait4_options[] = {
1741 { WNOHANG, "WNOHANG" },
1742#ifndef WSTOPPED
1743 { WUNTRACED, "WUNTRACED" },
1744#endif
1745#ifdef WEXITED
1746 { WEXITED, "WEXITED" },
1747#endif
1748#ifdef WTRAPPED
1749 { WTRAPPED, "WTRAPPED" },
1750#endif
1751#ifdef WSTOPPED
1752 { WSTOPPED, "WSTOPPED" },
1753#endif
1754#ifdef WCONTINUED
1755 { WCONTINUED, "WCONTINUED" },
1756#endif
1757#ifdef WNOWAIT
1758 { WNOWAIT, "WNOWAIT" },
1759#endif
1760#ifdef __WCLONE
1761 { __WCLONE, "__WCLONE" },
1762#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001763#ifdef __WALL
1764 { __WALL, "__WALL" },
1765#endif
1766#ifdef __WNOTHREAD
1767 { __WNOTHREAD, "__WNOTHREAD" },
1768#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001769 { 0, NULL },
1770};
1771
1772static int
1773printstatus(status)
1774int status;
1775{
1776 int exited = 0;
1777
1778 /*
1779 * Here is a tricky presentation problem. This solution
1780 * is still not entirely satisfactory but since there
1781 * are no wait status constructors it will have to do.
1782 */
1783 if (WIFSTOPPED(status))
1784 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001785 signame(WSTOPSIG(status)));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001786 else if WIFSIGNALED(status)
1787 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001788 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001789 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1790 else if WIFEXITED(status) {
1791 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1792 WEXITSTATUS(status));
1793 exited = 1;
1794 }
1795 else
1796 tprintf("[%#x]", status);
1797 return exited;
1798}
1799
1800static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001801printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001802struct tcb *tcp;
1803int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001804int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001805{
1806 int status;
1807 int exited = 0;
1808
1809 if (entering(tcp)) {
1810 tprintf("%ld, ", tcp->u_arg[0]);
1811 } else {
1812 /* status */
1813 if (!tcp->u_arg[1])
1814 tprintf("NULL");
1815 else if (syserror(tcp) || tcp->u_rval == 0)
1816 tprintf("%#lx", tcp->u_arg[1]);
1817 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1818 tprintf("[?]");
1819 else
1820 exited = printstatus(status);
1821 /* options */
1822 tprintf(", ");
1823 if (!printflags(wait4_options, tcp->u_arg[2]))
1824 tprintf("0");
1825 if (n == 4) {
1826 tprintf(", ");
1827 /* usage */
1828 if (!tcp->u_arg[3])
1829 tprintf("NULL");
1830#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001831 else if (tcp->u_rval > 0) {
1832#ifdef LINUX_64BIT
1833 if (bitness)
1834 printrusage32(tcp, tcp->u_arg[3]);
1835 else
1836#endif
1837 printrusage(tcp, tcp->u_arg[3]);
1838 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001839#endif /* LINUX */
1840#ifdef SUNOS4
1841 else if (tcp->u_rval > 0 && exited)
1842 printrusage(tcp, tcp->u_arg[3]);
1843#endif /* SUNOS4 */
1844 else
1845 tprintf("%#lx", tcp->u_arg[3]);
1846 }
1847 }
1848 return 0;
1849}
1850
1851int
1852internal_wait(tcp)
1853struct tcb *tcp;
1854{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001855 int got_kids;
1856
1857#ifdef TCB_CLONE_THREAD
1858 if (tcp->flags & TCB_CLONE_THREAD)
1859 /* The children we wait for are our parent's children. */
1860 got_kids = (tcp->parent->nchildren
1861 > tcp->parent->nclone_detached);
1862 else
1863 got_kids = (tcp->nchildren > tcp->nclone_detached);
1864#else
1865 got_kids = tcp->nchildren > 0;
1866#endif
1867
1868 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001869 /* There are children that this parent should block for.
1870 But ptrace made us the parent of the traced children
1871 and the real parent will get ECHILD from the wait call.
1872
1873 XXX If we attached with strace -f -p PID, then there
1874 may be untraced dead children the parent could be reaping
1875 now, but we make him block. */
1876
1877 /* ??? WTA: fix bug with hanging children */
1878
1879 if (!(tcp->u_arg[2] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00001880 /*
1881 * There are traced children. We'll make the parent
1882 * block to avoid a false ECHILD error due to our
1883 * ptrace having stolen the children. However,
1884 * we shouldn't block if there are zombies to reap.
1885 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1886 */
Roland McGrathfccfb942003-10-01 21:59:44 +00001887 struct tcb *child = NULL;
Roland McGrath09623452003-05-23 02:27:13 +00001888 if (tcp->nzombies > 0 &&
1889 (tcp->u_arg[0] == -1 ||
Roland McGrathfccfb942003-10-01 21:59:44 +00001890 (child = pid2tcb(tcp->u_arg[0])) == NULL))
Roland McGrath09623452003-05-23 02:27:13 +00001891 return 0;
Roland McGrathfccfb942003-10-01 21:59:44 +00001892 if (tcp->u_arg[0] > 0) {
1893 /*
1894 * If the parent waits for a specified child
1895 * PID, then it must get ECHILD right away
1896 * if that PID is not one of its children.
1897 * Make sure that the requested PID matches
1898 * one of the parent's children that we are
1899 * tracing, and don't suspend it otherwise.
1900 */
1901 if (child == NULL)
1902 child = pid2tcb(tcp->u_arg[0]);
1903 if (child == NULL || child->parent != (
1904#ifdef TCB_CLONE_THREAD
1905 (tcp->flags & TCB_CLONE_THREAD)
1906 ? tcp->parent :
1907#endif
1908 tcp))
1909 return 0;
1910 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001911 tcp->flags |= TCB_SUSPENDED;
1912 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001913#ifdef TCB_CLONE_THREAD
1914 if (tcp->flags & TCB_CLONE_THREAD)
1915 tcp->parent->nclone_waiting++;
1916#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001917 }
1918 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001919 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001920 if (tcp->u_arg[2] & WNOHANG) {
1921 /* We must force a fake result of 0 instead of
1922 the ECHILD error. */
1923 extern int force_result();
1924 return force_result(tcp, 0, 0);
1925 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00001926 }
Roland McGrath09623452003-05-23 02:27:13 +00001927 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
1928 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
1929 /*
1930 * We just reaped a child we don't know about,
1931 * presumably a zombie we already droptcb'd.
1932 */
1933 tcp->nzombies--;
1934 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001935 return 0;
1936}
1937
1938#ifdef SVR4
1939
1940int
1941sys_wait(tcp)
1942struct tcb *tcp;
1943{
1944 if (exiting(tcp)) {
1945 /* The library wrapper stuffs this into the user variable. */
1946 if (!syserror(tcp))
1947 printstatus(getrval2(tcp));
1948 }
1949 return 0;
1950}
1951
1952#endif /* SVR4 */
1953
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001954#ifdef FREEBSD
1955int
1956sys_wait(tcp)
1957struct tcb *tcp;
1958{
1959 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001960
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001961 if (exiting(tcp)) {
1962 if (!syserror(tcp)) {
1963 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1964 tprintf("%#lx", tcp->u_arg[0]);
1965 else
1966 printstatus(status);
1967 }
1968 }
1969 return 0;
1970}
1971#endif
1972
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001973int
1974sys_waitpid(tcp)
1975struct tcb *tcp;
1976{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001977 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001978}
1979
1980int
1981sys_wait4(tcp)
1982struct tcb *tcp;
1983{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001984 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001985}
1986
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001987#ifdef ALPHA
1988int
1989sys_osf_wait4(tcp)
1990struct tcb *tcp;
1991{
1992 return printwaitn(tcp, 4, 1);
1993}
1994#endif
1995
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001996#ifdef SVR4
1997
1998static struct xlat waitid_types[] = {
1999 { P_PID, "P_PID" },
2000 { P_PPID, "P_PPID" },
2001 { P_PGID, "P_PGID" },
2002 { P_SID, "P_SID" },
2003 { P_CID, "P_CID" },
2004 { P_UID, "P_UID" },
2005 { P_GID, "P_GID" },
2006 { P_ALL, "P_ALL" },
2007#ifdef P_LWPID
2008 { P_LWPID, "P_LWPID" },
2009#endif
2010 { 0, NULL },
2011};
2012
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002013int
2014sys_waitid(tcp)
2015struct tcb *tcp;
2016{
2017 siginfo_t si;
2018 int exited;
2019
2020 if (entering(tcp)) {
2021 printxval(waitid_types, tcp->u_arg[0], "P_???");
2022 tprintf(", %ld, ", tcp->u_arg[1]);
2023 if (tcp->nchildren > 0) {
2024 /* There are traced children */
2025 tcp->flags |= TCB_SUSPENDED;
2026 tcp->waitpid = tcp->u_arg[0];
2027 }
2028 }
2029 else {
2030 /* siginfo */
2031 exited = 0;
2032 if (!tcp->u_arg[2])
2033 tprintf("NULL");
2034 else if (syserror(tcp))
2035 tprintf("%#lx", tcp->u_arg[2]);
2036 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2037 tprintf("{???}");
2038 else
John Hughes58265892001-10-18 15:13:53 +00002039 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002040 /* options */
2041 tprintf(", ");
2042 if (!printflags(wait4_options, tcp->u_arg[3]))
2043 tprintf("0");
2044 }
2045 return 0;
2046}
2047
2048#endif /* SVR4 */
2049
2050int
2051sys_alarm(tcp)
2052struct tcb *tcp;
2053{
2054 if (entering(tcp))
2055 tprintf("%lu", tcp->u_arg[0]);
2056 return 0;
2057}
2058
2059int
2060sys_uname(tcp)
2061struct tcb *tcp;
2062{
2063 struct utsname uname;
2064
2065 if (exiting(tcp)) {
2066 if (syserror(tcp) || !verbose(tcp))
2067 tprintf("%#lx", tcp->u_arg[0]);
2068 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2069 tprintf("{...}");
2070 else if (!abbrev(tcp)) {
2071
2072 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2073 uname.sysname, uname.nodename);
2074 tprintf("release=\"%s\", version=\"%s\", ",
2075 uname.release, uname.version);
2076 tprintf("machine=\"%s\"", uname.machine);
2077#ifdef LINUX
2078#ifndef __GLIBC__
2079 tprintf(", domainname=\"%s\"", uname.domainname);
2080#endif /* __GLIBC__ */
2081#endif /* LINUX */
2082 tprintf("}");
2083 }
2084 else
2085 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2086 uname.sysname, uname.nodename);
2087 }
2088 return 0;
2089}
2090
2091#ifndef SVR4
2092
2093static struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002094#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002095 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2096 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2097 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2098 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2099 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2100 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2101 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2102 { PTRACE_CONT, "PTRACE_CONT" },
2103 { PTRACE_KILL, "PTRACE_KILL" },
2104 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2105 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2106 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002107#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002108 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002109#endif
2110#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002111 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002112#endif
2113#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002114 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002115#endif
2116#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002117 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002118#endif
2119#ifdef PTRACE_GETFPXREGS
2120 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2121#endif
2122#ifdef PTRACE_SETFPXREGS
2123 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2124#endif
2125#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002126 { PTRACE_READDATA, "PTRACE_READDATA" },
2127 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2128 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2129 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2130 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2131 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2132#ifdef SPARC
2133 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2134 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2135#else /* !SPARC */
2136 { PTRACE_22, "PTRACE_PTRACE_22" },
2137 { PTRACE_23, "PTRACE_PTRACE_23" },
2138#endif /* !SPARC */
2139#endif /* SUNOS4 */
2140 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2141#ifdef SUNOS4
2142 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2143#ifdef I386
2144 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2145 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2146 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2147#else /* !I386 */
2148 { PTRACE_26, "PTRACE_26" },
2149 { PTRACE_27, "PTRACE_27" },
2150 { PTRACE_28, "PTRACE_28" },
2151#endif /* !I386 */
2152 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2153#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002154#else /* FREEBSD */
2155 { PT_TRACE_ME, "PT_TRACE_ME" },
2156 { PT_READ_I, "PT_READ_I" },
2157 { PT_READ_D, "PT_READ_D" },
2158 { PT_WRITE_I, "PT_WRITE_I" },
2159 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002160#ifdef PT_READ_U
2161 { PT_READ_U, "PT_READ_U" },
2162#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002163 { PT_CONTINUE, "PT_CONTINUE" },
2164 { PT_KILL, "PT_KILL" },
2165 { PT_STEP, "PT_STEP" },
2166 { PT_ATTACH, "PT_ATTACH" },
2167 { PT_DETACH, "PT_DETACH" },
2168 { PT_GETREGS, "PT_GETREGS" },
2169 { PT_SETREGS, "PT_SETREGS" },
2170 { PT_GETFPREGS, "PT_GETFPREGS" },
2171 { PT_SETFPREGS, "PT_SETFPREGS" },
2172 { PT_GETDBREGS, "PT_GETDBREGS" },
2173 { PT_SETDBREGS, "PT_SETDBREGS" },
2174#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002175 { 0, NULL },
2176};
2177
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002178#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002179#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2180static
2181#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2182struct xlat struct_user_offsets[] = {
2183#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002184#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002185 { PT_PSWMASK, "psw_mask" },
2186 { PT_PSWADDR, "psw_addr" },
2187 { PT_GPR0, "gpr0" },
2188 { PT_GPR1, "gpr1" },
2189 { PT_GPR2, "gpr2" },
2190 { PT_GPR3, "gpr3" },
2191 { PT_GPR4, "gpr4" },
2192 { PT_GPR5, "gpr5" },
2193 { PT_GPR6, "gpr6" },
2194 { PT_GPR7, "gpr7" },
2195 { PT_GPR8, "gpr8" },
2196 { PT_GPR9, "gpr9" },
2197 { PT_GPR10, "gpr10" },
2198 { PT_GPR11, "gpr11" },
2199 { PT_GPR12, "gpr12" },
2200 { PT_GPR13, "gpr13" },
2201 { PT_GPR14, "gpr14" },
2202 { PT_GPR15, "gpr15" },
2203 { PT_ACR0, "acr0" },
2204 { PT_ACR1, "acr1" },
2205 { PT_ACR2, "acr2" },
2206 { PT_ACR3, "acr3" },
2207 { PT_ACR4, "acr4" },
2208 { PT_ACR5, "acr5" },
2209 { PT_ACR6, "acr6" },
2210 { PT_ACR7, "acr7" },
2211 { PT_ACR8, "acr8" },
2212 { PT_ACR9, "acr9" },
2213 { PT_ACR10, "acr10" },
2214 { PT_ACR11, "acr11" },
2215 { PT_ACR12, "acr12" },
2216 { PT_ACR13, "acr13" },
2217 { PT_ACR14, "acr14" },
2218 { PT_ACR15, "acr15" },
2219 { PT_ORIGGPR2, "orig_gpr2" },
2220 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002221#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002222 { PT_FPR0_HI, "fpr0.hi" },
2223 { PT_FPR0_LO, "fpr0.lo" },
2224 { PT_FPR1_HI, "fpr1.hi" },
2225 { PT_FPR1_LO, "fpr1.lo" },
2226 { PT_FPR2_HI, "fpr2.hi" },
2227 { PT_FPR2_LO, "fpr2.lo" },
2228 { PT_FPR3_HI, "fpr3.hi" },
2229 { PT_FPR3_LO, "fpr3.lo" },
2230 { PT_FPR4_HI, "fpr4.hi" },
2231 { PT_FPR4_LO, "fpr4.lo" },
2232 { PT_FPR5_HI, "fpr5.hi" },
2233 { PT_FPR5_LO, "fpr5.lo" },
2234 { PT_FPR6_HI, "fpr6.hi" },
2235 { PT_FPR6_LO, "fpr6.lo" },
2236 { PT_FPR7_HI, "fpr7.hi" },
2237 { PT_FPR7_LO, "fpr7.lo" },
2238 { PT_FPR8_HI, "fpr8.hi" },
2239 { PT_FPR8_LO, "fpr8.lo" },
2240 { PT_FPR9_HI, "fpr9.hi" },
2241 { PT_FPR9_LO, "fpr9.lo" },
2242 { PT_FPR10_HI, "fpr10.hi" },
2243 { PT_FPR10_LO, "fpr10.lo" },
2244 { PT_FPR11_HI, "fpr11.hi" },
2245 { PT_FPR11_LO, "fpr11.lo" },
2246 { PT_FPR12_HI, "fpr12.hi" },
2247 { PT_FPR12_LO, "fpr12.lo" },
2248 { PT_FPR13_HI, "fpr13.hi" },
2249 { PT_FPR13_LO, "fpr13.lo" },
2250 { PT_FPR14_HI, "fpr14.hi" },
2251 { PT_FPR14_LO, "fpr14.lo" },
2252 { PT_FPR15_HI, "fpr15.hi" },
2253 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002254#endif
2255#if defined(S390X)
2256 { PT_FPR0, "fpr0" },
2257 { PT_FPR1, "fpr1" },
2258 { PT_FPR2, "fpr2" },
2259 { PT_FPR3, "fpr3" },
2260 { PT_FPR4, "fpr4" },
2261 { PT_FPR5, "fpr5" },
2262 { PT_FPR6, "fpr6" },
2263 { PT_FPR7, "fpr7" },
2264 { PT_FPR8, "fpr8" },
2265 { PT_FPR9, "fpr9" },
2266 { PT_FPR10, "fpr10" },
2267 { PT_FPR11, "fpr11" },
2268 { PT_FPR12, "fpr12" },
2269 { PT_FPR13, "fpr13" },
2270 { PT_FPR14, "fpr14" },
2271 { PT_FPR15, "fpr15" },
2272#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002273 { PT_CR_9, "cr9" },
2274 { PT_CR_10, "cr10" },
2275 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002276 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002277#endif
2278#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002279 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002280#elif defined(HPPA)
2281 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002282#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002283#ifndef PT_ORIG_R3
2284#define PT_ORIG_R3 34
2285#endif
Roland McGratheb285352003-01-14 09:59:00 +00002286#define REGSIZE (sizeof(unsigned long))
2287 { REGSIZE*PT_R0, "r0" },
2288 { REGSIZE*PT_R1, "r1" },
2289 { REGSIZE*PT_R2, "r2" },
2290 { REGSIZE*PT_R3, "r3" },
2291 { REGSIZE*PT_R4, "r4" },
2292 { REGSIZE*PT_R5, "r5" },
2293 { REGSIZE*PT_R6, "r6" },
2294 { REGSIZE*PT_R7, "r7" },
2295 { REGSIZE*PT_R8, "r8" },
2296 { REGSIZE*PT_R9, "r9" },
2297 { REGSIZE*PT_R10, "r10" },
2298 { REGSIZE*PT_R11, "r11" },
2299 { REGSIZE*PT_R12, "r12" },
2300 { REGSIZE*PT_R13, "r13" },
2301 { REGSIZE*PT_R14, "r14" },
2302 { REGSIZE*PT_R15, "r15" },
2303 { REGSIZE*PT_R16, "r16" },
2304 { REGSIZE*PT_R17, "r17" },
2305 { REGSIZE*PT_R18, "r18" },
2306 { REGSIZE*PT_R19, "r19" },
2307 { REGSIZE*PT_R20, "r20" },
2308 { REGSIZE*PT_R21, "r21" },
2309 { REGSIZE*PT_R22, "r22" },
2310 { REGSIZE*PT_R23, "r23" },
2311 { REGSIZE*PT_R24, "r24" },
2312 { REGSIZE*PT_R25, "r25" },
2313 { REGSIZE*PT_R26, "r26" },
2314 { REGSIZE*PT_R27, "r27" },
2315 { REGSIZE*PT_R28, "r28" },
2316 { REGSIZE*PT_R29, "r29" },
2317 { REGSIZE*PT_R30, "r30" },
2318 { REGSIZE*PT_R31, "r31" },
2319 { REGSIZE*PT_NIP, "NIP" },
2320 { REGSIZE*PT_MSR, "MSR" },
2321 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2322 { REGSIZE*PT_CTR, "CTR" },
2323 { REGSIZE*PT_LNK, "LNK" },
2324 { REGSIZE*PT_XER, "XER" },
2325 { REGSIZE*PT_CCR, "CCR" },
2326 { REGSIZE*PT_FPR0, "FPR0" },
2327#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002328#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002329#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002330 { 0, "r0" },
2331 { 1, "r1" },
2332 { 2, "r2" },
2333 { 3, "r3" },
2334 { 4, "r4" },
2335 { 5, "r5" },
2336 { 6, "r6" },
2337 { 7, "r7" },
2338 { 8, "r8" },
2339 { 9, "r9" },
2340 { 10, "r10" },
2341 { 11, "r11" },
2342 { 12, "r12" },
2343 { 13, "r13" },
2344 { 14, "r14" },
2345 { 15, "r15" },
2346 { 16, "r16" },
2347 { 17, "r17" },
2348 { 18, "r18" },
2349 { 19, "r19" },
2350 { 20, "r20" },
2351 { 21, "r21" },
2352 { 22, "r22" },
2353 { 23, "r23" },
2354 { 24, "r24" },
2355 { 25, "r25" },
2356 { 26, "r26" },
2357 { 27, "r27" },
2358 { 28, "r28" },
2359 { 29, "gp" },
2360 { 30, "fp" },
2361 { 31, "zero" },
2362 { 32, "fp0" },
2363 { 33, "fp" },
2364 { 34, "fp2" },
2365 { 35, "fp3" },
2366 { 36, "fp4" },
2367 { 37, "fp5" },
2368 { 38, "fp6" },
2369 { 39, "fp7" },
2370 { 40, "fp8" },
2371 { 41, "fp9" },
2372 { 42, "fp10" },
2373 { 43, "fp11" },
2374 { 44, "fp12" },
2375 { 45, "fp13" },
2376 { 46, "fp14" },
2377 { 47, "fp15" },
2378 { 48, "fp16" },
2379 { 49, "fp17" },
2380 { 50, "fp18" },
2381 { 51, "fp19" },
2382 { 52, "fp20" },
2383 { 53, "fp21" },
2384 { 54, "fp22" },
2385 { 55, "fp23" },
2386 { 56, "fp24" },
2387 { 57, "fp25" },
2388 { 58, "fp26" },
2389 { 59, "fp27" },
2390 { 60, "fp28" },
2391 { 61, "fp29" },
2392 { 62, "fp30" },
2393 { 63, "fp31" },
2394 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002395#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002396#ifdef IA64
2397 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2398 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2399 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2400 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2401 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2402 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2403 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2404 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2405 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2406 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2407 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2408 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2409 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2410 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2411 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2412 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2413 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2414 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2415 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2416 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2417 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2418 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2419 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2420 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2421 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2422 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2423 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2424 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2425 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2426 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2427 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2428 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2429 /* switch stack: */
2430 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2431 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2432 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2433 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2434 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2435 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2436 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2437 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2438 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2439 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002440 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2441 { PT_B4, "b4" }, { PT_B5, "b5" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002442 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002443 /* pt_regs */
Roland McGrathca4e10c2004-01-13 10:13:20 +00002444 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2445 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002446 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2447 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2448 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2449 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2450 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2451 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2452 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2453 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2454 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2455 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2456 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2457 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2458 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2459 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2460 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002461 { PT_AR_CSD, "ar.csd" }, { PT_AR_SSD, "ar.ssd" },
2462 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002463#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002464#ifdef I386
2465 { 4*EBX, "4*EBX" },
2466 { 4*ECX, "4*ECX" },
2467 { 4*EDX, "4*EDX" },
2468 { 4*ESI, "4*ESI" },
2469 { 4*EDI, "4*EDI" },
2470 { 4*EBP, "4*EBP" },
2471 { 4*EAX, "4*EAX" },
2472 { 4*DS, "4*DS" },
2473 { 4*ES, "4*ES" },
2474 { 4*FS, "4*FS" },
2475 { 4*GS, "4*GS" },
2476 { 4*ORIG_EAX, "4*ORIG_EAX" },
2477 { 4*EIP, "4*EIP" },
2478 { 4*CS, "4*CS" },
2479 { 4*EFL, "4*EFL" },
2480 { 4*UESP, "4*UESP" },
2481 { 4*SS, "4*SS" },
2482#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002483#ifdef X86_64
2484 { 8*RDI, "8*RDI" },
2485 { 8*RSI, "8*RSI" },
2486 { 8*RDX, "8*RDX" },
2487 { 8*R10, "8*R10" },
2488 { 8*R8, "8*R8" },
2489 { 8*R9, "8*R9" },
2490 { 8*RBX, "8*RBX" },
2491 { 8*RCX, "8*RCX" },
2492 { 8*RBP, "8*RBP" },
2493 { 8*RAX, "8*RAX" },
2494#if 0
2495 { 8*DS, "8*DS" },
2496 { 8*ES, "8*ES" },
2497 { 8*FS, "8*FS" },
2498 { 8*GS, "8*GS" },
2499#endif
2500 { 8*ORIG_RAX, "8*ORIG_EAX" },
2501 { 8*RIP, "8*RIP" },
2502 { 8*CS, "8*CS" },
2503 { 8*EFLAGS, "8*EFL" },
2504 { 8*RSP, "8*RSP" },
2505 { 8*SS, "8*SS" },
2506 { 8*R11, "8*R11" },
2507 { 8*R12, "8*R12" },
2508 { 8*R13, "8*R13" },
2509 { 8*R14, "8*R14" },
2510 { 8*R15, "8*R15" },
2511#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002512#ifdef M68K
2513 { 4*PT_D1, "4*PT_D1" },
2514 { 4*PT_D2, "4*PT_D2" },
2515 { 4*PT_D3, "4*PT_D3" },
2516 { 4*PT_D4, "4*PT_D4" },
2517 { 4*PT_D5, "4*PT_D5" },
2518 { 4*PT_D6, "4*PT_D6" },
2519 { 4*PT_D7, "4*PT_D7" },
2520 { 4*PT_A0, "4*PT_A0" },
2521 { 4*PT_A1, "4*PT_A1" },
2522 { 4*PT_A2, "4*PT_A2" },
2523 { 4*PT_A3, "4*PT_A3" },
2524 { 4*PT_A4, "4*PT_A4" },
2525 { 4*PT_A5, "4*PT_A5" },
2526 { 4*PT_A6, "4*PT_A6" },
2527 { 4*PT_D0, "4*PT_D0" },
2528 { 4*PT_USP, "4*PT_USP" },
2529 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2530 { 4*PT_SR, "4*PT_SR" },
2531 { 4*PT_PC, "4*PT_PC" },
2532#endif /* M68K */
2533#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002534#ifdef SH
2535 { 4*REG_REG0, "4*REG_REG0" },
2536 { 4*(REG_REG0+1), "4*REG_REG1" },
2537 { 4*(REG_REG0+2), "4*REG_REG2" },
2538 { 4*(REG_REG0+3), "4*REG_REG3" },
2539 { 4*(REG_REG0+4), "4*REG_REG4" },
2540 { 4*(REG_REG0+5), "4*REG_REG5" },
2541 { 4*(REG_REG0+6), "4*REG_REG6" },
2542 { 4*(REG_REG0+7), "4*REG_REG7" },
2543 { 4*(REG_REG0+8), "4*REG_REG8" },
2544 { 4*(REG_REG0+9), "4*REG_REG9" },
2545 { 4*(REG_REG0+10), "4*REG_REG10" },
2546 { 4*(REG_REG0+11), "4*REG_REG11" },
2547 { 4*(REG_REG0+12), "4*REG_REG12" },
2548 { 4*(REG_REG0+13), "4*REG_REG13" },
2549 { 4*(REG_REG0+14), "4*REG_REG14" },
2550 { 4*REG_REG15, "4*REG_REG15" },
2551 { 4*REG_PC, "4*REG_PC" },
2552 { 4*REG_PR, "4*REG_PR" },
2553 { 4*REG_SR, "4*REG_SR" },
2554 { 4*REG_GBR, "4*REG_GBR" },
2555 { 4*REG_MACH, "4*REG_MACH" },
2556 { 4*REG_MACL, "4*REG_MACL" },
2557 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2558 { 4*REG_FPUL, "4*REG_FPUL" },
2559 { 4*REG_FPREG0, "4*REG_FPREG0" },
2560 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2561 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2562 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2563 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2564 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2565 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2566 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2567 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2568 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2569 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2570 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2571 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2572 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2573 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2574 { 4*REG_FPREG15, "4*REG_FPREG15" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002575#ifdef REG_XDREG0
Wichert Akkermanccef6372002-05-01 16:39:22 +00002576 { 4*REG_XDREG0, "4*REG_XDREG0" },
2577 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2578 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2579 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2580 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2581 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2582 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2583 { 4*REG_XDREG14, "4*REG_XDREG14" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002584#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002585 { 4*REG_FPSCR, "4*REG_FPSCR" },
2586#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002587#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002588 { 0, "PC(L)" },
2589 { 4, "PC(U)" },
2590 { 8, "SR(L)" },
2591 { 12, "SR(U)" },
2592 { 16, "syscall no.(L)" },
2593 { 20, "syscall_no.(U)" },
2594 { 24, "R0(L)" },
2595 { 28, "R0(U)" },
2596 { 32, "R1(L)" },
2597 { 36, "R1(U)" },
2598 { 40, "R2(L)" },
2599 { 44, "R2(U)" },
2600 { 48, "R3(L)" },
2601 { 52, "R3(U)" },
2602 { 56, "R4(L)" },
2603 { 60, "R4(U)" },
2604 { 64, "R5(L)" },
2605 { 68, "R5(U)" },
2606 { 72, "R6(L)" },
2607 { 76, "R6(U)" },
2608 { 80, "R7(L)" },
2609 { 84, "R7(U)" },
2610 { 88, "R8(L)" },
2611 { 92, "R8(U)" },
2612 { 96, "R9(L)" },
2613 { 100, "R9(U)" },
2614 { 104, "R10(L)" },
2615 { 108, "R10(U)" },
2616 { 112, "R11(L)" },
2617 { 116, "R11(U)" },
2618 { 120, "R12(L)" },
2619 { 124, "R12(U)" },
2620 { 128, "R13(L)" },
2621 { 132, "R13(U)" },
2622 { 136, "R14(L)" },
2623 { 140, "R14(U)" },
2624 { 144, "R15(L)" },
2625 { 148, "R15(U)" },
2626 { 152, "R16(L)" },
2627 { 156, "R16(U)" },
2628 { 160, "R17(L)" },
2629 { 164, "R17(U)" },
2630 { 168, "R18(L)" },
2631 { 172, "R18(U)" },
2632 { 176, "R19(L)" },
2633 { 180, "R19(U)" },
2634 { 184, "R20(L)" },
2635 { 188, "R20(U)" },
2636 { 192, "R21(L)" },
2637 { 196, "R21(U)" },
2638 { 200, "R22(L)" },
2639 { 204, "R22(U)" },
2640 { 208, "R23(L)" },
2641 { 212, "R23(U)" },
2642 { 216, "R24(L)" },
2643 { 220, "R24(U)" },
2644 { 224, "R25(L)" },
2645 { 228, "R25(U)" },
2646 { 232, "R26(L)" },
2647 { 236, "R26(U)" },
2648 { 240, "R27(L)" },
2649 { 244, "R27(U)" },
2650 { 248, "R28(L)" },
2651 { 252, "R28(U)" },
2652 { 256, "R29(L)" },
2653 { 260, "R29(U)" },
2654 { 264, "R30(L)" },
2655 { 268, "R30(U)" },
2656 { 272, "R31(L)" },
2657 { 276, "R31(U)" },
2658 { 280, "R32(L)" },
2659 { 284, "R32(U)" },
2660 { 288, "R33(L)" },
2661 { 292, "R33(U)" },
2662 { 296, "R34(L)" },
2663 { 300, "R34(U)" },
2664 { 304, "R35(L)" },
2665 { 308, "R35(U)" },
2666 { 312, "R36(L)" },
2667 { 316, "R36(U)" },
2668 { 320, "R37(L)" },
2669 { 324, "R37(U)" },
2670 { 328, "R38(L)" },
2671 { 332, "R38(U)" },
2672 { 336, "R39(L)" },
2673 { 340, "R39(U)" },
2674 { 344, "R40(L)" },
2675 { 348, "R40(U)" },
2676 { 352, "R41(L)" },
2677 { 356, "R41(U)" },
2678 { 360, "R42(L)" },
2679 { 364, "R42(U)" },
2680 { 368, "R43(L)" },
2681 { 372, "R43(U)" },
2682 { 376, "R44(L)" },
2683 { 380, "R44(U)" },
2684 { 384, "R45(L)" },
2685 { 388, "R45(U)" },
2686 { 392, "R46(L)" },
2687 { 396, "R46(U)" },
2688 { 400, "R47(L)" },
2689 { 404, "R47(U)" },
2690 { 408, "R48(L)" },
2691 { 412, "R48(U)" },
2692 { 416, "R49(L)" },
2693 { 420, "R49(U)" },
2694 { 424, "R50(L)" },
2695 { 428, "R50(U)" },
2696 { 432, "R51(L)" },
2697 { 436, "R51(U)" },
2698 { 440, "R52(L)" },
2699 { 444, "R52(U)" },
2700 { 448, "R53(L)" },
2701 { 452, "R53(U)" },
2702 { 456, "R54(L)" },
2703 { 460, "R54(U)" },
2704 { 464, "R55(L)" },
2705 { 468, "R55(U)" },
2706 { 472, "R56(L)" },
2707 { 476, "R56(U)" },
2708 { 480, "R57(L)" },
2709 { 484, "R57(U)" },
2710 { 488, "R58(L)" },
2711 { 492, "R58(U)" },
2712 { 496, "R59(L)" },
2713 { 500, "R59(U)" },
2714 { 504, "R60(L)" },
2715 { 508, "R60(U)" },
2716 { 512, "R61(L)" },
2717 { 516, "R61(U)" },
2718 { 520, "R62(L)" },
2719 { 524, "R62(U)" },
2720 { 528, "TR0(L)" },
2721 { 532, "TR0(U)" },
2722 { 536, "TR1(L)" },
2723 { 540, "TR1(U)" },
2724 { 544, "TR2(L)" },
2725 { 548, "TR2(U)" },
2726 { 552, "TR3(L)" },
2727 { 556, "TR3(U)" },
2728 { 560, "TR4(L)" },
2729 { 564, "TR4(U)" },
2730 { 568, "TR5(L)" },
2731 { 572, "TR5(U)" },
2732 { 576, "TR6(L)" },
2733 { 580, "TR6(U)" },
2734 { 584, "TR7(L)" },
2735 { 588, "TR7(U)" },
2736 /* This entry is in case pt_regs contains dregs (depends on
2737 the kernel build options). */
2738 { uoff(regs), "offsetof(struct user, regs)" },
2739 { uoff(fpu), "offsetof(struct user, fpu)" },
2740#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002741#ifdef ARM
2742 { uoff(regs.ARM_r0), "r0" },
2743 { uoff(regs.ARM_r1), "r1" },
2744 { uoff(regs.ARM_r2), "r2" },
2745 { uoff(regs.ARM_r3), "r3" },
2746 { uoff(regs.ARM_r4), "r4" },
2747 { uoff(regs.ARM_r5), "r5" },
2748 { uoff(regs.ARM_r6), "r6" },
2749 { uoff(regs.ARM_r7), "r7" },
2750 { uoff(regs.ARM_r8), "r8" },
2751 { uoff(regs.ARM_r9), "r9" },
2752 { uoff(regs.ARM_r10), "r10" },
2753 { uoff(regs.ARM_fp), "fp" },
2754 { uoff(regs.ARM_ip), "ip" },
2755 { uoff(regs.ARM_sp), "sp" },
2756 { uoff(regs.ARM_lr), "lr" },
2757 { uoff(regs.ARM_pc), "pc" },
2758 { uoff(regs.ARM_cpsr), "cpsr" },
2759#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002760
Michal Ludvig10a88d02002-10-07 14:31:00 +00002761#if !defined(S390) && !defined(S390X) && !defined(MIPS)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002762 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002763#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002764#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002765 { uoff(i387), "offsetof(struct user, i387)" },
2766#else /* !I386 */
2767#ifdef M68K
2768 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2769#endif /* M68K */
2770#endif /* !I386 */
2771 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2772 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2773 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2774 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrathf5a47772003-06-26 22:40:42 +00002775#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002776 { uoff(start_data), "offsetof(struct user, start_data)" },
2777#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002778 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2779 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrathf5a47772003-06-26 22:40:42 +00002780#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002781 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002782#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002783 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002784#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002785 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2786#endif
2787 { uoff(magic), "offsetof(struct user, magic)" },
2788 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002789#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002790 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2791#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002792#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002793#endif /* !ALPHA */
2794#endif /* !POWERPC/!SPARC */
2795#endif /* LINUX */
2796#ifdef SUNOS4
2797 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2798 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2799 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2800 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2801 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2802 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2803 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2804 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2805 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2806 { uoff(u_error), "offsetof(struct user, u_error)" },
2807 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2808 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2809 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2810 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2811 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2812 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2813 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2814 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2815 { uoff(u_code), "offsetof(struct user, u_code)" },
2816 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2817 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2818 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2819 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2820 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2821 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2822 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2823 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2824 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2825 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2826 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2827 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2828 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2829 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2830 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2831 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2832 { uoff(u_start), "offsetof(struct user, u_start)" },
2833 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2834 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2835 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2836 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2837 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2838 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2839 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2840 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2841 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2842#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002843#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002844 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002845#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002846 { 0, NULL },
2847};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002848#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002849
2850int
2851sys_ptrace(tcp)
2852struct tcb *tcp;
2853{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002854 struct xlat *x;
2855 long addr;
2856
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002857 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002858 printxval(ptrace_cmds, tcp->u_arg[0],
2859#ifndef FREEBSD
2860 "PTRACE_???"
2861#else
2862 "PT_???"
2863#endif
2864 );
2865 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002866 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002867#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002868 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2869 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2870 for (x = struct_user_offsets; x->str; x++) {
2871 if (x->val >= addr)
2872 break;
2873 }
2874 if (!x->str)
2875 tprintf("%#lx, ", addr);
2876 else if (x->val > addr && x != struct_user_offsets) {
2877 x--;
2878 tprintf("%s + %ld, ", x->str, addr - x->val);
2879 }
2880 else
2881 tprintf("%s, ", x->str);
2882 }
2883 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002884#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002885 tprintf("%#lx, ", tcp->u_arg[2]);
2886#ifdef LINUX
2887 switch (tcp->u_arg[0]) {
2888 case PTRACE_PEEKDATA:
2889 case PTRACE_PEEKTEXT:
2890 case PTRACE_PEEKUSER:
2891 break;
2892 case PTRACE_CONT:
2893 case PTRACE_SINGLESTEP:
2894 case PTRACE_SYSCALL:
2895 case PTRACE_DETACH:
2896 printsignal(tcp->u_arg[3]);
2897 break;
2898 default:
2899 tprintf("%#lx", tcp->u_arg[3]);
2900 break;
2901 }
2902 } else {
2903 switch (tcp->u_arg[0]) {
2904 case PTRACE_PEEKDATA:
2905 case PTRACE_PEEKTEXT:
2906 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00002907 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002908 break;
2909 }
2910 }
2911#endif /* LINUX */
2912#ifdef SUNOS4
2913 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2914 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2915 tprintf("%lu, ", tcp->u_arg[3]);
2916 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2917 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2918 tcp->u_arg[0] != PTRACE_READTEXT) {
2919 tprintf("%#lx", tcp->u_arg[3]);
2920 }
2921 } else {
2922 if (tcp->u_arg[0] == PTRACE_READDATA ||
2923 tcp->u_arg[0] == PTRACE_READTEXT) {
2924 tprintf("%lu, ", tcp->u_arg[3]);
2925 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2926 }
2927 }
2928#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002929#ifdef FREEBSD
2930 tprintf("%lu", tcp->u_arg[3]);
2931 }
2932#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002933 return 0;
2934}
2935
2936#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002937
2938#ifdef LINUX
2939static struct xlat futexops[] = {
2940 { FUTEX_WAIT, "FUTEX_WAIT" },
2941 { FUTEX_WAKE, "FUTEX_WAKE" },
2942 { FUTEX_FD, "FUTEX_FD" },
Roland McGrath88812d62003-06-26 22:27:23 +00002943 { FUTEX_REQUEUE,"FUTEX_REQUEUE" },
Roland McGrath5a223472002-12-15 23:58:26 +00002944 { 0, NULL }
2945};
2946
2947int
2948sys_futex(tcp)
2949struct tcb *tcp;
2950{
2951 if (entering(tcp)) {
2952 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00002953 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00002954 tprintf(", %ld", tcp->u_arg[2]);
2955 if (tcp->u_arg[1] == FUTEX_WAIT) {
2956 tprintf(", ");
2957 printtv(tcp, tcp->u_arg[3]);
Roland McGrath88812d62003-06-26 22:27:23 +00002958 } else if (tcp->u_arg[1] == FUTEX_REQUEUE)
2959 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath5a223472002-12-15 23:58:26 +00002960 }
2961 return 0;
2962}
2963
2964static void
2965print_affinitylist(list, len)
2966unsigned long *list;
2967unsigned int len;
2968{
2969 int first = 1;
2970 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00002971 while (len >= sizeof (unsigned long)) {
Roland McGrath5a223472002-12-15 23:58:26 +00002972 tprintf("%s %lx", first ? "" : ",", *list++);
2973 first = 0;
2974 len -= sizeof (unsigned long);
2975 }
2976 tprintf(" }");
2977}
2978
2979int
2980sys_sched_setaffinity(tcp)
2981struct tcb *tcp;
2982{
2983 if (entering(tcp)) {
2984 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2985 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2986 }
2987 return 0;
2988}
2989
2990int
2991sys_sched_getaffinity(tcp)
2992struct tcb *tcp;
2993{
2994 if (entering(tcp)) {
2995 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2996 } else {
2997 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);
2998 }
2999 return 0;
3000}
3001#endif