blob: 633a5820d9db847ebc5d3635d0385f3e8cbb6d50 [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
Roland McGrathbf621d42003-01-14 09:46:21 +000073#ifdef HAVE_LINUX_PTRACE_H
74#undef PTRACE_SYSCALL
75#include <linux/ptrace.h>
76#endif
77
Wichert Akkerman36915a11999-07-13 15:45:02 +000078#ifdef HAVE_SYS_REG_H
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000079# include <sys/reg.h>
Wichert Akkerman15dea971999-10-06 13:06:34 +000080#ifndef PTRACE_PEEKUSR
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000081# define PTRACE_PEEKUSR PTRACE_PEEKUSER
Wichert Akkerman15dea971999-10-06 13:06:34 +000082#endif
83#ifndef PTRACE_POKEUSR
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000084# define PTRACE_POKEUSR PTRACE_POKEUSER
85#endif
Wichert Akkerman15dea971999-10-06 13:06:34 +000086#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000087
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)) {
454 if (getrval2(tcp))
455 return 0;
456 if (!followfork)
457 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000458 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000459 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000460 if (syserror(tcp))
461 return 0;
462 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
463 fprintf(stderr, "sys_fork: tcb table full\n");
464 return 0;
465 }
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000466 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000467 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000468 }
469 return 0;
470}
471
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000472#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000473
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000474#ifdef LINUX
475
476/* defines copied from linux/sched.h since we can't include that
477 * ourselves (it conflicts with *lots* of libc includes)
478 */
479#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
480#define CLONE_VM 0x00000100 /* set if VM shared between processes */
481#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
482#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
483#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000484#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000485#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
486#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
487#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000488#define CLONE_THREAD 0x00010000 /* Same thread group? */
489#define CLONE_NEWNS 0x00020000 /* New namespace group? */
490#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
491#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
492#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
493#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
494#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
495#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
496#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000497
498static struct xlat clone_flags[] = {
499 { CLONE_VM, "CLONE_VM" },
500 { CLONE_FS, "CLONE_FS" },
501 { CLONE_FILES, "CLONE_FILES" },
502 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000503 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000504 { CLONE_PTRACE, "CLONE_PTRACE" },
505 { CLONE_VFORK, "CLONE_VFORK" },
506 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000507 { CLONE_THREAD, "CLONE_THREAD" },
508 { CLONE_NEWNS, "CLONE_NEWNS" },
509 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
510 { CLONE_SETTLS, "CLONE_SETTLS" },
511 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
512 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
513 { CLONE_DETACHED, "CLONE_DETACHED" },
514 { CLONE_UNTRACED, "CLONE_UNTRACED" },
515 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000516 { 0, NULL },
517};
518
Roland McGrath909875b2002-12-22 03:34:36 +0000519# ifdef I386
520# include <asm/ldt.h>
521extern void print_ldt_entry();
522# endif
523
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000524int
525sys_clone(tcp)
526struct tcb *tcp;
527{
528 if (exiting(tcp)) {
529 tprintf("child_stack=%#lx, flags=", tcp->u_arg[1]);
530 if (printflags(clone_flags, tcp->u_arg[0]) == 0)
531 tprintf("0");
Roland McGrath909875b2002-12-22 03:34:36 +0000532 if ((tcp->u_arg[0] & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
533 |CLONE_SETTLS)) == 0)
534 return 0;
535 if (tcp->u_arg[0] & CLONE_PARENT_SETTID) {
536 int pid;
537 if (umove(tcp, tcp->u_arg[2], &pid) == 0)
538 tprintf(", [%d]", pid);
539 else
540 tprintf(", %#lx", tcp->u_arg[2]);
541 }
542 else
543 tprintf(", <ignored>");
544#ifdef I386
545 if (tcp->u_arg[0] & CLONE_SETTLS) {
546 struct modify_ldt_ldt_s copy;
547 if (umove(tcp, tcp->u_arg[3], &copy) != -1) {
548 tprintf(", {entry_number:%d, ",
549 copy.entry_number);
550 if (!verbose(tcp))
551 tprintf("...}");
552 else
553 print_ldt_entry(&copy);
554 }
555 else
556 tprintf(", %#lx", tcp->u_arg[3]);
557 }
558 else
559 tprintf(", <ignored>");
560# define TIDARG 4
561#else
562# define TIDARG 3
563#endif
564 if (tcp->u_arg[0] & CLONE_CHILD_SETTID)
565 tprintf(", %#lx", tcp->u_arg[TIDARG]);
566#undef TIDARG
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000567 }
568 return 0;
569}
570
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000571int
572sys_clone2(tcp)
573struct tcb *tcp;
574{
575 if (exiting(tcp)) {
576 tprintf("child_stack=%#lx, stack_size=%#lx, flags=",
577 tcp->u_arg[1], tcp->u_arg[2]);
578 if (printflags(clone_flags, tcp->u_arg[0]) == 0)
579 tprintf("0");
580 }
581 return 0;
582}
583
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000584#endif
585
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000586int
587sys_fork(tcp)
588struct tcb *tcp;
589{
590 if (exiting(tcp))
591 return RVAL_UDECIMAL;
592 return 0;
593}
594
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000595int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000596change_syscall(tcp, new)
597struct tcb *tcp;
598int new;
599{
600#if defined(LINUX)
601#if defined(I386)
602 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000603 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000604 return -1;
605 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000606#elif defined(X86_64)
607 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000608 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000609 return -1;
610 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000611#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000612 if (ptrace(PTRACE_POKEUSER, tcp->pid,
613 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000614 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000615 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000616#elif defined(S390) || defined(S390X)
617 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
618 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
619 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000620 return 0;
621#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000622 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000623 return -1;
624 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000625#elif defined(SPARC)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000626 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000627 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
628 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000629 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000630 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
631 return -1;
632 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000633#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000634 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000635 return -1;
636 return 0;
637#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000638 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000639 return -1;
640 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000641#elif defined(IA64)
642 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
643 return -1;
644 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000645#elif defined(HPPA)
646 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
647 return -1;
648 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000649#elif defined(SH)
650 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), new)<0)
651 return -1;
652 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000653#else
654#warning Do not know how to handle change_syscall for this architecture
655#endif /* architecture */
656#endif /* LINUX */
657 return -1;
658}
659
660int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000661setarg(tcp, argnum)
662 struct tcb *tcp;
663 int argnum;
664{
665#if defined (IA64)
666 {
667 unsigned long *bsp, *ap;
668
669 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
670 return -1;
671
672 ap = ia64_rse_skip_regs(bsp, argnum);
673 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000674 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000675 if (errno)
676 return -1;
677
678 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000679#elif defined(I386)
680 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000681 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000682 if (errno)
683 return -1;
684 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000685#elif defined(X86_64)
686 {
687 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
688 if (errno)
689 return -1;
690 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000691#elif defined(POWERPC)
692#ifndef PT_ORIG_R3
693#define PT_ORIG_R3 34
694#endif
695 {
696 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000697 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000698 tcp->u_arg[argnum]);
699 if (errno)
700 return -1;
701 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000702#elif defined(MIPS)
703 {
704 errno = 0;
705 if (argnum < 4)
706 ptrace(PTRACE_POKEUSER, tcp->pid,
707 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
708 else {
709 unsigned long *sp;
710
711 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
712 return -1;
713
714 ptrace(PTRACE_POKEDATA, tcp->pid,
715 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
716 }
717 if (errno)
718 return -1;
719 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000720#elif defined(S390) || defined(S390X)
721 {
722 if(argnum <= 5)
723 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000724 (char *) (argnum==0 ? PT_ORIGGPR2 :
725 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000726 tcp->u_arg[argnum]);
727 else
728 return -E2BIG;
729 if (errno)
730 return -1;
731 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000732#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000733# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000734#endif
735 return 0;
736}
737
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000738#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000739int
740internal_clone(tcp)
741struct tcb *tcp;
742{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000743 struct tcb *tcpchild;
744 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000745 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000746 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000747 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000748 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000749 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000750 if (setbpt(tcp) < 0)
751 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000752 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000753 int bpt = tcp->flags & TCB_BPTSET;
754
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000755 if (!(tcp->flags & TCB_FOLLOWFORK))
756 return 0;
757
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000758 if (syserror(tcp)) {
759 if (bpt)
760 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000761 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000762 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000763
764 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000765
766#ifdef CLONE_PTRACE /* See new setbpt code. */
767 tcpchild = pid2tcb(pid);
768 if (tcpchild != NULL) {
769 /* The child already reported its startup trap
770 before the parent reported its syscall return. */
771 if ((tcpchild->flags
772 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
773 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
774 fprintf(stderr, "\
775[preattached child %d of %d in weird state!]\n",
776 pid, tcp->pid);
777 }
778 else
779#endif
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000780 if ((tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000781 if (bpt)
782 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000783 fprintf(stderr, " [tcb table full]\n");
784 kill(pid, SIGKILL); /* XXX */
785 return 0;
786 }
787
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000788#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000789 /* Attach to the new child */
790 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000791 if (bpt)
792 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000793 perror("PTRACE_ATTACH");
794 fprintf(stderr, "Too late?\n");
795 droptcb(tcpchild);
796 return 0;
797 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000798#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000799
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000800 if (bpt)
801 clearbpt(tcp);
802
Ulrich Drepper90512f01999-12-24 07:22:25 +0000803 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000804 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000805 if (bpt) {
806 tcpchild->flags |= TCB_BPTSET;
807 tcpchild->baddr = tcp->baddr;
808 memcpy(tcpchild->inst, tcp->inst,
809 sizeof tcpchild->inst);
810 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000811 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000812 tcp->nchildren++;
813 if (tcpchild->flags & TCB_SUSPENDED) {
814 /* The child was born suspended, due to our having
815 forced CLONE_PTRACE. */
816 if (bpt)
817 clearbpt(tcpchild);
818
819 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
820 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
821 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
822 return -1;
823 }
824
825 if (!qflag)
826 fprintf(stderr, "\
827Process %u resumed (parent %d ready)\n",
828 pid, tcp->pid);
829 }
830 else {
831 newoutf(tcpchild);
832 if (!qflag)
833 fprintf(stderr, "Process %d attached\n", pid);
834 }
835
836#ifdef TCB_CLONE_THREAD
837 if ((tcp->flags & TCB_CLONE_THREAD) && tcp->parent != NULL) {
838 /* The parent in this clone is itself a thread
839 belonging to another process. There is no
840 meaning to the parentage relationship of the new
841 child with the thread, only with the process.
842 We associate the new thread with our parent.
843 Since this is done for every new thread, there
844 will never be a TCB_CLONE_THREAD process that
845 has children. */
846 --tcp->nchildren;
847 tcp->u_arg[0] = tcp->parent->u_arg[0];
848 tcp = tcp->parent;
849 tcpchild->parent = tcp;
850 ++tcp->nchildren;
851 }
852
853 if (tcp->u_arg[0] & CLONE_THREAD) {
854 tcpchild->flags |= TCB_CLONE_THREAD;
855 ++tcp->nclone_threads;
856 }
857 if (tcp->u_arg[0] & CLONE_DETACHED) {
858 tcpchild->flags |= TCB_CLONE_DETACHED;
859 ++tcp->nclone_detached;
860 }
861#endif
862
863 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000864 return 0;
865}
866#endif
867
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000868int
869internal_fork(tcp)
870struct tcb *tcp;
871{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000872#ifdef LINUX
873 /* We do special magic with clone for any clone or fork. */
874 return internal_clone(tcp);
875#else
876
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000877 struct tcb *tcpchild;
878 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000879 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000880
881#ifdef SYS_vfork
Nate Sammonsccd8f211999-03-29 22:57:54 +0000882 if (tcp->scno == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000883 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000884 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000885 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000886 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000887 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000888#endif
889 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000890 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000891 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000892 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000893 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000894 if (setbpt(tcp) < 0)
895 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000896 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000897 else {
898 int bpt = tcp->flags & TCB_BPTSET;
899
900 if (!(tcp->flags & TCB_FOLLOWFORK))
901 return 0;
902 if (bpt)
903 clearbpt(tcp);
904
905 if (syserror(tcp))
906 return 0;
907
908 pid = tcp->u_rval;
909 if ((tcpchild = alloctcb(pid)) == NULL) {
910 fprintf(stderr, " [tcb table full]\n");
911 kill(pid, SIGKILL); /* XXX */
912 return 0;
913 }
914#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000915#ifdef HPPA
916 /* The child must have run before it can be attached. */
917 /* This must be a bug in the parisc kernel, but I havn't
918 * identified it yet. Seems to be an issue associated
919 * with attaching to a process (which sends it a signal)
920 * before that process has ever been scheduled. When
921 * debugging, I started seeing crashes in
922 * arch/parisc/kernel/signal.c:do_signal(), apparently
923 * caused by r8 getting corrupt over the dequeue_signal()
924 * call. Didn't make much sense though...
925 */
926 {
927 struct timeval tv;
928 tv.tv_sec = 0;
929 tv.tv_usec = 10000;
930 select(0, NULL, NULL, NULL, &tv);
931 }
932#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000933 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
934 perror("PTRACE_ATTACH");
935 fprintf(stderr, "Too late?\n");
936 droptcb(tcpchild);
937 return 0;
938 }
939#endif /* LINUX */
940#ifdef SUNOS4
941#ifdef oldway
942 /* The child must have run before it can be attached. */
943 {
944 struct timeval tv;
945 tv.tv_sec = 0;
946 tv.tv_usec = 10000;
947 select(0, NULL, NULL, NULL, &tv);
948 }
949 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
950 perror("PTRACE_ATTACH");
951 fprintf(stderr, "Too late?\n");
952 droptcb(tcpchild);
953 return 0;
954 }
955#else /* !oldway */
956 /* Try to catch the new process as soon as possible. */
957 {
958 int i;
959 for (i = 0; i < 1024; i++)
960 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
961 break;
962 if (i == 1024) {
963 perror("PTRACE_ATTACH");
964 fprintf(stderr, "Too late?\n");
965 droptcb(tcpchild);
966 return 0;
967 }
968 }
969#endif /* !oldway */
970#endif /* SUNOS4 */
971 tcpchild->flags |= TCB_ATTACHED;
972 /* Child has BPT too, must be removed on first occasion */
973 if (bpt) {
974 tcpchild->flags |= TCB_BPTSET;
975 tcpchild->baddr = tcp->baddr;
976 memcpy(tcpchild->inst, tcp->inst,
977 sizeof tcpchild->inst);
978 }
979 newoutf(tcpchild);
980 tcpchild->parent = tcp;
981 tcp->nchildren++;
982 if (!qflag)
983 fprintf(stderr, "Process %d attached\n", pid);
984 }
985 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000986#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000987}
988
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000989#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000990
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000991#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000992
993int
994sys_vfork(tcp)
995struct tcb *tcp;
996{
997 if (exiting(tcp))
998 return RVAL_UDECIMAL;
999 return 0;
1000}
1001
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001002#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001003
1004#ifndef LINUX
1005
1006static char idstr[16];
1007
1008int
1009sys_getpid(tcp)
1010struct tcb *tcp;
1011{
1012 if (exiting(tcp)) {
1013 sprintf(idstr, "ppid %lu", getrval2(tcp));
1014 tcp->auxstr = idstr;
1015 return RVAL_STR;
1016 }
1017 return 0;
1018}
1019
1020int
1021sys_getuid(tcp)
1022struct tcb *tcp;
1023{
1024 if (exiting(tcp)) {
1025 sprintf(idstr, "euid %lu", getrval2(tcp));
1026 tcp->auxstr = idstr;
1027 return RVAL_STR;
1028 }
1029 return 0;
1030}
1031
1032int
1033sys_getgid(tcp)
1034struct tcb *tcp;
1035{
1036 if (exiting(tcp)) {
1037 sprintf(idstr, "egid %lu", getrval2(tcp));
1038 tcp->auxstr = idstr;
1039 return RVAL_STR;
1040 }
1041 return 0;
1042}
1043
1044#endif /* !LINUX */
1045
1046#ifdef LINUX
1047
1048int
1049sys_setuid(tcp)
1050struct tcb *tcp;
1051{
1052 if (entering(tcp)) {
1053 tprintf("%u", (uid_t) tcp->u_arg[0]);
1054 }
1055 return 0;
1056}
1057
1058int
1059sys_setgid(tcp)
1060struct tcb *tcp;
1061{
1062 if (entering(tcp)) {
1063 tprintf("%u", (gid_t) tcp->u_arg[0]);
1064 }
1065 return 0;
1066}
1067
1068int
1069sys_getresuid(tcp)
1070 struct tcb *tcp;
1071{
1072 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001073 __kernel_uid_t uid;
1074 if (syserror(tcp))
1075 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1076 tcp->u_arg[1], tcp->u_arg[2]);
1077 else {
1078 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1079 tprintf("%#lx, ", tcp->u_arg[0]);
1080 else
1081 tprintf("ruid %lu, ", (unsigned long) uid);
1082 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1083 tprintf("%#lx, ", tcp->u_arg[0]);
1084 else
1085 tprintf("euid %lu, ", (unsigned long) uid);
1086 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1087 tprintf("%#lx", tcp->u_arg[0]);
1088 else
1089 tprintf("suid %lu", (unsigned long) uid);
1090 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001091 }
1092 return 0;
1093}
1094
1095int
1096sys_getresgid(tcp)
1097struct tcb *tcp;
1098{
1099 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001100 __kernel_gid_t gid;
1101 if (syserror(tcp))
1102 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1103 tcp->u_arg[1], tcp->u_arg[2]);
1104 else {
1105 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1106 tprintf("%#lx, ", tcp->u_arg[0]);
1107 else
1108 tprintf("rgid %lu, ", (unsigned long) gid);
1109 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1110 tprintf("%#lx, ", tcp->u_arg[0]);
1111 else
1112 tprintf("egid %lu, ", (unsigned long) gid);
1113 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1114 tprintf("%#lx", tcp->u_arg[0]);
1115 else
1116 tprintf("sgid %lu", (unsigned long) gid);
1117 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001118 }
1119 return 0;
1120}
1121
1122#endif /* LINUX */
1123
1124int
1125sys_setreuid(tcp)
1126struct tcb *tcp;
1127{
1128 if (entering(tcp)) {
1129 tprintf("%lu, %lu",
1130 (unsigned long) (uid_t) tcp->u_arg[0],
1131 (unsigned long) (uid_t) tcp->u_arg[1]);
1132 }
1133 return 0;
1134}
1135
1136int
1137sys_setregid(tcp)
1138struct tcb *tcp;
1139{
1140 if (entering(tcp)) {
1141 tprintf("%lu, %lu",
1142 (unsigned long) (gid_t) tcp->u_arg[0],
1143 (unsigned long) (gid_t) tcp->u_arg[1]);
1144 }
1145 return 0;
1146}
1147
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001148#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001149int
1150sys_setresuid(tcp)
1151 struct tcb *tcp;
1152{
1153 if (entering(tcp)) {
1154 tprintf("ruid %u, euid %u, suid %u",
1155 (uid_t) tcp->u_arg[0],
1156 (uid_t) tcp->u_arg[1],
1157 (uid_t) tcp->u_arg[2]);
1158 }
1159 return 0;
1160}
1161int
1162sys_setresgid(tcp)
1163 struct tcb *tcp;
1164{
1165 if (entering(tcp)) {
1166 tprintf("rgid %u, egid %u, sgid %u",
1167 (uid_t) tcp->u_arg[0],
1168 (uid_t) tcp->u_arg[1],
1169 (uid_t) tcp->u_arg[2]);
1170 }
1171 return 0;
1172}
1173
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001174#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001175
1176int
1177sys_setgroups(tcp)
1178struct tcb *tcp;
1179{
1180 int i, len;
1181 GETGROUPS_T *gidset;
1182
1183 if (entering(tcp)) {
1184 len = tcp->u_arg[0];
1185 tprintf("%u, ", len);
1186 if (len <= 0) {
1187 tprintf("[]");
1188 return 0;
1189 }
1190 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1191 if (gidset == NULL) {
1192 fprintf(stderr, "sys_setgroups: out of memory\n");
1193 return -1;
1194 }
1195 if (!verbose(tcp))
1196 tprintf("%#lx", tcp->u_arg[1]);
1197 else if (umoven(tcp, tcp->u_arg[1],
1198 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1199 tprintf("[?]");
1200 else {
1201 tprintf("[");
1202 for (i = 0; i < len; i++)
1203 tprintf("%s%lu", i ? ", " : "",
1204 (unsigned long) gidset[i]);
1205 tprintf("]");
1206 }
1207 free((char *) gidset);
1208 }
1209 return 0;
1210}
1211
1212int
1213sys_getgroups(tcp)
1214struct tcb *tcp;
1215{
1216 int i, len;
1217 GETGROUPS_T *gidset;
1218
1219 if (entering(tcp)) {
1220 len = tcp->u_arg[0];
1221 tprintf("%u, ", len);
1222 } else {
1223 len = tcp->u_rval;
1224 if (len <= 0) {
1225 tprintf("[]");
1226 return 0;
1227 }
1228 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1229 if (gidset == NULL) {
1230 fprintf(stderr, "sys_getgroups: out of memory\n");
1231 return -1;
1232 }
1233 if (!tcp->u_arg[1])
1234 tprintf("NULL");
1235 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1236 tprintf("%#lx", tcp->u_arg[1]);
1237 else if (umoven(tcp, tcp->u_arg[1],
1238 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1239 tprintf("[?]");
1240 else {
1241 tprintf("[");
1242 for (i = 0; i < len; i++)
1243 tprintf("%s%lu", i ? ", " : "",
1244 (unsigned long) gidset[i]);
1245 tprintf("]");
1246 }
1247 free((char *)gidset);
1248 }
1249 return 0;
1250}
1251
1252int
1253sys_setpgrp(tcp)
1254struct tcb *tcp;
1255{
1256 if (entering(tcp)) {
1257#ifndef SVR4
1258 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1259#endif /* !SVR4 */
1260 }
1261 return 0;
1262}
1263
1264int
1265sys_getpgrp(tcp)
1266struct tcb *tcp;
1267{
1268 if (entering(tcp)) {
1269#ifndef SVR4
1270 tprintf("%lu", tcp->u_arg[0]);
1271#endif /* !SVR4 */
1272 }
1273 return 0;
1274}
1275
1276int
1277sys_getsid(tcp)
1278struct tcb *tcp;
1279{
1280 if (entering(tcp)) {
1281 tprintf("%lu", tcp->u_arg[0]);
1282 }
1283 return 0;
1284}
1285
1286int
1287sys_setsid(tcp)
1288struct tcb *tcp;
1289{
1290 return 0;
1291}
1292
1293int
1294sys_getpgid(tcp)
1295struct tcb *tcp;
1296{
1297 if (entering(tcp)) {
1298 tprintf("%lu", tcp->u_arg[0]);
1299 }
1300 return 0;
1301}
1302
1303int
1304sys_setpgid(tcp)
1305struct tcb *tcp;
1306{
1307 if (entering(tcp)) {
1308 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1309 }
1310 return 0;
1311}
1312
John Hughesc61eb3d2002-05-17 11:37:50 +00001313#if UNIXWARE >= 2
1314
1315#include <sys/privilege.h>
1316
1317
1318static struct xlat procpriv_cmds [] = {
1319 { SETPRV, "SETPRV" },
1320 { CLRPRV, "CLRPRV" },
1321 { PUTPRV, "PUTPRV" },
1322 { GETPRV, "GETPRV" },
1323 { CNTPRV, "CNTPRV" },
1324 { 0, NULL },
1325};
1326
1327
1328static struct xlat procpriv_priv [] = {
1329 { P_OWNER, "P_OWNER" },
1330 { P_AUDIT, "P_AUDIT" },
1331 { P_COMPAT, "P_COMPAT" },
1332 { P_DACREAD, "P_DACREAD" },
1333 { P_DACWRITE, "P_DACWRITE" },
1334 { P_DEV, "P_DEV" },
1335 { P_FILESYS, "P_FILESYS" },
1336 { P_MACREAD, "P_MACREAD" },
1337 { P_MACWRITE, "P_MACWRITE" },
1338 { P_MOUNT, "P_MOUNT" },
1339 { P_MULTIDIR, "P_MULTIDIR" },
1340 { P_SETPLEVEL, "P_SETPLEVEL" },
1341 { P_SETSPRIV, "P_SETSPRIV" },
1342 { P_SETUID, "P_SETUID" },
1343 { P_SYSOPS, "P_SYSOPS" },
1344 { P_SETUPRIV, "P_SETUPRIV" },
1345 { P_DRIVER, "P_DRIVER" },
1346 { P_RTIME, "P_RTIME" },
1347 { P_MACUPGRADE, "P_MACUPGRADE" },
1348 { P_FSYSRANGE, "P_FSYSRANGE" },
1349 { P_SETFLEVEL, "P_SETFLEVEL" },
1350 { P_AUDITWR, "P_AUDITWR" },
1351 { P_TSHAR, "P_TSHAR" },
1352 { P_PLOCK, "P_PLOCK" },
1353 { P_CORE, "P_CORE" },
1354 { P_LOADMOD, "P_LOADMOD" },
1355 { P_BIND, "P_BIND" },
1356 { P_ALLPRIVS, "P_ALLPRIVS" },
1357 { 0, NULL },
1358};
1359
1360
1361static struct xlat procpriv_type [] = {
1362 { PS_FIX, "PS_FIX" },
1363 { PS_INH, "PS_INH" },
1364 { PS_MAX, "PS_MAX" },
1365 { PS_WKG, "PS_WKG" },
1366 { 0, NULL },
1367};
1368
1369
1370static void
1371printpriv(tcp, addr, len, opt)
1372struct tcb *tcp;
1373long addr;
1374int len;
1375struct xlat *opt;
1376{
1377 priv_t buf [128];
1378 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1379 int dots = len > max;
1380 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001381
John Hughesc61eb3d2002-05-17 11:37:50 +00001382 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001383
John Hughesc61eb3d2002-05-17 11:37:50 +00001384 if (len <= 0 ||
1385 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1386 {
1387 tprintf ("%#lx", addr);
1388 return;
1389 }
1390
1391 tprintf ("[");
1392
1393 for (i = 0; i < len; ++i) {
1394 char *t, *p;
1395
1396 if (i) tprintf (", ");
1397
1398 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1399 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1400 {
1401 tprintf ("%s|%s", t, p);
1402 }
1403 else {
1404 tprintf ("%#lx", buf [i]);
1405 }
1406 }
1407
1408 if (dots) tprintf (" ...");
1409
1410 tprintf ("]");
1411}
1412
1413
1414int
1415sys_procpriv(tcp)
1416struct tcb *tcp;
1417{
1418 if (entering(tcp)) {
1419 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1420 switch (tcp->u_arg[0]) {
1421 case CNTPRV:
1422 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1423 break;
1424
1425 case GETPRV:
1426 break;
1427
1428 default:
1429 tprintf (", ");
1430 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1431 tprintf (", %ld", tcp->u_arg[2]);
1432 }
1433 }
1434 else if (tcp->u_arg[0] == GETPRV) {
1435 if (syserror (tcp)) {
1436 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1437 }
1438 else {
1439 tprintf (", ");
1440 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1441 tprintf (", %ld", tcp->u_arg[2]);
1442 }
1443 }
Roland McGrath5a223472002-12-15 23:58:26 +00001444
John Hughesc61eb3d2002-05-17 11:37:50 +00001445 return 0;
1446}
1447
1448#endif
1449
1450
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001451void
1452fake_execve(tcp, program, argv, envp)
1453struct tcb *tcp;
1454char *program;
1455char *argv[];
1456char *envp[];
1457{
1458 int i;
1459
1460#ifdef ARM
1461 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1462 return;
1463#else
1464 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1465 return;
1466#endif /* !ARM */
1467 printleader(tcp);
1468 tprintf("execve(");
1469 string_quote(program);
1470 tprintf(", [");
1471 for (i = 0; argv[i] != NULL; i++) {
1472 if (i != 0)
1473 tprintf(", ");
1474 string_quote(argv[i]);
1475 }
1476 for (i = 0; envp[i] != NULL; i++)
1477 ;
1478 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1479 tabto(acolumn);
1480 tprintf("= 0");
1481 printtrailer(tcp);
1482}
1483
1484static void
1485printargv(tcp, addr)
1486struct tcb *tcp;
1487long addr;
1488{
1489 char *cp;
1490 char *sep;
1491 int max = max_strlen / 2;
1492
1493 for (sep = ""; --max >= 0; sep = ", ") {
1494 if (!abbrev(tcp))
1495 max++;
1496 if (umove(tcp, addr, &cp) < 0) {
1497 tprintf("%#lx", addr);
1498 return;
1499 }
1500 if (cp == 0)
1501 break;
1502 tprintf(sep);
1503 printstr(tcp, (long) cp, -1);
1504 addr += sizeof(char *);
1505 }
1506 if (cp)
1507 tprintf(", ...");
1508}
1509
1510static void
1511printargc(fmt, tcp, addr)
1512char *fmt;
1513struct tcb *tcp;
1514long addr;
1515{
1516 int count;
1517 char *cp;
1518
1519 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1520 addr += sizeof(char *);
1521 }
1522 tprintf(fmt, count, count == 1 ? "" : "s");
1523}
1524
1525int
1526sys_execv(tcp)
1527struct tcb *tcp;
1528{
1529 if (entering(tcp)) {
1530 printpath(tcp, tcp->u_arg[0]);
1531 if (!verbose(tcp))
1532 tprintf(", %#lx", tcp->u_arg[1]);
1533#if 0
1534 else if (abbrev(tcp))
1535 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1536#endif
1537 else {
1538 tprintf(", [");
1539 printargv(tcp, tcp->u_arg[1]);
1540 tprintf("]");
1541 }
1542 }
1543 return 0;
1544}
1545
1546int
1547sys_execve(tcp)
1548struct tcb *tcp;
1549{
1550 if (entering(tcp)) {
1551 printpath(tcp, tcp->u_arg[0]);
1552 if (!verbose(tcp))
1553 tprintf(", %#lx", tcp->u_arg[1]);
1554#if 0
1555 else if (abbrev(tcp))
1556 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1557#endif
1558 else {
1559 tprintf(", [");
1560 printargv(tcp, tcp->u_arg[1]);
1561 tprintf("]");
1562 }
1563 if (!verbose(tcp))
1564 tprintf(", %#lx", tcp->u_arg[2]);
1565 else if (abbrev(tcp))
1566 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1567 else {
1568 tprintf(", [");
1569 printargv(tcp, tcp->u_arg[2]);
1570 tprintf("]");
1571 }
1572 }
1573#ifdef LINUX
Wichert Akkermanccef6372002-05-01 16:39:22 +00001574#if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001575 tcp->flags |= TCB_WAITEXECVE;
Wichert Akkermanccef6372002-05-01 16:39:22 +00001576#endif /* ALPHA || SPARC || POWERPC || IA64 || HPPA || SH */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001577#endif /* LINUX */
1578 return 0;
1579}
1580
John Hughes4e36a812001-04-18 15:11:51 +00001581#if UNIXWARE > 2
1582
1583int sys_rexecve(tcp)
1584struct tcb *tcp;
1585{
1586 if (entering (tcp)) {
1587 sys_execve (tcp);
1588 tprintf (", %ld", tcp->u_arg[3]);
1589 }
1590 return 0;
1591}
1592
1593#endif
1594
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001595int
1596internal_exec(tcp)
1597struct tcb *tcp;
1598{
1599#ifdef SUNOS4
1600 if (exiting(tcp) && !syserror(tcp) && followfork)
1601 fixvfork(tcp);
1602#endif /* SUNOS4 */
1603 return 0;
1604}
1605
1606#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001607#ifndef __WNOTHREAD
1608#define __WNOTHREAD 0x20000000
1609#endif
1610#ifndef __WALL
1611#define __WALL 0x40000000
1612#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001613#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001614#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001615#endif
1616#endif /* LINUX */
1617
1618static struct xlat wait4_options[] = {
1619 { WNOHANG, "WNOHANG" },
1620#ifndef WSTOPPED
1621 { WUNTRACED, "WUNTRACED" },
1622#endif
1623#ifdef WEXITED
1624 { WEXITED, "WEXITED" },
1625#endif
1626#ifdef WTRAPPED
1627 { WTRAPPED, "WTRAPPED" },
1628#endif
1629#ifdef WSTOPPED
1630 { WSTOPPED, "WSTOPPED" },
1631#endif
1632#ifdef WCONTINUED
1633 { WCONTINUED, "WCONTINUED" },
1634#endif
1635#ifdef WNOWAIT
1636 { WNOWAIT, "WNOWAIT" },
1637#endif
1638#ifdef __WCLONE
1639 { __WCLONE, "__WCLONE" },
1640#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001641#ifdef __WALL
1642 { __WALL, "__WALL" },
1643#endif
1644#ifdef __WNOTHREAD
1645 { __WNOTHREAD, "__WNOTHREAD" },
1646#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001647 { 0, NULL },
1648};
1649
1650static int
1651printstatus(status)
1652int status;
1653{
1654 int exited = 0;
1655
1656 /*
1657 * Here is a tricky presentation problem. This solution
1658 * is still not entirely satisfactory but since there
1659 * are no wait status constructors it will have to do.
1660 */
1661 if (WIFSTOPPED(status))
1662 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001663 signame(WSTOPSIG(status)));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001664 else if WIFSIGNALED(status)
1665 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001666 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001667 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1668 else if WIFEXITED(status) {
1669 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1670 WEXITSTATUS(status));
1671 exited = 1;
1672 }
1673 else
1674 tprintf("[%#x]", status);
1675 return exited;
1676}
1677
1678static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001679printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001680struct tcb *tcp;
1681int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001682int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001683{
1684 int status;
1685 int exited = 0;
1686
1687 if (entering(tcp)) {
1688 tprintf("%ld, ", tcp->u_arg[0]);
1689 } else {
1690 /* status */
1691 if (!tcp->u_arg[1])
1692 tprintf("NULL");
1693 else if (syserror(tcp) || tcp->u_rval == 0)
1694 tprintf("%#lx", tcp->u_arg[1]);
1695 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1696 tprintf("[?]");
1697 else
1698 exited = printstatus(status);
1699 /* options */
1700 tprintf(", ");
1701 if (!printflags(wait4_options, tcp->u_arg[2]))
1702 tprintf("0");
1703 if (n == 4) {
1704 tprintf(", ");
1705 /* usage */
1706 if (!tcp->u_arg[3])
1707 tprintf("NULL");
1708#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001709 else if (tcp->u_rval > 0) {
1710#ifdef LINUX_64BIT
1711 if (bitness)
1712 printrusage32(tcp, tcp->u_arg[3]);
1713 else
1714#endif
1715 printrusage(tcp, tcp->u_arg[3]);
1716 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001717#endif /* LINUX */
1718#ifdef SUNOS4
1719 else if (tcp->u_rval > 0 && exited)
1720 printrusage(tcp, tcp->u_arg[3]);
1721#endif /* SUNOS4 */
1722 else
1723 tprintf("%#lx", tcp->u_arg[3]);
1724 }
1725 }
1726 return 0;
1727}
1728
1729int
1730internal_wait(tcp)
1731struct tcb *tcp;
1732{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001733 int got_kids;
1734
1735#ifdef TCB_CLONE_THREAD
1736 if (tcp->flags & TCB_CLONE_THREAD)
1737 /* The children we wait for are our parent's children. */
1738 got_kids = (tcp->parent->nchildren
1739 > tcp->parent->nclone_detached);
1740 else
1741 got_kids = (tcp->nchildren > tcp->nclone_detached);
1742#else
1743 got_kids = tcp->nchildren > 0;
1744#endif
1745
1746 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001747 /* There are children that this parent should block for.
1748 But ptrace made us the parent of the traced children
1749 and the real parent will get ECHILD from the wait call.
1750
1751 XXX If we attached with strace -f -p PID, then there
1752 may be untraced dead children the parent could be reaping
1753 now, but we make him block. */
1754
1755 /* ??? WTA: fix bug with hanging children */
1756
1757 if (!(tcp->u_arg[2] & WNOHANG)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001758 /* There are traced children */
1759 tcp->flags |= TCB_SUSPENDED;
1760 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001761#ifdef TCB_CLONE_THREAD
1762 if (tcp->flags & TCB_CLONE_THREAD)
1763 tcp->parent->nclone_waiting++;
1764#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001765 }
1766 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001767 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001768 if (tcp->u_arg[2] & WNOHANG) {
1769 /* We must force a fake result of 0 instead of
1770 the ECHILD error. */
1771 extern int force_result();
1772 return force_result(tcp, 0, 0);
1773 }
1774 else
1775 fprintf(stderr,
1776 "internal_wait: should not have resumed %d\n",
1777 tcp->pid);
1778 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001779 return 0;
1780}
1781
1782#ifdef SVR4
1783
1784int
1785sys_wait(tcp)
1786struct tcb *tcp;
1787{
1788 if (exiting(tcp)) {
1789 /* The library wrapper stuffs this into the user variable. */
1790 if (!syserror(tcp))
1791 printstatus(getrval2(tcp));
1792 }
1793 return 0;
1794}
1795
1796#endif /* SVR4 */
1797
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001798#ifdef FREEBSD
1799int
1800sys_wait(tcp)
1801struct tcb *tcp;
1802{
1803 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001804
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001805 if (exiting(tcp)) {
1806 if (!syserror(tcp)) {
1807 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1808 tprintf("%#lx", tcp->u_arg[0]);
1809 else
1810 printstatus(status);
1811 }
1812 }
1813 return 0;
1814}
1815#endif
1816
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001817int
1818sys_waitpid(tcp)
1819struct tcb *tcp;
1820{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001821 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001822}
1823
1824int
1825sys_wait4(tcp)
1826struct tcb *tcp;
1827{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001828 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001829}
1830
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001831#ifdef ALPHA
1832int
1833sys_osf_wait4(tcp)
1834struct tcb *tcp;
1835{
1836 return printwaitn(tcp, 4, 1);
1837}
1838#endif
1839
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001840#ifdef SVR4
1841
1842static struct xlat waitid_types[] = {
1843 { P_PID, "P_PID" },
1844 { P_PPID, "P_PPID" },
1845 { P_PGID, "P_PGID" },
1846 { P_SID, "P_SID" },
1847 { P_CID, "P_CID" },
1848 { P_UID, "P_UID" },
1849 { P_GID, "P_GID" },
1850 { P_ALL, "P_ALL" },
1851#ifdef P_LWPID
1852 { P_LWPID, "P_LWPID" },
1853#endif
1854 { 0, NULL },
1855};
1856
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001857int
1858sys_waitid(tcp)
1859struct tcb *tcp;
1860{
1861 siginfo_t si;
1862 int exited;
1863
1864 if (entering(tcp)) {
1865 printxval(waitid_types, tcp->u_arg[0], "P_???");
1866 tprintf(", %ld, ", tcp->u_arg[1]);
1867 if (tcp->nchildren > 0) {
1868 /* There are traced children */
1869 tcp->flags |= TCB_SUSPENDED;
1870 tcp->waitpid = tcp->u_arg[0];
1871 }
1872 }
1873 else {
1874 /* siginfo */
1875 exited = 0;
1876 if (!tcp->u_arg[2])
1877 tprintf("NULL");
1878 else if (syserror(tcp))
1879 tprintf("%#lx", tcp->u_arg[2]);
1880 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1881 tprintf("{???}");
1882 else
John Hughes58265892001-10-18 15:13:53 +00001883 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001884 /* options */
1885 tprintf(", ");
1886 if (!printflags(wait4_options, tcp->u_arg[3]))
1887 tprintf("0");
1888 }
1889 return 0;
1890}
1891
1892#endif /* SVR4 */
1893
1894int
1895sys_alarm(tcp)
1896struct tcb *tcp;
1897{
1898 if (entering(tcp))
1899 tprintf("%lu", tcp->u_arg[0]);
1900 return 0;
1901}
1902
1903int
1904sys_uname(tcp)
1905struct tcb *tcp;
1906{
1907 struct utsname uname;
1908
1909 if (exiting(tcp)) {
1910 if (syserror(tcp) || !verbose(tcp))
1911 tprintf("%#lx", tcp->u_arg[0]);
1912 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1913 tprintf("{...}");
1914 else if (!abbrev(tcp)) {
1915
1916 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1917 uname.sysname, uname.nodename);
1918 tprintf("release=\"%s\", version=\"%s\", ",
1919 uname.release, uname.version);
1920 tprintf("machine=\"%s\"", uname.machine);
1921#ifdef LINUX
1922#ifndef __GLIBC__
1923 tprintf(", domainname=\"%s\"", uname.domainname);
1924#endif /* __GLIBC__ */
1925#endif /* LINUX */
1926 tprintf("}");
1927 }
1928 else
1929 tprintf("{sys=\"%s\", node=\"%s\", ...}",
1930 uname.sysname, uname.nodename);
1931 }
1932 return 0;
1933}
1934
1935#ifndef SVR4
1936
1937static struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00001938#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001939 { PTRACE_TRACEME, "PTRACE_TRACEME" },
1940 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
1941 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
1942 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
1943 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
1944 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
1945 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
1946 { PTRACE_CONT, "PTRACE_CONT" },
1947 { PTRACE_KILL, "PTRACE_KILL" },
1948 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
1949 { PTRACE_ATTACH, "PTRACE_ATTACH" },
1950 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001951#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001952 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001953#endif
1954#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001955 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001956#endif
1957#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001958 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00001959#endif
1960#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001961 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00001962#endif
1963#ifdef PTRACE_GETFPXREGS
1964 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
1965#endif
1966#ifdef PTRACE_SETFPXREGS
1967 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
1968#endif
1969#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001970 { PTRACE_READDATA, "PTRACE_READDATA" },
1971 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
1972 { PTRACE_READTEXT, "PTRACE_READTEXT" },
1973 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
1974 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
1975 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
1976#ifdef SPARC
1977 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
1978 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
1979#else /* !SPARC */
1980 { PTRACE_22, "PTRACE_PTRACE_22" },
1981 { PTRACE_23, "PTRACE_PTRACE_23" },
1982#endif /* !SPARC */
1983#endif /* SUNOS4 */
1984 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
1985#ifdef SUNOS4
1986 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
1987#ifdef I386
1988 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
1989 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
1990 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
1991#else /* !I386 */
1992 { PTRACE_26, "PTRACE_26" },
1993 { PTRACE_27, "PTRACE_27" },
1994 { PTRACE_28, "PTRACE_28" },
1995#endif /* !I386 */
1996 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
1997#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001998#else /* FREEBSD */
1999 { PT_TRACE_ME, "PT_TRACE_ME" },
2000 { PT_READ_I, "PT_READ_I" },
2001 { PT_READ_D, "PT_READ_D" },
2002 { PT_WRITE_I, "PT_WRITE_I" },
2003 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002004#ifdef PT_READ_U
2005 { PT_READ_U, "PT_READ_U" },
2006#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002007 { PT_CONTINUE, "PT_CONTINUE" },
2008 { PT_KILL, "PT_KILL" },
2009 { PT_STEP, "PT_STEP" },
2010 { PT_ATTACH, "PT_ATTACH" },
2011 { PT_DETACH, "PT_DETACH" },
2012 { PT_GETREGS, "PT_GETREGS" },
2013 { PT_SETREGS, "PT_SETREGS" },
2014 { PT_GETFPREGS, "PT_GETFPREGS" },
2015 { PT_SETFPREGS, "PT_SETFPREGS" },
2016 { PT_GETDBREGS, "PT_GETDBREGS" },
2017 { PT_SETDBREGS, "PT_SETDBREGS" },
2018#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002019 { 0, NULL },
2020};
2021
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002022#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002023#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2024static
2025#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2026struct xlat struct_user_offsets[] = {
2027#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002028#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002029 { PT_PSWMASK, "psw_mask" },
2030 { PT_PSWADDR, "psw_addr" },
2031 { PT_GPR0, "gpr0" },
2032 { PT_GPR1, "gpr1" },
2033 { PT_GPR2, "gpr2" },
2034 { PT_GPR3, "gpr3" },
2035 { PT_GPR4, "gpr4" },
2036 { PT_GPR5, "gpr5" },
2037 { PT_GPR6, "gpr6" },
2038 { PT_GPR7, "gpr7" },
2039 { PT_GPR8, "gpr8" },
2040 { PT_GPR9, "gpr9" },
2041 { PT_GPR10, "gpr10" },
2042 { PT_GPR11, "gpr11" },
2043 { PT_GPR12, "gpr12" },
2044 { PT_GPR13, "gpr13" },
2045 { PT_GPR14, "gpr14" },
2046 { PT_GPR15, "gpr15" },
2047 { PT_ACR0, "acr0" },
2048 { PT_ACR1, "acr1" },
2049 { PT_ACR2, "acr2" },
2050 { PT_ACR3, "acr3" },
2051 { PT_ACR4, "acr4" },
2052 { PT_ACR5, "acr5" },
2053 { PT_ACR6, "acr6" },
2054 { PT_ACR7, "acr7" },
2055 { PT_ACR8, "acr8" },
2056 { PT_ACR9, "acr9" },
2057 { PT_ACR10, "acr10" },
2058 { PT_ACR11, "acr11" },
2059 { PT_ACR12, "acr12" },
2060 { PT_ACR13, "acr13" },
2061 { PT_ACR14, "acr14" },
2062 { PT_ACR15, "acr15" },
2063 { PT_ORIGGPR2, "orig_gpr2" },
2064 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002065#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002066 { PT_FPR0_HI, "fpr0.hi" },
2067 { PT_FPR0_LO, "fpr0.lo" },
2068 { PT_FPR1_HI, "fpr1.hi" },
2069 { PT_FPR1_LO, "fpr1.lo" },
2070 { PT_FPR2_HI, "fpr2.hi" },
2071 { PT_FPR2_LO, "fpr2.lo" },
2072 { PT_FPR3_HI, "fpr3.hi" },
2073 { PT_FPR3_LO, "fpr3.lo" },
2074 { PT_FPR4_HI, "fpr4.hi" },
2075 { PT_FPR4_LO, "fpr4.lo" },
2076 { PT_FPR5_HI, "fpr5.hi" },
2077 { PT_FPR5_LO, "fpr5.lo" },
2078 { PT_FPR6_HI, "fpr6.hi" },
2079 { PT_FPR6_LO, "fpr6.lo" },
2080 { PT_FPR7_HI, "fpr7.hi" },
2081 { PT_FPR7_LO, "fpr7.lo" },
2082 { PT_FPR8_HI, "fpr8.hi" },
2083 { PT_FPR8_LO, "fpr8.lo" },
2084 { PT_FPR9_HI, "fpr9.hi" },
2085 { PT_FPR9_LO, "fpr9.lo" },
2086 { PT_FPR10_HI, "fpr10.hi" },
2087 { PT_FPR10_LO, "fpr10.lo" },
2088 { PT_FPR11_HI, "fpr11.hi" },
2089 { PT_FPR11_LO, "fpr11.lo" },
2090 { PT_FPR12_HI, "fpr12.hi" },
2091 { PT_FPR12_LO, "fpr12.lo" },
2092 { PT_FPR13_HI, "fpr13.hi" },
2093 { PT_FPR13_LO, "fpr13.lo" },
2094 { PT_FPR14_HI, "fpr14.hi" },
2095 { PT_FPR14_LO, "fpr14.lo" },
2096 { PT_FPR15_HI, "fpr15.hi" },
2097 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002098#endif
2099#if defined(S390X)
2100 { PT_FPR0, "fpr0" },
2101 { PT_FPR1, "fpr1" },
2102 { PT_FPR2, "fpr2" },
2103 { PT_FPR3, "fpr3" },
2104 { PT_FPR4, "fpr4" },
2105 { PT_FPR5, "fpr5" },
2106 { PT_FPR6, "fpr6" },
2107 { PT_FPR7, "fpr7" },
2108 { PT_FPR8, "fpr8" },
2109 { PT_FPR9, "fpr9" },
2110 { PT_FPR10, "fpr10" },
2111 { PT_FPR11, "fpr11" },
2112 { PT_FPR12, "fpr12" },
2113 { PT_FPR13, "fpr13" },
2114 { PT_FPR14, "fpr14" },
2115 { PT_FPR15, "fpr15" },
2116#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002117 { PT_CR_9, "cr9" },
2118 { PT_CR_10, "cr10" },
2119 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002120 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002121#endif
2122#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002123 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002124#elif defined(HPPA)
2125 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002126#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002127#ifndef PT_ORIG_R3
2128#define PT_ORIG_R3 34
2129#endif
Roland McGratheb285352003-01-14 09:59:00 +00002130#define REGSIZE (sizeof(unsigned long))
2131 { REGSIZE*PT_R0, "r0" },
2132 { REGSIZE*PT_R1, "r1" },
2133 { REGSIZE*PT_R2, "r2" },
2134 { REGSIZE*PT_R3, "r3" },
2135 { REGSIZE*PT_R4, "r4" },
2136 { REGSIZE*PT_R5, "r5" },
2137 { REGSIZE*PT_R6, "r6" },
2138 { REGSIZE*PT_R7, "r7" },
2139 { REGSIZE*PT_R8, "r8" },
2140 { REGSIZE*PT_R9, "r9" },
2141 { REGSIZE*PT_R10, "r10" },
2142 { REGSIZE*PT_R11, "r11" },
2143 { REGSIZE*PT_R12, "r12" },
2144 { REGSIZE*PT_R13, "r13" },
2145 { REGSIZE*PT_R14, "r14" },
2146 { REGSIZE*PT_R15, "r15" },
2147 { REGSIZE*PT_R16, "r16" },
2148 { REGSIZE*PT_R17, "r17" },
2149 { REGSIZE*PT_R18, "r18" },
2150 { REGSIZE*PT_R19, "r19" },
2151 { REGSIZE*PT_R20, "r20" },
2152 { REGSIZE*PT_R21, "r21" },
2153 { REGSIZE*PT_R22, "r22" },
2154 { REGSIZE*PT_R23, "r23" },
2155 { REGSIZE*PT_R24, "r24" },
2156 { REGSIZE*PT_R25, "r25" },
2157 { REGSIZE*PT_R26, "r26" },
2158 { REGSIZE*PT_R27, "r27" },
2159 { REGSIZE*PT_R28, "r28" },
2160 { REGSIZE*PT_R29, "r29" },
2161 { REGSIZE*PT_R30, "r30" },
2162 { REGSIZE*PT_R31, "r31" },
2163 { REGSIZE*PT_NIP, "NIP" },
2164 { REGSIZE*PT_MSR, "MSR" },
2165 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2166 { REGSIZE*PT_CTR, "CTR" },
2167 { REGSIZE*PT_LNK, "LNK" },
2168 { REGSIZE*PT_XER, "XER" },
2169 { REGSIZE*PT_CCR, "CCR" },
2170 { REGSIZE*PT_FPR0, "FPR0" },
2171#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002172#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002173#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002174 { 0, "r0" },
2175 { 1, "r1" },
2176 { 2, "r2" },
2177 { 3, "r3" },
2178 { 4, "r4" },
2179 { 5, "r5" },
2180 { 6, "r6" },
2181 { 7, "r7" },
2182 { 8, "r8" },
2183 { 9, "r9" },
2184 { 10, "r10" },
2185 { 11, "r11" },
2186 { 12, "r12" },
2187 { 13, "r13" },
2188 { 14, "r14" },
2189 { 15, "r15" },
2190 { 16, "r16" },
2191 { 17, "r17" },
2192 { 18, "r18" },
2193 { 19, "r19" },
2194 { 20, "r20" },
2195 { 21, "r21" },
2196 { 22, "r22" },
2197 { 23, "r23" },
2198 { 24, "r24" },
2199 { 25, "r25" },
2200 { 26, "r26" },
2201 { 27, "r27" },
2202 { 28, "r28" },
2203 { 29, "gp" },
2204 { 30, "fp" },
2205 { 31, "zero" },
2206 { 32, "fp0" },
2207 { 33, "fp" },
2208 { 34, "fp2" },
2209 { 35, "fp3" },
2210 { 36, "fp4" },
2211 { 37, "fp5" },
2212 { 38, "fp6" },
2213 { 39, "fp7" },
2214 { 40, "fp8" },
2215 { 41, "fp9" },
2216 { 42, "fp10" },
2217 { 43, "fp11" },
2218 { 44, "fp12" },
2219 { 45, "fp13" },
2220 { 46, "fp14" },
2221 { 47, "fp15" },
2222 { 48, "fp16" },
2223 { 49, "fp17" },
2224 { 50, "fp18" },
2225 { 51, "fp19" },
2226 { 52, "fp20" },
2227 { 53, "fp21" },
2228 { 54, "fp22" },
2229 { 55, "fp23" },
2230 { 56, "fp24" },
2231 { 57, "fp25" },
2232 { 58, "fp26" },
2233 { 59, "fp27" },
2234 { 60, "fp28" },
2235 { 61, "fp29" },
2236 { 62, "fp30" },
2237 { 63, "fp31" },
2238 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002239#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002240#ifdef IA64
2241 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2242 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2243 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2244 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2245 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2246 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2247 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2248 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2249 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2250 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2251 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2252 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2253 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2254 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2255 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2256 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2257 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2258 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2259 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2260 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2261 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2262 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2263 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2264 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2265 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2266 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2267 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2268 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2269 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2270 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2271 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2272 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2273 /* switch stack: */
2274 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2275 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2276 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2277 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2278 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2279 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2280 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2281 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2282 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2283 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002284 { PT_B0, "kb0" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002285 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2286 { PT_B4, "b4" }, { PT_B5, "b5" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002287 { PT_AR_PFS, "kar.pfs" },
2288 { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" },
2289 { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" },
2290 { PT_PR, "k.pr" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002291 /* pt_regs */
2292 { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002293 /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002294 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2295 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2296 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2297 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2298 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2299 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2300 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2301 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2302 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2303 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2304 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2305 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2306 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2307 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2308 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2309#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002310#ifdef I386
2311 { 4*EBX, "4*EBX" },
2312 { 4*ECX, "4*ECX" },
2313 { 4*EDX, "4*EDX" },
2314 { 4*ESI, "4*ESI" },
2315 { 4*EDI, "4*EDI" },
2316 { 4*EBP, "4*EBP" },
2317 { 4*EAX, "4*EAX" },
2318 { 4*DS, "4*DS" },
2319 { 4*ES, "4*ES" },
2320 { 4*FS, "4*FS" },
2321 { 4*GS, "4*GS" },
2322 { 4*ORIG_EAX, "4*ORIG_EAX" },
2323 { 4*EIP, "4*EIP" },
2324 { 4*CS, "4*CS" },
2325 { 4*EFL, "4*EFL" },
2326 { 4*UESP, "4*UESP" },
2327 { 4*SS, "4*SS" },
2328#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002329#ifdef X86_64
2330 { 8*RDI, "8*RDI" },
2331 { 8*RSI, "8*RSI" },
2332 { 8*RDX, "8*RDX" },
2333 { 8*R10, "8*R10" },
2334 { 8*R8, "8*R8" },
2335 { 8*R9, "8*R9" },
2336 { 8*RBX, "8*RBX" },
2337 { 8*RCX, "8*RCX" },
2338 { 8*RBP, "8*RBP" },
2339 { 8*RAX, "8*RAX" },
2340#if 0
2341 { 8*DS, "8*DS" },
2342 { 8*ES, "8*ES" },
2343 { 8*FS, "8*FS" },
2344 { 8*GS, "8*GS" },
2345#endif
2346 { 8*ORIG_RAX, "8*ORIG_EAX" },
2347 { 8*RIP, "8*RIP" },
2348 { 8*CS, "8*CS" },
2349 { 8*EFLAGS, "8*EFL" },
2350 { 8*RSP, "8*RSP" },
2351 { 8*SS, "8*SS" },
2352 { 8*R11, "8*R11" },
2353 { 8*R12, "8*R12" },
2354 { 8*R13, "8*R13" },
2355 { 8*R14, "8*R14" },
2356 { 8*R15, "8*R15" },
2357#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002358#ifdef M68K
2359 { 4*PT_D1, "4*PT_D1" },
2360 { 4*PT_D2, "4*PT_D2" },
2361 { 4*PT_D3, "4*PT_D3" },
2362 { 4*PT_D4, "4*PT_D4" },
2363 { 4*PT_D5, "4*PT_D5" },
2364 { 4*PT_D6, "4*PT_D6" },
2365 { 4*PT_D7, "4*PT_D7" },
2366 { 4*PT_A0, "4*PT_A0" },
2367 { 4*PT_A1, "4*PT_A1" },
2368 { 4*PT_A2, "4*PT_A2" },
2369 { 4*PT_A3, "4*PT_A3" },
2370 { 4*PT_A4, "4*PT_A4" },
2371 { 4*PT_A5, "4*PT_A5" },
2372 { 4*PT_A6, "4*PT_A6" },
2373 { 4*PT_D0, "4*PT_D0" },
2374 { 4*PT_USP, "4*PT_USP" },
2375 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2376 { 4*PT_SR, "4*PT_SR" },
2377 { 4*PT_PC, "4*PT_PC" },
2378#endif /* M68K */
2379#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002380#ifdef SH
2381 { 4*REG_REG0, "4*REG_REG0" },
2382 { 4*(REG_REG0+1), "4*REG_REG1" },
2383 { 4*(REG_REG0+2), "4*REG_REG2" },
2384 { 4*(REG_REG0+3), "4*REG_REG3" },
2385 { 4*(REG_REG0+4), "4*REG_REG4" },
2386 { 4*(REG_REG0+5), "4*REG_REG5" },
2387 { 4*(REG_REG0+6), "4*REG_REG6" },
2388 { 4*(REG_REG0+7), "4*REG_REG7" },
2389 { 4*(REG_REG0+8), "4*REG_REG8" },
2390 { 4*(REG_REG0+9), "4*REG_REG9" },
2391 { 4*(REG_REG0+10), "4*REG_REG10" },
2392 { 4*(REG_REG0+11), "4*REG_REG11" },
2393 { 4*(REG_REG0+12), "4*REG_REG12" },
2394 { 4*(REG_REG0+13), "4*REG_REG13" },
2395 { 4*(REG_REG0+14), "4*REG_REG14" },
2396 { 4*REG_REG15, "4*REG_REG15" },
2397 { 4*REG_PC, "4*REG_PC" },
2398 { 4*REG_PR, "4*REG_PR" },
2399 { 4*REG_SR, "4*REG_SR" },
2400 { 4*REG_GBR, "4*REG_GBR" },
2401 { 4*REG_MACH, "4*REG_MACH" },
2402 { 4*REG_MACL, "4*REG_MACL" },
2403 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2404 { 4*REG_FPUL, "4*REG_FPUL" },
2405 { 4*REG_FPREG0, "4*REG_FPREG0" },
2406 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2407 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2408 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2409 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2410 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2411 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2412 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2413 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2414 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2415 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2416 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2417 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2418 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2419 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2420 { 4*REG_FPREG15, "4*REG_FPREG15" },
2421 { 4*REG_XDREG0, "4*REG_XDREG0" },
2422 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2423 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2424 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2425 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2426 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2427 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2428 { 4*REG_XDREG14, "4*REG_XDREG14" },
2429 { 4*REG_FPSCR, "4*REG_FPSCR" },
2430#endif /* SH */
2431
Michal Ludvig10a88d02002-10-07 14:31:00 +00002432#if !defined(S390) && !defined(S390X) && !defined(MIPS)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002433 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002434#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002435#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002436 { uoff(i387), "offsetof(struct user, i387)" },
2437#else /* !I386 */
2438#ifdef M68K
2439 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2440#endif /* M68K */
2441#endif /* !I386 */
2442 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2443 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2444 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2445 { uoff(start_code), "offsetof(struct user, start_code)" },
2446 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2447 { uoff(signal), "offsetof(struct user, signal)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002448#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002449 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002450#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002451 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002452#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002453 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2454#endif
2455 { uoff(magic), "offsetof(struct user, magic)" },
2456 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002457#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002458 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2459#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002460#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002461#endif /* !ALPHA */
2462#endif /* !POWERPC/!SPARC */
2463#endif /* LINUX */
2464#ifdef SUNOS4
2465 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2466 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2467 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2468 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2469 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2470 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2471 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2472 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2473 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2474 { uoff(u_error), "offsetof(struct user, u_error)" },
2475 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2476 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2477 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2478 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2479 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2480 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2481 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2482 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2483 { uoff(u_code), "offsetof(struct user, u_code)" },
2484 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2485 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2486 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2487 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2488 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2489 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2490 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2491 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2492 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2493 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2494 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2495 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2496 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2497 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2498 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2499 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2500 { uoff(u_start), "offsetof(struct user, u_start)" },
2501 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2502 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2503 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2504 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2505 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2506 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2507 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2508 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2509 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2510#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002511#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002512 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002513#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002514 { 0, NULL },
2515};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002516#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002517
2518int
2519sys_ptrace(tcp)
2520struct tcb *tcp;
2521{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002522 struct xlat *x;
2523 long addr;
2524
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002525 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002526 printxval(ptrace_cmds, tcp->u_arg[0],
2527#ifndef FREEBSD
2528 "PTRACE_???"
2529#else
2530 "PT_???"
2531#endif
2532 );
2533 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002534 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002535#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002536 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2537 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2538 for (x = struct_user_offsets; x->str; x++) {
2539 if (x->val >= addr)
2540 break;
2541 }
2542 if (!x->str)
2543 tprintf("%#lx, ", addr);
2544 else if (x->val > addr && x != struct_user_offsets) {
2545 x--;
2546 tprintf("%s + %ld, ", x->str, addr - x->val);
2547 }
2548 else
2549 tprintf("%s, ", x->str);
2550 }
2551 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002552#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002553 tprintf("%#lx, ", tcp->u_arg[2]);
2554#ifdef LINUX
2555 switch (tcp->u_arg[0]) {
2556 case PTRACE_PEEKDATA:
2557 case PTRACE_PEEKTEXT:
2558 case PTRACE_PEEKUSER:
2559 break;
2560 case PTRACE_CONT:
2561 case PTRACE_SINGLESTEP:
2562 case PTRACE_SYSCALL:
2563 case PTRACE_DETACH:
2564 printsignal(tcp->u_arg[3]);
2565 break;
2566 default:
2567 tprintf("%#lx", tcp->u_arg[3]);
2568 break;
2569 }
2570 } else {
2571 switch (tcp->u_arg[0]) {
2572 case PTRACE_PEEKDATA:
2573 case PTRACE_PEEKTEXT:
2574 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00002575 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002576 break;
2577 }
2578 }
2579#endif /* LINUX */
2580#ifdef SUNOS4
2581 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2582 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2583 tprintf("%lu, ", tcp->u_arg[3]);
2584 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2585 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2586 tcp->u_arg[0] != PTRACE_READTEXT) {
2587 tprintf("%#lx", tcp->u_arg[3]);
2588 }
2589 } else {
2590 if (tcp->u_arg[0] == PTRACE_READDATA ||
2591 tcp->u_arg[0] == PTRACE_READTEXT) {
2592 tprintf("%lu, ", tcp->u_arg[3]);
2593 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2594 }
2595 }
2596#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002597#ifdef FREEBSD
2598 tprintf("%lu", tcp->u_arg[3]);
2599 }
2600#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002601 return 0;
2602}
2603
2604#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002605
2606#ifdef LINUX
2607static struct xlat futexops[] = {
2608 { FUTEX_WAIT, "FUTEX_WAIT" },
2609 { FUTEX_WAKE, "FUTEX_WAKE" },
2610 { FUTEX_FD, "FUTEX_FD" },
2611 { 0, NULL }
2612};
2613
2614int
2615sys_futex(tcp)
2616struct tcb *tcp;
2617{
2618 if (entering(tcp)) {
2619 tprintf("%p, ", (void *) tcp->u_arg[0]);
2620 printflags(futexops, tcp->u_arg[1]);
2621 tprintf(", %ld, ", tcp->u_arg[2]);
2622 printtv(tcp, tcp->u_arg[3]);
2623 }
2624 return 0;
2625}
2626
2627static void
2628print_affinitylist(list, len)
2629unsigned long *list;
2630unsigned int len;
2631{
2632 int first = 1;
2633 tprintf(" {");
2634 while (len > sizeof (unsigned long)) {
2635 tprintf("%s %lx", first ? "" : ",", *list++);
2636 first = 0;
2637 len -= sizeof (unsigned long);
2638 }
2639 tprintf(" }");
2640}
2641
2642int
2643sys_sched_setaffinity(tcp)
2644struct tcb *tcp;
2645{
2646 if (entering(tcp)) {
2647 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2648 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2649 }
2650 return 0;
2651}
2652
2653int
2654sys_sched_getaffinity(tcp)
2655struct tcb *tcp;
2656{
2657 if (entering(tcp)) {
2658 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2659 } else {
2660 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);
2661 }
2662 return 0;
2663}
2664#endif