blob: ccd715e79a4ce1af569499f29aae7c4c8b608d0f [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 */
1798 if (WIFSTOPPED(status))
1799 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001800 signame(WSTOPSIG(status)));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001801 else if WIFSIGNALED(status)
1802 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001803 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001804 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1805 else if WIFEXITED(status) {
1806 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1807 WEXITSTATUS(status));
1808 exited = 1;
1809 }
1810 else
1811 tprintf("[%#x]", status);
1812 return exited;
1813}
1814
1815static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001816printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001817struct tcb *tcp;
1818int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001819int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001820{
1821 int status;
1822 int exited = 0;
1823
1824 if (entering(tcp)) {
1825 tprintf("%ld, ", tcp->u_arg[0]);
1826 } else {
1827 /* status */
1828 if (!tcp->u_arg[1])
1829 tprintf("NULL");
1830 else if (syserror(tcp) || tcp->u_rval == 0)
1831 tprintf("%#lx", tcp->u_arg[1]);
1832 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1833 tprintf("[?]");
1834 else
1835 exited = printstatus(status);
1836 /* options */
1837 tprintf(", ");
1838 if (!printflags(wait4_options, tcp->u_arg[2]))
1839 tprintf("0");
1840 if (n == 4) {
1841 tprintf(", ");
1842 /* usage */
1843 if (!tcp->u_arg[3])
1844 tprintf("NULL");
1845#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001846 else if (tcp->u_rval > 0) {
1847#ifdef LINUX_64BIT
1848 if (bitness)
1849 printrusage32(tcp, tcp->u_arg[3]);
1850 else
1851#endif
1852 printrusage(tcp, tcp->u_arg[3]);
1853 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001854#endif /* LINUX */
1855#ifdef SUNOS4
1856 else if (tcp->u_rval > 0 && exited)
1857 printrusage(tcp, tcp->u_arg[3]);
1858#endif /* SUNOS4 */
1859 else
1860 tprintf("%#lx", tcp->u_arg[3]);
1861 }
1862 }
1863 return 0;
1864}
1865
1866int
1867internal_wait(tcp)
1868struct tcb *tcp;
1869{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001870 int got_kids;
1871
1872#ifdef TCB_CLONE_THREAD
1873 if (tcp->flags & TCB_CLONE_THREAD)
1874 /* The children we wait for are our parent's children. */
1875 got_kids = (tcp->parent->nchildren
1876 > tcp->parent->nclone_detached);
1877 else
1878 got_kids = (tcp->nchildren > tcp->nclone_detached);
1879#else
1880 got_kids = tcp->nchildren > 0;
1881#endif
1882
1883 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001884 /* There are children that this parent should block for.
1885 But ptrace made us the parent of the traced children
1886 and the real parent will get ECHILD from the wait call.
1887
1888 XXX If we attached with strace -f -p PID, then there
1889 may be untraced dead children the parent could be reaping
1890 now, but we make him block. */
1891
1892 /* ??? WTA: fix bug with hanging children */
1893
1894 if (!(tcp->u_arg[2] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00001895 /*
1896 * There are traced children. We'll make the parent
1897 * block to avoid a false ECHILD error due to our
1898 * ptrace having stolen the children. However,
1899 * we shouldn't block if there are zombies to reap.
1900 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1901 */
Roland McGrathfccfb942003-10-01 21:59:44 +00001902 struct tcb *child = NULL;
Roland McGrath09623452003-05-23 02:27:13 +00001903 if (tcp->nzombies > 0 &&
1904 (tcp->u_arg[0] == -1 ||
Roland McGrathfccfb942003-10-01 21:59:44 +00001905 (child = pid2tcb(tcp->u_arg[0])) == NULL))
Roland McGrath09623452003-05-23 02:27:13 +00001906 return 0;
Roland McGrathfccfb942003-10-01 21:59:44 +00001907 if (tcp->u_arg[0] > 0) {
1908 /*
1909 * If the parent waits for a specified child
1910 * PID, then it must get ECHILD right away
1911 * if that PID is not one of its children.
1912 * Make sure that the requested PID matches
1913 * one of the parent's children that we are
1914 * tracing, and don't suspend it otherwise.
1915 */
1916 if (child == NULL)
1917 child = pid2tcb(tcp->u_arg[0]);
1918 if (child == NULL || child->parent != (
1919#ifdef TCB_CLONE_THREAD
1920 (tcp->flags & TCB_CLONE_THREAD)
1921 ? tcp->parent :
1922#endif
1923 tcp))
1924 return 0;
1925 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001926 tcp->flags |= TCB_SUSPENDED;
1927 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001928#ifdef TCB_CLONE_THREAD
1929 if (tcp->flags & TCB_CLONE_THREAD)
1930 tcp->parent->nclone_waiting++;
1931#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001932 }
1933 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001934 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001935 if (tcp->u_arg[2] & WNOHANG) {
1936 /* We must force a fake result of 0 instead of
1937 the ECHILD error. */
1938 extern int force_result();
1939 return force_result(tcp, 0, 0);
1940 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00001941 }
Roland McGrath09623452003-05-23 02:27:13 +00001942 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
1943 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
1944 /*
1945 * We just reaped a child we don't know about,
1946 * presumably a zombie we already droptcb'd.
1947 */
1948 tcp->nzombies--;
1949 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001950 return 0;
1951}
1952
1953#ifdef SVR4
1954
1955int
1956sys_wait(tcp)
1957struct tcb *tcp;
1958{
1959 if (exiting(tcp)) {
1960 /* The library wrapper stuffs this into the user variable. */
1961 if (!syserror(tcp))
1962 printstatus(getrval2(tcp));
1963 }
1964 return 0;
1965}
1966
1967#endif /* SVR4 */
1968
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001969#ifdef FREEBSD
1970int
1971sys_wait(tcp)
1972struct tcb *tcp;
1973{
1974 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001975
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001976 if (exiting(tcp)) {
1977 if (!syserror(tcp)) {
1978 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1979 tprintf("%#lx", tcp->u_arg[0]);
1980 else
1981 printstatus(status);
1982 }
1983 }
1984 return 0;
1985}
1986#endif
1987
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001988int
1989sys_waitpid(tcp)
1990struct tcb *tcp;
1991{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001992 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001993}
1994
1995int
1996sys_wait4(tcp)
1997struct tcb *tcp;
1998{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001999 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002000}
2001
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002002#ifdef ALPHA
2003int
2004sys_osf_wait4(tcp)
2005struct tcb *tcp;
2006{
2007 return printwaitn(tcp, 4, 1);
2008}
2009#endif
2010
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002011#ifdef SVR4
2012
2013static struct xlat waitid_types[] = {
2014 { P_PID, "P_PID" },
2015 { P_PPID, "P_PPID" },
2016 { P_PGID, "P_PGID" },
2017 { P_SID, "P_SID" },
2018 { P_CID, "P_CID" },
2019 { P_UID, "P_UID" },
2020 { P_GID, "P_GID" },
2021 { P_ALL, "P_ALL" },
2022#ifdef P_LWPID
2023 { P_LWPID, "P_LWPID" },
2024#endif
2025 { 0, NULL },
2026};
2027
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002028int
2029sys_waitid(tcp)
2030struct tcb *tcp;
2031{
2032 siginfo_t si;
2033 int exited;
2034
2035 if (entering(tcp)) {
2036 printxval(waitid_types, tcp->u_arg[0], "P_???");
2037 tprintf(", %ld, ", tcp->u_arg[1]);
2038 if (tcp->nchildren > 0) {
2039 /* There are traced children */
2040 tcp->flags |= TCB_SUSPENDED;
2041 tcp->waitpid = tcp->u_arg[0];
2042 }
2043 }
2044 else {
2045 /* siginfo */
2046 exited = 0;
2047 if (!tcp->u_arg[2])
2048 tprintf("NULL");
2049 else if (syserror(tcp))
2050 tprintf("%#lx", tcp->u_arg[2]);
2051 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2052 tprintf("{???}");
2053 else
John Hughes58265892001-10-18 15:13:53 +00002054 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002055 /* options */
2056 tprintf(", ");
2057 if (!printflags(wait4_options, tcp->u_arg[3]))
2058 tprintf("0");
2059 }
2060 return 0;
2061}
2062
2063#endif /* SVR4 */
2064
2065int
2066sys_alarm(tcp)
2067struct tcb *tcp;
2068{
2069 if (entering(tcp))
2070 tprintf("%lu", tcp->u_arg[0]);
2071 return 0;
2072}
2073
2074int
2075sys_uname(tcp)
2076struct tcb *tcp;
2077{
2078 struct utsname uname;
2079
2080 if (exiting(tcp)) {
2081 if (syserror(tcp) || !verbose(tcp))
2082 tprintf("%#lx", tcp->u_arg[0]);
2083 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2084 tprintf("{...}");
2085 else if (!abbrev(tcp)) {
2086
2087 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2088 uname.sysname, uname.nodename);
2089 tprintf("release=\"%s\", version=\"%s\", ",
2090 uname.release, uname.version);
2091 tprintf("machine=\"%s\"", uname.machine);
2092#ifdef LINUX
2093#ifndef __GLIBC__
2094 tprintf(", domainname=\"%s\"", uname.domainname);
2095#endif /* __GLIBC__ */
2096#endif /* LINUX */
2097 tprintf("}");
2098 }
2099 else
2100 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2101 uname.sysname, uname.nodename);
2102 }
2103 return 0;
2104}
2105
2106#ifndef SVR4
2107
2108static struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002109#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002110 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2111 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2112 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2113 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2114 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2115 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2116 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2117 { PTRACE_CONT, "PTRACE_CONT" },
2118 { PTRACE_KILL, "PTRACE_KILL" },
2119 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2120 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2121 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002122#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002123 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002124#endif
2125#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002126 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002127#endif
2128#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002129 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002130#endif
2131#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002132 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002133#endif
2134#ifdef PTRACE_GETFPXREGS
2135 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2136#endif
2137#ifdef PTRACE_SETFPXREGS
2138 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2139#endif
2140#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002141 { PTRACE_READDATA, "PTRACE_READDATA" },
2142 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2143 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2144 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2145 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2146 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2147#ifdef SPARC
2148 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2149 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2150#else /* !SPARC */
2151 { PTRACE_22, "PTRACE_PTRACE_22" },
2152 { PTRACE_23, "PTRACE_PTRACE_23" },
2153#endif /* !SPARC */
2154#endif /* SUNOS4 */
2155 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2156#ifdef SUNOS4
2157 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2158#ifdef I386
2159 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2160 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2161 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2162#else /* !I386 */
2163 { PTRACE_26, "PTRACE_26" },
2164 { PTRACE_27, "PTRACE_27" },
2165 { PTRACE_28, "PTRACE_28" },
2166#endif /* !I386 */
2167 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2168#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002169#else /* FREEBSD */
2170 { PT_TRACE_ME, "PT_TRACE_ME" },
2171 { PT_READ_I, "PT_READ_I" },
2172 { PT_READ_D, "PT_READ_D" },
2173 { PT_WRITE_I, "PT_WRITE_I" },
2174 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002175#ifdef PT_READ_U
2176 { PT_READ_U, "PT_READ_U" },
2177#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002178 { PT_CONTINUE, "PT_CONTINUE" },
2179 { PT_KILL, "PT_KILL" },
2180 { PT_STEP, "PT_STEP" },
2181 { PT_ATTACH, "PT_ATTACH" },
2182 { PT_DETACH, "PT_DETACH" },
2183 { PT_GETREGS, "PT_GETREGS" },
2184 { PT_SETREGS, "PT_SETREGS" },
2185 { PT_GETFPREGS, "PT_GETFPREGS" },
2186 { PT_SETFPREGS, "PT_SETFPREGS" },
2187 { PT_GETDBREGS, "PT_GETDBREGS" },
2188 { PT_SETDBREGS, "PT_SETDBREGS" },
2189#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002190 { 0, NULL },
2191};
2192
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002193#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002194#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2195static
2196#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2197struct xlat struct_user_offsets[] = {
2198#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002199#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002200 { PT_PSWMASK, "psw_mask" },
2201 { PT_PSWADDR, "psw_addr" },
2202 { PT_GPR0, "gpr0" },
2203 { PT_GPR1, "gpr1" },
2204 { PT_GPR2, "gpr2" },
2205 { PT_GPR3, "gpr3" },
2206 { PT_GPR4, "gpr4" },
2207 { PT_GPR5, "gpr5" },
2208 { PT_GPR6, "gpr6" },
2209 { PT_GPR7, "gpr7" },
2210 { PT_GPR8, "gpr8" },
2211 { PT_GPR9, "gpr9" },
2212 { PT_GPR10, "gpr10" },
2213 { PT_GPR11, "gpr11" },
2214 { PT_GPR12, "gpr12" },
2215 { PT_GPR13, "gpr13" },
2216 { PT_GPR14, "gpr14" },
2217 { PT_GPR15, "gpr15" },
2218 { PT_ACR0, "acr0" },
2219 { PT_ACR1, "acr1" },
2220 { PT_ACR2, "acr2" },
2221 { PT_ACR3, "acr3" },
2222 { PT_ACR4, "acr4" },
2223 { PT_ACR5, "acr5" },
2224 { PT_ACR6, "acr6" },
2225 { PT_ACR7, "acr7" },
2226 { PT_ACR8, "acr8" },
2227 { PT_ACR9, "acr9" },
2228 { PT_ACR10, "acr10" },
2229 { PT_ACR11, "acr11" },
2230 { PT_ACR12, "acr12" },
2231 { PT_ACR13, "acr13" },
2232 { PT_ACR14, "acr14" },
2233 { PT_ACR15, "acr15" },
2234 { PT_ORIGGPR2, "orig_gpr2" },
2235 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002236#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002237 { PT_FPR0_HI, "fpr0.hi" },
2238 { PT_FPR0_LO, "fpr0.lo" },
2239 { PT_FPR1_HI, "fpr1.hi" },
2240 { PT_FPR1_LO, "fpr1.lo" },
2241 { PT_FPR2_HI, "fpr2.hi" },
2242 { PT_FPR2_LO, "fpr2.lo" },
2243 { PT_FPR3_HI, "fpr3.hi" },
2244 { PT_FPR3_LO, "fpr3.lo" },
2245 { PT_FPR4_HI, "fpr4.hi" },
2246 { PT_FPR4_LO, "fpr4.lo" },
2247 { PT_FPR5_HI, "fpr5.hi" },
2248 { PT_FPR5_LO, "fpr5.lo" },
2249 { PT_FPR6_HI, "fpr6.hi" },
2250 { PT_FPR6_LO, "fpr6.lo" },
2251 { PT_FPR7_HI, "fpr7.hi" },
2252 { PT_FPR7_LO, "fpr7.lo" },
2253 { PT_FPR8_HI, "fpr8.hi" },
2254 { PT_FPR8_LO, "fpr8.lo" },
2255 { PT_FPR9_HI, "fpr9.hi" },
2256 { PT_FPR9_LO, "fpr9.lo" },
2257 { PT_FPR10_HI, "fpr10.hi" },
2258 { PT_FPR10_LO, "fpr10.lo" },
2259 { PT_FPR11_HI, "fpr11.hi" },
2260 { PT_FPR11_LO, "fpr11.lo" },
2261 { PT_FPR12_HI, "fpr12.hi" },
2262 { PT_FPR12_LO, "fpr12.lo" },
2263 { PT_FPR13_HI, "fpr13.hi" },
2264 { PT_FPR13_LO, "fpr13.lo" },
2265 { PT_FPR14_HI, "fpr14.hi" },
2266 { PT_FPR14_LO, "fpr14.lo" },
2267 { PT_FPR15_HI, "fpr15.hi" },
2268 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002269#endif
2270#if defined(S390X)
2271 { PT_FPR0, "fpr0" },
2272 { PT_FPR1, "fpr1" },
2273 { PT_FPR2, "fpr2" },
2274 { PT_FPR3, "fpr3" },
2275 { PT_FPR4, "fpr4" },
2276 { PT_FPR5, "fpr5" },
2277 { PT_FPR6, "fpr6" },
2278 { PT_FPR7, "fpr7" },
2279 { PT_FPR8, "fpr8" },
2280 { PT_FPR9, "fpr9" },
2281 { PT_FPR10, "fpr10" },
2282 { PT_FPR11, "fpr11" },
2283 { PT_FPR12, "fpr12" },
2284 { PT_FPR13, "fpr13" },
2285 { PT_FPR14, "fpr14" },
2286 { PT_FPR15, "fpr15" },
2287#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002288 { PT_CR_9, "cr9" },
2289 { PT_CR_10, "cr10" },
2290 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002291 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002292#endif
2293#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002294 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002295#elif defined(HPPA)
2296 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002297#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002298#ifndef PT_ORIG_R3
2299#define PT_ORIG_R3 34
2300#endif
Roland McGratheb285352003-01-14 09:59:00 +00002301#define REGSIZE (sizeof(unsigned long))
2302 { REGSIZE*PT_R0, "r0" },
2303 { REGSIZE*PT_R1, "r1" },
2304 { REGSIZE*PT_R2, "r2" },
2305 { REGSIZE*PT_R3, "r3" },
2306 { REGSIZE*PT_R4, "r4" },
2307 { REGSIZE*PT_R5, "r5" },
2308 { REGSIZE*PT_R6, "r6" },
2309 { REGSIZE*PT_R7, "r7" },
2310 { REGSIZE*PT_R8, "r8" },
2311 { REGSIZE*PT_R9, "r9" },
2312 { REGSIZE*PT_R10, "r10" },
2313 { REGSIZE*PT_R11, "r11" },
2314 { REGSIZE*PT_R12, "r12" },
2315 { REGSIZE*PT_R13, "r13" },
2316 { REGSIZE*PT_R14, "r14" },
2317 { REGSIZE*PT_R15, "r15" },
2318 { REGSIZE*PT_R16, "r16" },
2319 { REGSIZE*PT_R17, "r17" },
2320 { REGSIZE*PT_R18, "r18" },
2321 { REGSIZE*PT_R19, "r19" },
2322 { REGSIZE*PT_R20, "r20" },
2323 { REGSIZE*PT_R21, "r21" },
2324 { REGSIZE*PT_R22, "r22" },
2325 { REGSIZE*PT_R23, "r23" },
2326 { REGSIZE*PT_R24, "r24" },
2327 { REGSIZE*PT_R25, "r25" },
2328 { REGSIZE*PT_R26, "r26" },
2329 { REGSIZE*PT_R27, "r27" },
2330 { REGSIZE*PT_R28, "r28" },
2331 { REGSIZE*PT_R29, "r29" },
2332 { REGSIZE*PT_R30, "r30" },
2333 { REGSIZE*PT_R31, "r31" },
2334 { REGSIZE*PT_NIP, "NIP" },
2335 { REGSIZE*PT_MSR, "MSR" },
2336 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2337 { REGSIZE*PT_CTR, "CTR" },
2338 { REGSIZE*PT_LNK, "LNK" },
2339 { REGSIZE*PT_XER, "XER" },
2340 { REGSIZE*PT_CCR, "CCR" },
2341 { REGSIZE*PT_FPR0, "FPR0" },
2342#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002343#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002344#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002345 { 0, "r0" },
2346 { 1, "r1" },
2347 { 2, "r2" },
2348 { 3, "r3" },
2349 { 4, "r4" },
2350 { 5, "r5" },
2351 { 6, "r6" },
2352 { 7, "r7" },
2353 { 8, "r8" },
2354 { 9, "r9" },
2355 { 10, "r10" },
2356 { 11, "r11" },
2357 { 12, "r12" },
2358 { 13, "r13" },
2359 { 14, "r14" },
2360 { 15, "r15" },
2361 { 16, "r16" },
2362 { 17, "r17" },
2363 { 18, "r18" },
2364 { 19, "r19" },
2365 { 20, "r20" },
2366 { 21, "r21" },
2367 { 22, "r22" },
2368 { 23, "r23" },
2369 { 24, "r24" },
2370 { 25, "r25" },
2371 { 26, "r26" },
2372 { 27, "r27" },
2373 { 28, "r28" },
2374 { 29, "gp" },
2375 { 30, "fp" },
2376 { 31, "zero" },
2377 { 32, "fp0" },
2378 { 33, "fp" },
2379 { 34, "fp2" },
2380 { 35, "fp3" },
2381 { 36, "fp4" },
2382 { 37, "fp5" },
2383 { 38, "fp6" },
2384 { 39, "fp7" },
2385 { 40, "fp8" },
2386 { 41, "fp9" },
2387 { 42, "fp10" },
2388 { 43, "fp11" },
2389 { 44, "fp12" },
2390 { 45, "fp13" },
2391 { 46, "fp14" },
2392 { 47, "fp15" },
2393 { 48, "fp16" },
2394 { 49, "fp17" },
2395 { 50, "fp18" },
2396 { 51, "fp19" },
2397 { 52, "fp20" },
2398 { 53, "fp21" },
2399 { 54, "fp22" },
2400 { 55, "fp23" },
2401 { 56, "fp24" },
2402 { 57, "fp25" },
2403 { 58, "fp26" },
2404 { 59, "fp27" },
2405 { 60, "fp28" },
2406 { 61, "fp29" },
2407 { 62, "fp30" },
2408 { 63, "fp31" },
2409 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002410#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002411#ifdef IA64
2412 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2413 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2414 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2415 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2416 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2417 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2418 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2419 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2420 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2421 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2422 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2423 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2424 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2425 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2426 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2427 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2428 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2429 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2430 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2431 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2432 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2433 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2434 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2435 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2436 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2437 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2438 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2439 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2440 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2441 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2442 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2443 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2444 /* switch stack: */
2445 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2446 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2447 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2448 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2449 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2450 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2451 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2452 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2453 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2454 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002455 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2456 { PT_B4, "b4" }, { PT_B5, "b5" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002457 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002458 /* pt_regs */
Roland McGrathca4e10c2004-01-13 10:13:20 +00002459 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2460 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002461 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2462 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2463 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2464 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2465 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2466 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2467 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2468 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2469 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2470 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2471 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2472 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2473 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2474 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2475 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
Roland McGrathfb1bc072004-03-01 21:29:24 +00002476# ifdef PT_AR_CSD
2477 { PT_AR_CSD, "ar.csd" },
2478# endif
2479# ifdef PT_AR_SSD
2480 { PT_AR_SSD, "ar.ssd" },
2481# endif
Roland McGrathca4e10c2004-01-13 10:13:20 +00002482 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002483#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002484#ifdef I386
2485 { 4*EBX, "4*EBX" },
2486 { 4*ECX, "4*ECX" },
2487 { 4*EDX, "4*EDX" },
2488 { 4*ESI, "4*ESI" },
2489 { 4*EDI, "4*EDI" },
2490 { 4*EBP, "4*EBP" },
2491 { 4*EAX, "4*EAX" },
2492 { 4*DS, "4*DS" },
2493 { 4*ES, "4*ES" },
2494 { 4*FS, "4*FS" },
2495 { 4*GS, "4*GS" },
2496 { 4*ORIG_EAX, "4*ORIG_EAX" },
2497 { 4*EIP, "4*EIP" },
2498 { 4*CS, "4*CS" },
2499 { 4*EFL, "4*EFL" },
2500 { 4*UESP, "4*UESP" },
2501 { 4*SS, "4*SS" },
2502#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002503#ifdef X86_64
2504 { 8*RDI, "8*RDI" },
2505 { 8*RSI, "8*RSI" },
2506 { 8*RDX, "8*RDX" },
2507 { 8*R10, "8*R10" },
2508 { 8*R8, "8*R8" },
2509 { 8*R9, "8*R9" },
2510 { 8*RBX, "8*RBX" },
2511 { 8*RCX, "8*RCX" },
2512 { 8*RBP, "8*RBP" },
2513 { 8*RAX, "8*RAX" },
2514#if 0
2515 { 8*DS, "8*DS" },
2516 { 8*ES, "8*ES" },
2517 { 8*FS, "8*FS" },
2518 { 8*GS, "8*GS" },
2519#endif
2520 { 8*ORIG_RAX, "8*ORIG_EAX" },
2521 { 8*RIP, "8*RIP" },
2522 { 8*CS, "8*CS" },
2523 { 8*EFLAGS, "8*EFL" },
2524 { 8*RSP, "8*RSP" },
2525 { 8*SS, "8*SS" },
2526 { 8*R11, "8*R11" },
2527 { 8*R12, "8*R12" },
2528 { 8*R13, "8*R13" },
2529 { 8*R14, "8*R14" },
2530 { 8*R15, "8*R15" },
2531#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002532#ifdef M68K
2533 { 4*PT_D1, "4*PT_D1" },
2534 { 4*PT_D2, "4*PT_D2" },
2535 { 4*PT_D3, "4*PT_D3" },
2536 { 4*PT_D4, "4*PT_D4" },
2537 { 4*PT_D5, "4*PT_D5" },
2538 { 4*PT_D6, "4*PT_D6" },
2539 { 4*PT_D7, "4*PT_D7" },
2540 { 4*PT_A0, "4*PT_A0" },
2541 { 4*PT_A1, "4*PT_A1" },
2542 { 4*PT_A2, "4*PT_A2" },
2543 { 4*PT_A3, "4*PT_A3" },
2544 { 4*PT_A4, "4*PT_A4" },
2545 { 4*PT_A5, "4*PT_A5" },
2546 { 4*PT_A6, "4*PT_A6" },
2547 { 4*PT_D0, "4*PT_D0" },
2548 { 4*PT_USP, "4*PT_USP" },
2549 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2550 { 4*PT_SR, "4*PT_SR" },
2551 { 4*PT_PC, "4*PT_PC" },
2552#endif /* M68K */
2553#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002554#ifdef SH
2555 { 4*REG_REG0, "4*REG_REG0" },
2556 { 4*(REG_REG0+1), "4*REG_REG1" },
2557 { 4*(REG_REG0+2), "4*REG_REG2" },
2558 { 4*(REG_REG0+3), "4*REG_REG3" },
2559 { 4*(REG_REG0+4), "4*REG_REG4" },
2560 { 4*(REG_REG0+5), "4*REG_REG5" },
2561 { 4*(REG_REG0+6), "4*REG_REG6" },
2562 { 4*(REG_REG0+7), "4*REG_REG7" },
2563 { 4*(REG_REG0+8), "4*REG_REG8" },
2564 { 4*(REG_REG0+9), "4*REG_REG9" },
2565 { 4*(REG_REG0+10), "4*REG_REG10" },
2566 { 4*(REG_REG0+11), "4*REG_REG11" },
2567 { 4*(REG_REG0+12), "4*REG_REG12" },
2568 { 4*(REG_REG0+13), "4*REG_REG13" },
2569 { 4*(REG_REG0+14), "4*REG_REG14" },
2570 { 4*REG_REG15, "4*REG_REG15" },
2571 { 4*REG_PC, "4*REG_PC" },
2572 { 4*REG_PR, "4*REG_PR" },
2573 { 4*REG_SR, "4*REG_SR" },
2574 { 4*REG_GBR, "4*REG_GBR" },
2575 { 4*REG_MACH, "4*REG_MACH" },
2576 { 4*REG_MACL, "4*REG_MACL" },
2577 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2578 { 4*REG_FPUL, "4*REG_FPUL" },
2579 { 4*REG_FPREG0, "4*REG_FPREG0" },
2580 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2581 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2582 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2583 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2584 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2585 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2586 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2587 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2588 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2589 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2590 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2591 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2592 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2593 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2594 { 4*REG_FPREG15, "4*REG_FPREG15" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002595#ifdef REG_XDREG0
Wichert Akkermanccef6372002-05-01 16:39:22 +00002596 { 4*REG_XDREG0, "4*REG_XDREG0" },
2597 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2598 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2599 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2600 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2601 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2602 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2603 { 4*REG_XDREG14, "4*REG_XDREG14" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002604#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002605 { 4*REG_FPSCR, "4*REG_FPSCR" },
2606#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002607#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002608 { 0, "PC(L)" },
2609 { 4, "PC(U)" },
2610 { 8, "SR(L)" },
2611 { 12, "SR(U)" },
2612 { 16, "syscall no.(L)" },
2613 { 20, "syscall_no.(U)" },
2614 { 24, "R0(L)" },
2615 { 28, "R0(U)" },
2616 { 32, "R1(L)" },
2617 { 36, "R1(U)" },
2618 { 40, "R2(L)" },
2619 { 44, "R2(U)" },
2620 { 48, "R3(L)" },
2621 { 52, "R3(U)" },
2622 { 56, "R4(L)" },
2623 { 60, "R4(U)" },
2624 { 64, "R5(L)" },
2625 { 68, "R5(U)" },
2626 { 72, "R6(L)" },
2627 { 76, "R6(U)" },
2628 { 80, "R7(L)" },
2629 { 84, "R7(U)" },
2630 { 88, "R8(L)" },
2631 { 92, "R8(U)" },
2632 { 96, "R9(L)" },
2633 { 100, "R9(U)" },
2634 { 104, "R10(L)" },
2635 { 108, "R10(U)" },
2636 { 112, "R11(L)" },
2637 { 116, "R11(U)" },
2638 { 120, "R12(L)" },
2639 { 124, "R12(U)" },
2640 { 128, "R13(L)" },
2641 { 132, "R13(U)" },
2642 { 136, "R14(L)" },
2643 { 140, "R14(U)" },
2644 { 144, "R15(L)" },
2645 { 148, "R15(U)" },
2646 { 152, "R16(L)" },
2647 { 156, "R16(U)" },
2648 { 160, "R17(L)" },
2649 { 164, "R17(U)" },
2650 { 168, "R18(L)" },
2651 { 172, "R18(U)" },
2652 { 176, "R19(L)" },
2653 { 180, "R19(U)" },
2654 { 184, "R20(L)" },
2655 { 188, "R20(U)" },
2656 { 192, "R21(L)" },
2657 { 196, "R21(U)" },
2658 { 200, "R22(L)" },
2659 { 204, "R22(U)" },
2660 { 208, "R23(L)" },
2661 { 212, "R23(U)" },
2662 { 216, "R24(L)" },
2663 { 220, "R24(U)" },
2664 { 224, "R25(L)" },
2665 { 228, "R25(U)" },
2666 { 232, "R26(L)" },
2667 { 236, "R26(U)" },
2668 { 240, "R27(L)" },
2669 { 244, "R27(U)" },
2670 { 248, "R28(L)" },
2671 { 252, "R28(U)" },
2672 { 256, "R29(L)" },
2673 { 260, "R29(U)" },
2674 { 264, "R30(L)" },
2675 { 268, "R30(U)" },
2676 { 272, "R31(L)" },
2677 { 276, "R31(U)" },
2678 { 280, "R32(L)" },
2679 { 284, "R32(U)" },
2680 { 288, "R33(L)" },
2681 { 292, "R33(U)" },
2682 { 296, "R34(L)" },
2683 { 300, "R34(U)" },
2684 { 304, "R35(L)" },
2685 { 308, "R35(U)" },
2686 { 312, "R36(L)" },
2687 { 316, "R36(U)" },
2688 { 320, "R37(L)" },
2689 { 324, "R37(U)" },
2690 { 328, "R38(L)" },
2691 { 332, "R38(U)" },
2692 { 336, "R39(L)" },
2693 { 340, "R39(U)" },
2694 { 344, "R40(L)" },
2695 { 348, "R40(U)" },
2696 { 352, "R41(L)" },
2697 { 356, "R41(U)" },
2698 { 360, "R42(L)" },
2699 { 364, "R42(U)" },
2700 { 368, "R43(L)" },
2701 { 372, "R43(U)" },
2702 { 376, "R44(L)" },
2703 { 380, "R44(U)" },
2704 { 384, "R45(L)" },
2705 { 388, "R45(U)" },
2706 { 392, "R46(L)" },
2707 { 396, "R46(U)" },
2708 { 400, "R47(L)" },
2709 { 404, "R47(U)" },
2710 { 408, "R48(L)" },
2711 { 412, "R48(U)" },
2712 { 416, "R49(L)" },
2713 { 420, "R49(U)" },
2714 { 424, "R50(L)" },
2715 { 428, "R50(U)" },
2716 { 432, "R51(L)" },
2717 { 436, "R51(U)" },
2718 { 440, "R52(L)" },
2719 { 444, "R52(U)" },
2720 { 448, "R53(L)" },
2721 { 452, "R53(U)" },
2722 { 456, "R54(L)" },
2723 { 460, "R54(U)" },
2724 { 464, "R55(L)" },
2725 { 468, "R55(U)" },
2726 { 472, "R56(L)" },
2727 { 476, "R56(U)" },
2728 { 480, "R57(L)" },
2729 { 484, "R57(U)" },
2730 { 488, "R58(L)" },
2731 { 492, "R58(U)" },
2732 { 496, "R59(L)" },
2733 { 500, "R59(U)" },
2734 { 504, "R60(L)" },
2735 { 508, "R60(U)" },
2736 { 512, "R61(L)" },
2737 { 516, "R61(U)" },
2738 { 520, "R62(L)" },
2739 { 524, "R62(U)" },
2740 { 528, "TR0(L)" },
2741 { 532, "TR0(U)" },
2742 { 536, "TR1(L)" },
2743 { 540, "TR1(U)" },
2744 { 544, "TR2(L)" },
2745 { 548, "TR2(U)" },
2746 { 552, "TR3(L)" },
2747 { 556, "TR3(U)" },
2748 { 560, "TR4(L)" },
2749 { 564, "TR4(U)" },
2750 { 568, "TR5(L)" },
2751 { 572, "TR5(U)" },
2752 { 576, "TR6(L)" },
2753 { 580, "TR6(U)" },
2754 { 584, "TR7(L)" },
2755 { 588, "TR7(U)" },
2756 /* This entry is in case pt_regs contains dregs (depends on
2757 the kernel build options). */
2758 { uoff(regs), "offsetof(struct user, regs)" },
2759 { uoff(fpu), "offsetof(struct user, fpu)" },
2760#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002761#ifdef ARM
2762 { uoff(regs.ARM_r0), "r0" },
2763 { uoff(regs.ARM_r1), "r1" },
2764 { uoff(regs.ARM_r2), "r2" },
2765 { uoff(regs.ARM_r3), "r3" },
2766 { uoff(regs.ARM_r4), "r4" },
2767 { uoff(regs.ARM_r5), "r5" },
2768 { uoff(regs.ARM_r6), "r6" },
2769 { uoff(regs.ARM_r7), "r7" },
2770 { uoff(regs.ARM_r8), "r8" },
2771 { uoff(regs.ARM_r9), "r9" },
2772 { uoff(regs.ARM_r10), "r10" },
2773 { uoff(regs.ARM_fp), "fp" },
2774 { uoff(regs.ARM_ip), "ip" },
2775 { uoff(regs.ARM_sp), "sp" },
2776 { uoff(regs.ARM_lr), "lr" },
2777 { uoff(regs.ARM_pc), "pc" },
2778 { uoff(regs.ARM_cpsr), "cpsr" },
2779#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002780
Michal Ludvig10a88d02002-10-07 14:31:00 +00002781#if !defined(S390) && !defined(S390X) && !defined(MIPS)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002782 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002783#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002784#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002785 { uoff(i387), "offsetof(struct user, i387)" },
2786#else /* !I386 */
2787#ifdef M68K
2788 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2789#endif /* M68K */
2790#endif /* !I386 */
2791 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2792 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2793 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2794 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrathf5a47772003-06-26 22:40:42 +00002795#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002796 { uoff(start_data), "offsetof(struct user, start_data)" },
2797#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002798 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2799 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrathf5a47772003-06-26 22:40:42 +00002800#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002801 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002802#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002803 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002804#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002805 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2806#endif
2807 { uoff(magic), "offsetof(struct user, magic)" },
2808 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002809#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002810 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2811#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002812#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002813#endif /* !ALPHA */
2814#endif /* !POWERPC/!SPARC */
2815#endif /* LINUX */
2816#ifdef SUNOS4
2817 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2818 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2819 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2820 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2821 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2822 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2823 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2824 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2825 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2826 { uoff(u_error), "offsetof(struct user, u_error)" },
2827 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2828 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2829 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2830 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2831 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2832 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2833 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2834 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2835 { uoff(u_code), "offsetof(struct user, u_code)" },
2836 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2837 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2838 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2839 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2840 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2841 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2842 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2843 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2844 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2845 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2846 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2847 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2848 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2849 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2850 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2851 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2852 { uoff(u_start), "offsetof(struct user, u_start)" },
2853 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2854 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2855 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2856 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2857 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2858 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2859 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2860 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2861 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2862#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002863#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002864 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002865#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002866 { 0, NULL },
2867};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002868#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002869
2870int
2871sys_ptrace(tcp)
2872struct tcb *tcp;
2873{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002874 struct xlat *x;
2875 long addr;
2876
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002877 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002878 printxval(ptrace_cmds, tcp->u_arg[0],
2879#ifndef FREEBSD
2880 "PTRACE_???"
2881#else
2882 "PT_???"
2883#endif
2884 );
2885 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002886 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002887#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002888 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2889 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2890 for (x = struct_user_offsets; x->str; x++) {
2891 if (x->val >= addr)
2892 break;
2893 }
2894 if (!x->str)
2895 tprintf("%#lx, ", addr);
2896 else if (x->val > addr && x != struct_user_offsets) {
2897 x--;
2898 tprintf("%s + %ld, ", x->str, addr - x->val);
2899 }
2900 else
2901 tprintf("%s, ", x->str);
2902 }
2903 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002904#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002905 tprintf("%#lx, ", tcp->u_arg[2]);
2906#ifdef LINUX
2907 switch (tcp->u_arg[0]) {
2908 case PTRACE_PEEKDATA:
2909 case PTRACE_PEEKTEXT:
2910 case PTRACE_PEEKUSER:
2911 break;
2912 case PTRACE_CONT:
2913 case PTRACE_SINGLESTEP:
2914 case PTRACE_SYSCALL:
2915 case PTRACE_DETACH:
2916 printsignal(tcp->u_arg[3]);
2917 break;
2918 default:
2919 tprintf("%#lx", tcp->u_arg[3]);
2920 break;
2921 }
2922 } else {
2923 switch (tcp->u_arg[0]) {
2924 case PTRACE_PEEKDATA:
2925 case PTRACE_PEEKTEXT:
2926 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00002927 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002928 break;
2929 }
2930 }
2931#endif /* LINUX */
2932#ifdef SUNOS4
2933 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2934 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2935 tprintf("%lu, ", tcp->u_arg[3]);
2936 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2937 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2938 tcp->u_arg[0] != PTRACE_READTEXT) {
2939 tprintf("%#lx", tcp->u_arg[3]);
2940 }
2941 } else {
2942 if (tcp->u_arg[0] == PTRACE_READDATA ||
2943 tcp->u_arg[0] == PTRACE_READTEXT) {
2944 tprintf("%lu, ", tcp->u_arg[3]);
2945 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2946 }
2947 }
2948#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002949#ifdef FREEBSD
2950 tprintf("%lu", tcp->u_arg[3]);
2951 }
2952#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002953 return 0;
2954}
2955
2956#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002957
2958#ifdef LINUX
2959static struct xlat futexops[] = {
2960 { FUTEX_WAIT, "FUTEX_WAIT" },
2961 { FUTEX_WAKE, "FUTEX_WAKE" },
2962 { FUTEX_FD, "FUTEX_FD" },
Roland McGrath88812d62003-06-26 22:27:23 +00002963 { FUTEX_REQUEUE,"FUTEX_REQUEUE" },
Roland McGrath5a223472002-12-15 23:58:26 +00002964 { 0, NULL }
2965};
2966
2967int
2968sys_futex(tcp)
2969struct tcb *tcp;
2970{
2971 if (entering(tcp)) {
2972 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00002973 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00002974 tprintf(", %ld", tcp->u_arg[2]);
2975 if (tcp->u_arg[1] == FUTEX_WAIT) {
2976 tprintf(", ");
2977 printtv(tcp, tcp->u_arg[3]);
Roland McGrath88812d62003-06-26 22:27:23 +00002978 } else if (tcp->u_arg[1] == FUTEX_REQUEUE)
2979 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath5a223472002-12-15 23:58:26 +00002980 }
2981 return 0;
2982}
2983
2984static void
2985print_affinitylist(list, len)
2986unsigned long *list;
2987unsigned int len;
2988{
2989 int first = 1;
2990 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00002991 while (len >= sizeof (unsigned long)) {
Roland McGrath5a223472002-12-15 23:58:26 +00002992 tprintf("%s %lx", first ? "" : ",", *list++);
2993 first = 0;
2994 len -= sizeof (unsigned long);
2995 }
2996 tprintf(" }");
2997}
2998
2999int
3000sys_sched_setaffinity(tcp)
3001struct tcb *tcp;
3002{
3003 if (entering(tcp)) {
3004 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3005 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
3006 }
3007 return 0;
3008}
3009
3010int
3011sys_sched_getaffinity(tcp)
3012struct tcb *tcp;
3013{
3014 if (entering(tcp)) {
3015 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3016 } else {
3017 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);
3018 }
3019 return 0;
3020}
Roland McGrath279d3782004-03-01 20:27:37 +00003021
3022static struct xlat schedulers[] = {
3023 { SCHED_OTHER, "SCHED_OTHER" },
3024 { SCHED_RR, "SCHED_RR" },
3025 { SCHED_FIFO, "SCHED_FIFO" },
3026 { 0, NULL }
3027};
3028
3029int
3030sys_sched_getscheduler(tcp)
3031struct tcb *tcp;
3032{
3033 if (entering(tcp)) {
3034 tprintf("%d", (int) tcp->u_arg[0]);
3035 } else if (! syserror(tcp)) {
3036 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3037 if (tcp->auxstr != NULL)
3038 return RVAL_STR;
3039 }
3040 return 0;
3041}
3042
3043int
3044sys_sched_setscheduler(tcp)
3045struct tcb *tcp;
3046{
3047 if (entering(tcp)) {
3048 struct sched_param p;
3049 tprintf("%d, ", (int) tcp->u_arg[0]);
3050 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3051 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3052 tprintf(", %lx", tcp->u_arg[2]);
3053 else
3054 tprintf(", { %d }", p.__sched_priority);
3055 }
3056 return 0;
3057}
3058
3059int
3060sys_sched_getparam(tcp)
3061struct tcb *tcp;
3062{
3063 if (entering(tcp)) {
3064 tprintf("%d, ", (int) tcp->u_arg[0]);
3065 } else {
3066 struct sched_param p;
3067 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3068 tprintf("%lx", tcp->u_arg[1]);
3069 else
3070 tprintf("{ %d }", p.__sched_priority);
3071 }
3072 return 0;
3073}
3074
3075int
3076sys_sched_setparam(tcp)
3077struct tcb *tcp;
3078{
3079 if (entering(tcp)) {
3080 struct sched_param p;
3081 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3082 tprintf("%d, %lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3083 else
3084 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3085 }
3086 return 0;
3087}
3088
3089int
3090sys_sched_get_priority_min(tcp)
3091struct tcb *tcp;
3092{
3093 if (entering(tcp)) {
3094 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3095 }
3096 return 0;
3097}
Roland McGrath5a223472002-12-15 23:58:26 +00003098#endif