blob: 038fc14ee793720c2ddea46d7781644937460b75 [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00005 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Linux for s390 port by D.J. Barrow
8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
Wichert Akkermanccef6372002-05-01 16:39:22 +00009 * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH
10 * port by Greg Banks <gbanks@pocketpenguins.com>
11
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +000012 *
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000013 * All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * $Id$
38 */
39
40#include "defs.h"
41
42#include <fcntl.h>
43#include <sys/stat.h>
44#include <sys/time.h>
45#include <sys/wait.h>
46#include <sys/resource.h>
47#include <sys/utsname.h>
48#include <sys/user.h>
49#include <sys/syscall.h>
50#include <signal.h>
51#ifdef SUNOS4
52#include <machine/reg.h>
53#endif /* SUNOS4 */
54
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +000055#ifdef FREEBSD
56#include <sys/ptrace.h>
57#endif
58
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000059#if HAVE_ASM_REG_H
60#ifdef SPARC
61# define fpq kernel_fpq
62# define fq kernel_fq
63# define fpu kernel_fpu
64#endif
65#include <asm/reg.h>
66#ifdef SPARC
67# undef fpq
68# undef fq
Roland McGrath5a223472002-12-15 23:58:26 +000069# undef fpu
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000070#endif
71#endif /* HAVE_ASM_REG_H */
72
Wichert Akkerman36915a11999-07-13 15:45:02 +000073#ifdef HAVE_SYS_REG_H
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000074# include <sys/reg.h>
Wichert Akkerman15dea971999-10-06 13:06:34 +000075#ifndef PTRACE_PEEKUSR
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000076# define PTRACE_PEEKUSR PTRACE_PEEKUSER
Wichert Akkerman15dea971999-10-06 13:06:34 +000077#endif
78#ifndef PTRACE_POKEUSR
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000079# define PTRACE_POKEUSR PTRACE_POKEUSER
80#endif
Wichert Akkerman15dea971999-10-06 13:06:34 +000081#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000082
Roland McGrath5bd7cf82003-01-24 04:31:18 +000083#ifdef HAVE_LINUX_PTRACE_H
84#undef PTRACE_SYSCALL
Roland McGrathfb1bc072004-03-01 21:29:24 +000085# ifdef HAVE_STRUCT_IA64_FPREG
86# define ia64_fpreg XXX_ia64_fpreg
87# endif
88# ifdef HAVE_STRUCT_PT_ALL_USER_REGS
89# define pt_all_user_regs XXX_pt_all_user_regs
90# endif
Roland McGrath5bd7cf82003-01-24 04:31:18 +000091#include <linux/ptrace.h>
Roland McGrathfb1bc072004-03-01 21:29:24 +000092# undef ia64_fpreg
93# undef pt_all_user_regs
Roland McGrath5bd7cf82003-01-24 04:31:18 +000094#endif
95
Roland McGrath5a223472002-12-15 23:58:26 +000096#ifdef HAVE_LINUX_FUTEX_H
97#include <linux/futex.h>
98#endif
99#if defined LINUX
100# ifndef FUTEX_WAIT
101# define FUTEX_WAIT 0
102# endif
103# ifndef FUTEX_WAKE
104# define FUTEX_WAKE 1
105# endif
106# ifndef FUTEX_FD
107# define FUTEX_FD 2
108# endif
Roland McGrath88812d62003-06-26 22:27:23 +0000109# ifndef FUTEX_REQUEUE
110# define FUTEX_REQUEUE 3
111# endif
Roland McGrath5a223472002-12-15 23:58:26 +0000112#endif
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000113
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000114#ifdef LINUX
Roland McGrath279d3782004-03-01 20:27:37 +0000115#include <sched.h>
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000116#include <asm/posix_types.h>
117#undef GETGROUPS_T
118#define GETGROUPS_T __kernel_gid_t
Roland McGrath83bd47a2003-11-13 22:32:26 +0000119#undef GETGROUPS32_T
120#define GETGROUPS32_T __kernel_gid32_t
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000121#endif /* LINUX */
122
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000123#if defined(LINUX) && defined(IA64)
124# include <asm/ptrace_offsets.h>
125# include <asm/rse.h>
126#endif
127
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000128#ifdef HAVE_PRCTL
129#include <sys/prctl.h>
130#endif
131
132#ifndef WCOREDUMP
133#define WCOREDUMP(status) ((status) & 0200)
134#endif
135
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000136/* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000137#if defined(HAVE_PRCTL)
138static struct xlat prctl_options[] = {
139#ifdef PR_MAXPROCS
140 { PR_MAXPROCS, "PR_MAXPROCS" },
141#endif
142#ifdef PR_ISBLOCKED
143 { PR_ISBLOCKED, "PR_ISBLOCKED" },
144#endif
145#ifdef PR_SETSTACKSIZE
146 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
147#endif
148#ifdef PR_GETSTACKSIZE
149 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
150#endif
151#ifdef PR_MAXPPROCS
152 { PR_MAXPPROCS, "PR_MAXPPROCS" },
153#endif
154#ifdef PR_UNBLKONEXEC
155 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
156#endif
157#ifdef PR_ATOMICSIM
158 { PR_ATOMICSIM, "PR_ATOMICSIM" },
159#endif
160#ifdef PR_SETEXITSIG
161 { PR_SETEXITSIG, "PR_SETEXITSIG" },
162#endif
163#ifdef PR_RESIDENT
164 { PR_RESIDENT, "PR_RESIDENT" },
165#endif
166#ifdef PR_ATTACHADDR
167 { PR_ATTACHADDR, "PR_ATTACHADDR" },
168#endif
169#ifdef PR_DETACHADDR
170 { PR_DETACHADDR, "PR_DETACHADDR" },
171#endif
172#ifdef PR_TERMCHILD
173 { PR_TERMCHILD, "PR_TERMCHILD" },
174#endif
175#ifdef PR_GETSHMASK
176 { PR_GETSHMASK, "PR_GETSHMASK" },
177#endif
178#ifdef PR_GETNSHARE
179 { PR_GETNSHARE, "PR_GETNSHARE" },
180#endif
181#if defined(PR_SET_PDEATHSIG)
182 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
183#endif
Wichert Akkerman8829a551999-06-11 13:18:40 +0000184#ifdef PR_COREPID
185 { PR_COREPID, "PR_COREPID" },
186#endif
187#ifdef PR_ATTACHADDRPERM
188 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
189#endif
190#ifdef PR_PTHREADEXIT
191 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
192#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000193#ifdef PR_SET_PDEATHSIG
194 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
195#endif
196#ifdef PR_GET_PDEATHSIG
197 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
198#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000199#ifdef PR_GET_UNALIGN
200 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
201#endif
202#ifdef PR_SET_UNALIGN
203 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
204#endif
205#ifdef PR_GET_KEEPCAPS
206 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" },
207#endif
208#ifdef PR_SET_KEEPCAPS
209 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" },
210#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000211 { 0, NULL },
212};
213
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000214
215const char *
216unalignctl_string (unsigned int ctl)
217{
218 static char buf[16];
219
220 switch (ctl) {
221#ifdef PR_UNALIGN_NOPRINT
222 case PR_UNALIGN_NOPRINT:
223 return "NOPRINT";
224#endif
225#ifdef PR_UNALIGN_SIGBUS
226 case PR_UNALIGN_SIGBUS:
227 return "SIGBUS";
228#endif
229 default:
230 break;
231 }
232 sprintf(buf, "%x", ctl);
233 return buf;
234}
235
236
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000237int
238sys_prctl(tcp)
239struct tcb *tcp;
240{
241 int i;
242
243 if (entering(tcp)) {
244 printxval(prctl_options, tcp->u_arg[0], "PR_???");
245 switch (tcp->u_arg[0]) {
246#ifdef PR_GETNSHARE
247 case PR_GETNSHARE:
248 break;
249#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000250#ifdef PR_SET_DEATHSIG
251 case PR_GET_PDEATHSIG:
252 break;
253#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000254#ifdef PR_SET_UNALIGN
255 case PR_SET_UNALIGN:
256 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
257 break;
258#endif
259#ifdef PR_GET_UNALIGN
260 case PR_GET_UNALIGN:
261 tprintf(", %#lx", tcp->u_arg[1]);
262 break;
263#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000264 default:
265 for (i = 1; i < tcp->u_nargs; i++)
266 tprintf(", %#lx", tcp->u_arg[i]);
267 break;
268 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000269 } else {
270 switch (tcp->u_arg[0]) {
271#ifdef PR_GET_PDEATHSIG
272 case PR_GET_PDEATHSIG:
273 for (i=1; i<tcp->u_nargs; i++)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000274 tprintf(", %#lx", tcp->u_arg[i]);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000275 break;
276#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000277#ifdef PR_SET_UNALIGN
278 case PR_SET_UNALIGN:
279 break;
280#endif
281#ifdef PR_GET_UNALIGN
282 case PR_GET_UNALIGN:
283 {
284 int ctl;
285
286 umove(tcp, tcp->u_arg[1], &ctl);
287 tcp->auxstr = unalignctl_string(ctl);
288 return RVAL_STR;
289 }
290#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000291 default:
292 break;
293 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000294 }
295 return 0;
296}
297
298#endif /* HAVE_PRCTL */
299
300int
301sys_gethostid(tcp)
302struct tcb *tcp;
303{
304 if (exiting(tcp))
305 return RVAL_HEX;
306 return 0;
307}
308
309int
310sys_sethostname(tcp)
311struct tcb *tcp;
312{
313 if (entering(tcp)) {
314 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
315 tprintf(", %lu", tcp->u_arg[1]);
316 }
317 return 0;
318}
319
320int
321sys_gethostname(tcp)
322struct tcb *tcp;
323{
324 if (exiting(tcp)) {
325 if (syserror(tcp))
326 tprintf("%#lx", tcp->u_arg[0]);
327 else
328 printpath(tcp, tcp->u_arg[0]);
329 tprintf(", %lu", tcp->u_arg[1]);
330 }
331 return 0;
332}
333
334int
335sys_setdomainname(tcp)
336struct tcb *tcp;
337{
338 if (entering(tcp)) {
339 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
340 tprintf(", %lu", tcp->u_arg[1]);
341 }
342 return 0;
343}
344
Wichert Akkerman5daa0281999-03-15 19:49:42 +0000345#if !defined(LINUX)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000346
347int
348sys_getdomainname(tcp)
349struct tcb *tcp;
350{
351 if (exiting(tcp)) {
352 if (syserror(tcp))
353 tprintf("%#lx", tcp->u_arg[0]);
354 else
355 printpath(tcp, tcp->u_arg[0]);
356 tprintf(", %lu", tcp->u_arg[1]);
357 }
358 return 0;
359}
360#endif /* !LINUX */
361
362int
363sys_exit(tcp)
364struct tcb *tcp;
365{
366 if (exiting(tcp)) {
367 fprintf(stderr, "_exit returned!\n");
368 return -1;
369 }
370 /* special case: we stop tracing this process, finish line now */
371 tprintf("%ld) ", tcp->u_arg[0]);
372 tabto(acolumn);
373 tprintf("= ?");
374 printtrailer(tcp);
375 return 0;
376}
377
378int
379internal_exit(tcp)
380struct tcb *tcp;
381{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000382 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000383 tcp->flags |= TCB_EXITING;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000384#ifdef __NR_exit_group
Roland McGrath08267b82004-02-20 22:56:43 +0000385# ifdef IA64
386 if (ia32) {
387 if (tcp->scno == 252)
388 tcp->flags |= TCB_GROUP_EXITING;
389 } else
390# endif
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000391 if (tcp->scno == __NR_exit_group)
392 tcp->flags |= TCB_GROUP_EXITING;
393#endif
394 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000395 return 0;
396}
397
Roland McGrathee9d4352002-12-18 04:16:10 +0000398/* TCP is creating a child we want to follow.
399 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
400 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
401static int
402fork_tcb(struct tcb *tcp)
403{
404 if (nprocs == tcbtabsize) {
405 /* Allocate some more TCBs and expand the table.
406 We don't want to relocate the TCBs because our
407 callers have pointers and it would be a pain.
408 So tcbtab is a table of pointers. Since we never
409 free the TCBs, we allocate a single chunk of many. */
410 struct tcb **newtab = (struct tcb **)
411 realloc(tcbtab, 2 * tcbtabsize * sizeof tcbtab[0]);
412 struct tcb *newtcbs = (struct tcb *) calloc(tcbtabsize,
413 sizeof *newtcbs);
414 int i;
415 if (newtab == NULL || newtcbs == NULL) {
416 if (newtab != NULL)
417 free(newtab);
418 tcp->flags &= ~TCB_FOLLOWFORK;
419 fprintf(stderr, "sys_fork: tcb table full\n");
420 return 1;
421 }
422 for (i = tcbtabsize; i < 2 * tcbtabsize; ++i)
423 newtab[i] = &newtcbs[i - tcbtabsize];
424 tcbtabsize *= 2;
425 tcbtab = newtab;
426 }
427
428 tcp->flags |= TCB_FOLLOWFORK;
429 return 0;
430}
431
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000432#ifdef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000433
434int
435sys_fork(tcp)
436struct tcb *tcp;
437{
438 if (exiting(tcp)) {
439 if (getrval2(tcp)) {
440 tcp->auxstr = "child process";
441 return RVAL_UDECIMAL | RVAL_STR;
442 }
443 }
444 return 0;
445}
446
John Hughes4e36a812001-04-18 15:11:51 +0000447#if UNIXWARE > 2
448
449int
450sys_rfork(tcp)
451struct tcb *tcp;
452{
453 if (entering(tcp)) {
454 tprintf ("%ld", tcp->u_arg[0]);
455 }
456 else {
457 if (getrval2(tcp)) {
458 tcp->auxstr = "child process";
459 return RVAL_UDECIMAL | RVAL_STR;
460 }
461 }
462 return 0;
463}
464
465#endif
466
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000467int
468internal_fork(tcp)
469struct tcb *tcp;
470{
471 struct tcb *tcpchild;
472
473 if (exiting(tcp)) {
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000474#ifdef SYS_rfork
475 if (tcp->scno == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
476 return 0;
477#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000478 if (getrval2(tcp))
479 return 0;
480 if (!followfork)
481 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000482 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000483 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000484 if (syserror(tcp))
485 return 0;
486 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
487 fprintf(stderr, "sys_fork: tcb table full\n");
488 return 0;
489 }
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000490 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000491 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000492 }
493 return 0;
494}
495
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000496#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000497
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000498#ifdef LINUX
499
500/* defines copied from linux/sched.h since we can't include that
501 * ourselves (it conflicts with *lots* of libc includes)
502 */
503#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
504#define CLONE_VM 0x00000100 /* set if VM shared between processes */
505#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
506#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
507#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000508#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000509#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
510#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
511#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000512#define CLONE_THREAD 0x00010000 /* Same thread group? */
513#define CLONE_NEWNS 0x00020000 /* New namespace group? */
514#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
515#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
516#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
517#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
518#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
519#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
520#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000521
522static struct xlat clone_flags[] = {
523 { CLONE_VM, "CLONE_VM" },
524 { CLONE_FS, "CLONE_FS" },
525 { CLONE_FILES, "CLONE_FILES" },
526 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000527 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000528 { CLONE_PTRACE, "CLONE_PTRACE" },
529 { CLONE_VFORK, "CLONE_VFORK" },
530 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000531 { CLONE_THREAD, "CLONE_THREAD" },
532 { CLONE_NEWNS, "CLONE_NEWNS" },
533 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
534 { CLONE_SETTLS, "CLONE_SETTLS" },
535 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
536 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
537 { CLONE_DETACHED, "CLONE_DETACHED" },
538 { CLONE_UNTRACED, "CLONE_UNTRACED" },
539 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000540 { 0, NULL },
541};
542
Roland McGrath909875b2002-12-22 03:34:36 +0000543# ifdef I386
544# include <asm/ldt.h>
Roland McGrath7decfb22004-03-01 22:10:52 +0000545# ifdef HAVE_STRUCT_USER_DESC
546# define modify_ldt_ldt_s user_desc
547# endif
Roland McGrath909875b2002-12-22 03:34:36 +0000548extern void print_ldt_entry();
549# endif
550
Roland McGrath9677b3a2003-03-12 09:54:36 +0000551# if defined IA64
552# define ARG_FLAGS 0
553# define ARG_STACK 1
554# define ARG_STACKSIZE (tcp->scno == SYS_clone2 ? 2 : -1)
Roland McGrathc03981d2003-03-14 10:32:36 +0000555# define ARG_PTID (tcp->scno == SYS_clone2 ? 3 : 2)
556# define ARG_CTID (tcp->scno == SYS_clone2 ? 4 : 3)
557# define ARG_TLS (tcp->scno == SYS_clone2 ? 5 : 4)
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000558# elif defined S390 || defined S390X
Roland McGrath9677b3a2003-03-12 09:54:36 +0000559# define ARG_STACK 0
560# define ARG_FLAGS 1
561# define ARG_PTID 2
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000562# define ARG_CTID 3
563# define ARG_TLS 4
Roland McGrath9c555e72003-07-09 09:47:59 +0000564# elif defined X86_64 || defined ALPHA
Roland McGrath361aac52003-03-18 07:43:42 +0000565# define ARG_FLAGS 0
566# define ARG_STACK 1
567# define ARG_PTID 2
568# define ARG_CTID 3
569# define ARG_TLS 4
Roland McGrath9677b3a2003-03-12 09:54:36 +0000570# else
571# define ARG_FLAGS 0
572# define ARG_STACK 1
573# define ARG_PTID 2
574# define ARG_TLS 3
575# define ARG_CTID 4
576# endif
577
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000578int
579sys_clone(tcp)
580struct tcb *tcp;
581{
582 if (exiting(tcp)) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000583 unsigned long flags = tcp->u_arg[ARG_FLAGS];
584 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
585# ifdef ARG_STACKSIZE
586 if (ARG_STACKSIZE != -1)
587 tprintf("stack_size=%#lx, ",
588 tcp->u_arg[ARG_STACKSIZE]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000589# endif
Roland McGrath9677b3a2003-03-12 09:54:36 +0000590 tprintf("flags=");
Roland McGrath984154d2003-05-23 01:08:42 +0000591 if (printflags(clone_flags, flags &~ CSIGNAL) == 0)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000592 tprintf("0");
Roland McGrath984154d2003-05-23 01:08:42 +0000593 if ((flags & CSIGNAL) != 0)
594 tprintf("|%s", signame(flags & CSIGNAL));
Roland McGrathb4968be2003-01-20 09:04:33 +0000595 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
Roland McGrath9677b3a2003-03-12 09:54:36 +0000596 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
Roland McGrath909875b2002-12-22 03:34:36 +0000597 return 0;
Roland McGrath6f67a982003-03-21 07:33:15 +0000598 if (flags & CLONE_PARENT_SETTID)
599 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000600 if (flags & CLONE_SETTLS) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000601# ifdef I386
Roland McGrath909875b2002-12-22 03:34:36 +0000602 struct modify_ldt_ldt_s copy;
Roland McGrath9677b3a2003-03-12 09:54:36 +0000603 if (umove(tcp, tcp->u_arg[ARG_TLS], &copy) != -1) {
Roland McGrath909875b2002-12-22 03:34:36 +0000604 tprintf(", {entry_number:%d, ",
605 copy.entry_number);
606 if (!verbose(tcp))
607 tprintf("...}");
608 else
609 print_ldt_entry(&copy);
610 }
611 else
Roland McGrath9677b3a2003-03-12 09:54:36 +0000612# endif
Roland McGrath43f2c842003-03-12 09:58:14 +0000613 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
Roland McGrath909875b2002-12-22 03:34:36 +0000614 }
Roland McGrath9677b3a2003-03-12 09:54:36 +0000615 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
616 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000617 }
618 return 0;
619}
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000620#endif
621
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000622int
623sys_fork(tcp)
624struct tcb *tcp;
625{
626 if (exiting(tcp))
627 return RVAL_UDECIMAL;
628 return 0;
629}
630
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000631int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000632change_syscall(tcp, new)
633struct tcb *tcp;
634int new;
635{
636#if defined(LINUX)
637#if defined(I386)
638 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000639 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000640 return -1;
641 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000642#elif defined(X86_64)
643 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000644 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000645 return -1;
646 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000647#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000648 if (ptrace(PTRACE_POKEUSER, tcp->pid,
649 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000650 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000651 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000652#elif defined(S390) || defined(S390X)
653 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
654 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
655 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000656 return 0;
657#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000658 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000659 return -1;
660 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000661#elif defined(SPARC)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000662 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000663 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
664 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000665 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000666 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
667 return -1;
668 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000669#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000670 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000671 return -1;
672 return 0;
673#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000674 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000675 return -1;
676 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000677#elif defined(IA64)
Roland McGrath08267b82004-02-20 22:56:43 +0000678 if (ia32) {
679 switch (new) {
680 case 2: break; /* x86 SYS_fork */
681 case SYS_clone: new = 120; break;
682 default:
683 fprintf(stderr, "%s: unexpected syscall %d\n",
684 __FUNCTION__, new);
685 return -1;
686 }
687 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
688 return -1;
689 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000690 return -1;
691 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000692#elif defined(HPPA)
693 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
694 return -1;
695 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000696#elif defined(SH)
Roland McGrathac971c22003-03-31 01:03:33 +0000697 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
Wichert Akkermanccef6372002-05-01 16:39:22 +0000698 return -1;
699 return 0;
Roland McGrathf5a47772003-06-26 22:40:42 +0000700#elif defined(SH64)
Roland McGrathe1e584b2003-06-02 19:18:58 +0000701 /* Top half of reg encodes the no. of args n as 0x1n.
702 Assume 0 args as kernel never actually checks... */
703 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
704 0x100000 | new) < 0)
705 return -1;
706 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000707#else
708#warning Do not know how to handle change_syscall for this architecture
709#endif /* architecture */
710#endif /* LINUX */
711 return -1;
712}
713
714int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000715setarg(tcp, argnum)
716 struct tcb *tcp;
717 int argnum;
718{
719#if defined (IA64)
720 {
721 unsigned long *bsp, *ap;
722
723 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
724 return -1;
725
726 ap = ia64_rse_skip_regs(bsp, argnum);
727 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000728 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000729 if (errno)
730 return -1;
731
732 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000733#elif defined(I386)
734 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000735 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000736 if (errno)
737 return -1;
738 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000739#elif defined(X86_64)
740 {
741 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
742 if (errno)
743 return -1;
744 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000745#elif defined(POWERPC)
746#ifndef PT_ORIG_R3
747#define PT_ORIG_R3 34
748#endif
749 {
750 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000751 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000752 tcp->u_arg[argnum]);
753 if (errno)
754 return -1;
755 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000756#elif defined(MIPS)
757 {
758 errno = 0;
759 if (argnum < 4)
760 ptrace(PTRACE_POKEUSER, tcp->pid,
761 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
762 else {
763 unsigned long *sp;
764
765 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
766 return -1;
767
768 ptrace(PTRACE_POKEDATA, tcp->pid,
769 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
770 }
771 if (errno)
772 return -1;
773 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000774#elif defined(S390) || defined(S390X)
775 {
776 if(argnum <= 5)
777 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000778 (char *) (argnum==0 ? PT_ORIGGPR2 :
779 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000780 tcp->u_arg[argnum]);
781 else
782 return -E2BIG;
783 if (errno)
784 return -1;
785 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000786#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000787# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000788#endif
789 return 0;
790}
791
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000792#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000793int
794internal_clone(tcp)
795struct tcb *tcp;
796{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000797 struct tcb *tcpchild;
798 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000799 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000800 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000801 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000802 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000803 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000804 if (setbpt(tcp) < 0)
805 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000806 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000807 int bpt = tcp->flags & TCB_BPTSET;
808
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000809 if (!(tcp->flags & TCB_FOLLOWFORK))
810 return 0;
811
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000812 if (syserror(tcp)) {
813 if (bpt)
814 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000815 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000816 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000817
818 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000819
820#ifdef CLONE_PTRACE /* See new setbpt code. */
821 tcpchild = pid2tcb(pid);
822 if (tcpchild != NULL) {
823 /* The child already reported its startup trap
824 before the parent reported its syscall return. */
825 if ((tcpchild->flags
826 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
827 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
828 fprintf(stderr, "\
829[preattached child %d of %d in weird state!]\n",
830 pid, tcp->pid);
831 }
832 else
833#endif
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000834 if ((tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000835 if (bpt)
836 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000837 fprintf(stderr, " [tcb table full]\n");
838 kill(pid, SIGKILL); /* XXX */
839 return 0;
840 }
841
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000842#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000843 /* Attach to the new child */
844 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000845 if (bpt)
846 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000847 perror("PTRACE_ATTACH");
848 fprintf(stderr, "Too late?\n");
849 droptcb(tcpchild);
850 return 0;
851 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000852#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000853
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000854 if (bpt)
855 clearbpt(tcp);
856
Ulrich Drepper90512f01999-12-24 07:22:25 +0000857 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000858 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000859 if (bpt) {
860 tcpchild->flags |= TCB_BPTSET;
861 tcpchild->baddr = tcp->baddr;
862 memcpy(tcpchild->inst, tcp->inst,
863 sizeof tcpchild->inst);
864 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000865 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000866 tcp->nchildren++;
867 if (tcpchild->flags & TCB_SUSPENDED) {
868 /* The child was born suspended, due to our having
869 forced CLONE_PTRACE. */
870 if (bpt)
871 clearbpt(tcpchild);
872
873 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
874 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
875 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
876 return -1;
877 }
878
879 if (!qflag)
880 fprintf(stderr, "\
881Process %u resumed (parent %d ready)\n",
882 pid, tcp->pid);
883 }
884 else {
885 newoutf(tcpchild);
886 if (!qflag)
887 fprintf(stderr, "Process %d attached\n", pid);
888 }
889
890#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000891 {
892 /*
893 * Save the flags used in this call,
894 * in case we point TCP to our parent below.
895 */
896 int call_flags = tcp->u_arg[ARG_FLAGS];
897 if ((tcp->flags & TCB_CLONE_THREAD) &&
898 tcp->parent != NULL) {
899 /* The parent in this clone is itself a
900 thread belonging to another process.
901 There is no meaning to the parentage
902 relationship of the new child with the
903 thread, only with the process. We
904 associate the new thread with our
905 parent. Since this is done for every
906 new thread, there will never be a
907 TCB_CLONE_THREAD process that has
908 children. */
909 --tcp->nchildren;
910 tcp = tcp->parent;
911 tcpchild->parent = tcp;
912 ++tcp->nchildren;
913 }
914 if (call_flags & CLONE_THREAD) {
915 tcpchild->flags |= TCB_CLONE_THREAD;
916 ++tcp->nclone_threads;
917 }
918 if (call_flags & CLONE_DETACHED) {
919 tcpchild->flags |= TCB_CLONE_DETACHED;
920 ++tcp->nclone_detached;
921 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000922 }
923#endif
924
925 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000926 return 0;
927}
928#endif
929
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000930int
931internal_fork(tcp)
932struct tcb *tcp;
933{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000934#ifdef LINUX
935 /* We do special magic with clone for any clone or fork. */
936 return internal_clone(tcp);
937#else
938
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000939 struct tcb *tcpchild;
940 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000941 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000942
943#ifdef SYS_vfork
Nate Sammonsccd8f211999-03-29 22:57:54 +0000944 if (tcp->scno == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000945 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000946 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000947 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000948 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000949 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000950#endif
951 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000952 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000953 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000954 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000955 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000956 if (setbpt(tcp) < 0)
957 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000958 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000959 else {
960 int bpt = tcp->flags & TCB_BPTSET;
961
962 if (!(tcp->flags & TCB_FOLLOWFORK))
963 return 0;
964 if (bpt)
965 clearbpt(tcp);
966
967 if (syserror(tcp))
968 return 0;
969
970 pid = tcp->u_rval;
971 if ((tcpchild = alloctcb(pid)) == NULL) {
972 fprintf(stderr, " [tcb table full]\n");
973 kill(pid, SIGKILL); /* XXX */
974 return 0;
975 }
976#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000977#ifdef HPPA
978 /* The child must have run before it can be attached. */
979 /* This must be a bug in the parisc kernel, but I havn't
980 * identified it yet. Seems to be an issue associated
981 * with attaching to a process (which sends it a signal)
982 * before that process has ever been scheduled. When
983 * debugging, I started seeing crashes in
984 * arch/parisc/kernel/signal.c:do_signal(), apparently
985 * caused by r8 getting corrupt over the dequeue_signal()
986 * call. Didn't make much sense though...
987 */
988 {
989 struct timeval tv;
990 tv.tv_sec = 0;
991 tv.tv_usec = 10000;
992 select(0, NULL, NULL, NULL, &tv);
993 }
994#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000995 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
996 perror("PTRACE_ATTACH");
997 fprintf(stderr, "Too late?\n");
998 droptcb(tcpchild);
999 return 0;
1000 }
1001#endif /* LINUX */
1002#ifdef SUNOS4
1003#ifdef oldway
1004 /* The child must have run before it can be attached. */
1005 {
1006 struct timeval tv;
1007 tv.tv_sec = 0;
1008 tv.tv_usec = 10000;
1009 select(0, NULL, NULL, NULL, &tv);
1010 }
1011 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1012 perror("PTRACE_ATTACH");
1013 fprintf(stderr, "Too late?\n");
1014 droptcb(tcpchild);
1015 return 0;
1016 }
1017#else /* !oldway */
1018 /* Try to catch the new process as soon as possible. */
1019 {
1020 int i;
1021 for (i = 0; i < 1024; i++)
1022 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1023 break;
1024 if (i == 1024) {
1025 perror("PTRACE_ATTACH");
1026 fprintf(stderr, "Too late?\n");
1027 droptcb(tcpchild);
1028 return 0;
1029 }
1030 }
1031#endif /* !oldway */
1032#endif /* SUNOS4 */
1033 tcpchild->flags |= TCB_ATTACHED;
1034 /* Child has BPT too, must be removed on first occasion */
1035 if (bpt) {
1036 tcpchild->flags |= TCB_BPTSET;
1037 tcpchild->baddr = tcp->baddr;
1038 memcpy(tcpchild->inst, tcp->inst,
1039 sizeof tcpchild->inst);
1040 }
1041 newoutf(tcpchild);
1042 tcpchild->parent = tcp;
1043 tcp->nchildren++;
1044 if (!qflag)
1045 fprintf(stderr, "Process %d attached\n", pid);
1046 }
1047 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001048#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001049}
1050
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001051#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001052
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001053#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001054
1055int
1056sys_vfork(tcp)
1057struct tcb *tcp;
1058{
1059 if (exiting(tcp))
1060 return RVAL_UDECIMAL;
1061 return 0;
1062}
1063
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001064#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001065
1066#ifndef LINUX
1067
1068static char idstr[16];
1069
1070int
1071sys_getpid(tcp)
1072struct tcb *tcp;
1073{
1074 if (exiting(tcp)) {
1075 sprintf(idstr, "ppid %lu", getrval2(tcp));
1076 tcp->auxstr = idstr;
1077 return RVAL_STR;
1078 }
1079 return 0;
1080}
1081
1082int
1083sys_getuid(tcp)
1084struct tcb *tcp;
1085{
1086 if (exiting(tcp)) {
1087 sprintf(idstr, "euid %lu", getrval2(tcp));
1088 tcp->auxstr = idstr;
1089 return RVAL_STR;
1090 }
1091 return 0;
1092}
1093
1094int
1095sys_getgid(tcp)
1096struct tcb *tcp;
1097{
1098 if (exiting(tcp)) {
1099 sprintf(idstr, "egid %lu", getrval2(tcp));
1100 tcp->auxstr = idstr;
1101 return RVAL_STR;
1102 }
1103 return 0;
1104}
1105
1106#endif /* !LINUX */
1107
1108#ifdef LINUX
1109
1110int
1111sys_setuid(tcp)
1112struct tcb *tcp;
1113{
1114 if (entering(tcp)) {
1115 tprintf("%u", (uid_t) tcp->u_arg[0]);
1116 }
1117 return 0;
1118}
1119
1120int
1121sys_setgid(tcp)
1122struct tcb *tcp;
1123{
1124 if (entering(tcp)) {
1125 tprintf("%u", (gid_t) tcp->u_arg[0]);
1126 }
1127 return 0;
1128}
1129
1130int
1131sys_getresuid(tcp)
1132 struct tcb *tcp;
1133{
1134 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001135 __kernel_uid_t uid;
1136 if (syserror(tcp))
1137 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1138 tcp->u_arg[1], tcp->u_arg[2]);
1139 else {
1140 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1141 tprintf("%#lx, ", tcp->u_arg[0]);
1142 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001143 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001144 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1145 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001146 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001147 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001148 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1149 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001150 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001151 tprintf("[%lu]", (unsigned long) uid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001152 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001153 }
1154 return 0;
1155}
1156
1157int
1158sys_getresgid(tcp)
1159struct tcb *tcp;
1160{
1161 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001162 __kernel_gid_t gid;
1163 if (syserror(tcp))
1164 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1165 tcp->u_arg[1], tcp->u_arg[2]);
1166 else {
1167 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1168 tprintf("%#lx, ", tcp->u_arg[0]);
1169 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001170 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001171 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1172 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001173 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001174 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001175 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1176 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001177 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001178 tprintf("[%lu]", (unsigned long) gid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001179 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001180 }
1181 return 0;
1182}
1183
1184#endif /* LINUX */
1185
1186int
1187sys_setreuid(tcp)
1188struct tcb *tcp;
1189{
1190 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001191 printuid("", tcp->u_arg[0]);
1192 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001193 }
1194 return 0;
1195}
1196
1197int
1198sys_setregid(tcp)
1199struct tcb *tcp;
1200{
1201 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001202 printuid("", tcp->u_arg[0]);
1203 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001204 }
1205 return 0;
1206}
1207
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001208#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001209int
1210sys_setresuid(tcp)
1211 struct tcb *tcp;
1212{
1213 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001214 printuid("", tcp->u_arg[0]);
1215 printuid(", ", tcp->u_arg[1]);
1216 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001217 }
1218 return 0;
1219}
1220int
1221sys_setresgid(tcp)
1222 struct tcb *tcp;
1223{
1224 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001225 printuid("", tcp->u_arg[0]);
1226 printuid(", ", tcp->u_arg[1]);
1227 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001228 }
1229 return 0;
1230}
1231
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001232#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001233
1234int
1235sys_setgroups(tcp)
1236struct tcb *tcp;
1237{
1238 int i, len;
1239 GETGROUPS_T *gidset;
1240
1241 if (entering(tcp)) {
1242 len = tcp->u_arg[0];
1243 tprintf("%u, ", len);
1244 if (len <= 0) {
1245 tprintf("[]");
1246 return 0;
1247 }
1248 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1249 if (gidset == NULL) {
1250 fprintf(stderr, "sys_setgroups: out of memory\n");
1251 return -1;
1252 }
1253 if (!verbose(tcp))
1254 tprintf("%#lx", tcp->u_arg[1]);
1255 else if (umoven(tcp, tcp->u_arg[1],
1256 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1257 tprintf("[?]");
1258 else {
1259 tprintf("[");
1260 for (i = 0; i < len; i++)
1261 tprintf("%s%lu", i ? ", " : "",
1262 (unsigned long) gidset[i]);
1263 tprintf("]");
1264 }
1265 free((char *) gidset);
1266 }
1267 return 0;
1268}
1269
1270int
1271sys_getgroups(tcp)
1272struct tcb *tcp;
1273{
1274 int i, len;
1275 GETGROUPS_T *gidset;
1276
1277 if (entering(tcp)) {
1278 len = tcp->u_arg[0];
1279 tprintf("%u, ", len);
1280 } else {
1281 len = tcp->u_rval;
1282 if (len <= 0) {
1283 tprintf("[]");
1284 return 0;
1285 }
1286 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1287 if (gidset == NULL) {
1288 fprintf(stderr, "sys_getgroups: out of memory\n");
1289 return -1;
1290 }
1291 if (!tcp->u_arg[1])
1292 tprintf("NULL");
1293 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1294 tprintf("%#lx", tcp->u_arg[1]);
1295 else if (umoven(tcp, tcp->u_arg[1],
1296 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1297 tprintf("[?]");
1298 else {
1299 tprintf("[");
1300 for (i = 0; i < len; i++)
1301 tprintf("%s%lu", i ? ", " : "",
1302 (unsigned long) gidset[i]);
1303 tprintf("]");
1304 }
1305 free((char *)gidset);
1306 }
1307 return 0;
1308}
1309
Roland McGrath83bd47a2003-11-13 22:32:26 +00001310#ifdef LINUX
1311int
1312sys_setgroups32(tcp)
1313struct tcb *tcp;
1314{
1315 int i, len;
1316 GETGROUPS32_T *gidset;
1317
1318 if (entering(tcp)) {
1319 len = tcp->u_arg[0];
1320 tprintf("%u, ", len);
1321 if (len <= 0) {
1322 tprintf("[]");
1323 return 0;
1324 }
1325 gidset = (GETGROUPS32_T *) malloc(len * sizeof(GETGROUPS32_T));
1326 if (gidset == NULL) {
1327 fprintf(stderr, "sys_setgroups32: out of memory\n");
1328 return -1;
1329 }
1330 if (!verbose(tcp))
1331 tprintf("%#lx", tcp->u_arg[1]);
1332 else if (umoven(tcp, tcp->u_arg[1],
1333 len * sizeof(GETGROUPS32_T), (char *) gidset) < 0)
1334 tprintf("[?]");
1335 else {
1336 tprintf("[");
1337 for (i = 0; i < len; i++)
1338 tprintf("%s%lu", i ? ", " : "",
1339 (unsigned long) gidset[i]);
1340 tprintf("]");
1341 }
1342 free((char *) gidset);
1343 }
1344 return 0;
1345}
1346
1347int
1348sys_getgroups32(tcp)
1349struct tcb *tcp;
1350{
1351 int i, len;
1352 GETGROUPS32_T *gidset;
1353
1354 if (entering(tcp)) {
1355 len = tcp->u_arg[0];
1356 tprintf("%u, ", len);
1357 } else {
1358 len = tcp->u_rval;
1359 if (len <= 0) {
1360 tprintf("[]");
1361 return 0;
1362 }
1363 gidset = (GETGROUPS32_T *) malloc(len * sizeof(GETGROUPS32_T));
1364 if (gidset == NULL) {
1365 fprintf(stderr, "sys_getgroups32: out of memory\n");
1366 return -1;
1367 }
1368 if (!tcp->u_arg[1])
1369 tprintf("NULL");
1370 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1371 tprintf("%#lx", tcp->u_arg[1]);
1372 else if (umoven(tcp, tcp->u_arg[1],
1373 len * sizeof(GETGROUPS32_T), (char *) gidset) < 0)
1374 tprintf("[?]");
1375 else {
1376 tprintf("[");
1377 for (i = 0; i < len; i++)
1378 tprintf("%s%lu", i ? ", " : "",
1379 (unsigned long) gidset[i]);
1380 tprintf("]");
1381 }
1382 free((char *)gidset);
1383 }
1384 return 0;
1385}
1386#endif /* LINUX */
1387
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001388int
1389sys_setpgrp(tcp)
1390struct tcb *tcp;
1391{
1392 if (entering(tcp)) {
1393#ifndef SVR4
1394 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1395#endif /* !SVR4 */
1396 }
1397 return 0;
1398}
1399
1400int
1401sys_getpgrp(tcp)
1402struct tcb *tcp;
1403{
1404 if (entering(tcp)) {
1405#ifndef SVR4
1406 tprintf("%lu", tcp->u_arg[0]);
1407#endif /* !SVR4 */
1408 }
1409 return 0;
1410}
1411
1412int
1413sys_getsid(tcp)
1414struct tcb *tcp;
1415{
1416 if (entering(tcp)) {
1417 tprintf("%lu", tcp->u_arg[0]);
1418 }
1419 return 0;
1420}
1421
1422int
1423sys_setsid(tcp)
1424struct tcb *tcp;
1425{
1426 return 0;
1427}
1428
1429int
1430sys_getpgid(tcp)
1431struct tcb *tcp;
1432{
1433 if (entering(tcp)) {
1434 tprintf("%lu", tcp->u_arg[0]);
1435 }
1436 return 0;
1437}
1438
1439int
1440sys_setpgid(tcp)
1441struct tcb *tcp;
1442{
1443 if (entering(tcp)) {
1444 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1445 }
1446 return 0;
1447}
1448
John Hughesc61eb3d2002-05-17 11:37:50 +00001449#if UNIXWARE >= 2
1450
1451#include <sys/privilege.h>
1452
1453
1454static struct xlat procpriv_cmds [] = {
1455 { SETPRV, "SETPRV" },
1456 { CLRPRV, "CLRPRV" },
1457 { PUTPRV, "PUTPRV" },
1458 { GETPRV, "GETPRV" },
1459 { CNTPRV, "CNTPRV" },
1460 { 0, NULL },
1461};
1462
1463
1464static struct xlat procpriv_priv [] = {
1465 { P_OWNER, "P_OWNER" },
1466 { P_AUDIT, "P_AUDIT" },
1467 { P_COMPAT, "P_COMPAT" },
1468 { P_DACREAD, "P_DACREAD" },
1469 { P_DACWRITE, "P_DACWRITE" },
1470 { P_DEV, "P_DEV" },
1471 { P_FILESYS, "P_FILESYS" },
1472 { P_MACREAD, "P_MACREAD" },
1473 { P_MACWRITE, "P_MACWRITE" },
1474 { P_MOUNT, "P_MOUNT" },
1475 { P_MULTIDIR, "P_MULTIDIR" },
1476 { P_SETPLEVEL, "P_SETPLEVEL" },
1477 { P_SETSPRIV, "P_SETSPRIV" },
1478 { P_SETUID, "P_SETUID" },
1479 { P_SYSOPS, "P_SYSOPS" },
1480 { P_SETUPRIV, "P_SETUPRIV" },
1481 { P_DRIVER, "P_DRIVER" },
1482 { P_RTIME, "P_RTIME" },
1483 { P_MACUPGRADE, "P_MACUPGRADE" },
1484 { P_FSYSRANGE, "P_FSYSRANGE" },
1485 { P_SETFLEVEL, "P_SETFLEVEL" },
1486 { P_AUDITWR, "P_AUDITWR" },
1487 { P_TSHAR, "P_TSHAR" },
1488 { P_PLOCK, "P_PLOCK" },
1489 { P_CORE, "P_CORE" },
1490 { P_LOADMOD, "P_LOADMOD" },
1491 { P_BIND, "P_BIND" },
1492 { P_ALLPRIVS, "P_ALLPRIVS" },
1493 { 0, NULL },
1494};
1495
1496
1497static struct xlat procpriv_type [] = {
1498 { PS_FIX, "PS_FIX" },
1499 { PS_INH, "PS_INH" },
1500 { PS_MAX, "PS_MAX" },
1501 { PS_WKG, "PS_WKG" },
1502 { 0, NULL },
1503};
1504
1505
1506static void
1507printpriv(tcp, addr, len, opt)
1508struct tcb *tcp;
1509long addr;
1510int len;
1511struct xlat *opt;
1512{
1513 priv_t buf [128];
1514 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1515 int dots = len > max;
1516 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001517
John Hughesc61eb3d2002-05-17 11:37:50 +00001518 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001519
John Hughesc61eb3d2002-05-17 11:37:50 +00001520 if (len <= 0 ||
1521 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1522 {
1523 tprintf ("%#lx", addr);
1524 return;
1525 }
1526
1527 tprintf ("[");
1528
1529 for (i = 0; i < len; ++i) {
1530 char *t, *p;
1531
1532 if (i) tprintf (", ");
1533
1534 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1535 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1536 {
1537 tprintf ("%s|%s", t, p);
1538 }
1539 else {
1540 tprintf ("%#lx", buf [i]);
1541 }
1542 }
1543
1544 if (dots) tprintf (" ...");
1545
1546 tprintf ("]");
1547}
1548
1549
1550int
1551sys_procpriv(tcp)
1552struct tcb *tcp;
1553{
1554 if (entering(tcp)) {
1555 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1556 switch (tcp->u_arg[0]) {
1557 case CNTPRV:
1558 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1559 break;
1560
1561 case GETPRV:
1562 break;
1563
1564 default:
1565 tprintf (", ");
1566 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1567 tprintf (", %ld", tcp->u_arg[2]);
1568 }
1569 }
1570 else if (tcp->u_arg[0] == GETPRV) {
1571 if (syserror (tcp)) {
1572 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1573 }
1574 else {
1575 tprintf (", ");
1576 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1577 tprintf (", %ld", tcp->u_arg[2]);
1578 }
1579 }
Roland McGrath5a223472002-12-15 23:58:26 +00001580
John Hughesc61eb3d2002-05-17 11:37:50 +00001581 return 0;
1582}
1583
1584#endif
1585
1586
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001587void
1588fake_execve(tcp, program, argv, envp)
1589struct tcb *tcp;
1590char *program;
1591char *argv[];
1592char *envp[];
1593{
1594 int i;
1595
1596#ifdef ARM
1597 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1598 return;
1599#else
1600 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1601 return;
1602#endif /* !ARM */
1603 printleader(tcp);
1604 tprintf("execve(");
1605 string_quote(program);
1606 tprintf(", [");
1607 for (i = 0; argv[i] != NULL; i++) {
1608 if (i != 0)
1609 tprintf(", ");
1610 string_quote(argv[i]);
1611 }
1612 for (i = 0; envp[i] != NULL; i++)
1613 ;
1614 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1615 tabto(acolumn);
1616 tprintf("= 0");
1617 printtrailer(tcp);
1618}
1619
1620static void
1621printargv(tcp, addr)
1622struct tcb *tcp;
1623long addr;
1624{
1625 char *cp;
1626 char *sep;
1627 int max = max_strlen / 2;
1628
1629 for (sep = ""; --max >= 0; sep = ", ") {
1630 if (!abbrev(tcp))
1631 max++;
1632 if (umove(tcp, addr, &cp) < 0) {
1633 tprintf("%#lx", addr);
1634 return;
1635 }
1636 if (cp == 0)
1637 break;
1638 tprintf(sep);
1639 printstr(tcp, (long) cp, -1);
1640 addr += sizeof(char *);
1641 }
1642 if (cp)
1643 tprintf(", ...");
1644}
1645
1646static void
1647printargc(fmt, tcp, addr)
1648char *fmt;
1649struct tcb *tcp;
1650long addr;
1651{
1652 int count;
1653 char *cp;
1654
1655 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1656 addr += sizeof(char *);
1657 }
1658 tprintf(fmt, count, count == 1 ? "" : "s");
1659}
1660
1661int
1662sys_execv(tcp)
1663struct tcb *tcp;
1664{
1665 if (entering(tcp)) {
1666 printpath(tcp, tcp->u_arg[0]);
1667 if (!verbose(tcp))
1668 tprintf(", %#lx", tcp->u_arg[1]);
1669#if 0
1670 else if (abbrev(tcp))
1671 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1672#endif
1673 else {
1674 tprintf(", [");
1675 printargv(tcp, tcp->u_arg[1]);
1676 tprintf("]");
1677 }
1678 }
1679 return 0;
1680}
1681
1682int
1683sys_execve(tcp)
1684struct tcb *tcp;
1685{
1686 if (entering(tcp)) {
1687 printpath(tcp, tcp->u_arg[0]);
1688 if (!verbose(tcp))
1689 tprintf(", %#lx", tcp->u_arg[1]);
1690#if 0
1691 else if (abbrev(tcp))
1692 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1693#endif
1694 else {
1695 tprintf(", [");
1696 printargv(tcp, tcp->u_arg[1]);
1697 tprintf("]");
1698 }
1699 if (!verbose(tcp))
1700 tprintf(", %#lx", tcp->u_arg[2]);
1701 else if (abbrev(tcp))
1702 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1703 else {
1704 tprintf(", [");
1705 printargv(tcp, tcp->u_arg[2]);
1706 tprintf("]");
1707 }
1708 }
Roland McGrathb4968be2003-01-20 09:04:33 +00001709#if defined LINUX && defined TCB_WAITEXECVE
Roland McGrathb09e33a2004-03-01 22:03:58 +00001710 if (exiting(tcp) && syserror(tcp))
1711 tcp->flags &= ~TCB_WAITEXECVE;
1712 else
1713 tcp->flags |= TCB_WAITEXECVE;
Roland McGrathb4968be2003-01-20 09:04:33 +00001714#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001715 return 0;
1716}
1717
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001718#if UNIXWARE > 2
John Hughes4e36a812001-04-18 15:11:51 +00001719
1720int sys_rexecve(tcp)
1721struct tcb *tcp;
1722{
1723 if (entering (tcp)) {
1724 sys_execve (tcp);
1725 tprintf (", %ld", tcp->u_arg[3]);
1726 }
1727 return 0;
1728}
1729
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001730#endif
John Hughes4e36a812001-04-18 15:11:51 +00001731
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001732int
1733internal_exec(tcp)
1734struct tcb *tcp;
1735{
1736#ifdef SUNOS4
1737 if (exiting(tcp) && !syserror(tcp) && followfork)
1738 fixvfork(tcp);
1739#endif /* SUNOS4 */
1740 return 0;
1741}
1742
1743#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001744#ifndef __WNOTHREAD
1745#define __WNOTHREAD 0x20000000
1746#endif
1747#ifndef __WALL
1748#define __WALL 0x40000000
1749#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001750#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001751#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001752#endif
1753#endif /* LINUX */
1754
1755static struct xlat wait4_options[] = {
1756 { WNOHANG, "WNOHANG" },
1757#ifndef WSTOPPED
1758 { WUNTRACED, "WUNTRACED" },
1759#endif
1760#ifdef WEXITED
1761 { WEXITED, "WEXITED" },
1762#endif
1763#ifdef WTRAPPED
1764 { WTRAPPED, "WTRAPPED" },
1765#endif
1766#ifdef WSTOPPED
1767 { WSTOPPED, "WSTOPPED" },
1768#endif
1769#ifdef WCONTINUED
1770 { WCONTINUED, "WCONTINUED" },
1771#endif
1772#ifdef WNOWAIT
1773 { WNOWAIT, "WNOWAIT" },
1774#endif
1775#ifdef __WCLONE
1776 { __WCLONE, "__WCLONE" },
1777#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001778#ifdef __WALL
1779 { __WALL, "__WALL" },
1780#endif
1781#ifdef __WNOTHREAD
1782 { __WNOTHREAD, "__WNOTHREAD" },
1783#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001784 { 0, NULL },
1785};
1786
1787static int
1788printstatus(status)
1789int status;
1790{
1791 int exited = 0;
1792
1793 /*
1794 * Here is a tricky presentation problem. This solution
1795 * is still not entirely satisfactory but since there
1796 * are no wait status constructors it will have to do.
1797 */
Roland McGrath79fbda52004-04-14 02:45:55 +00001798 if (WIFSTOPPED(status)) {
1799 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001800 signame(WSTOPSIG(status)));
Roland McGrath79fbda52004-04-14 02:45:55 +00001801 status &= ~W_STOPCODE(WSTOPSIG(status));
1802 }
1803 else if (WIFSIGNALED(status)) {
1804 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001805 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001806 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
Roland McGrath79fbda52004-04-14 02:45:55 +00001807 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1808 }
1809 else if (WIFEXITED(status)) {
1810 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001811 WEXITSTATUS(status));
1812 exited = 1;
Roland McGrath79fbda52004-04-14 02:45:55 +00001813 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001814 }
Roland McGrath79fbda52004-04-14 02:45:55 +00001815 else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001816 tprintf("[%#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001817 return 0;
1818 }
1819
1820 if (status == 0)
1821 tprintf("]");
1822 else
Roland McGrathf8cc83c2004-06-04 01:24:07 +00001823 tprintf(" | %#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001824
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001825 return exited;
1826}
1827
1828static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001829printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001830struct tcb *tcp;
1831int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001832int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001833{
1834 int status;
1835 int exited = 0;
1836
1837 if (entering(tcp)) {
1838 tprintf("%ld, ", tcp->u_arg[0]);
1839 } else {
1840 /* status */
1841 if (!tcp->u_arg[1])
1842 tprintf("NULL");
1843 else if (syserror(tcp) || tcp->u_rval == 0)
1844 tprintf("%#lx", tcp->u_arg[1]);
1845 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1846 tprintf("[?]");
1847 else
1848 exited = printstatus(status);
1849 /* options */
1850 tprintf(", ");
1851 if (!printflags(wait4_options, tcp->u_arg[2]))
1852 tprintf("0");
1853 if (n == 4) {
1854 tprintf(", ");
1855 /* usage */
1856 if (!tcp->u_arg[3])
1857 tprintf("NULL");
1858#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001859 else if (tcp->u_rval > 0) {
1860#ifdef LINUX_64BIT
1861 if (bitness)
1862 printrusage32(tcp, tcp->u_arg[3]);
1863 else
1864#endif
1865 printrusage(tcp, tcp->u_arg[3]);
1866 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001867#endif /* LINUX */
1868#ifdef SUNOS4
1869 else if (tcp->u_rval > 0 && exited)
1870 printrusage(tcp, tcp->u_arg[3]);
1871#endif /* SUNOS4 */
1872 else
1873 tprintf("%#lx", tcp->u_arg[3]);
1874 }
1875 }
1876 return 0;
1877}
1878
1879int
1880internal_wait(tcp)
1881struct tcb *tcp;
1882{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001883 int got_kids;
1884
1885#ifdef TCB_CLONE_THREAD
1886 if (tcp->flags & TCB_CLONE_THREAD)
1887 /* The children we wait for are our parent's children. */
1888 got_kids = (tcp->parent->nchildren
1889 > tcp->parent->nclone_detached);
1890 else
1891 got_kids = (tcp->nchildren > tcp->nclone_detached);
1892#else
1893 got_kids = tcp->nchildren > 0;
1894#endif
1895
1896 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001897 /* There are children that this parent should block for.
1898 But ptrace made us the parent of the traced children
1899 and the real parent will get ECHILD from the wait call.
1900
1901 XXX If we attached with strace -f -p PID, then there
1902 may be untraced dead children the parent could be reaping
1903 now, but we make him block. */
1904
1905 /* ??? WTA: fix bug with hanging children */
1906
1907 if (!(tcp->u_arg[2] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00001908 /*
1909 * There are traced children. We'll make the parent
1910 * block to avoid a false ECHILD error due to our
1911 * ptrace having stolen the children. However,
1912 * we shouldn't block if there are zombies to reap.
1913 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1914 */
Roland McGrathfccfb942003-10-01 21:59:44 +00001915 struct tcb *child = NULL;
Roland McGrath09623452003-05-23 02:27:13 +00001916 if (tcp->nzombies > 0 &&
1917 (tcp->u_arg[0] == -1 ||
Roland McGrathfccfb942003-10-01 21:59:44 +00001918 (child = pid2tcb(tcp->u_arg[0])) == NULL))
Roland McGrath09623452003-05-23 02:27:13 +00001919 return 0;
Roland McGrathfccfb942003-10-01 21:59:44 +00001920 if (tcp->u_arg[0] > 0) {
1921 /*
1922 * If the parent waits for a specified child
1923 * PID, then it must get ECHILD right away
1924 * if that PID is not one of its children.
1925 * Make sure that the requested PID matches
1926 * one of the parent's children that we are
1927 * tracing, and don't suspend it otherwise.
1928 */
1929 if (child == NULL)
1930 child = pid2tcb(tcp->u_arg[0]);
1931 if (child == NULL || child->parent != (
1932#ifdef TCB_CLONE_THREAD
1933 (tcp->flags & TCB_CLONE_THREAD)
1934 ? tcp->parent :
1935#endif
1936 tcp))
1937 return 0;
1938 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001939 tcp->flags |= TCB_SUSPENDED;
1940 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001941#ifdef TCB_CLONE_THREAD
1942 if (tcp->flags & TCB_CLONE_THREAD)
1943 tcp->parent->nclone_waiting++;
1944#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001945 }
1946 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001947 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001948 if (tcp->u_arg[2] & WNOHANG) {
1949 /* We must force a fake result of 0 instead of
1950 the ECHILD error. */
1951 extern int force_result();
1952 return force_result(tcp, 0, 0);
1953 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00001954 }
Roland McGrath09623452003-05-23 02:27:13 +00001955 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
1956 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
1957 /*
1958 * We just reaped a child we don't know about,
1959 * presumably a zombie we already droptcb'd.
1960 */
1961 tcp->nzombies--;
1962 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001963 return 0;
1964}
1965
1966#ifdef SVR4
1967
1968int
1969sys_wait(tcp)
1970struct tcb *tcp;
1971{
1972 if (exiting(tcp)) {
1973 /* The library wrapper stuffs this into the user variable. */
1974 if (!syserror(tcp))
1975 printstatus(getrval2(tcp));
1976 }
1977 return 0;
1978}
1979
1980#endif /* SVR4 */
1981
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001982#ifdef FREEBSD
1983int
1984sys_wait(tcp)
1985struct tcb *tcp;
1986{
1987 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001988
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001989 if (exiting(tcp)) {
1990 if (!syserror(tcp)) {
1991 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1992 tprintf("%#lx", tcp->u_arg[0]);
1993 else
1994 printstatus(status);
1995 }
1996 }
1997 return 0;
1998}
1999#endif
2000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002001int
2002sys_waitpid(tcp)
2003struct tcb *tcp;
2004{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002005 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002006}
2007
2008int
2009sys_wait4(tcp)
2010struct tcb *tcp;
2011{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002012 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002013}
2014
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002015#ifdef ALPHA
2016int
2017sys_osf_wait4(tcp)
2018struct tcb *tcp;
2019{
2020 return printwaitn(tcp, 4, 1);
2021}
2022#endif
2023
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002024#ifdef SVR4
2025
2026static struct xlat waitid_types[] = {
2027 { P_PID, "P_PID" },
2028 { P_PPID, "P_PPID" },
2029 { P_PGID, "P_PGID" },
2030 { P_SID, "P_SID" },
2031 { P_CID, "P_CID" },
2032 { P_UID, "P_UID" },
2033 { P_GID, "P_GID" },
2034 { P_ALL, "P_ALL" },
2035#ifdef P_LWPID
2036 { P_LWPID, "P_LWPID" },
2037#endif
2038 { 0, NULL },
2039};
2040
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002041int
2042sys_waitid(tcp)
2043struct tcb *tcp;
2044{
2045 siginfo_t si;
2046 int exited;
2047
2048 if (entering(tcp)) {
2049 printxval(waitid_types, tcp->u_arg[0], "P_???");
2050 tprintf(", %ld, ", tcp->u_arg[1]);
2051 if (tcp->nchildren > 0) {
2052 /* There are traced children */
2053 tcp->flags |= TCB_SUSPENDED;
2054 tcp->waitpid = tcp->u_arg[0];
2055 }
2056 }
2057 else {
2058 /* siginfo */
2059 exited = 0;
2060 if (!tcp->u_arg[2])
2061 tprintf("NULL");
2062 else if (syserror(tcp))
2063 tprintf("%#lx", tcp->u_arg[2]);
2064 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2065 tprintf("{???}");
2066 else
John Hughes58265892001-10-18 15:13:53 +00002067 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002068 /* options */
2069 tprintf(", ");
2070 if (!printflags(wait4_options, tcp->u_arg[3]))
2071 tprintf("0");
2072 }
2073 return 0;
2074}
2075
2076#endif /* SVR4 */
2077
2078int
2079sys_alarm(tcp)
2080struct tcb *tcp;
2081{
2082 if (entering(tcp))
2083 tprintf("%lu", tcp->u_arg[0]);
2084 return 0;
2085}
2086
2087int
2088sys_uname(tcp)
2089struct tcb *tcp;
2090{
2091 struct utsname uname;
2092
2093 if (exiting(tcp)) {
2094 if (syserror(tcp) || !verbose(tcp))
2095 tprintf("%#lx", tcp->u_arg[0]);
2096 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2097 tprintf("{...}");
2098 else if (!abbrev(tcp)) {
2099
2100 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2101 uname.sysname, uname.nodename);
2102 tprintf("release=\"%s\", version=\"%s\", ",
2103 uname.release, uname.version);
2104 tprintf("machine=\"%s\"", uname.machine);
2105#ifdef LINUX
2106#ifndef __GLIBC__
2107 tprintf(", domainname=\"%s\"", uname.domainname);
2108#endif /* __GLIBC__ */
2109#endif /* LINUX */
2110 tprintf("}");
2111 }
2112 else
2113 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2114 uname.sysname, uname.nodename);
2115 }
2116 return 0;
2117}
2118
2119#ifndef SVR4
2120
2121static struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002122#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002123 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2124 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2125 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2126 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2127 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2128 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2129 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2130 { PTRACE_CONT, "PTRACE_CONT" },
2131 { PTRACE_KILL, "PTRACE_KILL" },
2132 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2133 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2134 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002135#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002136 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002137#endif
2138#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002139 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002140#endif
2141#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002142 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002143#endif
2144#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002145 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002146#endif
2147#ifdef PTRACE_GETFPXREGS
2148 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2149#endif
2150#ifdef PTRACE_SETFPXREGS
2151 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2152#endif
2153#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002154 { PTRACE_READDATA, "PTRACE_READDATA" },
2155 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2156 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2157 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2158 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2159 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2160#ifdef SPARC
2161 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2162 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2163#else /* !SPARC */
2164 { PTRACE_22, "PTRACE_PTRACE_22" },
2165 { PTRACE_23, "PTRACE_PTRACE_23" },
2166#endif /* !SPARC */
2167#endif /* SUNOS4 */
2168 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2169#ifdef SUNOS4
2170 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2171#ifdef I386
2172 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2173 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2174 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2175#else /* !I386 */
2176 { PTRACE_26, "PTRACE_26" },
2177 { PTRACE_27, "PTRACE_27" },
2178 { PTRACE_28, "PTRACE_28" },
2179#endif /* !I386 */
2180 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2181#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002182#else /* FREEBSD */
2183 { PT_TRACE_ME, "PT_TRACE_ME" },
2184 { PT_READ_I, "PT_READ_I" },
2185 { PT_READ_D, "PT_READ_D" },
2186 { PT_WRITE_I, "PT_WRITE_I" },
2187 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002188#ifdef PT_READ_U
2189 { PT_READ_U, "PT_READ_U" },
2190#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002191 { PT_CONTINUE, "PT_CONTINUE" },
2192 { PT_KILL, "PT_KILL" },
2193 { PT_STEP, "PT_STEP" },
2194 { PT_ATTACH, "PT_ATTACH" },
2195 { PT_DETACH, "PT_DETACH" },
2196 { PT_GETREGS, "PT_GETREGS" },
2197 { PT_SETREGS, "PT_SETREGS" },
2198 { PT_GETFPREGS, "PT_GETFPREGS" },
2199 { PT_SETFPREGS, "PT_SETFPREGS" },
2200 { PT_GETDBREGS, "PT_GETDBREGS" },
2201 { PT_SETDBREGS, "PT_SETDBREGS" },
2202#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002203 { 0, NULL },
2204};
2205
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002206#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002207#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2208static
2209#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2210struct xlat struct_user_offsets[] = {
2211#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002212#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002213 { PT_PSWMASK, "psw_mask" },
2214 { PT_PSWADDR, "psw_addr" },
2215 { PT_GPR0, "gpr0" },
2216 { PT_GPR1, "gpr1" },
2217 { PT_GPR2, "gpr2" },
2218 { PT_GPR3, "gpr3" },
2219 { PT_GPR4, "gpr4" },
2220 { PT_GPR5, "gpr5" },
2221 { PT_GPR6, "gpr6" },
2222 { PT_GPR7, "gpr7" },
2223 { PT_GPR8, "gpr8" },
2224 { PT_GPR9, "gpr9" },
2225 { PT_GPR10, "gpr10" },
2226 { PT_GPR11, "gpr11" },
2227 { PT_GPR12, "gpr12" },
2228 { PT_GPR13, "gpr13" },
2229 { PT_GPR14, "gpr14" },
2230 { PT_GPR15, "gpr15" },
2231 { PT_ACR0, "acr0" },
2232 { PT_ACR1, "acr1" },
2233 { PT_ACR2, "acr2" },
2234 { PT_ACR3, "acr3" },
2235 { PT_ACR4, "acr4" },
2236 { PT_ACR5, "acr5" },
2237 { PT_ACR6, "acr6" },
2238 { PT_ACR7, "acr7" },
2239 { PT_ACR8, "acr8" },
2240 { PT_ACR9, "acr9" },
2241 { PT_ACR10, "acr10" },
2242 { PT_ACR11, "acr11" },
2243 { PT_ACR12, "acr12" },
2244 { PT_ACR13, "acr13" },
2245 { PT_ACR14, "acr14" },
2246 { PT_ACR15, "acr15" },
2247 { PT_ORIGGPR2, "orig_gpr2" },
2248 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002249#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002250 { PT_FPR0_HI, "fpr0.hi" },
2251 { PT_FPR0_LO, "fpr0.lo" },
2252 { PT_FPR1_HI, "fpr1.hi" },
2253 { PT_FPR1_LO, "fpr1.lo" },
2254 { PT_FPR2_HI, "fpr2.hi" },
2255 { PT_FPR2_LO, "fpr2.lo" },
2256 { PT_FPR3_HI, "fpr3.hi" },
2257 { PT_FPR3_LO, "fpr3.lo" },
2258 { PT_FPR4_HI, "fpr4.hi" },
2259 { PT_FPR4_LO, "fpr4.lo" },
2260 { PT_FPR5_HI, "fpr5.hi" },
2261 { PT_FPR5_LO, "fpr5.lo" },
2262 { PT_FPR6_HI, "fpr6.hi" },
2263 { PT_FPR6_LO, "fpr6.lo" },
2264 { PT_FPR7_HI, "fpr7.hi" },
2265 { PT_FPR7_LO, "fpr7.lo" },
2266 { PT_FPR8_HI, "fpr8.hi" },
2267 { PT_FPR8_LO, "fpr8.lo" },
2268 { PT_FPR9_HI, "fpr9.hi" },
2269 { PT_FPR9_LO, "fpr9.lo" },
2270 { PT_FPR10_HI, "fpr10.hi" },
2271 { PT_FPR10_LO, "fpr10.lo" },
2272 { PT_FPR11_HI, "fpr11.hi" },
2273 { PT_FPR11_LO, "fpr11.lo" },
2274 { PT_FPR12_HI, "fpr12.hi" },
2275 { PT_FPR12_LO, "fpr12.lo" },
2276 { PT_FPR13_HI, "fpr13.hi" },
2277 { PT_FPR13_LO, "fpr13.lo" },
2278 { PT_FPR14_HI, "fpr14.hi" },
2279 { PT_FPR14_LO, "fpr14.lo" },
2280 { PT_FPR15_HI, "fpr15.hi" },
2281 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002282#endif
2283#if defined(S390X)
2284 { PT_FPR0, "fpr0" },
2285 { PT_FPR1, "fpr1" },
2286 { PT_FPR2, "fpr2" },
2287 { PT_FPR3, "fpr3" },
2288 { PT_FPR4, "fpr4" },
2289 { PT_FPR5, "fpr5" },
2290 { PT_FPR6, "fpr6" },
2291 { PT_FPR7, "fpr7" },
2292 { PT_FPR8, "fpr8" },
2293 { PT_FPR9, "fpr9" },
2294 { PT_FPR10, "fpr10" },
2295 { PT_FPR11, "fpr11" },
2296 { PT_FPR12, "fpr12" },
2297 { PT_FPR13, "fpr13" },
2298 { PT_FPR14, "fpr14" },
2299 { PT_FPR15, "fpr15" },
2300#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002301 { PT_CR_9, "cr9" },
2302 { PT_CR_10, "cr10" },
2303 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002304 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002305#endif
2306#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002307 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002308#elif defined(HPPA)
2309 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002310#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002311#ifndef PT_ORIG_R3
2312#define PT_ORIG_R3 34
2313#endif
Roland McGratheb285352003-01-14 09:59:00 +00002314#define REGSIZE (sizeof(unsigned long))
2315 { REGSIZE*PT_R0, "r0" },
2316 { REGSIZE*PT_R1, "r1" },
2317 { REGSIZE*PT_R2, "r2" },
2318 { REGSIZE*PT_R3, "r3" },
2319 { REGSIZE*PT_R4, "r4" },
2320 { REGSIZE*PT_R5, "r5" },
2321 { REGSIZE*PT_R6, "r6" },
2322 { REGSIZE*PT_R7, "r7" },
2323 { REGSIZE*PT_R8, "r8" },
2324 { REGSIZE*PT_R9, "r9" },
2325 { REGSIZE*PT_R10, "r10" },
2326 { REGSIZE*PT_R11, "r11" },
2327 { REGSIZE*PT_R12, "r12" },
2328 { REGSIZE*PT_R13, "r13" },
2329 { REGSIZE*PT_R14, "r14" },
2330 { REGSIZE*PT_R15, "r15" },
2331 { REGSIZE*PT_R16, "r16" },
2332 { REGSIZE*PT_R17, "r17" },
2333 { REGSIZE*PT_R18, "r18" },
2334 { REGSIZE*PT_R19, "r19" },
2335 { REGSIZE*PT_R20, "r20" },
2336 { REGSIZE*PT_R21, "r21" },
2337 { REGSIZE*PT_R22, "r22" },
2338 { REGSIZE*PT_R23, "r23" },
2339 { REGSIZE*PT_R24, "r24" },
2340 { REGSIZE*PT_R25, "r25" },
2341 { REGSIZE*PT_R26, "r26" },
2342 { REGSIZE*PT_R27, "r27" },
2343 { REGSIZE*PT_R28, "r28" },
2344 { REGSIZE*PT_R29, "r29" },
2345 { REGSIZE*PT_R30, "r30" },
2346 { REGSIZE*PT_R31, "r31" },
2347 { REGSIZE*PT_NIP, "NIP" },
2348 { REGSIZE*PT_MSR, "MSR" },
2349 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2350 { REGSIZE*PT_CTR, "CTR" },
2351 { REGSIZE*PT_LNK, "LNK" },
2352 { REGSIZE*PT_XER, "XER" },
2353 { REGSIZE*PT_CCR, "CCR" },
2354 { REGSIZE*PT_FPR0, "FPR0" },
2355#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002356#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002357#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002358 { 0, "r0" },
2359 { 1, "r1" },
2360 { 2, "r2" },
2361 { 3, "r3" },
2362 { 4, "r4" },
2363 { 5, "r5" },
2364 { 6, "r6" },
2365 { 7, "r7" },
2366 { 8, "r8" },
2367 { 9, "r9" },
2368 { 10, "r10" },
2369 { 11, "r11" },
2370 { 12, "r12" },
2371 { 13, "r13" },
2372 { 14, "r14" },
2373 { 15, "r15" },
2374 { 16, "r16" },
2375 { 17, "r17" },
2376 { 18, "r18" },
2377 { 19, "r19" },
2378 { 20, "r20" },
2379 { 21, "r21" },
2380 { 22, "r22" },
2381 { 23, "r23" },
2382 { 24, "r24" },
2383 { 25, "r25" },
2384 { 26, "r26" },
2385 { 27, "r27" },
2386 { 28, "r28" },
2387 { 29, "gp" },
2388 { 30, "fp" },
2389 { 31, "zero" },
2390 { 32, "fp0" },
2391 { 33, "fp" },
2392 { 34, "fp2" },
2393 { 35, "fp3" },
2394 { 36, "fp4" },
2395 { 37, "fp5" },
2396 { 38, "fp6" },
2397 { 39, "fp7" },
2398 { 40, "fp8" },
2399 { 41, "fp9" },
2400 { 42, "fp10" },
2401 { 43, "fp11" },
2402 { 44, "fp12" },
2403 { 45, "fp13" },
2404 { 46, "fp14" },
2405 { 47, "fp15" },
2406 { 48, "fp16" },
2407 { 49, "fp17" },
2408 { 50, "fp18" },
2409 { 51, "fp19" },
2410 { 52, "fp20" },
2411 { 53, "fp21" },
2412 { 54, "fp22" },
2413 { 55, "fp23" },
2414 { 56, "fp24" },
2415 { 57, "fp25" },
2416 { 58, "fp26" },
2417 { 59, "fp27" },
2418 { 60, "fp28" },
2419 { 61, "fp29" },
2420 { 62, "fp30" },
2421 { 63, "fp31" },
2422 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002423#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002424#ifdef IA64
2425 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2426 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2427 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2428 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2429 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2430 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2431 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2432 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2433 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2434 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2435 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2436 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2437 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2438 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2439 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2440 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2441 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2442 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2443 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2444 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2445 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2446 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2447 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2448 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2449 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2450 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2451 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2452 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2453 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2454 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2455 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2456 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2457 /* switch stack: */
2458 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2459 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2460 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2461 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2462 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2463 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2464 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2465 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2466 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2467 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002468 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2469 { PT_B4, "b4" }, { PT_B5, "b5" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002470 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002471 /* pt_regs */
Roland McGrathca4e10c2004-01-13 10:13:20 +00002472 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2473 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002474 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2475 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2476 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2477 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2478 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2479 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2480 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2481 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2482 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2483 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2484 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2485 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2486 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2487 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2488 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
Roland McGrathfb1bc072004-03-01 21:29:24 +00002489# ifdef PT_AR_CSD
2490 { PT_AR_CSD, "ar.csd" },
2491# endif
2492# ifdef PT_AR_SSD
2493 { PT_AR_SSD, "ar.ssd" },
2494# endif
Roland McGrathca4e10c2004-01-13 10:13:20 +00002495 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002496#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002497#ifdef I386
2498 { 4*EBX, "4*EBX" },
2499 { 4*ECX, "4*ECX" },
2500 { 4*EDX, "4*EDX" },
2501 { 4*ESI, "4*ESI" },
2502 { 4*EDI, "4*EDI" },
2503 { 4*EBP, "4*EBP" },
2504 { 4*EAX, "4*EAX" },
2505 { 4*DS, "4*DS" },
2506 { 4*ES, "4*ES" },
2507 { 4*FS, "4*FS" },
2508 { 4*GS, "4*GS" },
2509 { 4*ORIG_EAX, "4*ORIG_EAX" },
2510 { 4*EIP, "4*EIP" },
2511 { 4*CS, "4*CS" },
2512 { 4*EFL, "4*EFL" },
2513 { 4*UESP, "4*UESP" },
2514 { 4*SS, "4*SS" },
2515#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002516#ifdef X86_64
2517 { 8*RDI, "8*RDI" },
2518 { 8*RSI, "8*RSI" },
2519 { 8*RDX, "8*RDX" },
2520 { 8*R10, "8*R10" },
2521 { 8*R8, "8*R8" },
2522 { 8*R9, "8*R9" },
2523 { 8*RBX, "8*RBX" },
2524 { 8*RCX, "8*RCX" },
2525 { 8*RBP, "8*RBP" },
2526 { 8*RAX, "8*RAX" },
2527#if 0
2528 { 8*DS, "8*DS" },
2529 { 8*ES, "8*ES" },
2530 { 8*FS, "8*FS" },
2531 { 8*GS, "8*GS" },
2532#endif
2533 { 8*ORIG_RAX, "8*ORIG_EAX" },
2534 { 8*RIP, "8*RIP" },
2535 { 8*CS, "8*CS" },
2536 { 8*EFLAGS, "8*EFL" },
2537 { 8*RSP, "8*RSP" },
2538 { 8*SS, "8*SS" },
2539 { 8*R11, "8*R11" },
2540 { 8*R12, "8*R12" },
2541 { 8*R13, "8*R13" },
2542 { 8*R14, "8*R14" },
2543 { 8*R15, "8*R15" },
2544#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002545#ifdef M68K
2546 { 4*PT_D1, "4*PT_D1" },
2547 { 4*PT_D2, "4*PT_D2" },
2548 { 4*PT_D3, "4*PT_D3" },
2549 { 4*PT_D4, "4*PT_D4" },
2550 { 4*PT_D5, "4*PT_D5" },
2551 { 4*PT_D6, "4*PT_D6" },
2552 { 4*PT_D7, "4*PT_D7" },
2553 { 4*PT_A0, "4*PT_A0" },
2554 { 4*PT_A1, "4*PT_A1" },
2555 { 4*PT_A2, "4*PT_A2" },
2556 { 4*PT_A3, "4*PT_A3" },
2557 { 4*PT_A4, "4*PT_A4" },
2558 { 4*PT_A5, "4*PT_A5" },
2559 { 4*PT_A6, "4*PT_A6" },
2560 { 4*PT_D0, "4*PT_D0" },
2561 { 4*PT_USP, "4*PT_USP" },
2562 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2563 { 4*PT_SR, "4*PT_SR" },
2564 { 4*PT_PC, "4*PT_PC" },
2565#endif /* M68K */
2566#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002567#ifdef SH
2568 { 4*REG_REG0, "4*REG_REG0" },
2569 { 4*(REG_REG0+1), "4*REG_REG1" },
2570 { 4*(REG_REG0+2), "4*REG_REG2" },
2571 { 4*(REG_REG0+3), "4*REG_REG3" },
2572 { 4*(REG_REG0+4), "4*REG_REG4" },
2573 { 4*(REG_REG0+5), "4*REG_REG5" },
2574 { 4*(REG_REG0+6), "4*REG_REG6" },
2575 { 4*(REG_REG0+7), "4*REG_REG7" },
2576 { 4*(REG_REG0+8), "4*REG_REG8" },
2577 { 4*(REG_REG0+9), "4*REG_REG9" },
2578 { 4*(REG_REG0+10), "4*REG_REG10" },
2579 { 4*(REG_REG0+11), "4*REG_REG11" },
2580 { 4*(REG_REG0+12), "4*REG_REG12" },
2581 { 4*(REG_REG0+13), "4*REG_REG13" },
2582 { 4*(REG_REG0+14), "4*REG_REG14" },
2583 { 4*REG_REG15, "4*REG_REG15" },
2584 { 4*REG_PC, "4*REG_PC" },
2585 { 4*REG_PR, "4*REG_PR" },
2586 { 4*REG_SR, "4*REG_SR" },
2587 { 4*REG_GBR, "4*REG_GBR" },
2588 { 4*REG_MACH, "4*REG_MACH" },
2589 { 4*REG_MACL, "4*REG_MACL" },
2590 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2591 { 4*REG_FPUL, "4*REG_FPUL" },
2592 { 4*REG_FPREG0, "4*REG_FPREG0" },
2593 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2594 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2595 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2596 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2597 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2598 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2599 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2600 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2601 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2602 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2603 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2604 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2605 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2606 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2607 { 4*REG_FPREG15, "4*REG_FPREG15" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002608#ifdef REG_XDREG0
Wichert Akkermanccef6372002-05-01 16:39:22 +00002609 { 4*REG_XDREG0, "4*REG_XDREG0" },
2610 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2611 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2612 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2613 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2614 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2615 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2616 { 4*REG_XDREG14, "4*REG_XDREG14" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002617#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002618 { 4*REG_FPSCR, "4*REG_FPSCR" },
2619#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002620#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002621 { 0, "PC(L)" },
2622 { 4, "PC(U)" },
2623 { 8, "SR(L)" },
2624 { 12, "SR(U)" },
2625 { 16, "syscall no.(L)" },
2626 { 20, "syscall_no.(U)" },
2627 { 24, "R0(L)" },
2628 { 28, "R0(U)" },
2629 { 32, "R1(L)" },
2630 { 36, "R1(U)" },
2631 { 40, "R2(L)" },
2632 { 44, "R2(U)" },
2633 { 48, "R3(L)" },
2634 { 52, "R3(U)" },
2635 { 56, "R4(L)" },
2636 { 60, "R4(U)" },
2637 { 64, "R5(L)" },
2638 { 68, "R5(U)" },
2639 { 72, "R6(L)" },
2640 { 76, "R6(U)" },
2641 { 80, "R7(L)" },
2642 { 84, "R7(U)" },
2643 { 88, "R8(L)" },
2644 { 92, "R8(U)" },
2645 { 96, "R9(L)" },
2646 { 100, "R9(U)" },
2647 { 104, "R10(L)" },
2648 { 108, "R10(U)" },
2649 { 112, "R11(L)" },
2650 { 116, "R11(U)" },
2651 { 120, "R12(L)" },
2652 { 124, "R12(U)" },
2653 { 128, "R13(L)" },
2654 { 132, "R13(U)" },
2655 { 136, "R14(L)" },
2656 { 140, "R14(U)" },
2657 { 144, "R15(L)" },
2658 { 148, "R15(U)" },
2659 { 152, "R16(L)" },
2660 { 156, "R16(U)" },
2661 { 160, "R17(L)" },
2662 { 164, "R17(U)" },
2663 { 168, "R18(L)" },
2664 { 172, "R18(U)" },
2665 { 176, "R19(L)" },
2666 { 180, "R19(U)" },
2667 { 184, "R20(L)" },
2668 { 188, "R20(U)" },
2669 { 192, "R21(L)" },
2670 { 196, "R21(U)" },
2671 { 200, "R22(L)" },
2672 { 204, "R22(U)" },
2673 { 208, "R23(L)" },
2674 { 212, "R23(U)" },
2675 { 216, "R24(L)" },
2676 { 220, "R24(U)" },
2677 { 224, "R25(L)" },
2678 { 228, "R25(U)" },
2679 { 232, "R26(L)" },
2680 { 236, "R26(U)" },
2681 { 240, "R27(L)" },
2682 { 244, "R27(U)" },
2683 { 248, "R28(L)" },
2684 { 252, "R28(U)" },
2685 { 256, "R29(L)" },
2686 { 260, "R29(U)" },
2687 { 264, "R30(L)" },
2688 { 268, "R30(U)" },
2689 { 272, "R31(L)" },
2690 { 276, "R31(U)" },
2691 { 280, "R32(L)" },
2692 { 284, "R32(U)" },
2693 { 288, "R33(L)" },
2694 { 292, "R33(U)" },
2695 { 296, "R34(L)" },
2696 { 300, "R34(U)" },
2697 { 304, "R35(L)" },
2698 { 308, "R35(U)" },
2699 { 312, "R36(L)" },
2700 { 316, "R36(U)" },
2701 { 320, "R37(L)" },
2702 { 324, "R37(U)" },
2703 { 328, "R38(L)" },
2704 { 332, "R38(U)" },
2705 { 336, "R39(L)" },
2706 { 340, "R39(U)" },
2707 { 344, "R40(L)" },
2708 { 348, "R40(U)" },
2709 { 352, "R41(L)" },
2710 { 356, "R41(U)" },
2711 { 360, "R42(L)" },
2712 { 364, "R42(U)" },
2713 { 368, "R43(L)" },
2714 { 372, "R43(U)" },
2715 { 376, "R44(L)" },
2716 { 380, "R44(U)" },
2717 { 384, "R45(L)" },
2718 { 388, "R45(U)" },
2719 { 392, "R46(L)" },
2720 { 396, "R46(U)" },
2721 { 400, "R47(L)" },
2722 { 404, "R47(U)" },
2723 { 408, "R48(L)" },
2724 { 412, "R48(U)" },
2725 { 416, "R49(L)" },
2726 { 420, "R49(U)" },
2727 { 424, "R50(L)" },
2728 { 428, "R50(U)" },
2729 { 432, "R51(L)" },
2730 { 436, "R51(U)" },
2731 { 440, "R52(L)" },
2732 { 444, "R52(U)" },
2733 { 448, "R53(L)" },
2734 { 452, "R53(U)" },
2735 { 456, "R54(L)" },
2736 { 460, "R54(U)" },
2737 { 464, "R55(L)" },
2738 { 468, "R55(U)" },
2739 { 472, "R56(L)" },
2740 { 476, "R56(U)" },
2741 { 480, "R57(L)" },
2742 { 484, "R57(U)" },
2743 { 488, "R58(L)" },
2744 { 492, "R58(U)" },
2745 { 496, "R59(L)" },
2746 { 500, "R59(U)" },
2747 { 504, "R60(L)" },
2748 { 508, "R60(U)" },
2749 { 512, "R61(L)" },
2750 { 516, "R61(U)" },
2751 { 520, "R62(L)" },
2752 { 524, "R62(U)" },
2753 { 528, "TR0(L)" },
2754 { 532, "TR0(U)" },
2755 { 536, "TR1(L)" },
2756 { 540, "TR1(U)" },
2757 { 544, "TR2(L)" },
2758 { 548, "TR2(U)" },
2759 { 552, "TR3(L)" },
2760 { 556, "TR3(U)" },
2761 { 560, "TR4(L)" },
2762 { 564, "TR4(U)" },
2763 { 568, "TR5(L)" },
2764 { 572, "TR5(U)" },
2765 { 576, "TR6(L)" },
2766 { 580, "TR6(U)" },
2767 { 584, "TR7(L)" },
2768 { 588, "TR7(U)" },
2769 /* This entry is in case pt_regs contains dregs (depends on
2770 the kernel build options). */
2771 { uoff(regs), "offsetof(struct user, regs)" },
2772 { uoff(fpu), "offsetof(struct user, fpu)" },
2773#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002774#ifdef ARM
2775 { uoff(regs.ARM_r0), "r0" },
2776 { uoff(regs.ARM_r1), "r1" },
2777 { uoff(regs.ARM_r2), "r2" },
2778 { uoff(regs.ARM_r3), "r3" },
2779 { uoff(regs.ARM_r4), "r4" },
2780 { uoff(regs.ARM_r5), "r5" },
2781 { uoff(regs.ARM_r6), "r6" },
2782 { uoff(regs.ARM_r7), "r7" },
2783 { uoff(regs.ARM_r8), "r8" },
2784 { uoff(regs.ARM_r9), "r9" },
2785 { uoff(regs.ARM_r10), "r10" },
2786 { uoff(regs.ARM_fp), "fp" },
2787 { uoff(regs.ARM_ip), "ip" },
2788 { uoff(regs.ARM_sp), "sp" },
2789 { uoff(regs.ARM_lr), "lr" },
2790 { uoff(regs.ARM_pc), "pc" },
2791 { uoff(regs.ARM_cpsr), "cpsr" },
2792#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002793
Michal Ludvig10a88d02002-10-07 14:31:00 +00002794#if !defined(S390) && !defined(S390X) && !defined(MIPS)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002795 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002796#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002797#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002798 { uoff(i387), "offsetof(struct user, i387)" },
2799#else /* !I386 */
2800#ifdef M68K
2801 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2802#endif /* M68K */
2803#endif /* !I386 */
2804 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2805 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2806 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2807 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrathf5a47772003-06-26 22:40:42 +00002808#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002809 { uoff(start_data), "offsetof(struct user, start_data)" },
2810#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002811 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2812 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrathf5a47772003-06-26 22:40:42 +00002813#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002814 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002815#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002816 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002817#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002818 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2819#endif
2820 { uoff(magic), "offsetof(struct user, magic)" },
2821 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002822#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002823 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2824#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002825#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002826#endif /* !ALPHA */
2827#endif /* !POWERPC/!SPARC */
2828#endif /* LINUX */
2829#ifdef SUNOS4
2830 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2831 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2832 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2833 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2834 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2835 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2836 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2837 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2838 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2839 { uoff(u_error), "offsetof(struct user, u_error)" },
2840 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2841 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2842 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2843 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2844 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2845 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2846 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2847 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2848 { uoff(u_code), "offsetof(struct user, u_code)" },
2849 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2850 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2851 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2852 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2853 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2854 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2855 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2856 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2857 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2858 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2859 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2860 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2861 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2862 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2863 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2864 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2865 { uoff(u_start), "offsetof(struct user, u_start)" },
2866 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2867 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2868 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2869 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2870 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2871 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2872 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2873 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2874 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2875#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002876#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002877 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002878#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002879 { 0, NULL },
2880};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002881#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002882
2883int
2884sys_ptrace(tcp)
2885struct tcb *tcp;
2886{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002887 struct xlat *x;
2888 long addr;
2889
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002890 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002891 printxval(ptrace_cmds, tcp->u_arg[0],
2892#ifndef FREEBSD
2893 "PTRACE_???"
2894#else
2895 "PT_???"
2896#endif
2897 );
2898 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002899 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002900#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002901 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2902 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2903 for (x = struct_user_offsets; x->str; x++) {
2904 if (x->val >= addr)
2905 break;
2906 }
2907 if (!x->str)
2908 tprintf("%#lx, ", addr);
2909 else if (x->val > addr && x != struct_user_offsets) {
2910 x--;
2911 tprintf("%s + %ld, ", x->str, addr - x->val);
2912 }
2913 else
2914 tprintf("%s, ", x->str);
2915 }
2916 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002917#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002918 tprintf("%#lx, ", tcp->u_arg[2]);
2919#ifdef LINUX
2920 switch (tcp->u_arg[0]) {
2921 case PTRACE_PEEKDATA:
2922 case PTRACE_PEEKTEXT:
2923 case PTRACE_PEEKUSER:
2924 break;
2925 case PTRACE_CONT:
2926 case PTRACE_SINGLESTEP:
2927 case PTRACE_SYSCALL:
2928 case PTRACE_DETACH:
2929 printsignal(tcp->u_arg[3]);
2930 break;
2931 default:
2932 tprintf("%#lx", tcp->u_arg[3]);
2933 break;
2934 }
2935 } else {
2936 switch (tcp->u_arg[0]) {
2937 case PTRACE_PEEKDATA:
2938 case PTRACE_PEEKTEXT:
2939 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00002940 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002941 break;
2942 }
2943 }
2944#endif /* LINUX */
2945#ifdef SUNOS4
2946 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2947 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2948 tprintf("%lu, ", tcp->u_arg[3]);
2949 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2950 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2951 tcp->u_arg[0] != PTRACE_READTEXT) {
2952 tprintf("%#lx", tcp->u_arg[3]);
2953 }
2954 } else {
2955 if (tcp->u_arg[0] == PTRACE_READDATA ||
2956 tcp->u_arg[0] == PTRACE_READTEXT) {
2957 tprintf("%lu, ", tcp->u_arg[3]);
2958 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2959 }
2960 }
2961#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002962#ifdef FREEBSD
2963 tprintf("%lu", tcp->u_arg[3]);
2964 }
2965#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002966 return 0;
2967}
2968
2969#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002970
2971#ifdef LINUX
2972static struct xlat futexops[] = {
2973 { FUTEX_WAIT, "FUTEX_WAIT" },
2974 { FUTEX_WAKE, "FUTEX_WAKE" },
2975 { FUTEX_FD, "FUTEX_FD" },
Roland McGrath88812d62003-06-26 22:27:23 +00002976 { FUTEX_REQUEUE,"FUTEX_REQUEUE" },
Roland McGrath5a223472002-12-15 23:58:26 +00002977 { 0, NULL }
2978};
2979
2980int
2981sys_futex(tcp)
2982struct tcb *tcp;
2983{
2984 if (entering(tcp)) {
2985 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00002986 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00002987 tprintf(", %ld", tcp->u_arg[2]);
2988 if (tcp->u_arg[1] == FUTEX_WAIT) {
2989 tprintf(", ");
2990 printtv(tcp, tcp->u_arg[3]);
Roland McGrath88812d62003-06-26 22:27:23 +00002991 } else if (tcp->u_arg[1] == FUTEX_REQUEUE)
2992 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath5a223472002-12-15 23:58:26 +00002993 }
2994 return 0;
2995}
2996
2997static void
Roland McGrath79fbda52004-04-14 02:45:55 +00002998print_affinitylist(tcp, list, len)
2999struct tcb *tcp;
3000long list;
Roland McGrath5a223472002-12-15 23:58:26 +00003001unsigned int len;
3002{
3003 int first = 1;
3004 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00003005 while (len >= sizeof (unsigned long)) {
Roland McGrath79fbda52004-04-14 02:45:55 +00003006 unsigned long w;
3007 umove(tcp, list, &w);
3008 tprintf("%s %lx", first ? "" : ",", w);
Roland McGrath5a223472002-12-15 23:58:26 +00003009 first = 0;
3010 len -= sizeof (unsigned long);
Roland McGrath79fbda52004-04-14 02:45:55 +00003011 list += sizeof(unsigned long);
Roland McGrath5a223472002-12-15 23:58:26 +00003012 }
3013 tprintf(" }");
3014}
3015
3016int
3017sys_sched_setaffinity(tcp)
3018struct tcb *tcp;
3019{
3020 if (entering(tcp)) {
3021 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath79fbda52004-04-14 02:45:55 +00003022 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
Roland McGrath5a223472002-12-15 23:58:26 +00003023 }
3024 return 0;
3025}
3026
3027int
3028sys_sched_getaffinity(tcp)
3029struct tcb *tcp;
3030{
3031 if (entering(tcp)) {
3032 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3033 } else {
Roland McGrath79fbda52004-04-14 02:45:55 +00003034 if (tcp->u_rval == -1)
3035 tprintf("%#lx", tcp->u_arg[2]);
3036 else
3037 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
Roland McGrath5a223472002-12-15 23:58:26 +00003038 }
3039 return 0;
3040}
Roland McGrath279d3782004-03-01 20:27:37 +00003041
3042static struct xlat schedulers[] = {
3043 { SCHED_OTHER, "SCHED_OTHER" },
3044 { SCHED_RR, "SCHED_RR" },
3045 { SCHED_FIFO, "SCHED_FIFO" },
3046 { 0, NULL }
3047};
3048
3049int
3050sys_sched_getscheduler(tcp)
3051struct tcb *tcp;
3052{
3053 if (entering(tcp)) {
3054 tprintf("%d", (int) tcp->u_arg[0]);
3055 } else if (! syserror(tcp)) {
3056 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3057 if (tcp->auxstr != NULL)
3058 return RVAL_STR;
3059 }
3060 return 0;
3061}
3062
3063int
3064sys_sched_setscheduler(tcp)
3065struct tcb *tcp;
3066{
3067 if (entering(tcp)) {
3068 struct sched_param p;
3069 tprintf("%d, ", (int) tcp->u_arg[0]);
3070 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3071 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3072 tprintf(", %lx", tcp->u_arg[2]);
3073 else
3074 tprintf(", { %d }", p.__sched_priority);
3075 }
3076 return 0;
3077}
3078
3079int
3080sys_sched_getparam(tcp)
3081struct tcb *tcp;
3082{
3083 if (entering(tcp)) {
3084 tprintf("%d, ", (int) tcp->u_arg[0]);
3085 } else {
3086 struct sched_param p;
3087 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3088 tprintf("%lx", tcp->u_arg[1]);
3089 else
3090 tprintf("{ %d }", p.__sched_priority);
3091 }
3092 return 0;
3093}
3094
3095int
3096sys_sched_setparam(tcp)
3097struct tcb *tcp;
3098{
3099 if (entering(tcp)) {
3100 struct sched_param p;
3101 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3102 tprintf("%d, %lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3103 else
3104 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3105 }
3106 return 0;
3107}
3108
3109int
3110sys_sched_get_priority_min(tcp)
3111struct tcb *tcp;
3112{
3113 if (entering(tcp)) {
3114 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3115 }
3116 return 0;
3117}
Roland McGrath5a223472002-12-15 23:58:26 +00003118#endif