blob: 8a36b6decd2565a7b78de4def9cfecb60be3a8e4 [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00005 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Linux for s390 port by D.J. Barrow
8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
Wichert Akkermanccef6372002-05-01 16:39:22 +00009 * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH
10 * port by Greg Banks <gbanks@pocketpenguins.com>
11
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +000012 *
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000013 * All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * $Id$
38 */
39
40#include "defs.h"
41
42#include <fcntl.h>
43#include <sys/stat.h>
44#include <sys/time.h>
45#include <sys/wait.h>
46#include <sys/resource.h>
47#include <sys/utsname.h>
48#include <sys/user.h>
49#include <sys/syscall.h>
50#include <signal.h>
51#ifdef SUNOS4
52#include <machine/reg.h>
53#endif /* SUNOS4 */
54
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +000055#ifdef FREEBSD
56#include <sys/ptrace.h>
57#endif
58
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000059#if HAVE_ASM_REG_H
60#ifdef SPARC
61# define fpq kernel_fpq
62# define fq kernel_fq
63# define fpu kernel_fpu
64#endif
65#include <asm/reg.h>
66#ifdef SPARC
67# undef fpq
68# undef fq
Roland McGrath5a223472002-12-15 23:58:26 +000069# undef fpu
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000070#endif
71#endif /* HAVE_ASM_REG_H */
72
Wichert Akkerman36915a11999-07-13 15:45:02 +000073#ifdef HAVE_SYS_REG_H
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000074# include <sys/reg.h>
Wichert Akkerman15dea971999-10-06 13:06:34 +000075#ifndef PTRACE_PEEKUSR
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000076# define PTRACE_PEEKUSR PTRACE_PEEKUSER
Wichert Akkerman15dea971999-10-06 13:06:34 +000077#endif
78#ifndef PTRACE_POKEUSR
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000079# define PTRACE_POKEUSR PTRACE_POKEUSER
80#endif
Wichert Akkerman15dea971999-10-06 13:06:34 +000081#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000082
Roland McGrath5bd7cf82003-01-24 04:31:18 +000083#ifdef HAVE_LINUX_PTRACE_H
84#undef PTRACE_SYSCALL
85#include <linux/ptrace.h>
86#endif
87
Roland McGrath5a223472002-12-15 23:58:26 +000088#ifdef HAVE_LINUX_FUTEX_H
89#include <linux/futex.h>
90#endif
91#if defined LINUX
92# ifndef FUTEX_WAIT
93# define FUTEX_WAIT 0
94# endif
95# ifndef FUTEX_WAKE
96# define FUTEX_WAKE 1
97# endif
98# ifndef FUTEX_FD
99# define FUTEX_FD 2
100# endif
101#endif
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000102
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000103#ifdef LINUX
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000104#include <asm/posix_types.h>
105#undef GETGROUPS_T
106#define GETGROUPS_T __kernel_gid_t
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000107#endif /* LINUX */
108
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000109#if defined(LINUX) && defined(IA64)
110# include <asm/ptrace_offsets.h>
111# include <asm/rse.h>
112#endif
113
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000114#ifdef HAVE_PRCTL
115#include <sys/prctl.h>
116#endif
117
118#ifndef WCOREDUMP
119#define WCOREDUMP(status) ((status) & 0200)
120#endif
121
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000122/* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000123#if defined(HAVE_PRCTL)
124static struct xlat prctl_options[] = {
125#ifdef PR_MAXPROCS
126 { PR_MAXPROCS, "PR_MAXPROCS" },
127#endif
128#ifdef PR_ISBLOCKED
129 { PR_ISBLOCKED, "PR_ISBLOCKED" },
130#endif
131#ifdef PR_SETSTACKSIZE
132 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
133#endif
134#ifdef PR_GETSTACKSIZE
135 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
136#endif
137#ifdef PR_MAXPPROCS
138 { PR_MAXPPROCS, "PR_MAXPPROCS" },
139#endif
140#ifdef PR_UNBLKONEXEC
141 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
142#endif
143#ifdef PR_ATOMICSIM
144 { PR_ATOMICSIM, "PR_ATOMICSIM" },
145#endif
146#ifdef PR_SETEXITSIG
147 { PR_SETEXITSIG, "PR_SETEXITSIG" },
148#endif
149#ifdef PR_RESIDENT
150 { PR_RESIDENT, "PR_RESIDENT" },
151#endif
152#ifdef PR_ATTACHADDR
153 { PR_ATTACHADDR, "PR_ATTACHADDR" },
154#endif
155#ifdef PR_DETACHADDR
156 { PR_DETACHADDR, "PR_DETACHADDR" },
157#endif
158#ifdef PR_TERMCHILD
159 { PR_TERMCHILD, "PR_TERMCHILD" },
160#endif
161#ifdef PR_GETSHMASK
162 { PR_GETSHMASK, "PR_GETSHMASK" },
163#endif
164#ifdef PR_GETNSHARE
165 { PR_GETNSHARE, "PR_GETNSHARE" },
166#endif
167#if defined(PR_SET_PDEATHSIG)
168 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
169#endif
Wichert Akkerman8829a551999-06-11 13:18:40 +0000170#ifdef PR_COREPID
171 { PR_COREPID, "PR_COREPID" },
172#endif
173#ifdef PR_ATTACHADDRPERM
174 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
175#endif
176#ifdef PR_PTHREADEXIT
177 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
178#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000179#ifdef PR_SET_PDEATHSIG
180 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
181#endif
182#ifdef PR_GET_PDEATHSIG
183 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
184#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000185#ifdef PR_GET_UNALIGN
186 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
187#endif
188#ifdef PR_SET_UNALIGN
189 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
190#endif
191#ifdef PR_GET_KEEPCAPS
192 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" },
193#endif
194#ifdef PR_SET_KEEPCAPS
195 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" },
196#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000197 { 0, NULL },
198};
199
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000200
201const char *
202unalignctl_string (unsigned int ctl)
203{
204 static char buf[16];
205
206 switch (ctl) {
207#ifdef PR_UNALIGN_NOPRINT
208 case PR_UNALIGN_NOPRINT:
209 return "NOPRINT";
210#endif
211#ifdef PR_UNALIGN_SIGBUS
212 case PR_UNALIGN_SIGBUS:
213 return "SIGBUS";
214#endif
215 default:
216 break;
217 }
218 sprintf(buf, "%x", ctl);
219 return buf;
220}
221
222
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000223int
224sys_prctl(tcp)
225struct tcb *tcp;
226{
227 int i;
228
229 if (entering(tcp)) {
230 printxval(prctl_options, tcp->u_arg[0], "PR_???");
231 switch (tcp->u_arg[0]) {
232#ifdef PR_GETNSHARE
233 case PR_GETNSHARE:
234 break;
235#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000236#ifdef PR_SET_DEATHSIG
237 case PR_GET_PDEATHSIG:
238 break;
239#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000240#ifdef PR_SET_UNALIGN
241 case PR_SET_UNALIGN:
242 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
243 break;
244#endif
245#ifdef PR_GET_UNALIGN
246 case PR_GET_UNALIGN:
247 tprintf(", %#lx", tcp->u_arg[1]);
248 break;
249#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000250 default:
251 for (i = 1; i < tcp->u_nargs; i++)
252 tprintf(", %#lx", tcp->u_arg[i]);
253 break;
254 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000255 } else {
256 switch (tcp->u_arg[0]) {
257#ifdef PR_GET_PDEATHSIG
258 case PR_GET_PDEATHSIG:
259 for (i=1; i<tcp->u_nargs; i++)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000260 tprintf(", %#lx", tcp->u_arg[i]);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000261 break;
262#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000263#ifdef PR_SET_UNALIGN
264 case PR_SET_UNALIGN:
265 break;
266#endif
267#ifdef PR_GET_UNALIGN
268 case PR_GET_UNALIGN:
269 {
270 int ctl;
271
272 umove(tcp, tcp->u_arg[1], &ctl);
273 tcp->auxstr = unalignctl_string(ctl);
274 return RVAL_STR;
275 }
276#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000277 default:
278 break;
279 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000280 }
281 return 0;
282}
283
284#endif /* HAVE_PRCTL */
285
286int
287sys_gethostid(tcp)
288struct tcb *tcp;
289{
290 if (exiting(tcp))
291 return RVAL_HEX;
292 return 0;
293}
294
295int
296sys_sethostname(tcp)
297struct tcb *tcp;
298{
299 if (entering(tcp)) {
300 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
301 tprintf(", %lu", tcp->u_arg[1]);
302 }
303 return 0;
304}
305
306int
307sys_gethostname(tcp)
308struct tcb *tcp;
309{
310 if (exiting(tcp)) {
311 if (syserror(tcp))
312 tprintf("%#lx", tcp->u_arg[0]);
313 else
314 printpath(tcp, tcp->u_arg[0]);
315 tprintf(", %lu", tcp->u_arg[1]);
316 }
317 return 0;
318}
319
320int
321sys_setdomainname(tcp)
322struct tcb *tcp;
323{
324 if (entering(tcp)) {
325 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
326 tprintf(", %lu", tcp->u_arg[1]);
327 }
328 return 0;
329}
330
Wichert Akkerman5daa0281999-03-15 19:49:42 +0000331#if !defined(LINUX)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000332
333int
334sys_getdomainname(tcp)
335struct tcb *tcp;
336{
337 if (exiting(tcp)) {
338 if (syserror(tcp))
339 tprintf("%#lx", tcp->u_arg[0]);
340 else
341 printpath(tcp, tcp->u_arg[0]);
342 tprintf(", %lu", tcp->u_arg[1]);
343 }
344 return 0;
345}
346#endif /* !LINUX */
347
348int
349sys_exit(tcp)
350struct tcb *tcp;
351{
352 if (exiting(tcp)) {
353 fprintf(stderr, "_exit returned!\n");
354 return -1;
355 }
356 /* special case: we stop tracing this process, finish line now */
357 tprintf("%ld) ", tcp->u_arg[0]);
358 tabto(acolumn);
359 tprintf("= ?");
360 printtrailer(tcp);
361 return 0;
362}
363
364int
365internal_exit(tcp)
366struct tcb *tcp;
367{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000368 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000369 tcp->flags |= TCB_EXITING;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000370#ifdef __NR_exit_group
371 if (tcp->scno == __NR_exit_group)
372 tcp->flags |= TCB_GROUP_EXITING;
373#endif
374 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000375 return 0;
376}
377
Roland McGrathee9d4352002-12-18 04:16:10 +0000378/* TCP is creating a child we want to follow.
379 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
380 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
381static int
382fork_tcb(struct tcb *tcp)
383{
384 if (nprocs == tcbtabsize) {
385 /* Allocate some more TCBs and expand the table.
386 We don't want to relocate the TCBs because our
387 callers have pointers and it would be a pain.
388 So tcbtab is a table of pointers. Since we never
389 free the TCBs, we allocate a single chunk of many. */
390 struct tcb **newtab = (struct tcb **)
391 realloc(tcbtab, 2 * tcbtabsize * sizeof tcbtab[0]);
392 struct tcb *newtcbs = (struct tcb *) calloc(tcbtabsize,
393 sizeof *newtcbs);
394 int i;
395 if (newtab == NULL || newtcbs == NULL) {
396 if (newtab != NULL)
397 free(newtab);
398 tcp->flags &= ~TCB_FOLLOWFORK;
399 fprintf(stderr, "sys_fork: tcb table full\n");
400 return 1;
401 }
402 for (i = tcbtabsize; i < 2 * tcbtabsize; ++i)
403 newtab[i] = &newtcbs[i - tcbtabsize];
404 tcbtabsize *= 2;
405 tcbtab = newtab;
406 }
407
408 tcp->flags |= TCB_FOLLOWFORK;
409 return 0;
410}
411
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000412#ifdef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000413
414int
415sys_fork(tcp)
416struct tcb *tcp;
417{
418 if (exiting(tcp)) {
419 if (getrval2(tcp)) {
420 tcp->auxstr = "child process";
421 return RVAL_UDECIMAL | RVAL_STR;
422 }
423 }
424 return 0;
425}
426
John Hughes4e36a812001-04-18 15:11:51 +0000427#if UNIXWARE > 2
428
429int
430sys_rfork(tcp)
431struct tcb *tcp;
432{
433 if (entering(tcp)) {
434 tprintf ("%ld", tcp->u_arg[0]);
435 }
436 else {
437 if (getrval2(tcp)) {
438 tcp->auxstr = "child process";
439 return RVAL_UDECIMAL | RVAL_STR;
440 }
441 }
442 return 0;
443}
444
445#endif
446
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000447int
448internal_fork(tcp)
449struct tcb *tcp;
450{
451 struct tcb *tcpchild;
452
453 if (exiting(tcp)) {
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000454#ifdef SYS_rfork
455 if (tcp->scno == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
456 return 0;
457#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000458 if (getrval2(tcp))
459 return 0;
460 if (!followfork)
461 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000462 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000463 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000464 if (syserror(tcp))
465 return 0;
466 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
467 fprintf(stderr, "sys_fork: tcb table full\n");
468 return 0;
469 }
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000470 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000471 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000472 }
473 return 0;
474}
475
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000476#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000477
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000478#ifdef LINUX
479
480/* defines copied from linux/sched.h since we can't include that
481 * ourselves (it conflicts with *lots* of libc includes)
482 */
483#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
484#define CLONE_VM 0x00000100 /* set if VM shared between processes */
485#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
486#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
487#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000488#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000489#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
490#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
491#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000492#define CLONE_THREAD 0x00010000 /* Same thread group? */
493#define CLONE_NEWNS 0x00020000 /* New namespace group? */
494#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
495#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
496#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
497#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
498#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
499#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
500#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000501
502static struct xlat clone_flags[] = {
503 { CLONE_VM, "CLONE_VM" },
504 { CLONE_FS, "CLONE_FS" },
505 { CLONE_FILES, "CLONE_FILES" },
506 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000507 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000508 { CLONE_PTRACE, "CLONE_PTRACE" },
509 { CLONE_VFORK, "CLONE_VFORK" },
510 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000511 { CLONE_THREAD, "CLONE_THREAD" },
512 { CLONE_NEWNS, "CLONE_NEWNS" },
513 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
514 { CLONE_SETTLS, "CLONE_SETTLS" },
515 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
516 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
517 { CLONE_DETACHED, "CLONE_DETACHED" },
518 { CLONE_UNTRACED, "CLONE_UNTRACED" },
519 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000520 { 0, NULL },
521};
522
Roland McGrath909875b2002-12-22 03:34:36 +0000523# ifdef I386
524# include <asm/ldt.h>
525extern void print_ldt_entry();
526# endif
527
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000528int
529sys_clone(tcp)
530struct tcb *tcp;
531{
532 if (exiting(tcp)) {
Roland McGrathb4968be2003-01-20 09:04:33 +0000533 long flags, stack;
534# if defined S390 || defined S390X
535 /* For some reason, S390 has the stack argument first. */
536 stack = tcp->u_arg[0];
537 flags = tcp->u_arg[1];
538# else
539 flags = tcp->u_arg[0];
540 stack = tcp->u_arg[1];
541# endif
542 tprintf("child_stack=%#lx, flags=", stack);
543 if (printflags(clone_flags, flags) == 0)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000544 tprintf("0");
Roland McGrathb4968be2003-01-20 09:04:33 +0000545 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
Roland McGrath909875b2002-12-22 03:34:36 +0000546 |CLONE_SETTLS)) == 0)
547 return 0;
Roland McGrathb4968be2003-01-20 09:04:33 +0000548 if (flags & CLONE_PARENT_SETTID) {
Roland McGrath909875b2002-12-22 03:34:36 +0000549 int pid;
550 if (umove(tcp, tcp->u_arg[2], &pid) == 0)
551 tprintf(", [%d]", pid);
552 else
553 tprintf(", %#lx", tcp->u_arg[2]);
554 }
555 else
556 tprintf(", <ignored>");
557#ifdef I386
Roland McGrathb4968be2003-01-20 09:04:33 +0000558 if (flags & CLONE_SETTLS) {
Roland McGrath909875b2002-12-22 03:34:36 +0000559 struct modify_ldt_ldt_s copy;
560 if (umove(tcp, tcp->u_arg[3], &copy) != -1) {
561 tprintf(", {entry_number:%d, ",
562 copy.entry_number);
563 if (!verbose(tcp))
564 tprintf("...}");
565 else
566 print_ldt_entry(&copy);
567 }
568 else
569 tprintf(", %#lx", tcp->u_arg[3]);
570 }
571 else
572 tprintf(", <ignored>");
573# define TIDARG 4
574#else
575# define TIDARG 3
576#endif
Roland McGrathb4968be2003-01-20 09:04:33 +0000577 if (flags & CLONE_CHILD_SETTID)
Roland McGrath909875b2002-12-22 03:34:36 +0000578 tprintf(", %#lx", tcp->u_arg[TIDARG]);
579#undef TIDARG
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000580 }
581 return 0;
582}
583
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000584int
585sys_clone2(tcp)
586struct tcb *tcp;
587{
588 if (exiting(tcp)) {
589 tprintf("child_stack=%#lx, stack_size=%#lx, flags=",
590 tcp->u_arg[1], tcp->u_arg[2]);
591 if (printflags(clone_flags, tcp->u_arg[0]) == 0)
592 tprintf("0");
593 }
594 return 0;
595}
596
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000597#endif
598
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000599int
600sys_fork(tcp)
601struct tcb *tcp;
602{
603 if (exiting(tcp))
604 return RVAL_UDECIMAL;
605 return 0;
606}
607
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000608int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000609change_syscall(tcp, new)
610struct tcb *tcp;
611int new;
612{
613#if defined(LINUX)
614#if defined(I386)
615 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000616 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000617 return -1;
618 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000619#elif defined(X86_64)
620 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000621 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000622 return -1;
623 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000624#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000625 if (ptrace(PTRACE_POKEUSER, tcp->pid,
626 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000627 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000628 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000629#elif defined(S390) || defined(S390X)
630 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
631 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
632 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000633 return 0;
634#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000635 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000636 return -1;
637 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000638#elif defined(SPARC)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000639 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000640 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
641 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000642 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000643 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
644 return -1;
645 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000646#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000647 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000648 return -1;
649 return 0;
650#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000651 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000652 return -1;
653 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000654#elif defined(IA64)
655 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
656 return -1;
657 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000658#elif defined(HPPA)
659 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
660 return -1;
661 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000662#elif defined(SH)
663 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), new)<0)
664 return -1;
665 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000666#else
667#warning Do not know how to handle change_syscall for this architecture
668#endif /* architecture */
669#endif /* LINUX */
670 return -1;
671}
672
673int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000674setarg(tcp, argnum)
675 struct tcb *tcp;
676 int argnum;
677{
678#if defined (IA64)
679 {
680 unsigned long *bsp, *ap;
681
682 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
683 return -1;
684
685 ap = ia64_rse_skip_regs(bsp, argnum);
686 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000687 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000688 if (errno)
689 return -1;
690
691 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000692#elif defined(I386)
693 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000694 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000695 if (errno)
696 return -1;
697 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000698#elif defined(X86_64)
699 {
700 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
701 if (errno)
702 return -1;
703 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000704#elif defined(POWERPC)
705#ifndef PT_ORIG_R3
706#define PT_ORIG_R3 34
707#endif
708 {
709 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000710 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000711 tcp->u_arg[argnum]);
712 if (errno)
713 return -1;
714 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000715#elif defined(MIPS)
716 {
717 errno = 0;
718 if (argnum < 4)
719 ptrace(PTRACE_POKEUSER, tcp->pid,
720 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
721 else {
722 unsigned long *sp;
723
724 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
725 return -1;
726
727 ptrace(PTRACE_POKEDATA, tcp->pid,
728 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
729 }
730 if (errno)
731 return -1;
732 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000733#elif defined(S390) || defined(S390X)
734 {
735 if(argnum <= 5)
736 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000737 (char *) (argnum==0 ? PT_ORIGGPR2 :
738 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000739 tcp->u_arg[argnum]);
740 else
741 return -E2BIG;
742 if (errno)
743 return -1;
744 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000745#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000746# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000747#endif
748 return 0;
749}
750
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000751#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000752int
753internal_clone(tcp)
754struct tcb *tcp;
755{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000756 struct tcb *tcpchild;
757 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000758 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000759 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000760 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000761 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000762 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000763 if (setbpt(tcp) < 0)
764 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000765 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000766 int bpt = tcp->flags & TCB_BPTSET;
767
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000768 if (!(tcp->flags & TCB_FOLLOWFORK))
769 return 0;
770
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000771 if (syserror(tcp)) {
772 if (bpt)
773 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000774 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000775 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000776
777 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000778
779#ifdef CLONE_PTRACE /* See new setbpt code. */
780 tcpchild = pid2tcb(pid);
781 if (tcpchild != NULL) {
782 /* The child already reported its startup trap
783 before the parent reported its syscall return. */
784 if ((tcpchild->flags
785 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
786 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
787 fprintf(stderr, "\
788[preattached child %d of %d in weird state!]\n",
789 pid, tcp->pid);
790 }
791 else
792#endif
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000793 if ((tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000794 if (bpt)
795 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000796 fprintf(stderr, " [tcb table full]\n");
797 kill(pid, SIGKILL); /* XXX */
798 return 0;
799 }
800
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000801#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000802 /* Attach to the new child */
803 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000804 if (bpt)
805 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000806 perror("PTRACE_ATTACH");
807 fprintf(stderr, "Too late?\n");
808 droptcb(tcpchild);
809 return 0;
810 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000811#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000812
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000813 if (bpt)
814 clearbpt(tcp);
815
Ulrich Drepper90512f01999-12-24 07:22:25 +0000816 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000817 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000818 if (bpt) {
819 tcpchild->flags |= TCB_BPTSET;
820 tcpchild->baddr = tcp->baddr;
821 memcpy(tcpchild->inst, tcp->inst,
822 sizeof tcpchild->inst);
823 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000824 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000825 tcp->nchildren++;
826 if (tcpchild->flags & TCB_SUSPENDED) {
827 /* The child was born suspended, due to our having
828 forced CLONE_PTRACE. */
829 if (bpt)
830 clearbpt(tcpchild);
831
832 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
833 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
834 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
835 return -1;
836 }
837
838 if (!qflag)
839 fprintf(stderr, "\
840Process %u resumed (parent %d ready)\n",
841 pid, tcp->pid);
842 }
843 else {
844 newoutf(tcpchild);
845 if (!qflag)
846 fprintf(stderr, "Process %d attached\n", pid);
847 }
848
849#ifdef TCB_CLONE_THREAD
850 if ((tcp->flags & TCB_CLONE_THREAD) && tcp->parent != NULL) {
851 /* The parent in this clone is itself a thread
852 belonging to another process. There is no
853 meaning to the parentage relationship of the new
854 child with the thread, only with the process.
855 We associate the new thread with our parent.
856 Since this is done for every new thread, there
857 will never be a TCB_CLONE_THREAD process that
858 has children. */
859 --tcp->nchildren;
860 tcp->u_arg[0] = tcp->parent->u_arg[0];
861 tcp = tcp->parent;
862 tcpchild->parent = tcp;
863 ++tcp->nchildren;
864 }
865
866 if (tcp->u_arg[0] & CLONE_THREAD) {
867 tcpchild->flags |= TCB_CLONE_THREAD;
868 ++tcp->nclone_threads;
869 }
870 if (tcp->u_arg[0] & CLONE_DETACHED) {
871 tcpchild->flags |= TCB_CLONE_DETACHED;
872 ++tcp->nclone_detached;
873 }
874#endif
875
876 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000877 return 0;
878}
879#endif
880
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000881int
882internal_fork(tcp)
883struct tcb *tcp;
884{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000885#ifdef LINUX
886 /* We do special magic with clone for any clone or fork. */
887 return internal_clone(tcp);
888#else
889
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000890 struct tcb *tcpchild;
891 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000892 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000893
894#ifdef SYS_vfork
Nate Sammonsccd8f211999-03-29 22:57:54 +0000895 if (tcp->scno == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000896 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000897 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000898 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000899 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000900 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000901#endif
902 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000903 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000904 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000905 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000906 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000907 if (setbpt(tcp) < 0)
908 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000909 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000910 else {
911 int bpt = tcp->flags & TCB_BPTSET;
912
913 if (!(tcp->flags & TCB_FOLLOWFORK))
914 return 0;
915 if (bpt)
916 clearbpt(tcp);
917
918 if (syserror(tcp))
919 return 0;
920
921 pid = tcp->u_rval;
922 if ((tcpchild = alloctcb(pid)) == NULL) {
923 fprintf(stderr, " [tcb table full]\n");
924 kill(pid, SIGKILL); /* XXX */
925 return 0;
926 }
927#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000928#ifdef HPPA
929 /* The child must have run before it can be attached. */
930 /* This must be a bug in the parisc kernel, but I havn't
931 * identified it yet. Seems to be an issue associated
932 * with attaching to a process (which sends it a signal)
933 * before that process has ever been scheduled. When
934 * debugging, I started seeing crashes in
935 * arch/parisc/kernel/signal.c:do_signal(), apparently
936 * caused by r8 getting corrupt over the dequeue_signal()
937 * call. Didn't make much sense though...
938 */
939 {
940 struct timeval tv;
941 tv.tv_sec = 0;
942 tv.tv_usec = 10000;
943 select(0, NULL, NULL, NULL, &tv);
944 }
945#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000946 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
947 perror("PTRACE_ATTACH");
948 fprintf(stderr, "Too late?\n");
949 droptcb(tcpchild);
950 return 0;
951 }
952#endif /* LINUX */
953#ifdef SUNOS4
954#ifdef oldway
955 /* The child must have run before it can be attached. */
956 {
957 struct timeval tv;
958 tv.tv_sec = 0;
959 tv.tv_usec = 10000;
960 select(0, NULL, NULL, NULL, &tv);
961 }
962 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
963 perror("PTRACE_ATTACH");
964 fprintf(stderr, "Too late?\n");
965 droptcb(tcpchild);
966 return 0;
967 }
968#else /* !oldway */
969 /* Try to catch the new process as soon as possible. */
970 {
971 int i;
972 for (i = 0; i < 1024; i++)
973 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
974 break;
975 if (i == 1024) {
976 perror("PTRACE_ATTACH");
977 fprintf(stderr, "Too late?\n");
978 droptcb(tcpchild);
979 return 0;
980 }
981 }
982#endif /* !oldway */
983#endif /* SUNOS4 */
984 tcpchild->flags |= TCB_ATTACHED;
985 /* Child has BPT too, must be removed on first occasion */
986 if (bpt) {
987 tcpchild->flags |= TCB_BPTSET;
988 tcpchild->baddr = tcp->baddr;
989 memcpy(tcpchild->inst, tcp->inst,
990 sizeof tcpchild->inst);
991 }
992 newoutf(tcpchild);
993 tcpchild->parent = tcp;
994 tcp->nchildren++;
995 if (!qflag)
996 fprintf(stderr, "Process %d attached\n", pid);
997 }
998 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000999#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001000}
1001
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001002#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001003
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001004#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001005
1006int
1007sys_vfork(tcp)
1008struct tcb *tcp;
1009{
1010 if (exiting(tcp))
1011 return RVAL_UDECIMAL;
1012 return 0;
1013}
1014
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001015#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001016
1017#ifndef LINUX
1018
1019static char idstr[16];
1020
1021int
1022sys_getpid(tcp)
1023struct tcb *tcp;
1024{
1025 if (exiting(tcp)) {
1026 sprintf(idstr, "ppid %lu", getrval2(tcp));
1027 tcp->auxstr = idstr;
1028 return RVAL_STR;
1029 }
1030 return 0;
1031}
1032
1033int
1034sys_getuid(tcp)
1035struct tcb *tcp;
1036{
1037 if (exiting(tcp)) {
1038 sprintf(idstr, "euid %lu", getrval2(tcp));
1039 tcp->auxstr = idstr;
1040 return RVAL_STR;
1041 }
1042 return 0;
1043}
1044
1045int
1046sys_getgid(tcp)
1047struct tcb *tcp;
1048{
1049 if (exiting(tcp)) {
1050 sprintf(idstr, "egid %lu", getrval2(tcp));
1051 tcp->auxstr = idstr;
1052 return RVAL_STR;
1053 }
1054 return 0;
1055}
1056
1057#endif /* !LINUX */
1058
1059#ifdef LINUX
1060
1061int
1062sys_setuid(tcp)
1063struct tcb *tcp;
1064{
1065 if (entering(tcp)) {
1066 tprintf("%u", (uid_t) tcp->u_arg[0]);
1067 }
1068 return 0;
1069}
1070
1071int
1072sys_setgid(tcp)
1073struct tcb *tcp;
1074{
1075 if (entering(tcp)) {
1076 tprintf("%u", (gid_t) tcp->u_arg[0]);
1077 }
1078 return 0;
1079}
1080
1081int
1082sys_getresuid(tcp)
1083 struct tcb *tcp;
1084{
1085 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001086 __kernel_uid_t uid;
1087 if (syserror(tcp))
1088 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1089 tcp->u_arg[1], tcp->u_arg[2]);
1090 else {
1091 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1092 tprintf("%#lx, ", tcp->u_arg[0]);
1093 else
1094 tprintf("ruid %lu, ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001095 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1096 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001097 else
1098 tprintf("euid %lu, ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001099 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1100 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001101 else
1102 tprintf("suid %lu", (unsigned long) uid);
1103 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001104 }
1105 return 0;
1106}
1107
1108int
1109sys_getresgid(tcp)
1110struct tcb *tcp;
1111{
1112 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001113 __kernel_gid_t gid;
1114 if (syserror(tcp))
1115 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1116 tcp->u_arg[1], tcp->u_arg[2]);
1117 else {
1118 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1119 tprintf("%#lx, ", tcp->u_arg[0]);
1120 else
1121 tprintf("rgid %lu, ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001122 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1123 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001124 else
1125 tprintf("egid %lu, ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001126 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1127 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001128 else
1129 tprintf("sgid %lu", (unsigned long) gid);
1130 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001131 }
1132 return 0;
1133}
1134
1135#endif /* LINUX */
1136
1137int
1138sys_setreuid(tcp)
1139struct tcb *tcp;
1140{
1141 if (entering(tcp)) {
1142 tprintf("%lu, %lu",
1143 (unsigned long) (uid_t) tcp->u_arg[0],
1144 (unsigned long) (uid_t) tcp->u_arg[1]);
1145 }
1146 return 0;
1147}
1148
1149int
1150sys_setregid(tcp)
1151struct tcb *tcp;
1152{
1153 if (entering(tcp)) {
1154 tprintf("%lu, %lu",
1155 (unsigned long) (gid_t) tcp->u_arg[0],
1156 (unsigned long) (gid_t) tcp->u_arg[1]);
1157 }
1158 return 0;
1159}
1160
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001161#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001162int
1163sys_setresuid(tcp)
1164 struct tcb *tcp;
1165{
1166 if (entering(tcp)) {
1167 tprintf("ruid %u, euid %u, suid %u",
1168 (uid_t) tcp->u_arg[0],
1169 (uid_t) tcp->u_arg[1],
1170 (uid_t) tcp->u_arg[2]);
1171 }
1172 return 0;
1173}
1174int
1175sys_setresgid(tcp)
1176 struct tcb *tcp;
1177{
1178 if (entering(tcp)) {
1179 tprintf("rgid %u, egid %u, sgid %u",
1180 (uid_t) tcp->u_arg[0],
1181 (uid_t) tcp->u_arg[1],
1182 (uid_t) tcp->u_arg[2]);
1183 }
1184 return 0;
1185}
1186
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001187#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001188
1189int
1190sys_setgroups(tcp)
1191struct tcb *tcp;
1192{
1193 int i, len;
1194 GETGROUPS_T *gidset;
1195
1196 if (entering(tcp)) {
1197 len = tcp->u_arg[0];
1198 tprintf("%u, ", len);
1199 if (len <= 0) {
1200 tprintf("[]");
1201 return 0;
1202 }
1203 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1204 if (gidset == NULL) {
1205 fprintf(stderr, "sys_setgroups: out of memory\n");
1206 return -1;
1207 }
1208 if (!verbose(tcp))
1209 tprintf("%#lx", tcp->u_arg[1]);
1210 else if (umoven(tcp, tcp->u_arg[1],
1211 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1212 tprintf("[?]");
1213 else {
1214 tprintf("[");
1215 for (i = 0; i < len; i++)
1216 tprintf("%s%lu", i ? ", " : "",
1217 (unsigned long) gidset[i]);
1218 tprintf("]");
1219 }
1220 free((char *) gidset);
1221 }
1222 return 0;
1223}
1224
1225int
1226sys_getgroups(tcp)
1227struct tcb *tcp;
1228{
1229 int i, len;
1230 GETGROUPS_T *gidset;
1231
1232 if (entering(tcp)) {
1233 len = tcp->u_arg[0];
1234 tprintf("%u, ", len);
1235 } else {
1236 len = tcp->u_rval;
1237 if (len <= 0) {
1238 tprintf("[]");
1239 return 0;
1240 }
1241 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1242 if (gidset == NULL) {
1243 fprintf(stderr, "sys_getgroups: out of memory\n");
1244 return -1;
1245 }
1246 if (!tcp->u_arg[1])
1247 tprintf("NULL");
1248 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1249 tprintf("%#lx", tcp->u_arg[1]);
1250 else if (umoven(tcp, tcp->u_arg[1],
1251 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1252 tprintf("[?]");
1253 else {
1254 tprintf("[");
1255 for (i = 0; i < len; i++)
1256 tprintf("%s%lu", i ? ", " : "",
1257 (unsigned long) gidset[i]);
1258 tprintf("]");
1259 }
1260 free((char *)gidset);
1261 }
1262 return 0;
1263}
1264
1265int
1266sys_setpgrp(tcp)
1267struct tcb *tcp;
1268{
1269 if (entering(tcp)) {
1270#ifndef SVR4
1271 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1272#endif /* !SVR4 */
1273 }
1274 return 0;
1275}
1276
1277int
1278sys_getpgrp(tcp)
1279struct tcb *tcp;
1280{
1281 if (entering(tcp)) {
1282#ifndef SVR4
1283 tprintf("%lu", tcp->u_arg[0]);
1284#endif /* !SVR4 */
1285 }
1286 return 0;
1287}
1288
1289int
1290sys_getsid(tcp)
1291struct tcb *tcp;
1292{
1293 if (entering(tcp)) {
1294 tprintf("%lu", tcp->u_arg[0]);
1295 }
1296 return 0;
1297}
1298
1299int
1300sys_setsid(tcp)
1301struct tcb *tcp;
1302{
1303 return 0;
1304}
1305
1306int
1307sys_getpgid(tcp)
1308struct tcb *tcp;
1309{
1310 if (entering(tcp)) {
1311 tprintf("%lu", tcp->u_arg[0]);
1312 }
1313 return 0;
1314}
1315
1316int
1317sys_setpgid(tcp)
1318struct tcb *tcp;
1319{
1320 if (entering(tcp)) {
1321 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1322 }
1323 return 0;
1324}
1325
John Hughesc61eb3d2002-05-17 11:37:50 +00001326#if UNIXWARE >= 2
1327
1328#include <sys/privilege.h>
1329
1330
1331static struct xlat procpriv_cmds [] = {
1332 { SETPRV, "SETPRV" },
1333 { CLRPRV, "CLRPRV" },
1334 { PUTPRV, "PUTPRV" },
1335 { GETPRV, "GETPRV" },
1336 { CNTPRV, "CNTPRV" },
1337 { 0, NULL },
1338};
1339
1340
1341static struct xlat procpriv_priv [] = {
1342 { P_OWNER, "P_OWNER" },
1343 { P_AUDIT, "P_AUDIT" },
1344 { P_COMPAT, "P_COMPAT" },
1345 { P_DACREAD, "P_DACREAD" },
1346 { P_DACWRITE, "P_DACWRITE" },
1347 { P_DEV, "P_DEV" },
1348 { P_FILESYS, "P_FILESYS" },
1349 { P_MACREAD, "P_MACREAD" },
1350 { P_MACWRITE, "P_MACWRITE" },
1351 { P_MOUNT, "P_MOUNT" },
1352 { P_MULTIDIR, "P_MULTIDIR" },
1353 { P_SETPLEVEL, "P_SETPLEVEL" },
1354 { P_SETSPRIV, "P_SETSPRIV" },
1355 { P_SETUID, "P_SETUID" },
1356 { P_SYSOPS, "P_SYSOPS" },
1357 { P_SETUPRIV, "P_SETUPRIV" },
1358 { P_DRIVER, "P_DRIVER" },
1359 { P_RTIME, "P_RTIME" },
1360 { P_MACUPGRADE, "P_MACUPGRADE" },
1361 { P_FSYSRANGE, "P_FSYSRANGE" },
1362 { P_SETFLEVEL, "P_SETFLEVEL" },
1363 { P_AUDITWR, "P_AUDITWR" },
1364 { P_TSHAR, "P_TSHAR" },
1365 { P_PLOCK, "P_PLOCK" },
1366 { P_CORE, "P_CORE" },
1367 { P_LOADMOD, "P_LOADMOD" },
1368 { P_BIND, "P_BIND" },
1369 { P_ALLPRIVS, "P_ALLPRIVS" },
1370 { 0, NULL },
1371};
1372
1373
1374static struct xlat procpriv_type [] = {
1375 { PS_FIX, "PS_FIX" },
1376 { PS_INH, "PS_INH" },
1377 { PS_MAX, "PS_MAX" },
1378 { PS_WKG, "PS_WKG" },
1379 { 0, NULL },
1380};
1381
1382
1383static void
1384printpriv(tcp, addr, len, opt)
1385struct tcb *tcp;
1386long addr;
1387int len;
1388struct xlat *opt;
1389{
1390 priv_t buf [128];
1391 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1392 int dots = len > max;
1393 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001394
John Hughesc61eb3d2002-05-17 11:37:50 +00001395 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001396
John Hughesc61eb3d2002-05-17 11:37:50 +00001397 if (len <= 0 ||
1398 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1399 {
1400 tprintf ("%#lx", addr);
1401 return;
1402 }
1403
1404 tprintf ("[");
1405
1406 for (i = 0; i < len; ++i) {
1407 char *t, *p;
1408
1409 if (i) tprintf (", ");
1410
1411 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1412 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1413 {
1414 tprintf ("%s|%s", t, p);
1415 }
1416 else {
1417 tprintf ("%#lx", buf [i]);
1418 }
1419 }
1420
1421 if (dots) tprintf (" ...");
1422
1423 tprintf ("]");
1424}
1425
1426
1427int
1428sys_procpriv(tcp)
1429struct tcb *tcp;
1430{
1431 if (entering(tcp)) {
1432 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1433 switch (tcp->u_arg[0]) {
1434 case CNTPRV:
1435 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1436 break;
1437
1438 case GETPRV:
1439 break;
1440
1441 default:
1442 tprintf (", ");
1443 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1444 tprintf (", %ld", tcp->u_arg[2]);
1445 }
1446 }
1447 else if (tcp->u_arg[0] == GETPRV) {
1448 if (syserror (tcp)) {
1449 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1450 }
1451 else {
1452 tprintf (", ");
1453 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1454 tprintf (", %ld", tcp->u_arg[2]);
1455 }
1456 }
Roland McGrath5a223472002-12-15 23:58:26 +00001457
John Hughesc61eb3d2002-05-17 11:37:50 +00001458 return 0;
1459}
1460
1461#endif
1462
1463
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001464void
1465fake_execve(tcp, program, argv, envp)
1466struct tcb *tcp;
1467char *program;
1468char *argv[];
1469char *envp[];
1470{
1471 int i;
1472
1473#ifdef ARM
1474 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1475 return;
1476#else
1477 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1478 return;
1479#endif /* !ARM */
1480 printleader(tcp);
1481 tprintf("execve(");
1482 string_quote(program);
1483 tprintf(", [");
1484 for (i = 0; argv[i] != NULL; i++) {
1485 if (i != 0)
1486 tprintf(", ");
1487 string_quote(argv[i]);
1488 }
1489 for (i = 0; envp[i] != NULL; i++)
1490 ;
1491 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1492 tabto(acolumn);
1493 tprintf("= 0");
1494 printtrailer(tcp);
1495}
1496
1497static void
1498printargv(tcp, addr)
1499struct tcb *tcp;
1500long addr;
1501{
1502 char *cp;
1503 char *sep;
1504 int max = max_strlen / 2;
1505
1506 for (sep = ""; --max >= 0; sep = ", ") {
1507 if (!abbrev(tcp))
1508 max++;
1509 if (umove(tcp, addr, &cp) < 0) {
1510 tprintf("%#lx", addr);
1511 return;
1512 }
1513 if (cp == 0)
1514 break;
1515 tprintf(sep);
1516 printstr(tcp, (long) cp, -1);
1517 addr += sizeof(char *);
1518 }
1519 if (cp)
1520 tprintf(", ...");
1521}
1522
1523static void
1524printargc(fmt, tcp, addr)
1525char *fmt;
1526struct tcb *tcp;
1527long addr;
1528{
1529 int count;
1530 char *cp;
1531
1532 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1533 addr += sizeof(char *);
1534 }
1535 tprintf(fmt, count, count == 1 ? "" : "s");
1536}
1537
1538int
1539sys_execv(tcp)
1540struct tcb *tcp;
1541{
1542 if (entering(tcp)) {
1543 printpath(tcp, tcp->u_arg[0]);
1544 if (!verbose(tcp))
1545 tprintf(", %#lx", tcp->u_arg[1]);
1546#if 0
1547 else if (abbrev(tcp))
1548 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1549#endif
1550 else {
1551 tprintf(", [");
1552 printargv(tcp, tcp->u_arg[1]);
1553 tprintf("]");
1554 }
1555 }
1556 return 0;
1557}
1558
1559int
1560sys_execve(tcp)
1561struct tcb *tcp;
1562{
1563 if (entering(tcp)) {
1564 printpath(tcp, tcp->u_arg[0]);
1565 if (!verbose(tcp))
1566 tprintf(", %#lx", tcp->u_arg[1]);
1567#if 0
1568 else if (abbrev(tcp))
1569 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1570#endif
1571 else {
1572 tprintf(", [");
1573 printargv(tcp, tcp->u_arg[1]);
1574 tprintf("]");
1575 }
1576 if (!verbose(tcp))
1577 tprintf(", %#lx", tcp->u_arg[2]);
1578 else if (abbrev(tcp))
1579 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1580 else {
1581 tprintf(", [");
1582 printargv(tcp, tcp->u_arg[2]);
1583 tprintf("]");
1584 }
1585 }
Roland McGrathb4968be2003-01-20 09:04:33 +00001586#if defined LINUX && defined TCB_WAITEXECVE
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001587 tcp->flags |= TCB_WAITEXECVE;
Roland McGrathb4968be2003-01-20 09:04:33 +00001588#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001589 return 0;
1590}
1591
John Hughes4e36a812001-04-18 15:11:51 +00001592#if UNIXWARE > 2
1593
1594int sys_rexecve(tcp)
1595struct tcb *tcp;
1596{
1597 if (entering (tcp)) {
1598 sys_execve (tcp);
1599 tprintf (", %ld", tcp->u_arg[3]);
1600 }
1601 return 0;
1602}
1603
1604#endif
1605
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001606int
1607internal_exec(tcp)
1608struct tcb *tcp;
1609{
1610#ifdef SUNOS4
1611 if (exiting(tcp) && !syserror(tcp) && followfork)
1612 fixvfork(tcp);
1613#endif /* SUNOS4 */
1614 return 0;
1615}
1616
1617#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001618#ifndef __WNOTHREAD
1619#define __WNOTHREAD 0x20000000
1620#endif
1621#ifndef __WALL
1622#define __WALL 0x40000000
1623#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001624#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001625#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001626#endif
1627#endif /* LINUX */
1628
1629static struct xlat wait4_options[] = {
1630 { WNOHANG, "WNOHANG" },
1631#ifndef WSTOPPED
1632 { WUNTRACED, "WUNTRACED" },
1633#endif
1634#ifdef WEXITED
1635 { WEXITED, "WEXITED" },
1636#endif
1637#ifdef WTRAPPED
1638 { WTRAPPED, "WTRAPPED" },
1639#endif
1640#ifdef WSTOPPED
1641 { WSTOPPED, "WSTOPPED" },
1642#endif
1643#ifdef WCONTINUED
1644 { WCONTINUED, "WCONTINUED" },
1645#endif
1646#ifdef WNOWAIT
1647 { WNOWAIT, "WNOWAIT" },
1648#endif
1649#ifdef __WCLONE
1650 { __WCLONE, "__WCLONE" },
1651#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001652#ifdef __WALL
1653 { __WALL, "__WALL" },
1654#endif
1655#ifdef __WNOTHREAD
1656 { __WNOTHREAD, "__WNOTHREAD" },
1657#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001658 { 0, NULL },
1659};
1660
1661static int
1662printstatus(status)
1663int status;
1664{
1665 int exited = 0;
1666
1667 /*
1668 * Here is a tricky presentation problem. This solution
1669 * is still not entirely satisfactory but since there
1670 * are no wait status constructors it will have to do.
1671 */
1672 if (WIFSTOPPED(status))
1673 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001674 signame(WSTOPSIG(status)));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001675 else if WIFSIGNALED(status)
1676 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001677 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001678 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1679 else if WIFEXITED(status) {
1680 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1681 WEXITSTATUS(status));
1682 exited = 1;
1683 }
1684 else
1685 tprintf("[%#x]", status);
1686 return exited;
1687}
1688
1689static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001690printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001691struct tcb *tcp;
1692int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001693int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001694{
1695 int status;
1696 int exited = 0;
1697
1698 if (entering(tcp)) {
1699 tprintf("%ld, ", tcp->u_arg[0]);
1700 } else {
1701 /* status */
1702 if (!tcp->u_arg[1])
1703 tprintf("NULL");
1704 else if (syserror(tcp) || tcp->u_rval == 0)
1705 tprintf("%#lx", tcp->u_arg[1]);
1706 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1707 tprintf("[?]");
1708 else
1709 exited = printstatus(status);
1710 /* options */
1711 tprintf(", ");
1712 if (!printflags(wait4_options, tcp->u_arg[2]))
1713 tprintf("0");
1714 if (n == 4) {
1715 tprintf(", ");
1716 /* usage */
1717 if (!tcp->u_arg[3])
1718 tprintf("NULL");
1719#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001720 else if (tcp->u_rval > 0) {
1721#ifdef LINUX_64BIT
1722 if (bitness)
1723 printrusage32(tcp, tcp->u_arg[3]);
1724 else
1725#endif
1726 printrusage(tcp, tcp->u_arg[3]);
1727 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001728#endif /* LINUX */
1729#ifdef SUNOS4
1730 else if (tcp->u_rval > 0 && exited)
1731 printrusage(tcp, tcp->u_arg[3]);
1732#endif /* SUNOS4 */
1733 else
1734 tprintf("%#lx", tcp->u_arg[3]);
1735 }
1736 }
1737 return 0;
1738}
1739
1740int
1741internal_wait(tcp)
1742struct tcb *tcp;
1743{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001744 int got_kids;
1745
1746#ifdef TCB_CLONE_THREAD
1747 if (tcp->flags & TCB_CLONE_THREAD)
1748 /* The children we wait for are our parent's children. */
1749 got_kids = (tcp->parent->nchildren
1750 > tcp->parent->nclone_detached);
1751 else
1752 got_kids = (tcp->nchildren > tcp->nclone_detached);
1753#else
1754 got_kids = tcp->nchildren > 0;
1755#endif
1756
1757 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001758 /* There are children that this parent should block for.
1759 But ptrace made us the parent of the traced children
1760 and the real parent will get ECHILD from the wait call.
1761
1762 XXX If we attached with strace -f -p PID, then there
1763 may be untraced dead children the parent could be reaping
1764 now, but we make him block. */
1765
1766 /* ??? WTA: fix bug with hanging children */
1767
1768 if (!(tcp->u_arg[2] & WNOHANG)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001769 /* There are traced children */
1770 tcp->flags |= TCB_SUSPENDED;
1771 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001772#ifdef TCB_CLONE_THREAD
1773 if (tcp->flags & TCB_CLONE_THREAD)
1774 tcp->parent->nclone_waiting++;
1775#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001776 }
1777 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001778 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001779 if (tcp->u_arg[2] & WNOHANG) {
1780 /* We must force a fake result of 0 instead of
1781 the ECHILD error. */
1782 extern int force_result();
1783 return force_result(tcp, 0, 0);
1784 }
1785 else
1786 fprintf(stderr,
1787 "internal_wait: should not have resumed %d\n",
1788 tcp->pid);
1789 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001790 return 0;
1791}
1792
1793#ifdef SVR4
1794
1795int
1796sys_wait(tcp)
1797struct tcb *tcp;
1798{
1799 if (exiting(tcp)) {
1800 /* The library wrapper stuffs this into the user variable. */
1801 if (!syserror(tcp))
1802 printstatus(getrval2(tcp));
1803 }
1804 return 0;
1805}
1806
1807#endif /* SVR4 */
1808
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001809#ifdef FREEBSD
1810int
1811sys_wait(tcp)
1812struct tcb *tcp;
1813{
1814 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001815
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001816 if (exiting(tcp)) {
1817 if (!syserror(tcp)) {
1818 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1819 tprintf("%#lx", tcp->u_arg[0]);
1820 else
1821 printstatus(status);
1822 }
1823 }
1824 return 0;
1825}
1826#endif
1827
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001828int
1829sys_waitpid(tcp)
1830struct tcb *tcp;
1831{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001832 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001833}
1834
1835int
1836sys_wait4(tcp)
1837struct tcb *tcp;
1838{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001839 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001840}
1841
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001842#ifdef ALPHA
1843int
1844sys_osf_wait4(tcp)
1845struct tcb *tcp;
1846{
1847 return printwaitn(tcp, 4, 1);
1848}
1849#endif
1850
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001851#ifdef SVR4
1852
1853static struct xlat waitid_types[] = {
1854 { P_PID, "P_PID" },
1855 { P_PPID, "P_PPID" },
1856 { P_PGID, "P_PGID" },
1857 { P_SID, "P_SID" },
1858 { P_CID, "P_CID" },
1859 { P_UID, "P_UID" },
1860 { P_GID, "P_GID" },
1861 { P_ALL, "P_ALL" },
1862#ifdef P_LWPID
1863 { P_LWPID, "P_LWPID" },
1864#endif
1865 { 0, NULL },
1866};
1867
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001868int
1869sys_waitid(tcp)
1870struct tcb *tcp;
1871{
1872 siginfo_t si;
1873 int exited;
1874
1875 if (entering(tcp)) {
1876 printxval(waitid_types, tcp->u_arg[0], "P_???");
1877 tprintf(", %ld, ", tcp->u_arg[1]);
1878 if (tcp->nchildren > 0) {
1879 /* There are traced children */
1880 tcp->flags |= TCB_SUSPENDED;
1881 tcp->waitpid = tcp->u_arg[0];
1882 }
1883 }
1884 else {
1885 /* siginfo */
1886 exited = 0;
1887 if (!tcp->u_arg[2])
1888 tprintf("NULL");
1889 else if (syserror(tcp))
1890 tprintf("%#lx", tcp->u_arg[2]);
1891 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1892 tprintf("{???}");
1893 else
John Hughes58265892001-10-18 15:13:53 +00001894 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001895 /* options */
1896 tprintf(", ");
1897 if (!printflags(wait4_options, tcp->u_arg[3]))
1898 tprintf("0");
1899 }
1900 return 0;
1901}
1902
1903#endif /* SVR4 */
1904
1905int
1906sys_alarm(tcp)
1907struct tcb *tcp;
1908{
1909 if (entering(tcp))
1910 tprintf("%lu", tcp->u_arg[0]);
1911 return 0;
1912}
1913
1914int
1915sys_uname(tcp)
1916struct tcb *tcp;
1917{
1918 struct utsname uname;
1919
1920 if (exiting(tcp)) {
1921 if (syserror(tcp) || !verbose(tcp))
1922 tprintf("%#lx", tcp->u_arg[0]);
1923 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1924 tprintf("{...}");
1925 else if (!abbrev(tcp)) {
1926
1927 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1928 uname.sysname, uname.nodename);
1929 tprintf("release=\"%s\", version=\"%s\", ",
1930 uname.release, uname.version);
1931 tprintf("machine=\"%s\"", uname.machine);
1932#ifdef LINUX
1933#ifndef __GLIBC__
1934 tprintf(", domainname=\"%s\"", uname.domainname);
1935#endif /* __GLIBC__ */
1936#endif /* LINUX */
1937 tprintf("}");
1938 }
1939 else
1940 tprintf("{sys=\"%s\", node=\"%s\", ...}",
1941 uname.sysname, uname.nodename);
1942 }
1943 return 0;
1944}
1945
1946#ifndef SVR4
1947
1948static struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00001949#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001950 { PTRACE_TRACEME, "PTRACE_TRACEME" },
1951 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
1952 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
1953 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
1954 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
1955 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
1956 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
1957 { PTRACE_CONT, "PTRACE_CONT" },
1958 { PTRACE_KILL, "PTRACE_KILL" },
1959 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
1960 { PTRACE_ATTACH, "PTRACE_ATTACH" },
1961 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001962#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001963 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001964#endif
1965#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001966 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001967#endif
1968#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001969 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00001970#endif
1971#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001972 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00001973#endif
1974#ifdef PTRACE_GETFPXREGS
1975 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
1976#endif
1977#ifdef PTRACE_SETFPXREGS
1978 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
1979#endif
1980#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001981 { PTRACE_READDATA, "PTRACE_READDATA" },
1982 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
1983 { PTRACE_READTEXT, "PTRACE_READTEXT" },
1984 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
1985 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
1986 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
1987#ifdef SPARC
1988 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
1989 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
1990#else /* !SPARC */
1991 { PTRACE_22, "PTRACE_PTRACE_22" },
1992 { PTRACE_23, "PTRACE_PTRACE_23" },
1993#endif /* !SPARC */
1994#endif /* SUNOS4 */
1995 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
1996#ifdef SUNOS4
1997 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
1998#ifdef I386
1999 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2000 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2001 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2002#else /* !I386 */
2003 { PTRACE_26, "PTRACE_26" },
2004 { PTRACE_27, "PTRACE_27" },
2005 { PTRACE_28, "PTRACE_28" },
2006#endif /* !I386 */
2007 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2008#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002009#else /* FREEBSD */
2010 { PT_TRACE_ME, "PT_TRACE_ME" },
2011 { PT_READ_I, "PT_READ_I" },
2012 { PT_READ_D, "PT_READ_D" },
2013 { PT_WRITE_I, "PT_WRITE_I" },
2014 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002015#ifdef PT_READ_U
2016 { PT_READ_U, "PT_READ_U" },
2017#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002018 { PT_CONTINUE, "PT_CONTINUE" },
2019 { PT_KILL, "PT_KILL" },
2020 { PT_STEP, "PT_STEP" },
2021 { PT_ATTACH, "PT_ATTACH" },
2022 { PT_DETACH, "PT_DETACH" },
2023 { PT_GETREGS, "PT_GETREGS" },
2024 { PT_SETREGS, "PT_SETREGS" },
2025 { PT_GETFPREGS, "PT_GETFPREGS" },
2026 { PT_SETFPREGS, "PT_SETFPREGS" },
2027 { PT_GETDBREGS, "PT_GETDBREGS" },
2028 { PT_SETDBREGS, "PT_SETDBREGS" },
2029#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002030 { 0, NULL },
2031};
2032
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002033#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002034#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2035static
2036#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2037struct xlat struct_user_offsets[] = {
2038#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002039#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002040 { PT_PSWMASK, "psw_mask" },
2041 { PT_PSWADDR, "psw_addr" },
2042 { PT_GPR0, "gpr0" },
2043 { PT_GPR1, "gpr1" },
2044 { PT_GPR2, "gpr2" },
2045 { PT_GPR3, "gpr3" },
2046 { PT_GPR4, "gpr4" },
2047 { PT_GPR5, "gpr5" },
2048 { PT_GPR6, "gpr6" },
2049 { PT_GPR7, "gpr7" },
2050 { PT_GPR8, "gpr8" },
2051 { PT_GPR9, "gpr9" },
2052 { PT_GPR10, "gpr10" },
2053 { PT_GPR11, "gpr11" },
2054 { PT_GPR12, "gpr12" },
2055 { PT_GPR13, "gpr13" },
2056 { PT_GPR14, "gpr14" },
2057 { PT_GPR15, "gpr15" },
2058 { PT_ACR0, "acr0" },
2059 { PT_ACR1, "acr1" },
2060 { PT_ACR2, "acr2" },
2061 { PT_ACR3, "acr3" },
2062 { PT_ACR4, "acr4" },
2063 { PT_ACR5, "acr5" },
2064 { PT_ACR6, "acr6" },
2065 { PT_ACR7, "acr7" },
2066 { PT_ACR8, "acr8" },
2067 { PT_ACR9, "acr9" },
2068 { PT_ACR10, "acr10" },
2069 { PT_ACR11, "acr11" },
2070 { PT_ACR12, "acr12" },
2071 { PT_ACR13, "acr13" },
2072 { PT_ACR14, "acr14" },
2073 { PT_ACR15, "acr15" },
2074 { PT_ORIGGPR2, "orig_gpr2" },
2075 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002076#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002077 { PT_FPR0_HI, "fpr0.hi" },
2078 { PT_FPR0_LO, "fpr0.lo" },
2079 { PT_FPR1_HI, "fpr1.hi" },
2080 { PT_FPR1_LO, "fpr1.lo" },
2081 { PT_FPR2_HI, "fpr2.hi" },
2082 { PT_FPR2_LO, "fpr2.lo" },
2083 { PT_FPR3_HI, "fpr3.hi" },
2084 { PT_FPR3_LO, "fpr3.lo" },
2085 { PT_FPR4_HI, "fpr4.hi" },
2086 { PT_FPR4_LO, "fpr4.lo" },
2087 { PT_FPR5_HI, "fpr5.hi" },
2088 { PT_FPR5_LO, "fpr5.lo" },
2089 { PT_FPR6_HI, "fpr6.hi" },
2090 { PT_FPR6_LO, "fpr6.lo" },
2091 { PT_FPR7_HI, "fpr7.hi" },
2092 { PT_FPR7_LO, "fpr7.lo" },
2093 { PT_FPR8_HI, "fpr8.hi" },
2094 { PT_FPR8_LO, "fpr8.lo" },
2095 { PT_FPR9_HI, "fpr9.hi" },
2096 { PT_FPR9_LO, "fpr9.lo" },
2097 { PT_FPR10_HI, "fpr10.hi" },
2098 { PT_FPR10_LO, "fpr10.lo" },
2099 { PT_FPR11_HI, "fpr11.hi" },
2100 { PT_FPR11_LO, "fpr11.lo" },
2101 { PT_FPR12_HI, "fpr12.hi" },
2102 { PT_FPR12_LO, "fpr12.lo" },
2103 { PT_FPR13_HI, "fpr13.hi" },
2104 { PT_FPR13_LO, "fpr13.lo" },
2105 { PT_FPR14_HI, "fpr14.hi" },
2106 { PT_FPR14_LO, "fpr14.lo" },
2107 { PT_FPR15_HI, "fpr15.hi" },
2108 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002109#endif
2110#if defined(S390X)
2111 { PT_FPR0, "fpr0" },
2112 { PT_FPR1, "fpr1" },
2113 { PT_FPR2, "fpr2" },
2114 { PT_FPR3, "fpr3" },
2115 { PT_FPR4, "fpr4" },
2116 { PT_FPR5, "fpr5" },
2117 { PT_FPR6, "fpr6" },
2118 { PT_FPR7, "fpr7" },
2119 { PT_FPR8, "fpr8" },
2120 { PT_FPR9, "fpr9" },
2121 { PT_FPR10, "fpr10" },
2122 { PT_FPR11, "fpr11" },
2123 { PT_FPR12, "fpr12" },
2124 { PT_FPR13, "fpr13" },
2125 { PT_FPR14, "fpr14" },
2126 { PT_FPR15, "fpr15" },
2127#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002128 { PT_CR_9, "cr9" },
2129 { PT_CR_10, "cr10" },
2130 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002131 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002132#endif
2133#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002134 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002135#elif defined(HPPA)
2136 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002137#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002138#ifndef PT_ORIG_R3
2139#define PT_ORIG_R3 34
2140#endif
Roland McGratheb285352003-01-14 09:59:00 +00002141#define REGSIZE (sizeof(unsigned long))
2142 { REGSIZE*PT_R0, "r0" },
2143 { REGSIZE*PT_R1, "r1" },
2144 { REGSIZE*PT_R2, "r2" },
2145 { REGSIZE*PT_R3, "r3" },
2146 { REGSIZE*PT_R4, "r4" },
2147 { REGSIZE*PT_R5, "r5" },
2148 { REGSIZE*PT_R6, "r6" },
2149 { REGSIZE*PT_R7, "r7" },
2150 { REGSIZE*PT_R8, "r8" },
2151 { REGSIZE*PT_R9, "r9" },
2152 { REGSIZE*PT_R10, "r10" },
2153 { REGSIZE*PT_R11, "r11" },
2154 { REGSIZE*PT_R12, "r12" },
2155 { REGSIZE*PT_R13, "r13" },
2156 { REGSIZE*PT_R14, "r14" },
2157 { REGSIZE*PT_R15, "r15" },
2158 { REGSIZE*PT_R16, "r16" },
2159 { REGSIZE*PT_R17, "r17" },
2160 { REGSIZE*PT_R18, "r18" },
2161 { REGSIZE*PT_R19, "r19" },
2162 { REGSIZE*PT_R20, "r20" },
2163 { REGSIZE*PT_R21, "r21" },
2164 { REGSIZE*PT_R22, "r22" },
2165 { REGSIZE*PT_R23, "r23" },
2166 { REGSIZE*PT_R24, "r24" },
2167 { REGSIZE*PT_R25, "r25" },
2168 { REGSIZE*PT_R26, "r26" },
2169 { REGSIZE*PT_R27, "r27" },
2170 { REGSIZE*PT_R28, "r28" },
2171 { REGSIZE*PT_R29, "r29" },
2172 { REGSIZE*PT_R30, "r30" },
2173 { REGSIZE*PT_R31, "r31" },
2174 { REGSIZE*PT_NIP, "NIP" },
2175 { REGSIZE*PT_MSR, "MSR" },
2176 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2177 { REGSIZE*PT_CTR, "CTR" },
2178 { REGSIZE*PT_LNK, "LNK" },
2179 { REGSIZE*PT_XER, "XER" },
2180 { REGSIZE*PT_CCR, "CCR" },
2181 { REGSIZE*PT_FPR0, "FPR0" },
2182#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002183#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002184#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002185 { 0, "r0" },
2186 { 1, "r1" },
2187 { 2, "r2" },
2188 { 3, "r3" },
2189 { 4, "r4" },
2190 { 5, "r5" },
2191 { 6, "r6" },
2192 { 7, "r7" },
2193 { 8, "r8" },
2194 { 9, "r9" },
2195 { 10, "r10" },
2196 { 11, "r11" },
2197 { 12, "r12" },
2198 { 13, "r13" },
2199 { 14, "r14" },
2200 { 15, "r15" },
2201 { 16, "r16" },
2202 { 17, "r17" },
2203 { 18, "r18" },
2204 { 19, "r19" },
2205 { 20, "r20" },
2206 { 21, "r21" },
2207 { 22, "r22" },
2208 { 23, "r23" },
2209 { 24, "r24" },
2210 { 25, "r25" },
2211 { 26, "r26" },
2212 { 27, "r27" },
2213 { 28, "r28" },
2214 { 29, "gp" },
2215 { 30, "fp" },
2216 { 31, "zero" },
2217 { 32, "fp0" },
2218 { 33, "fp" },
2219 { 34, "fp2" },
2220 { 35, "fp3" },
2221 { 36, "fp4" },
2222 { 37, "fp5" },
2223 { 38, "fp6" },
2224 { 39, "fp7" },
2225 { 40, "fp8" },
2226 { 41, "fp9" },
2227 { 42, "fp10" },
2228 { 43, "fp11" },
2229 { 44, "fp12" },
2230 { 45, "fp13" },
2231 { 46, "fp14" },
2232 { 47, "fp15" },
2233 { 48, "fp16" },
2234 { 49, "fp17" },
2235 { 50, "fp18" },
2236 { 51, "fp19" },
2237 { 52, "fp20" },
2238 { 53, "fp21" },
2239 { 54, "fp22" },
2240 { 55, "fp23" },
2241 { 56, "fp24" },
2242 { 57, "fp25" },
2243 { 58, "fp26" },
2244 { 59, "fp27" },
2245 { 60, "fp28" },
2246 { 61, "fp29" },
2247 { 62, "fp30" },
2248 { 63, "fp31" },
2249 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002250#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002251#ifdef IA64
2252 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2253 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2254 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2255 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2256 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2257 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2258 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2259 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2260 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2261 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2262 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2263 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2264 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2265 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2266 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2267 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2268 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2269 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2270 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2271 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2272 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2273 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2274 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2275 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2276 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2277 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2278 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2279 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2280 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2281 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2282 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2283 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2284 /* switch stack: */
2285 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2286 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2287 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2288 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2289 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2290 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2291 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2292 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2293 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2294 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002295 { PT_B0, "kb0" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002296 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2297 { PT_B4, "b4" }, { PT_B5, "b5" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002298 { PT_AR_PFS, "kar.pfs" },
2299 { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" },
2300 { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" },
2301 { PT_PR, "k.pr" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002302 /* pt_regs */
2303 { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002304 /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002305 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2306 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2307 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2308 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2309 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2310 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2311 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2312 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2313 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2314 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2315 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2316 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2317 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2318 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2319 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2320#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002321#ifdef I386
2322 { 4*EBX, "4*EBX" },
2323 { 4*ECX, "4*ECX" },
2324 { 4*EDX, "4*EDX" },
2325 { 4*ESI, "4*ESI" },
2326 { 4*EDI, "4*EDI" },
2327 { 4*EBP, "4*EBP" },
2328 { 4*EAX, "4*EAX" },
2329 { 4*DS, "4*DS" },
2330 { 4*ES, "4*ES" },
2331 { 4*FS, "4*FS" },
2332 { 4*GS, "4*GS" },
2333 { 4*ORIG_EAX, "4*ORIG_EAX" },
2334 { 4*EIP, "4*EIP" },
2335 { 4*CS, "4*CS" },
2336 { 4*EFL, "4*EFL" },
2337 { 4*UESP, "4*UESP" },
2338 { 4*SS, "4*SS" },
2339#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002340#ifdef X86_64
2341 { 8*RDI, "8*RDI" },
2342 { 8*RSI, "8*RSI" },
2343 { 8*RDX, "8*RDX" },
2344 { 8*R10, "8*R10" },
2345 { 8*R8, "8*R8" },
2346 { 8*R9, "8*R9" },
2347 { 8*RBX, "8*RBX" },
2348 { 8*RCX, "8*RCX" },
2349 { 8*RBP, "8*RBP" },
2350 { 8*RAX, "8*RAX" },
2351#if 0
2352 { 8*DS, "8*DS" },
2353 { 8*ES, "8*ES" },
2354 { 8*FS, "8*FS" },
2355 { 8*GS, "8*GS" },
2356#endif
2357 { 8*ORIG_RAX, "8*ORIG_EAX" },
2358 { 8*RIP, "8*RIP" },
2359 { 8*CS, "8*CS" },
2360 { 8*EFLAGS, "8*EFL" },
2361 { 8*RSP, "8*RSP" },
2362 { 8*SS, "8*SS" },
2363 { 8*R11, "8*R11" },
2364 { 8*R12, "8*R12" },
2365 { 8*R13, "8*R13" },
2366 { 8*R14, "8*R14" },
2367 { 8*R15, "8*R15" },
2368#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002369#ifdef M68K
2370 { 4*PT_D1, "4*PT_D1" },
2371 { 4*PT_D2, "4*PT_D2" },
2372 { 4*PT_D3, "4*PT_D3" },
2373 { 4*PT_D4, "4*PT_D4" },
2374 { 4*PT_D5, "4*PT_D5" },
2375 { 4*PT_D6, "4*PT_D6" },
2376 { 4*PT_D7, "4*PT_D7" },
2377 { 4*PT_A0, "4*PT_A0" },
2378 { 4*PT_A1, "4*PT_A1" },
2379 { 4*PT_A2, "4*PT_A2" },
2380 { 4*PT_A3, "4*PT_A3" },
2381 { 4*PT_A4, "4*PT_A4" },
2382 { 4*PT_A5, "4*PT_A5" },
2383 { 4*PT_A6, "4*PT_A6" },
2384 { 4*PT_D0, "4*PT_D0" },
2385 { 4*PT_USP, "4*PT_USP" },
2386 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2387 { 4*PT_SR, "4*PT_SR" },
2388 { 4*PT_PC, "4*PT_PC" },
2389#endif /* M68K */
2390#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002391#ifdef SH
2392 { 4*REG_REG0, "4*REG_REG0" },
2393 { 4*(REG_REG0+1), "4*REG_REG1" },
2394 { 4*(REG_REG0+2), "4*REG_REG2" },
2395 { 4*(REG_REG0+3), "4*REG_REG3" },
2396 { 4*(REG_REG0+4), "4*REG_REG4" },
2397 { 4*(REG_REG0+5), "4*REG_REG5" },
2398 { 4*(REG_REG0+6), "4*REG_REG6" },
2399 { 4*(REG_REG0+7), "4*REG_REG7" },
2400 { 4*(REG_REG0+8), "4*REG_REG8" },
2401 { 4*(REG_REG0+9), "4*REG_REG9" },
2402 { 4*(REG_REG0+10), "4*REG_REG10" },
2403 { 4*(REG_REG0+11), "4*REG_REG11" },
2404 { 4*(REG_REG0+12), "4*REG_REG12" },
2405 { 4*(REG_REG0+13), "4*REG_REG13" },
2406 { 4*(REG_REG0+14), "4*REG_REG14" },
2407 { 4*REG_REG15, "4*REG_REG15" },
2408 { 4*REG_PC, "4*REG_PC" },
2409 { 4*REG_PR, "4*REG_PR" },
2410 { 4*REG_SR, "4*REG_SR" },
2411 { 4*REG_GBR, "4*REG_GBR" },
2412 { 4*REG_MACH, "4*REG_MACH" },
2413 { 4*REG_MACL, "4*REG_MACL" },
2414 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2415 { 4*REG_FPUL, "4*REG_FPUL" },
2416 { 4*REG_FPREG0, "4*REG_FPREG0" },
2417 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2418 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2419 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2420 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2421 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2422 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2423 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2424 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2425 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2426 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2427 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2428 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2429 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2430 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2431 { 4*REG_FPREG15, "4*REG_FPREG15" },
2432 { 4*REG_XDREG0, "4*REG_XDREG0" },
2433 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2434 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2435 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2436 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2437 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2438 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2439 { 4*REG_XDREG14, "4*REG_XDREG14" },
2440 { 4*REG_FPSCR, "4*REG_FPSCR" },
2441#endif /* SH */
2442
Michal Ludvig10a88d02002-10-07 14:31:00 +00002443#if !defined(S390) && !defined(S390X) && !defined(MIPS)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002444 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002445#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002446#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002447 { uoff(i387), "offsetof(struct user, i387)" },
2448#else /* !I386 */
2449#ifdef M68K
2450 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2451#endif /* M68K */
2452#endif /* !I386 */
2453 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2454 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2455 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2456 { uoff(start_code), "offsetof(struct user, start_code)" },
2457 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2458 { uoff(signal), "offsetof(struct user, signal)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002459#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002460 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002461#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002462 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002463#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002464 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2465#endif
2466 { uoff(magic), "offsetof(struct user, magic)" },
2467 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002468#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002469 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2470#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002471#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002472#endif /* !ALPHA */
2473#endif /* !POWERPC/!SPARC */
2474#endif /* LINUX */
2475#ifdef SUNOS4
2476 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2477 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2478 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2479 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2480 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2481 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2482 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2483 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2484 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2485 { uoff(u_error), "offsetof(struct user, u_error)" },
2486 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2487 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2488 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2489 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2490 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2491 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2492 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2493 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2494 { uoff(u_code), "offsetof(struct user, u_code)" },
2495 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2496 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2497 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2498 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2499 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2500 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2501 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2502 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2503 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2504 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2505 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2506 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2507 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2508 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2509 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2510 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2511 { uoff(u_start), "offsetof(struct user, u_start)" },
2512 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2513 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2514 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2515 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2516 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2517 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2518 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2519 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2520 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2521#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002522#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002523 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002524#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002525 { 0, NULL },
2526};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002527#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002528
2529int
2530sys_ptrace(tcp)
2531struct tcb *tcp;
2532{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002533 struct xlat *x;
2534 long addr;
2535
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002536 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002537 printxval(ptrace_cmds, tcp->u_arg[0],
2538#ifndef FREEBSD
2539 "PTRACE_???"
2540#else
2541 "PT_???"
2542#endif
2543 );
2544 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002545 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002546#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002547 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2548 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2549 for (x = struct_user_offsets; x->str; x++) {
2550 if (x->val >= addr)
2551 break;
2552 }
2553 if (!x->str)
2554 tprintf("%#lx, ", addr);
2555 else if (x->val > addr && x != struct_user_offsets) {
2556 x--;
2557 tprintf("%s + %ld, ", x->str, addr - x->val);
2558 }
2559 else
2560 tprintf("%s, ", x->str);
2561 }
2562 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002563#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002564 tprintf("%#lx, ", tcp->u_arg[2]);
2565#ifdef LINUX
2566 switch (tcp->u_arg[0]) {
2567 case PTRACE_PEEKDATA:
2568 case PTRACE_PEEKTEXT:
2569 case PTRACE_PEEKUSER:
2570 break;
2571 case PTRACE_CONT:
2572 case PTRACE_SINGLESTEP:
2573 case PTRACE_SYSCALL:
2574 case PTRACE_DETACH:
2575 printsignal(tcp->u_arg[3]);
2576 break;
2577 default:
2578 tprintf("%#lx", tcp->u_arg[3]);
2579 break;
2580 }
2581 } else {
2582 switch (tcp->u_arg[0]) {
2583 case PTRACE_PEEKDATA:
2584 case PTRACE_PEEKTEXT:
2585 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00002586 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002587 break;
2588 }
2589 }
2590#endif /* LINUX */
2591#ifdef SUNOS4
2592 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2593 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2594 tprintf("%lu, ", tcp->u_arg[3]);
2595 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2596 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2597 tcp->u_arg[0] != PTRACE_READTEXT) {
2598 tprintf("%#lx", tcp->u_arg[3]);
2599 }
2600 } else {
2601 if (tcp->u_arg[0] == PTRACE_READDATA ||
2602 tcp->u_arg[0] == PTRACE_READTEXT) {
2603 tprintf("%lu, ", tcp->u_arg[3]);
2604 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2605 }
2606 }
2607#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002608#ifdef FREEBSD
2609 tprintf("%lu", tcp->u_arg[3]);
2610 }
2611#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002612 return 0;
2613}
2614
2615#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002616
2617#ifdef LINUX
2618static struct xlat futexops[] = {
2619 { FUTEX_WAIT, "FUTEX_WAIT" },
2620 { FUTEX_WAKE, "FUTEX_WAKE" },
2621 { FUTEX_FD, "FUTEX_FD" },
2622 { 0, NULL }
2623};
2624
2625int
2626sys_futex(tcp)
2627struct tcb *tcp;
2628{
2629 if (entering(tcp)) {
2630 tprintf("%p, ", (void *) tcp->u_arg[0]);
2631 printflags(futexops, tcp->u_arg[1]);
2632 tprintf(", %ld, ", tcp->u_arg[2]);
2633 printtv(tcp, tcp->u_arg[3]);
2634 }
2635 return 0;
2636}
2637
2638static void
2639print_affinitylist(list, len)
2640unsigned long *list;
2641unsigned int len;
2642{
2643 int first = 1;
2644 tprintf(" {");
2645 while (len > sizeof (unsigned long)) {
2646 tprintf("%s %lx", first ? "" : ",", *list++);
2647 first = 0;
2648 len -= sizeof (unsigned long);
2649 }
2650 tprintf(" }");
2651}
2652
2653int
2654sys_sched_setaffinity(tcp)
2655struct tcb *tcp;
2656{
2657 if (entering(tcp)) {
2658 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2659 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2660 }
2661 return 0;
2662}
2663
2664int
2665sys_sched_getaffinity(tcp)
2666struct tcb *tcp;
2667{
2668 if (entering(tcp)) {
2669 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2670 } else {
2671 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);
2672 }
2673 return 0;
2674}
2675#endif