blob: baa13a0aa7a2868d09f1529abb874a470b5e21e2 [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)) {
Roland McGrathb4968be2003-01-20 09:04:33 +0000529 long flags, stack;
530# if defined S390 || defined S390X
531 /* For some reason, S390 has the stack argument first. */
532 stack = tcp->u_arg[0];
533 flags = tcp->u_arg[1];
534# else
535 flags = tcp->u_arg[0];
536 stack = tcp->u_arg[1];
537# endif
538 tprintf("child_stack=%#lx, flags=", stack);
539 if (printflags(clone_flags, flags) == 0)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000540 tprintf("0");
Roland McGrathb4968be2003-01-20 09:04:33 +0000541 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
Roland McGrath909875b2002-12-22 03:34:36 +0000542 |CLONE_SETTLS)) == 0)
543 return 0;
Roland McGrathb4968be2003-01-20 09:04:33 +0000544 if (flags & CLONE_PARENT_SETTID) {
Roland McGrath909875b2002-12-22 03:34:36 +0000545 int pid;
546 if (umove(tcp, tcp->u_arg[2], &pid) == 0)
547 tprintf(", [%d]", pid);
548 else
549 tprintf(", %#lx", tcp->u_arg[2]);
550 }
551 else
552 tprintf(", <ignored>");
553#ifdef I386
Roland McGrathb4968be2003-01-20 09:04:33 +0000554 if (flags & CLONE_SETTLS) {
Roland McGrath909875b2002-12-22 03:34:36 +0000555 struct modify_ldt_ldt_s copy;
556 if (umove(tcp, tcp->u_arg[3], &copy) != -1) {
557 tprintf(", {entry_number:%d, ",
558 copy.entry_number);
559 if (!verbose(tcp))
560 tprintf("...}");
561 else
562 print_ldt_entry(&copy);
563 }
564 else
565 tprintf(", %#lx", tcp->u_arg[3]);
566 }
567 else
568 tprintf(", <ignored>");
569# define TIDARG 4
570#else
571# define TIDARG 3
572#endif
Roland McGrathb4968be2003-01-20 09:04:33 +0000573 if (flags & CLONE_CHILD_SETTID)
Roland McGrath909875b2002-12-22 03:34:36 +0000574 tprintf(", %#lx", tcp->u_arg[TIDARG]);
575#undef TIDARG
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000576 }
577 return 0;
578}
579
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000580int
581sys_clone2(tcp)
582struct tcb *tcp;
583{
584 if (exiting(tcp)) {
585 tprintf("child_stack=%#lx, stack_size=%#lx, flags=",
586 tcp->u_arg[1], tcp->u_arg[2]);
587 if (printflags(clone_flags, tcp->u_arg[0]) == 0)
588 tprintf("0");
589 }
590 return 0;
591}
592
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000593#endif
594
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000595int
596sys_fork(tcp)
597struct tcb *tcp;
598{
599 if (exiting(tcp))
600 return RVAL_UDECIMAL;
601 return 0;
602}
603
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000604int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000605change_syscall(tcp, new)
606struct tcb *tcp;
607int new;
608{
609#if defined(LINUX)
610#if defined(I386)
611 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000612 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000613 return -1;
614 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000615#elif defined(X86_64)
616 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000617 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000618 return -1;
619 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000620#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000621 if (ptrace(PTRACE_POKEUSER, tcp->pid,
622 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000623 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000624 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000625#elif defined(S390) || defined(S390X)
626 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
627 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
628 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000629 return 0;
630#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000631 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000632 return -1;
633 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000634#elif defined(SPARC)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000635 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000636 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
637 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000638 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000639 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
640 return -1;
641 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000642#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000643 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000644 return -1;
645 return 0;
646#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000647 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000648 return -1;
649 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000650#elif defined(IA64)
651 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
652 return -1;
653 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000654#elif defined(HPPA)
655 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
656 return -1;
657 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000658#elif defined(SH)
659 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), new)<0)
660 return -1;
661 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000662#else
663#warning Do not know how to handle change_syscall for this architecture
664#endif /* architecture */
665#endif /* LINUX */
666 return -1;
667}
668
669int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000670setarg(tcp, argnum)
671 struct tcb *tcp;
672 int argnum;
673{
674#if defined (IA64)
675 {
676 unsigned long *bsp, *ap;
677
678 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
679 return -1;
680
681 ap = ia64_rse_skip_regs(bsp, argnum);
682 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000683 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000684 if (errno)
685 return -1;
686
687 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000688#elif defined(I386)
689 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000690 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000691 if (errno)
692 return -1;
693 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000694#elif defined(X86_64)
695 {
696 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
697 if (errno)
698 return -1;
699 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000700#elif defined(POWERPC)
701#ifndef PT_ORIG_R3
702#define PT_ORIG_R3 34
703#endif
704 {
705 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000706 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000707 tcp->u_arg[argnum]);
708 if (errno)
709 return -1;
710 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000711#elif defined(MIPS)
712 {
713 errno = 0;
714 if (argnum < 4)
715 ptrace(PTRACE_POKEUSER, tcp->pid,
716 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
717 else {
718 unsigned long *sp;
719
720 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
721 return -1;
722
723 ptrace(PTRACE_POKEDATA, tcp->pid,
724 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
725 }
726 if (errno)
727 return -1;
728 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000729#elif defined(S390) || defined(S390X)
730 {
731 if(argnum <= 5)
732 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000733 (char *) (argnum==0 ? PT_ORIGGPR2 :
734 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000735 tcp->u_arg[argnum]);
736 else
737 return -E2BIG;
738 if (errno)
739 return -1;
740 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000741#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000742# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000743#endif
744 return 0;
745}
746
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000747#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000748int
749internal_clone(tcp)
750struct tcb *tcp;
751{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000752 struct tcb *tcpchild;
753 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000754 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000755 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000756 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000757 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000758 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000759 if (setbpt(tcp) < 0)
760 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000761 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000762 int bpt = tcp->flags & TCB_BPTSET;
763
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000764 if (!(tcp->flags & TCB_FOLLOWFORK))
765 return 0;
766
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000767 if (syserror(tcp)) {
768 if (bpt)
769 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000770 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000771 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000772
773 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000774
775#ifdef CLONE_PTRACE /* See new setbpt code. */
776 tcpchild = pid2tcb(pid);
777 if (tcpchild != NULL) {
778 /* The child already reported its startup trap
779 before the parent reported its syscall return. */
780 if ((tcpchild->flags
781 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
782 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
783 fprintf(stderr, "\
784[preattached child %d of %d in weird state!]\n",
785 pid, tcp->pid);
786 }
787 else
788#endif
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000789 if ((tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000790 if (bpt)
791 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000792 fprintf(stderr, " [tcb table full]\n");
793 kill(pid, SIGKILL); /* XXX */
794 return 0;
795 }
796
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000797#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000798 /* Attach to the new child */
799 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000800 if (bpt)
801 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000802 perror("PTRACE_ATTACH");
803 fprintf(stderr, "Too late?\n");
804 droptcb(tcpchild);
805 return 0;
806 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000807#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000808
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000809 if (bpt)
810 clearbpt(tcp);
811
Ulrich Drepper90512f01999-12-24 07:22:25 +0000812 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000813 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000814 if (bpt) {
815 tcpchild->flags |= TCB_BPTSET;
816 tcpchild->baddr = tcp->baddr;
817 memcpy(tcpchild->inst, tcp->inst,
818 sizeof tcpchild->inst);
819 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000820 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000821 tcp->nchildren++;
822 if (tcpchild->flags & TCB_SUSPENDED) {
823 /* The child was born suspended, due to our having
824 forced CLONE_PTRACE. */
825 if (bpt)
826 clearbpt(tcpchild);
827
828 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
829 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
830 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
831 return -1;
832 }
833
834 if (!qflag)
835 fprintf(stderr, "\
836Process %u resumed (parent %d ready)\n",
837 pid, tcp->pid);
838 }
839 else {
840 newoutf(tcpchild);
841 if (!qflag)
842 fprintf(stderr, "Process %d attached\n", pid);
843 }
844
845#ifdef TCB_CLONE_THREAD
846 if ((tcp->flags & TCB_CLONE_THREAD) && tcp->parent != NULL) {
847 /* The parent in this clone is itself a thread
848 belonging to another process. There is no
849 meaning to the parentage relationship of the new
850 child with the thread, only with the process.
851 We associate the new thread with our parent.
852 Since this is done for every new thread, there
853 will never be a TCB_CLONE_THREAD process that
854 has children. */
855 --tcp->nchildren;
856 tcp->u_arg[0] = tcp->parent->u_arg[0];
857 tcp = tcp->parent;
858 tcpchild->parent = tcp;
859 ++tcp->nchildren;
860 }
861
862 if (tcp->u_arg[0] & CLONE_THREAD) {
863 tcpchild->flags |= TCB_CLONE_THREAD;
864 ++tcp->nclone_threads;
865 }
866 if (tcp->u_arg[0] & CLONE_DETACHED) {
867 tcpchild->flags |= TCB_CLONE_DETACHED;
868 ++tcp->nclone_detached;
869 }
870#endif
871
872 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000873 return 0;
874}
875#endif
876
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000877int
878internal_fork(tcp)
879struct tcb *tcp;
880{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000881#ifdef LINUX
882 /* We do special magic with clone for any clone or fork. */
883 return internal_clone(tcp);
884#else
885
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000886 struct tcb *tcpchild;
887 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000888 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000889
890#ifdef SYS_vfork
Nate Sammonsccd8f211999-03-29 22:57:54 +0000891 if (tcp->scno == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000892 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000893 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000894 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000895 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000896 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000897#endif
898 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000899 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000900 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000901 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000902 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000903 if (setbpt(tcp) < 0)
904 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000905 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000906 else {
907 int bpt = tcp->flags & TCB_BPTSET;
908
909 if (!(tcp->flags & TCB_FOLLOWFORK))
910 return 0;
911 if (bpt)
912 clearbpt(tcp);
913
914 if (syserror(tcp))
915 return 0;
916
917 pid = tcp->u_rval;
918 if ((tcpchild = alloctcb(pid)) == NULL) {
919 fprintf(stderr, " [tcb table full]\n");
920 kill(pid, SIGKILL); /* XXX */
921 return 0;
922 }
923#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000924#ifdef HPPA
925 /* The child must have run before it can be attached. */
926 /* This must be a bug in the parisc kernel, but I havn't
927 * identified it yet. Seems to be an issue associated
928 * with attaching to a process (which sends it a signal)
929 * before that process has ever been scheduled. When
930 * debugging, I started seeing crashes in
931 * arch/parisc/kernel/signal.c:do_signal(), apparently
932 * caused by r8 getting corrupt over the dequeue_signal()
933 * call. Didn't make much sense though...
934 */
935 {
936 struct timeval tv;
937 tv.tv_sec = 0;
938 tv.tv_usec = 10000;
939 select(0, NULL, NULL, NULL, &tv);
940 }
941#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000942 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
943 perror("PTRACE_ATTACH");
944 fprintf(stderr, "Too late?\n");
945 droptcb(tcpchild);
946 return 0;
947 }
948#endif /* LINUX */
949#ifdef SUNOS4
950#ifdef oldway
951 /* The child must have run before it can be attached. */
952 {
953 struct timeval tv;
954 tv.tv_sec = 0;
955 tv.tv_usec = 10000;
956 select(0, NULL, NULL, NULL, &tv);
957 }
958 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
959 perror("PTRACE_ATTACH");
960 fprintf(stderr, "Too late?\n");
961 droptcb(tcpchild);
962 return 0;
963 }
964#else /* !oldway */
965 /* Try to catch the new process as soon as possible. */
966 {
967 int i;
968 for (i = 0; i < 1024; i++)
969 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
970 break;
971 if (i == 1024) {
972 perror("PTRACE_ATTACH");
973 fprintf(stderr, "Too late?\n");
974 droptcb(tcpchild);
975 return 0;
976 }
977 }
978#endif /* !oldway */
979#endif /* SUNOS4 */
980 tcpchild->flags |= TCB_ATTACHED;
981 /* Child has BPT too, must be removed on first occasion */
982 if (bpt) {
983 tcpchild->flags |= TCB_BPTSET;
984 tcpchild->baddr = tcp->baddr;
985 memcpy(tcpchild->inst, tcp->inst,
986 sizeof tcpchild->inst);
987 }
988 newoutf(tcpchild);
989 tcpchild->parent = tcp;
990 tcp->nchildren++;
991 if (!qflag)
992 fprintf(stderr, "Process %d attached\n", pid);
993 }
994 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000995#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000996}
997
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000998#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000999
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001000#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001001
1002int
1003sys_vfork(tcp)
1004struct tcb *tcp;
1005{
1006 if (exiting(tcp))
1007 return RVAL_UDECIMAL;
1008 return 0;
1009}
1010
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001011#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001012
1013#ifndef LINUX
1014
1015static char idstr[16];
1016
1017int
1018sys_getpid(tcp)
1019struct tcb *tcp;
1020{
1021 if (exiting(tcp)) {
1022 sprintf(idstr, "ppid %lu", getrval2(tcp));
1023 tcp->auxstr = idstr;
1024 return RVAL_STR;
1025 }
1026 return 0;
1027}
1028
1029int
1030sys_getuid(tcp)
1031struct tcb *tcp;
1032{
1033 if (exiting(tcp)) {
1034 sprintf(idstr, "euid %lu", getrval2(tcp));
1035 tcp->auxstr = idstr;
1036 return RVAL_STR;
1037 }
1038 return 0;
1039}
1040
1041int
1042sys_getgid(tcp)
1043struct tcb *tcp;
1044{
1045 if (exiting(tcp)) {
1046 sprintf(idstr, "egid %lu", getrval2(tcp));
1047 tcp->auxstr = idstr;
1048 return RVAL_STR;
1049 }
1050 return 0;
1051}
1052
1053#endif /* !LINUX */
1054
1055#ifdef LINUX
1056
1057int
1058sys_setuid(tcp)
1059struct tcb *tcp;
1060{
1061 if (entering(tcp)) {
1062 tprintf("%u", (uid_t) tcp->u_arg[0]);
1063 }
1064 return 0;
1065}
1066
1067int
1068sys_setgid(tcp)
1069struct tcb *tcp;
1070{
1071 if (entering(tcp)) {
1072 tprintf("%u", (gid_t) tcp->u_arg[0]);
1073 }
1074 return 0;
1075}
1076
1077int
1078sys_getresuid(tcp)
1079 struct tcb *tcp;
1080{
1081 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001082 __kernel_uid_t uid;
1083 if (syserror(tcp))
1084 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1085 tcp->u_arg[1], tcp->u_arg[2]);
1086 else {
1087 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1088 tprintf("%#lx, ", tcp->u_arg[0]);
1089 else
1090 tprintf("ruid %lu, ", (unsigned long) uid);
1091 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1092 tprintf("%#lx, ", tcp->u_arg[0]);
1093 else
1094 tprintf("euid %lu, ", (unsigned long) uid);
1095 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1096 tprintf("%#lx", tcp->u_arg[0]);
1097 else
1098 tprintf("suid %lu", (unsigned long) uid);
1099 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001100 }
1101 return 0;
1102}
1103
1104int
1105sys_getresgid(tcp)
1106struct tcb *tcp;
1107{
1108 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001109 __kernel_gid_t gid;
1110 if (syserror(tcp))
1111 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1112 tcp->u_arg[1], tcp->u_arg[2]);
1113 else {
1114 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1115 tprintf("%#lx, ", tcp->u_arg[0]);
1116 else
1117 tprintf("rgid %lu, ", (unsigned long) gid);
1118 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1119 tprintf("%#lx, ", tcp->u_arg[0]);
1120 else
1121 tprintf("egid %lu, ", (unsigned long) gid);
1122 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1123 tprintf("%#lx", tcp->u_arg[0]);
1124 else
1125 tprintf("sgid %lu", (unsigned long) gid);
1126 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001127 }
1128 return 0;
1129}
1130
1131#endif /* LINUX */
1132
1133int
1134sys_setreuid(tcp)
1135struct tcb *tcp;
1136{
1137 if (entering(tcp)) {
1138 tprintf("%lu, %lu",
1139 (unsigned long) (uid_t) tcp->u_arg[0],
1140 (unsigned long) (uid_t) tcp->u_arg[1]);
1141 }
1142 return 0;
1143}
1144
1145int
1146sys_setregid(tcp)
1147struct tcb *tcp;
1148{
1149 if (entering(tcp)) {
1150 tprintf("%lu, %lu",
1151 (unsigned long) (gid_t) tcp->u_arg[0],
1152 (unsigned long) (gid_t) tcp->u_arg[1]);
1153 }
1154 return 0;
1155}
1156
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001157#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001158int
1159sys_setresuid(tcp)
1160 struct tcb *tcp;
1161{
1162 if (entering(tcp)) {
1163 tprintf("ruid %u, euid %u, suid %u",
1164 (uid_t) tcp->u_arg[0],
1165 (uid_t) tcp->u_arg[1],
1166 (uid_t) tcp->u_arg[2]);
1167 }
1168 return 0;
1169}
1170int
1171sys_setresgid(tcp)
1172 struct tcb *tcp;
1173{
1174 if (entering(tcp)) {
1175 tprintf("rgid %u, egid %u, sgid %u",
1176 (uid_t) tcp->u_arg[0],
1177 (uid_t) tcp->u_arg[1],
1178 (uid_t) tcp->u_arg[2]);
1179 }
1180 return 0;
1181}
1182
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001183#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001184
1185int
1186sys_setgroups(tcp)
1187struct tcb *tcp;
1188{
1189 int i, len;
1190 GETGROUPS_T *gidset;
1191
1192 if (entering(tcp)) {
1193 len = tcp->u_arg[0];
1194 tprintf("%u, ", len);
1195 if (len <= 0) {
1196 tprintf("[]");
1197 return 0;
1198 }
1199 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1200 if (gidset == NULL) {
1201 fprintf(stderr, "sys_setgroups: out of memory\n");
1202 return -1;
1203 }
1204 if (!verbose(tcp))
1205 tprintf("%#lx", tcp->u_arg[1]);
1206 else if (umoven(tcp, tcp->u_arg[1],
1207 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1208 tprintf("[?]");
1209 else {
1210 tprintf("[");
1211 for (i = 0; i < len; i++)
1212 tprintf("%s%lu", i ? ", " : "",
1213 (unsigned long) gidset[i]);
1214 tprintf("]");
1215 }
1216 free((char *) gidset);
1217 }
1218 return 0;
1219}
1220
1221int
1222sys_getgroups(tcp)
1223struct tcb *tcp;
1224{
1225 int i, len;
1226 GETGROUPS_T *gidset;
1227
1228 if (entering(tcp)) {
1229 len = tcp->u_arg[0];
1230 tprintf("%u, ", len);
1231 } else {
1232 len = tcp->u_rval;
1233 if (len <= 0) {
1234 tprintf("[]");
1235 return 0;
1236 }
1237 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1238 if (gidset == NULL) {
1239 fprintf(stderr, "sys_getgroups: out of memory\n");
1240 return -1;
1241 }
1242 if (!tcp->u_arg[1])
1243 tprintf("NULL");
1244 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1245 tprintf("%#lx", tcp->u_arg[1]);
1246 else if (umoven(tcp, tcp->u_arg[1],
1247 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1248 tprintf("[?]");
1249 else {
1250 tprintf("[");
1251 for (i = 0; i < len; i++)
1252 tprintf("%s%lu", i ? ", " : "",
1253 (unsigned long) gidset[i]);
1254 tprintf("]");
1255 }
1256 free((char *)gidset);
1257 }
1258 return 0;
1259}
1260
1261int
1262sys_setpgrp(tcp)
1263struct tcb *tcp;
1264{
1265 if (entering(tcp)) {
1266#ifndef SVR4
1267 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1268#endif /* !SVR4 */
1269 }
1270 return 0;
1271}
1272
1273int
1274sys_getpgrp(tcp)
1275struct tcb *tcp;
1276{
1277 if (entering(tcp)) {
1278#ifndef SVR4
1279 tprintf("%lu", tcp->u_arg[0]);
1280#endif /* !SVR4 */
1281 }
1282 return 0;
1283}
1284
1285int
1286sys_getsid(tcp)
1287struct tcb *tcp;
1288{
1289 if (entering(tcp)) {
1290 tprintf("%lu", tcp->u_arg[0]);
1291 }
1292 return 0;
1293}
1294
1295int
1296sys_setsid(tcp)
1297struct tcb *tcp;
1298{
1299 return 0;
1300}
1301
1302int
1303sys_getpgid(tcp)
1304struct tcb *tcp;
1305{
1306 if (entering(tcp)) {
1307 tprintf("%lu", tcp->u_arg[0]);
1308 }
1309 return 0;
1310}
1311
1312int
1313sys_setpgid(tcp)
1314struct tcb *tcp;
1315{
1316 if (entering(tcp)) {
1317 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1318 }
1319 return 0;
1320}
1321
John Hughesc61eb3d2002-05-17 11:37:50 +00001322#if UNIXWARE >= 2
1323
1324#include <sys/privilege.h>
1325
1326
1327static struct xlat procpriv_cmds [] = {
1328 { SETPRV, "SETPRV" },
1329 { CLRPRV, "CLRPRV" },
1330 { PUTPRV, "PUTPRV" },
1331 { GETPRV, "GETPRV" },
1332 { CNTPRV, "CNTPRV" },
1333 { 0, NULL },
1334};
1335
1336
1337static struct xlat procpriv_priv [] = {
1338 { P_OWNER, "P_OWNER" },
1339 { P_AUDIT, "P_AUDIT" },
1340 { P_COMPAT, "P_COMPAT" },
1341 { P_DACREAD, "P_DACREAD" },
1342 { P_DACWRITE, "P_DACWRITE" },
1343 { P_DEV, "P_DEV" },
1344 { P_FILESYS, "P_FILESYS" },
1345 { P_MACREAD, "P_MACREAD" },
1346 { P_MACWRITE, "P_MACWRITE" },
1347 { P_MOUNT, "P_MOUNT" },
1348 { P_MULTIDIR, "P_MULTIDIR" },
1349 { P_SETPLEVEL, "P_SETPLEVEL" },
1350 { P_SETSPRIV, "P_SETSPRIV" },
1351 { P_SETUID, "P_SETUID" },
1352 { P_SYSOPS, "P_SYSOPS" },
1353 { P_SETUPRIV, "P_SETUPRIV" },
1354 { P_DRIVER, "P_DRIVER" },
1355 { P_RTIME, "P_RTIME" },
1356 { P_MACUPGRADE, "P_MACUPGRADE" },
1357 { P_FSYSRANGE, "P_FSYSRANGE" },
1358 { P_SETFLEVEL, "P_SETFLEVEL" },
1359 { P_AUDITWR, "P_AUDITWR" },
1360 { P_TSHAR, "P_TSHAR" },
1361 { P_PLOCK, "P_PLOCK" },
1362 { P_CORE, "P_CORE" },
1363 { P_LOADMOD, "P_LOADMOD" },
1364 { P_BIND, "P_BIND" },
1365 { P_ALLPRIVS, "P_ALLPRIVS" },
1366 { 0, NULL },
1367};
1368
1369
1370static struct xlat procpriv_type [] = {
1371 { PS_FIX, "PS_FIX" },
1372 { PS_INH, "PS_INH" },
1373 { PS_MAX, "PS_MAX" },
1374 { PS_WKG, "PS_WKG" },
1375 { 0, NULL },
1376};
1377
1378
1379static void
1380printpriv(tcp, addr, len, opt)
1381struct tcb *tcp;
1382long addr;
1383int len;
1384struct xlat *opt;
1385{
1386 priv_t buf [128];
1387 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1388 int dots = len > max;
1389 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001390
John Hughesc61eb3d2002-05-17 11:37:50 +00001391 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001392
John Hughesc61eb3d2002-05-17 11:37:50 +00001393 if (len <= 0 ||
1394 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1395 {
1396 tprintf ("%#lx", addr);
1397 return;
1398 }
1399
1400 tprintf ("[");
1401
1402 for (i = 0; i < len; ++i) {
1403 char *t, *p;
1404
1405 if (i) tprintf (", ");
1406
1407 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1408 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1409 {
1410 tprintf ("%s|%s", t, p);
1411 }
1412 else {
1413 tprintf ("%#lx", buf [i]);
1414 }
1415 }
1416
1417 if (dots) tprintf (" ...");
1418
1419 tprintf ("]");
1420}
1421
1422
1423int
1424sys_procpriv(tcp)
1425struct tcb *tcp;
1426{
1427 if (entering(tcp)) {
1428 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1429 switch (tcp->u_arg[0]) {
1430 case CNTPRV:
1431 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1432 break;
1433
1434 case GETPRV:
1435 break;
1436
1437 default:
1438 tprintf (", ");
1439 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1440 tprintf (", %ld", tcp->u_arg[2]);
1441 }
1442 }
1443 else if (tcp->u_arg[0] == GETPRV) {
1444 if (syserror (tcp)) {
1445 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1446 }
1447 else {
1448 tprintf (", ");
1449 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1450 tprintf (", %ld", tcp->u_arg[2]);
1451 }
1452 }
Roland McGrath5a223472002-12-15 23:58:26 +00001453
John Hughesc61eb3d2002-05-17 11:37:50 +00001454 return 0;
1455}
1456
1457#endif
1458
1459
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001460void
1461fake_execve(tcp, program, argv, envp)
1462struct tcb *tcp;
1463char *program;
1464char *argv[];
1465char *envp[];
1466{
1467 int i;
1468
1469#ifdef ARM
1470 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1471 return;
1472#else
1473 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1474 return;
1475#endif /* !ARM */
1476 printleader(tcp);
1477 tprintf("execve(");
1478 string_quote(program);
1479 tprintf(", [");
1480 for (i = 0; argv[i] != NULL; i++) {
1481 if (i != 0)
1482 tprintf(", ");
1483 string_quote(argv[i]);
1484 }
1485 for (i = 0; envp[i] != NULL; i++)
1486 ;
1487 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1488 tabto(acolumn);
1489 tprintf("= 0");
1490 printtrailer(tcp);
1491}
1492
1493static void
1494printargv(tcp, addr)
1495struct tcb *tcp;
1496long addr;
1497{
1498 char *cp;
1499 char *sep;
1500 int max = max_strlen / 2;
1501
1502 for (sep = ""; --max >= 0; sep = ", ") {
1503 if (!abbrev(tcp))
1504 max++;
1505 if (umove(tcp, addr, &cp) < 0) {
1506 tprintf("%#lx", addr);
1507 return;
1508 }
1509 if (cp == 0)
1510 break;
1511 tprintf(sep);
1512 printstr(tcp, (long) cp, -1);
1513 addr += sizeof(char *);
1514 }
1515 if (cp)
1516 tprintf(", ...");
1517}
1518
1519static void
1520printargc(fmt, tcp, addr)
1521char *fmt;
1522struct tcb *tcp;
1523long addr;
1524{
1525 int count;
1526 char *cp;
1527
1528 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1529 addr += sizeof(char *);
1530 }
1531 tprintf(fmt, count, count == 1 ? "" : "s");
1532}
1533
1534int
1535sys_execv(tcp)
1536struct tcb *tcp;
1537{
1538 if (entering(tcp)) {
1539 printpath(tcp, tcp->u_arg[0]);
1540 if (!verbose(tcp))
1541 tprintf(", %#lx", tcp->u_arg[1]);
1542#if 0
1543 else if (abbrev(tcp))
1544 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1545#endif
1546 else {
1547 tprintf(", [");
1548 printargv(tcp, tcp->u_arg[1]);
1549 tprintf("]");
1550 }
1551 }
1552 return 0;
1553}
1554
1555int
1556sys_execve(tcp)
1557struct tcb *tcp;
1558{
1559 if (entering(tcp)) {
1560 printpath(tcp, tcp->u_arg[0]);
1561 if (!verbose(tcp))
1562 tprintf(", %#lx", tcp->u_arg[1]);
1563#if 0
1564 else if (abbrev(tcp))
1565 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1566#endif
1567 else {
1568 tprintf(", [");
1569 printargv(tcp, tcp->u_arg[1]);
1570 tprintf("]");
1571 }
1572 if (!verbose(tcp))
1573 tprintf(", %#lx", tcp->u_arg[2]);
1574 else if (abbrev(tcp))
1575 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1576 else {
1577 tprintf(", [");
1578 printargv(tcp, tcp->u_arg[2]);
1579 tprintf("]");
1580 }
1581 }
Roland McGrathb4968be2003-01-20 09:04:33 +00001582#if defined LINUX && defined TCB_WAITEXECVE
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001583 tcp->flags |= TCB_WAITEXECVE;
Roland McGrathb4968be2003-01-20 09:04:33 +00001584#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001585 return 0;
1586}
1587
John Hughes4e36a812001-04-18 15:11:51 +00001588#if UNIXWARE > 2
1589
1590int sys_rexecve(tcp)
1591struct tcb *tcp;
1592{
1593 if (entering (tcp)) {
1594 sys_execve (tcp);
1595 tprintf (", %ld", tcp->u_arg[3]);
1596 }
1597 return 0;
1598}
1599
1600#endif
1601
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001602int
1603internal_exec(tcp)
1604struct tcb *tcp;
1605{
1606#ifdef SUNOS4
1607 if (exiting(tcp) && !syserror(tcp) && followfork)
1608 fixvfork(tcp);
1609#endif /* SUNOS4 */
1610 return 0;
1611}
1612
1613#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001614#ifndef __WNOTHREAD
1615#define __WNOTHREAD 0x20000000
1616#endif
1617#ifndef __WALL
1618#define __WALL 0x40000000
1619#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001620#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001621#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001622#endif
1623#endif /* LINUX */
1624
1625static struct xlat wait4_options[] = {
1626 { WNOHANG, "WNOHANG" },
1627#ifndef WSTOPPED
1628 { WUNTRACED, "WUNTRACED" },
1629#endif
1630#ifdef WEXITED
1631 { WEXITED, "WEXITED" },
1632#endif
1633#ifdef WTRAPPED
1634 { WTRAPPED, "WTRAPPED" },
1635#endif
1636#ifdef WSTOPPED
1637 { WSTOPPED, "WSTOPPED" },
1638#endif
1639#ifdef WCONTINUED
1640 { WCONTINUED, "WCONTINUED" },
1641#endif
1642#ifdef WNOWAIT
1643 { WNOWAIT, "WNOWAIT" },
1644#endif
1645#ifdef __WCLONE
1646 { __WCLONE, "__WCLONE" },
1647#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001648#ifdef __WALL
1649 { __WALL, "__WALL" },
1650#endif
1651#ifdef __WNOTHREAD
1652 { __WNOTHREAD, "__WNOTHREAD" },
1653#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001654 { 0, NULL },
1655};
1656
1657static int
1658printstatus(status)
1659int status;
1660{
1661 int exited = 0;
1662
1663 /*
1664 * Here is a tricky presentation problem. This solution
1665 * is still not entirely satisfactory but since there
1666 * are no wait status constructors it will have to do.
1667 */
1668 if (WIFSTOPPED(status))
1669 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001670 signame(WSTOPSIG(status)));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001671 else if WIFSIGNALED(status)
1672 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001673 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001674 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1675 else if WIFEXITED(status) {
1676 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1677 WEXITSTATUS(status));
1678 exited = 1;
1679 }
1680 else
1681 tprintf("[%#x]", status);
1682 return exited;
1683}
1684
1685static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001686printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001687struct tcb *tcp;
1688int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001689int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001690{
1691 int status;
1692 int exited = 0;
1693
1694 if (entering(tcp)) {
1695 tprintf("%ld, ", tcp->u_arg[0]);
1696 } else {
1697 /* status */
1698 if (!tcp->u_arg[1])
1699 tprintf("NULL");
1700 else if (syserror(tcp) || tcp->u_rval == 0)
1701 tprintf("%#lx", tcp->u_arg[1]);
1702 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1703 tprintf("[?]");
1704 else
1705 exited = printstatus(status);
1706 /* options */
1707 tprintf(", ");
1708 if (!printflags(wait4_options, tcp->u_arg[2]))
1709 tprintf("0");
1710 if (n == 4) {
1711 tprintf(", ");
1712 /* usage */
1713 if (!tcp->u_arg[3])
1714 tprintf("NULL");
1715#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001716 else if (tcp->u_rval > 0) {
1717#ifdef LINUX_64BIT
1718 if (bitness)
1719 printrusage32(tcp, tcp->u_arg[3]);
1720 else
1721#endif
1722 printrusage(tcp, tcp->u_arg[3]);
1723 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001724#endif /* LINUX */
1725#ifdef SUNOS4
1726 else if (tcp->u_rval > 0 && exited)
1727 printrusage(tcp, tcp->u_arg[3]);
1728#endif /* SUNOS4 */
1729 else
1730 tprintf("%#lx", tcp->u_arg[3]);
1731 }
1732 }
1733 return 0;
1734}
1735
1736int
1737internal_wait(tcp)
1738struct tcb *tcp;
1739{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001740 int got_kids;
1741
1742#ifdef TCB_CLONE_THREAD
1743 if (tcp->flags & TCB_CLONE_THREAD)
1744 /* The children we wait for are our parent's children. */
1745 got_kids = (tcp->parent->nchildren
1746 > tcp->parent->nclone_detached);
1747 else
1748 got_kids = (tcp->nchildren > tcp->nclone_detached);
1749#else
1750 got_kids = tcp->nchildren > 0;
1751#endif
1752
1753 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001754 /* There are children that this parent should block for.
1755 But ptrace made us the parent of the traced children
1756 and the real parent will get ECHILD from the wait call.
1757
1758 XXX If we attached with strace -f -p PID, then there
1759 may be untraced dead children the parent could be reaping
1760 now, but we make him block. */
1761
1762 /* ??? WTA: fix bug with hanging children */
1763
1764 if (!(tcp->u_arg[2] & WNOHANG)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001765 /* There are traced children */
1766 tcp->flags |= TCB_SUSPENDED;
1767 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001768#ifdef TCB_CLONE_THREAD
1769 if (tcp->flags & TCB_CLONE_THREAD)
1770 tcp->parent->nclone_waiting++;
1771#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001772 }
1773 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001774 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001775 if (tcp->u_arg[2] & WNOHANG) {
1776 /* We must force a fake result of 0 instead of
1777 the ECHILD error. */
1778 extern int force_result();
1779 return force_result(tcp, 0, 0);
1780 }
1781 else
1782 fprintf(stderr,
1783 "internal_wait: should not have resumed %d\n",
1784 tcp->pid);
1785 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001786 return 0;
1787}
1788
1789#ifdef SVR4
1790
1791int
1792sys_wait(tcp)
1793struct tcb *tcp;
1794{
1795 if (exiting(tcp)) {
1796 /* The library wrapper stuffs this into the user variable. */
1797 if (!syserror(tcp))
1798 printstatus(getrval2(tcp));
1799 }
1800 return 0;
1801}
1802
1803#endif /* SVR4 */
1804
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001805#ifdef FREEBSD
1806int
1807sys_wait(tcp)
1808struct tcb *tcp;
1809{
1810 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001811
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001812 if (exiting(tcp)) {
1813 if (!syserror(tcp)) {
1814 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1815 tprintf("%#lx", tcp->u_arg[0]);
1816 else
1817 printstatus(status);
1818 }
1819 }
1820 return 0;
1821}
1822#endif
1823
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001824int
1825sys_waitpid(tcp)
1826struct tcb *tcp;
1827{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001828 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001829}
1830
1831int
1832sys_wait4(tcp)
1833struct tcb *tcp;
1834{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001835 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001836}
1837
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001838#ifdef ALPHA
1839int
1840sys_osf_wait4(tcp)
1841struct tcb *tcp;
1842{
1843 return printwaitn(tcp, 4, 1);
1844}
1845#endif
1846
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001847#ifdef SVR4
1848
1849static struct xlat waitid_types[] = {
1850 { P_PID, "P_PID" },
1851 { P_PPID, "P_PPID" },
1852 { P_PGID, "P_PGID" },
1853 { P_SID, "P_SID" },
1854 { P_CID, "P_CID" },
1855 { P_UID, "P_UID" },
1856 { P_GID, "P_GID" },
1857 { P_ALL, "P_ALL" },
1858#ifdef P_LWPID
1859 { P_LWPID, "P_LWPID" },
1860#endif
1861 { 0, NULL },
1862};
1863
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001864int
1865sys_waitid(tcp)
1866struct tcb *tcp;
1867{
1868 siginfo_t si;
1869 int exited;
1870
1871 if (entering(tcp)) {
1872 printxval(waitid_types, tcp->u_arg[0], "P_???");
1873 tprintf(", %ld, ", tcp->u_arg[1]);
1874 if (tcp->nchildren > 0) {
1875 /* There are traced children */
1876 tcp->flags |= TCB_SUSPENDED;
1877 tcp->waitpid = tcp->u_arg[0];
1878 }
1879 }
1880 else {
1881 /* siginfo */
1882 exited = 0;
1883 if (!tcp->u_arg[2])
1884 tprintf("NULL");
1885 else if (syserror(tcp))
1886 tprintf("%#lx", tcp->u_arg[2]);
1887 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1888 tprintf("{???}");
1889 else
John Hughes58265892001-10-18 15:13:53 +00001890 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001891 /* options */
1892 tprintf(", ");
1893 if (!printflags(wait4_options, tcp->u_arg[3]))
1894 tprintf("0");
1895 }
1896 return 0;
1897}
1898
1899#endif /* SVR4 */
1900
1901int
1902sys_alarm(tcp)
1903struct tcb *tcp;
1904{
1905 if (entering(tcp))
1906 tprintf("%lu", tcp->u_arg[0]);
1907 return 0;
1908}
1909
1910int
1911sys_uname(tcp)
1912struct tcb *tcp;
1913{
1914 struct utsname uname;
1915
1916 if (exiting(tcp)) {
1917 if (syserror(tcp) || !verbose(tcp))
1918 tprintf("%#lx", tcp->u_arg[0]);
1919 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1920 tprintf("{...}");
1921 else if (!abbrev(tcp)) {
1922
1923 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1924 uname.sysname, uname.nodename);
1925 tprintf("release=\"%s\", version=\"%s\", ",
1926 uname.release, uname.version);
1927 tprintf("machine=\"%s\"", uname.machine);
1928#ifdef LINUX
1929#ifndef __GLIBC__
1930 tprintf(", domainname=\"%s\"", uname.domainname);
1931#endif /* __GLIBC__ */
1932#endif /* LINUX */
1933 tprintf("}");
1934 }
1935 else
1936 tprintf("{sys=\"%s\", node=\"%s\", ...}",
1937 uname.sysname, uname.nodename);
1938 }
1939 return 0;
1940}
1941
1942#ifndef SVR4
1943
1944static struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00001945#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001946 { PTRACE_TRACEME, "PTRACE_TRACEME" },
1947 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
1948 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
1949 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
1950 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
1951 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
1952 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
1953 { PTRACE_CONT, "PTRACE_CONT" },
1954 { PTRACE_KILL, "PTRACE_KILL" },
1955 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
1956 { PTRACE_ATTACH, "PTRACE_ATTACH" },
1957 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001958#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001959 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001960#endif
1961#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001962 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00001963#endif
1964#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001965 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00001966#endif
1967#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001968 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00001969#endif
1970#ifdef PTRACE_GETFPXREGS
1971 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
1972#endif
1973#ifdef PTRACE_SETFPXREGS
1974 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
1975#endif
1976#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001977 { PTRACE_READDATA, "PTRACE_READDATA" },
1978 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
1979 { PTRACE_READTEXT, "PTRACE_READTEXT" },
1980 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
1981 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
1982 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
1983#ifdef SPARC
1984 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
1985 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
1986#else /* !SPARC */
1987 { PTRACE_22, "PTRACE_PTRACE_22" },
1988 { PTRACE_23, "PTRACE_PTRACE_23" },
1989#endif /* !SPARC */
1990#endif /* SUNOS4 */
1991 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
1992#ifdef SUNOS4
1993 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
1994#ifdef I386
1995 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
1996 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
1997 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
1998#else /* !I386 */
1999 { PTRACE_26, "PTRACE_26" },
2000 { PTRACE_27, "PTRACE_27" },
2001 { PTRACE_28, "PTRACE_28" },
2002#endif /* !I386 */
2003 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2004#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002005#else /* FREEBSD */
2006 { PT_TRACE_ME, "PT_TRACE_ME" },
2007 { PT_READ_I, "PT_READ_I" },
2008 { PT_READ_D, "PT_READ_D" },
2009 { PT_WRITE_I, "PT_WRITE_I" },
2010 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002011#ifdef PT_READ_U
2012 { PT_READ_U, "PT_READ_U" },
2013#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002014 { PT_CONTINUE, "PT_CONTINUE" },
2015 { PT_KILL, "PT_KILL" },
2016 { PT_STEP, "PT_STEP" },
2017 { PT_ATTACH, "PT_ATTACH" },
2018 { PT_DETACH, "PT_DETACH" },
2019 { PT_GETREGS, "PT_GETREGS" },
2020 { PT_SETREGS, "PT_SETREGS" },
2021 { PT_GETFPREGS, "PT_GETFPREGS" },
2022 { PT_SETFPREGS, "PT_SETFPREGS" },
2023 { PT_GETDBREGS, "PT_GETDBREGS" },
2024 { PT_SETDBREGS, "PT_SETDBREGS" },
2025#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002026 { 0, NULL },
2027};
2028
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002029#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002030#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2031static
2032#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2033struct xlat struct_user_offsets[] = {
2034#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002035#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002036 { PT_PSWMASK, "psw_mask" },
2037 { PT_PSWADDR, "psw_addr" },
2038 { PT_GPR0, "gpr0" },
2039 { PT_GPR1, "gpr1" },
2040 { PT_GPR2, "gpr2" },
2041 { PT_GPR3, "gpr3" },
2042 { PT_GPR4, "gpr4" },
2043 { PT_GPR5, "gpr5" },
2044 { PT_GPR6, "gpr6" },
2045 { PT_GPR7, "gpr7" },
2046 { PT_GPR8, "gpr8" },
2047 { PT_GPR9, "gpr9" },
2048 { PT_GPR10, "gpr10" },
2049 { PT_GPR11, "gpr11" },
2050 { PT_GPR12, "gpr12" },
2051 { PT_GPR13, "gpr13" },
2052 { PT_GPR14, "gpr14" },
2053 { PT_GPR15, "gpr15" },
2054 { PT_ACR0, "acr0" },
2055 { PT_ACR1, "acr1" },
2056 { PT_ACR2, "acr2" },
2057 { PT_ACR3, "acr3" },
2058 { PT_ACR4, "acr4" },
2059 { PT_ACR5, "acr5" },
2060 { PT_ACR6, "acr6" },
2061 { PT_ACR7, "acr7" },
2062 { PT_ACR8, "acr8" },
2063 { PT_ACR9, "acr9" },
2064 { PT_ACR10, "acr10" },
2065 { PT_ACR11, "acr11" },
2066 { PT_ACR12, "acr12" },
2067 { PT_ACR13, "acr13" },
2068 { PT_ACR14, "acr14" },
2069 { PT_ACR15, "acr15" },
2070 { PT_ORIGGPR2, "orig_gpr2" },
2071 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002072#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002073 { PT_FPR0_HI, "fpr0.hi" },
2074 { PT_FPR0_LO, "fpr0.lo" },
2075 { PT_FPR1_HI, "fpr1.hi" },
2076 { PT_FPR1_LO, "fpr1.lo" },
2077 { PT_FPR2_HI, "fpr2.hi" },
2078 { PT_FPR2_LO, "fpr2.lo" },
2079 { PT_FPR3_HI, "fpr3.hi" },
2080 { PT_FPR3_LO, "fpr3.lo" },
2081 { PT_FPR4_HI, "fpr4.hi" },
2082 { PT_FPR4_LO, "fpr4.lo" },
2083 { PT_FPR5_HI, "fpr5.hi" },
2084 { PT_FPR5_LO, "fpr5.lo" },
2085 { PT_FPR6_HI, "fpr6.hi" },
2086 { PT_FPR6_LO, "fpr6.lo" },
2087 { PT_FPR7_HI, "fpr7.hi" },
2088 { PT_FPR7_LO, "fpr7.lo" },
2089 { PT_FPR8_HI, "fpr8.hi" },
2090 { PT_FPR8_LO, "fpr8.lo" },
2091 { PT_FPR9_HI, "fpr9.hi" },
2092 { PT_FPR9_LO, "fpr9.lo" },
2093 { PT_FPR10_HI, "fpr10.hi" },
2094 { PT_FPR10_LO, "fpr10.lo" },
2095 { PT_FPR11_HI, "fpr11.hi" },
2096 { PT_FPR11_LO, "fpr11.lo" },
2097 { PT_FPR12_HI, "fpr12.hi" },
2098 { PT_FPR12_LO, "fpr12.lo" },
2099 { PT_FPR13_HI, "fpr13.hi" },
2100 { PT_FPR13_LO, "fpr13.lo" },
2101 { PT_FPR14_HI, "fpr14.hi" },
2102 { PT_FPR14_LO, "fpr14.lo" },
2103 { PT_FPR15_HI, "fpr15.hi" },
2104 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002105#endif
2106#if defined(S390X)
2107 { PT_FPR0, "fpr0" },
2108 { PT_FPR1, "fpr1" },
2109 { PT_FPR2, "fpr2" },
2110 { PT_FPR3, "fpr3" },
2111 { PT_FPR4, "fpr4" },
2112 { PT_FPR5, "fpr5" },
2113 { PT_FPR6, "fpr6" },
2114 { PT_FPR7, "fpr7" },
2115 { PT_FPR8, "fpr8" },
2116 { PT_FPR9, "fpr9" },
2117 { PT_FPR10, "fpr10" },
2118 { PT_FPR11, "fpr11" },
2119 { PT_FPR12, "fpr12" },
2120 { PT_FPR13, "fpr13" },
2121 { PT_FPR14, "fpr14" },
2122 { PT_FPR15, "fpr15" },
2123#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002124 { PT_CR_9, "cr9" },
2125 { PT_CR_10, "cr10" },
2126 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002127 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002128#endif
2129#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002130 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002131#elif defined(HPPA)
2132 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002133#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002134#ifndef PT_ORIG_R3
2135#define PT_ORIG_R3 34
2136#endif
Roland McGratheb285352003-01-14 09:59:00 +00002137#define REGSIZE (sizeof(unsigned long))
2138 { REGSIZE*PT_R0, "r0" },
2139 { REGSIZE*PT_R1, "r1" },
2140 { REGSIZE*PT_R2, "r2" },
2141 { REGSIZE*PT_R3, "r3" },
2142 { REGSIZE*PT_R4, "r4" },
2143 { REGSIZE*PT_R5, "r5" },
2144 { REGSIZE*PT_R6, "r6" },
2145 { REGSIZE*PT_R7, "r7" },
2146 { REGSIZE*PT_R8, "r8" },
2147 { REGSIZE*PT_R9, "r9" },
2148 { REGSIZE*PT_R10, "r10" },
2149 { REGSIZE*PT_R11, "r11" },
2150 { REGSIZE*PT_R12, "r12" },
2151 { REGSIZE*PT_R13, "r13" },
2152 { REGSIZE*PT_R14, "r14" },
2153 { REGSIZE*PT_R15, "r15" },
2154 { REGSIZE*PT_R16, "r16" },
2155 { REGSIZE*PT_R17, "r17" },
2156 { REGSIZE*PT_R18, "r18" },
2157 { REGSIZE*PT_R19, "r19" },
2158 { REGSIZE*PT_R20, "r20" },
2159 { REGSIZE*PT_R21, "r21" },
2160 { REGSIZE*PT_R22, "r22" },
2161 { REGSIZE*PT_R23, "r23" },
2162 { REGSIZE*PT_R24, "r24" },
2163 { REGSIZE*PT_R25, "r25" },
2164 { REGSIZE*PT_R26, "r26" },
2165 { REGSIZE*PT_R27, "r27" },
2166 { REGSIZE*PT_R28, "r28" },
2167 { REGSIZE*PT_R29, "r29" },
2168 { REGSIZE*PT_R30, "r30" },
2169 { REGSIZE*PT_R31, "r31" },
2170 { REGSIZE*PT_NIP, "NIP" },
2171 { REGSIZE*PT_MSR, "MSR" },
2172 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2173 { REGSIZE*PT_CTR, "CTR" },
2174 { REGSIZE*PT_LNK, "LNK" },
2175 { REGSIZE*PT_XER, "XER" },
2176 { REGSIZE*PT_CCR, "CCR" },
2177 { REGSIZE*PT_FPR0, "FPR0" },
2178#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002179#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002180#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002181 { 0, "r0" },
2182 { 1, "r1" },
2183 { 2, "r2" },
2184 { 3, "r3" },
2185 { 4, "r4" },
2186 { 5, "r5" },
2187 { 6, "r6" },
2188 { 7, "r7" },
2189 { 8, "r8" },
2190 { 9, "r9" },
2191 { 10, "r10" },
2192 { 11, "r11" },
2193 { 12, "r12" },
2194 { 13, "r13" },
2195 { 14, "r14" },
2196 { 15, "r15" },
2197 { 16, "r16" },
2198 { 17, "r17" },
2199 { 18, "r18" },
2200 { 19, "r19" },
2201 { 20, "r20" },
2202 { 21, "r21" },
2203 { 22, "r22" },
2204 { 23, "r23" },
2205 { 24, "r24" },
2206 { 25, "r25" },
2207 { 26, "r26" },
2208 { 27, "r27" },
2209 { 28, "r28" },
2210 { 29, "gp" },
2211 { 30, "fp" },
2212 { 31, "zero" },
2213 { 32, "fp0" },
2214 { 33, "fp" },
2215 { 34, "fp2" },
2216 { 35, "fp3" },
2217 { 36, "fp4" },
2218 { 37, "fp5" },
2219 { 38, "fp6" },
2220 { 39, "fp7" },
2221 { 40, "fp8" },
2222 { 41, "fp9" },
2223 { 42, "fp10" },
2224 { 43, "fp11" },
2225 { 44, "fp12" },
2226 { 45, "fp13" },
2227 { 46, "fp14" },
2228 { 47, "fp15" },
2229 { 48, "fp16" },
2230 { 49, "fp17" },
2231 { 50, "fp18" },
2232 { 51, "fp19" },
2233 { 52, "fp20" },
2234 { 53, "fp21" },
2235 { 54, "fp22" },
2236 { 55, "fp23" },
2237 { 56, "fp24" },
2238 { 57, "fp25" },
2239 { 58, "fp26" },
2240 { 59, "fp27" },
2241 { 60, "fp28" },
2242 { 61, "fp29" },
2243 { 62, "fp30" },
2244 { 63, "fp31" },
2245 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002246#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002247#ifdef IA64
2248 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2249 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2250 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2251 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2252 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2253 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2254 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2255 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2256 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2257 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2258 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2259 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2260 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2261 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2262 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2263 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2264 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2265 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2266 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2267 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2268 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2269 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2270 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2271 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2272 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2273 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2274 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2275 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2276 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2277 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2278 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2279 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2280 /* switch stack: */
2281 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2282 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2283 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2284 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2285 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2286 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2287 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2288 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2289 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2290 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002291 { PT_B0, "kb0" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002292 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2293 { PT_B4, "b4" }, { PT_B5, "b5" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002294 { PT_AR_PFS, "kar.pfs" },
2295 { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" },
2296 { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" },
2297 { PT_PR, "k.pr" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002298 /* pt_regs */
2299 { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002300 /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002301 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2302 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2303 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2304 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2305 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2306 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2307 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2308 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2309 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2310 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2311 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2312 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2313 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2314 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2315 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2316#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002317#ifdef I386
2318 { 4*EBX, "4*EBX" },
2319 { 4*ECX, "4*ECX" },
2320 { 4*EDX, "4*EDX" },
2321 { 4*ESI, "4*ESI" },
2322 { 4*EDI, "4*EDI" },
2323 { 4*EBP, "4*EBP" },
2324 { 4*EAX, "4*EAX" },
2325 { 4*DS, "4*DS" },
2326 { 4*ES, "4*ES" },
2327 { 4*FS, "4*FS" },
2328 { 4*GS, "4*GS" },
2329 { 4*ORIG_EAX, "4*ORIG_EAX" },
2330 { 4*EIP, "4*EIP" },
2331 { 4*CS, "4*CS" },
2332 { 4*EFL, "4*EFL" },
2333 { 4*UESP, "4*UESP" },
2334 { 4*SS, "4*SS" },
2335#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002336#ifdef X86_64
2337 { 8*RDI, "8*RDI" },
2338 { 8*RSI, "8*RSI" },
2339 { 8*RDX, "8*RDX" },
2340 { 8*R10, "8*R10" },
2341 { 8*R8, "8*R8" },
2342 { 8*R9, "8*R9" },
2343 { 8*RBX, "8*RBX" },
2344 { 8*RCX, "8*RCX" },
2345 { 8*RBP, "8*RBP" },
2346 { 8*RAX, "8*RAX" },
2347#if 0
2348 { 8*DS, "8*DS" },
2349 { 8*ES, "8*ES" },
2350 { 8*FS, "8*FS" },
2351 { 8*GS, "8*GS" },
2352#endif
2353 { 8*ORIG_RAX, "8*ORIG_EAX" },
2354 { 8*RIP, "8*RIP" },
2355 { 8*CS, "8*CS" },
2356 { 8*EFLAGS, "8*EFL" },
2357 { 8*RSP, "8*RSP" },
2358 { 8*SS, "8*SS" },
2359 { 8*R11, "8*R11" },
2360 { 8*R12, "8*R12" },
2361 { 8*R13, "8*R13" },
2362 { 8*R14, "8*R14" },
2363 { 8*R15, "8*R15" },
2364#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002365#ifdef M68K
2366 { 4*PT_D1, "4*PT_D1" },
2367 { 4*PT_D2, "4*PT_D2" },
2368 { 4*PT_D3, "4*PT_D3" },
2369 { 4*PT_D4, "4*PT_D4" },
2370 { 4*PT_D5, "4*PT_D5" },
2371 { 4*PT_D6, "4*PT_D6" },
2372 { 4*PT_D7, "4*PT_D7" },
2373 { 4*PT_A0, "4*PT_A0" },
2374 { 4*PT_A1, "4*PT_A1" },
2375 { 4*PT_A2, "4*PT_A2" },
2376 { 4*PT_A3, "4*PT_A3" },
2377 { 4*PT_A4, "4*PT_A4" },
2378 { 4*PT_A5, "4*PT_A5" },
2379 { 4*PT_A6, "4*PT_A6" },
2380 { 4*PT_D0, "4*PT_D0" },
2381 { 4*PT_USP, "4*PT_USP" },
2382 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2383 { 4*PT_SR, "4*PT_SR" },
2384 { 4*PT_PC, "4*PT_PC" },
2385#endif /* M68K */
2386#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002387#ifdef SH
2388 { 4*REG_REG0, "4*REG_REG0" },
2389 { 4*(REG_REG0+1), "4*REG_REG1" },
2390 { 4*(REG_REG0+2), "4*REG_REG2" },
2391 { 4*(REG_REG0+3), "4*REG_REG3" },
2392 { 4*(REG_REG0+4), "4*REG_REG4" },
2393 { 4*(REG_REG0+5), "4*REG_REG5" },
2394 { 4*(REG_REG0+6), "4*REG_REG6" },
2395 { 4*(REG_REG0+7), "4*REG_REG7" },
2396 { 4*(REG_REG0+8), "4*REG_REG8" },
2397 { 4*(REG_REG0+9), "4*REG_REG9" },
2398 { 4*(REG_REG0+10), "4*REG_REG10" },
2399 { 4*(REG_REG0+11), "4*REG_REG11" },
2400 { 4*(REG_REG0+12), "4*REG_REG12" },
2401 { 4*(REG_REG0+13), "4*REG_REG13" },
2402 { 4*(REG_REG0+14), "4*REG_REG14" },
2403 { 4*REG_REG15, "4*REG_REG15" },
2404 { 4*REG_PC, "4*REG_PC" },
2405 { 4*REG_PR, "4*REG_PR" },
2406 { 4*REG_SR, "4*REG_SR" },
2407 { 4*REG_GBR, "4*REG_GBR" },
2408 { 4*REG_MACH, "4*REG_MACH" },
2409 { 4*REG_MACL, "4*REG_MACL" },
2410 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2411 { 4*REG_FPUL, "4*REG_FPUL" },
2412 { 4*REG_FPREG0, "4*REG_FPREG0" },
2413 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2414 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2415 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2416 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2417 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2418 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2419 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2420 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2421 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2422 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2423 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2424 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2425 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2426 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2427 { 4*REG_FPREG15, "4*REG_FPREG15" },
2428 { 4*REG_XDREG0, "4*REG_XDREG0" },
2429 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2430 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2431 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2432 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2433 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2434 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2435 { 4*REG_XDREG14, "4*REG_XDREG14" },
2436 { 4*REG_FPSCR, "4*REG_FPSCR" },
2437#endif /* SH */
2438
Michal Ludvig10a88d02002-10-07 14:31:00 +00002439#if !defined(S390) && !defined(S390X) && !defined(MIPS)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002440 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002441#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002442#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002443 { uoff(i387), "offsetof(struct user, i387)" },
2444#else /* !I386 */
2445#ifdef M68K
2446 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2447#endif /* M68K */
2448#endif /* !I386 */
2449 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2450 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2451 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2452 { uoff(start_code), "offsetof(struct user, start_code)" },
2453 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2454 { uoff(signal), "offsetof(struct user, signal)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002455#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002456 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002457#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002458 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002459#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002460 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2461#endif
2462 { uoff(magic), "offsetof(struct user, magic)" },
2463 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002464#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002465 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2466#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002467#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002468#endif /* !ALPHA */
2469#endif /* !POWERPC/!SPARC */
2470#endif /* LINUX */
2471#ifdef SUNOS4
2472 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2473 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2474 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2475 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2476 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2477 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2478 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2479 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2480 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2481 { uoff(u_error), "offsetof(struct user, u_error)" },
2482 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2483 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2484 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2485 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2486 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2487 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2488 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2489 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2490 { uoff(u_code), "offsetof(struct user, u_code)" },
2491 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2492 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2493 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2494 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2495 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2496 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2497 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2498 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2499 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2500 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2501 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2502 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2503 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2504 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2505 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2506 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2507 { uoff(u_start), "offsetof(struct user, u_start)" },
2508 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2509 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2510 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2511 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2512 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2513 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2514 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2515 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2516 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2517#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002518#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002519 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002520#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002521 { 0, NULL },
2522};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002523#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002524
2525int
2526sys_ptrace(tcp)
2527struct tcb *tcp;
2528{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002529 struct xlat *x;
2530 long addr;
2531
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002532 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002533 printxval(ptrace_cmds, tcp->u_arg[0],
2534#ifndef FREEBSD
2535 "PTRACE_???"
2536#else
2537 "PT_???"
2538#endif
2539 );
2540 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002541 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002542#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002543 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2544 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2545 for (x = struct_user_offsets; x->str; x++) {
2546 if (x->val >= addr)
2547 break;
2548 }
2549 if (!x->str)
2550 tprintf("%#lx, ", addr);
2551 else if (x->val > addr && x != struct_user_offsets) {
2552 x--;
2553 tprintf("%s + %ld, ", x->str, addr - x->val);
2554 }
2555 else
2556 tprintf("%s, ", x->str);
2557 }
2558 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002559#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002560 tprintf("%#lx, ", tcp->u_arg[2]);
2561#ifdef LINUX
2562 switch (tcp->u_arg[0]) {
2563 case PTRACE_PEEKDATA:
2564 case PTRACE_PEEKTEXT:
2565 case PTRACE_PEEKUSER:
2566 break;
2567 case PTRACE_CONT:
2568 case PTRACE_SINGLESTEP:
2569 case PTRACE_SYSCALL:
2570 case PTRACE_DETACH:
2571 printsignal(tcp->u_arg[3]);
2572 break;
2573 default:
2574 tprintf("%#lx", tcp->u_arg[3]);
2575 break;
2576 }
2577 } else {
2578 switch (tcp->u_arg[0]) {
2579 case PTRACE_PEEKDATA:
2580 case PTRACE_PEEKTEXT:
2581 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00002582 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002583 break;
2584 }
2585 }
2586#endif /* LINUX */
2587#ifdef SUNOS4
2588 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2589 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2590 tprintf("%lu, ", tcp->u_arg[3]);
2591 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2592 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2593 tcp->u_arg[0] != PTRACE_READTEXT) {
2594 tprintf("%#lx", tcp->u_arg[3]);
2595 }
2596 } else {
2597 if (tcp->u_arg[0] == PTRACE_READDATA ||
2598 tcp->u_arg[0] == PTRACE_READTEXT) {
2599 tprintf("%lu, ", tcp->u_arg[3]);
2600 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2601 }
2602 }
2603#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002604#ifdef FREEBSD
2605 tprintf("%lu", tcp->u_arg[3]);
2606 }
2607#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002608 return 0;
2609}
2610
2611#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002612
2613#ifdef LINUX
2614static struct xlat futexops[] = {
2615 { FUTEX_WAIT, "FUTEX_WAIT" },
2616 { FUTEX_WAKE, "FUTEX_WAKE" },
2617 { FUTEX_FD, "FUTEX_FD" },
2618 { 0, NULL }
2619};
2620
2621int
2622sys_futex(tcp)
2623struct tcb *tcp;
2624{
2625 if (entering(tcp)) {
2626 tprintf("%p, ", (void *) tcp->u_arg[0]);
2627 printflags(futexops, tcp->u_arg[1]);
2628 tprintf(", %ld, ", tcp->u_arg[2]);
2629 printtv(tcp, tcp->u_arg[3]);
2630 }
2631 return 0;
2632}
2633
2634static void
2635print_affinitylist(list, len)
2636unsigned long *list;
2637unsigned int len;
2638{
2639 int first = 1;
2640 tprintf(" {");
2641 while (len > sizeof (unsigned long)) {
2642 tprintf("%s %lx", first ? "" : ",", *list++);
2643 first = 0;
2644 len -= sizeof (unsigned long);
2645 }
2646 tprintf(" }");
2647}
2648
2649int
2650sys_sched_setaffinity(tcp)
2651struct tcb *tcp;
2652{
2653 if (entering(tcp)) {
2654 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2655 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2656 }
2657 return 0;
2658}
2659
2660int
2661sys_sched_getaffinity(tcp)
2662struct tcb *tcp;
2663{
2664 if (entering(tcp)) {
2665 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2666 } else {
2667 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);
2668 }
2669 return 0;
2670}
2671#endif