blob: d478293f72157886422cae1be2d7f82a6e52b4ce [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
Roland McGrath6d1a65c2004-07-12 07:44:08 +000060#if defined (SPARC) || defined (SPARC64)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000061# define fpq kernel_fpq
62# define fq kernel_fq
63# define fpu kernel_fpu
Roland McGrath6d1a65c2004-07-12 07:44:08 +000064#endif /* SPARC || SPARC64 */
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000065#include <asm/reg.h>
Roland McGrath6d1a65c2004-07-12 07:44:08 +000066#if defined (SPARC) || defined (SPARC64)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000067# undef fpq
68# undef fq
Roland McGrath5a223472002-12-15 23:58:26 +000069# undef fpu
Roland McGrath6d1a65c2004-07-12 07:44:08 +000070#endif /* SPARC || SPARC64 */
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000071#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 McGrath6d1a65c2004-07-12 07:44:08 +000096#if defined (LINUX) && defined (SPARC64)
97# define r_pc r_tpc
98# undef PTRACE_GETREGS
99# define PTRACE_GETREGS PTRACE_GETREGS64
100# undef PTRACE_SETREGS
101# define PTRACE_SETREGS PTRACE_SETREGS64
102#endif /* LINUX && SPARC64 */
103
Roland McGrath5a223472002-12-15 23:58:26 +0000104#ifdef HAVE_LINUX_FUTEX_H
105#include <linux/futex.h>
106#endif
107#if defined LINUX
108# ifndef FUTEX_WAIT
109# define FUTEX_WAIT 0
110# endif
111# ifndef FUTEX_WAKE
112# define FUTEX_WAKE 1
113# endif
114# ifndef FUTEX_FD
115# define FUTEX_FD 2
116# endif
Roland McGrath88812d62003-06-26 22:27:23 +0000117# ifndef FUTEX_REQUEUE
118# define FUTEX_REQUEUE 3
119# endif
Roland McGrath5a223472002-12-15 23:58:26 +0000120#endif
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000121
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000122#ifdef LINUX
Roland McGrath279d3782004-03-01 20:27:37 +0000123#include <sched.h>
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000124#include <asm/posix_types.h>
125#undef GETGROUPS_T
126#define GETGROUPS_T __kernel_gid_t
Roland McGrath83bd47a2003-11-13 22:32:26 +0000127#undef GETGROUPS32_T
128#define GETGROUPS32_T __kernel_gid32_t
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000129#endif /* LINUX */
130
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000131#if defined(LINUX) && defined(IA64)
132# include <asm/ptrace_offsets.h>
133# include <asm/rse.h>
134#endif
135
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000136#ifdef HAVE_PRCTL
137#include <sys/prctl.h>
138#endif
139
140#ifndef WCOREDUMP
141#define WCOREDUMP(status) ((status) & 0200)
142#endif
143
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000144/* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000145#if defined(HAVE_PRCTL)
Roland McGrathd9f816f2004-09-04 03:39:20 +0000146static const struct xlat prctl_options[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000147#ifdef PR_MAXPROCS
148 { PR_MAXPROCS, "PR_MAXPROCS" },
149#endif
150#ifdef PR_ISBLOCKED
151 { PR_ISBLOCKED, "PR_ISBLOCKED" },
152#endif
153#ifdef PR_SETSTACKSIZE
154 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
155#endif
156#ifdef PR_GETSTACKSIZE
157 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
158#endif
159#ifdef PR_MAXPPROCS
160 { PR_MAXPPROCS, "PR_MAXPPROCS" },
161#endif
162#ifdef PR_UNBLKONEXEC
163 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
164#endif
165#ifdef PR_ATOMICSIM
166 { PR_ATOMICSIM, "PR_ATOMICSIM" },
167#endif
168#ifdef PR_SETEXITSIG
169 { PR_SETEXITSIG, "PR_SETEXITSIG" },
170#endif
171#ifdef PR_RESIDENT
172 { PR_RESIDENT, "PR_RESIDENT" },
173#endif
174#ifdef PR_ATTACHADDR
175 { PR_ATTACHADDR, "PR_ATTACHADDR" },
176#endif
177#ifdef PR_DETACHADDR
178 { PR_DETACHADDR, "PR_DETACHADDR" },
179#endif
180#ifdef PR_TERMCHILD
181 { PR_TERMCHILD, "PR_TERMCHILD" },
182#endif
183#ifdef PR_GETSHMASK
184 { PR_GETSHMASK, "PR_GETSHMASK" },
185#endif
186#ifdef PR_GETNSHARE
187 { PR_GETNSHARE, "PR_GETNSHARE" },
188#endif
189#if defined(PR_SET_PDEATHSIG)
190 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
191#endif
Wichert Akkerman8829a551999-06-11 13:18:40 +0000192#ifdef PR_COREPID
193 { PR_COREPID, "PR_COREPID" },
194#endif
195#ifdef PR_ATTACHADDRPERM
196 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
197#endif
198#ifdef PR_PTHREADEXIT
199 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
200#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000201#ifdef PR_SET_PDEATHSIG
202 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
203#endif
204#ifdef PR_GET_PDEATHSIG
205 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
206#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000207#ifdef PR_GET_UNALIGN
208 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
209#endif
210#ifdef PR_SET_UNALIGN
211 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
212#endif
213#ifdef PR_GET_KEEPCAPS
214 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" },
215#endif
216#ifdef PR_SET_KEEPCAPS
217 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" },
218#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000219 { 0, NULL },
220};
221
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000222
Roland McGratha4d48532005-06-08 20:45:28 +0000223static const char *
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000224unalignctl_string (unsigned int ctl)
225{
226 static char buf[16];
227
228 switch (ctl) {
229#ifdef PR_UNALIGN_NOPRINT
230 case PR_UNALIGN_NOPRINT:
231 return "NOPRINT";
232#endif
233#ifdef PR_UNALIGN_SIGBUS
234 case PR_UNALIGN_SIGBUS:
235 return "SIGBUS";
236#endif
237 default:
238 break;
239 }
240 sprintf(buf, "%x", ctl);
241 return buf;
242}
243
244
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000245int
246sys_prctl(tcp)
247struct tcb *tcp;
248{
249 int i;
250
251 if (entering(tcp)) {
252 printxval(prctl_options, tcp->u_arg[0], "PR_???");
253 switch (tcp->u_arg[0]) {
254#ifdef PR_GETNSHARE
255 case PR_GETNSHARE:
256 break;
257#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000258#ifdef PR_SET_DEATHSIG
259 case PR_GET_PDEATHSIG:
260 break;
261#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000262#ifdef PR_SET_UNALIGN
263 case PR_SET_UNALIGN:
264 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
265 break;
266#endif
267#ifdef PR_GET_UNALIGN
268 case PR_GET_UNALIGN:
269 tprintf(", %#lx", tcp->u_arg[1]);
270 break;
271#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000272 default:
273 for (i = 1; i < tcp->u_nargs; i++)
274 tprintf(", %#lx", tcp->u_arg[i]);
275 break;
276 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000277 } else {
278 switch (tcp->u_arg[0]) {
279#ifdef PR_GET_PDEATHSIG
280 case PR_GET_PDEATHSIG:
281 for (i=1; i<tcp->u_nargs; i++)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000282 tprintf(", %#lx", tcp->u_arg[i]);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000283 break;
284#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000285#ifdef PR_SET_UNALIGN
286 case PR_SET_UNALIGN:
287 break;
288#endif
289#ifdef PR_GET_UNALIGN
290 case PR_GET_UNALIGN:
291 {
292 int ctl;
293
294 umove(tcp, tcp->u_arg[1], &ctl);
295 tcp->auxstr = unalignctl_string(ctl);
296 return RVAL_STR;
297 }
298#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000299 default:
300 break;
301 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000302 }
303 return 0;
304}
305
306#endif /* HAVE_PRCTL */
307
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000308#if defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000309int
310sys_gethostid(tcp)
311struct tcb *tcp;
312{
313 if (exiting(tcp))
314 return RVAL_HEX;
315 return 0;
316}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000317#endif /* FREEBSD || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000318
319int
320sys_sethostname(tcp)
321struct tcb *tcp;
322{
323 if (entering(tcp)) {
324 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
325 tprintf(", %lu", tcp->u_arg[1]);
326 }
327 return 0;
328}
329
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000330#if defined(ALPHA) || defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000331int
332sys_gethostname(tcp)
333struct tcb *tcp;
334{
335 if (exiting(tcp)) {
336 if (syserror(tcp))
337 tprintf("%#lx", tcp->u_arg[0]);
338 else
339 printpath(tcp, tcp->u_arg[0]);
340 tprintf(", %lu", tcp->u_arg[1]);
341 }
342 return 0;
343}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000344#endif /* ALPHA || FREEBSD || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000345
346int
347sys_setdomainname(tcp)
348struct tcb *tcp;
349{
350 if (entering(tcp)) {
351 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
352 tprintf(", %lu", tcp->u_arg[1]);
353 }
354 return 0;
355}
356
Wichert Akkerman5daa0281999-03-15 19:49:42 +0000357#if !defined(LINUX)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000358
359int
360sys_getdomainname(tcp)
361struct tcb *tcp;
362{
363 if (exiting(tcp)) {
364 if (syserror(tcp))
365 tprintf("%#lx", tcp->u_arg[0]);
366 else
367 printpath(tcp, tcp->u_arg[0]);
368 tprintf(", %lu", tcp->u_arg[1]);
369 }
370 return 0;
371}
372#endif /* !LINUX */
373
374int
375sys_exit(tcp)
376struct tcb *tcp;
377{
378 if (exiting(tcp)) {
379 fprintf(stderr, "_exit returned!\n");
380 return -1;
381 }
382 /* special case: we stop tracing this process, finish line now */
383 tprintf("%ld) ", tcp->u_arg[0]);
384 tabto(acolumn);
385 tprintf("= ?");
386 printtrailer(tcp);
387 return 0;
388}
389
390int
391internal_exit(tcp)
392struct tcb *tcp;
393{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000394 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000395 tcp->flags |= TCB_EXITING;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000396#ifdef __NR_exit_group
Roland McGrath08267b82004-02-20 22:56:43 +0000397# ifdef IA64
398 if (ia32) {
399 if (tcp->scno == 252)
400 tcp->flags |= TCB_GROUP_EXITING;
401 } else
402# endif
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000403 if (known_scno(tcp) == __NR_exit_group)
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000404 tcp->flags |= TCB_GROUP_EXITING;
405#endif
406 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000407 return 0;
408}
409
Roland McGrathee9d4352002-12-18 04:16:10 +0000410/* TCP is creating a child we want to follow.
411 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
412 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
413static int
414fork_tcb(struct tcb *tcp)
415{
416 if (nprocs == tcbtabsize) {
Roland McGrath7b54a7a2004-06-04 01:50:45 +0000417 if (expand_tcbtab()) {
Roland McGrathee9d4352002-12-18 04:16:10 +0000418 tcp->flags &= ~TCB_FOLLOWFORK;
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000419 return 1;
Roland McGrathee9d4352002-12-18 04:16:10 +0000420 }
Roland McGrathee9d4352002-12-18 04:16:10 +0000421 }
422
423 tcp->flags |= TCB_FOLLOWFORK;
424 return 0;
425}
426
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000427#ifdef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000428
429int
430sys_fork(tcp)
431struct tcb *tcp;
432{
433 if (exiting(tcp)) {
434 if (getrval2(tcp)) {
435 tcp->auxstr = "child process";
436 return RVAL_UDECIMAL | RVAL_STR;
437 }
438 }
439 return 0;
440}
441
John Hughes4e36a812001-04-18 15:11:51 +0000442#if UNIXWARE > 2
443
444int
445sys_rfork(tcp)
446struct tcb *tcp;
447{
448 if (entering(tcp)) {
449 tprintf ("%ld", tcp->u_arg[0]);
450 }
451 else {
452 if (getrval2(tcp)) {
453 tcp->auxstr = "child process";
454 return RVAL_UDECIMAL | RVAL_STR;
455 }
456 }
457 return 0;
458}
459
460#endif
461
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000462int
463internal_fork(tcp)
464struct tcb *tcp;
465{
466 struct tcb *tcpchild;
467
468 if (exiting(tcp)) {
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000469#ifdef SYS_rfork
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000470 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000471 return 0;
472#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000473 if (getrval2(tcp))
474 return 0;
475 if (!followfork)
476 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000477 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000478 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000479 if (syserror(tcp))
480 return 0;
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000481 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000482 return 0;
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000483 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000484 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000485 }
486 return 0;
487}
488
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000489#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000490
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000491#ifdef LINUX
492
493/* defines copied from linux/sched.h since we can't include that
494 * ourselves (it conflicts with *lots* of libc includes)
495 */
496#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
497#define CLONE_VM 0x00000100 /* set if VM shared between processes */
498#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
499#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
500#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000501#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000502#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
503#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
504#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000505#define CLONE_THREAD 0x00010000 /* Same thread group? */
506#define CLONE_NEWNS 0x00020000 /* New namespace group? */
507#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
508#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
509#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
510#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
511#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
512#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
513#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000514
Roland McGrathd9f816f2004-09-04 03:39:20 +0000515static const struct xlat clone_flags[] = {
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000516 { CLONE_VM, "CLONE_VM" },
517 { CLONE_FS, "CLONE_FS" },
518 { CLONE_FILES, "CLONE_FILES" },
519 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000520 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000521 { CLONE_PTRACE, "CLONE_PTRACE" },
522 { CLONE_VFORK, "CLONE_VFORK" },
523 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000524 { CLONE_THREAD, "CLONE_THREAD" },
525 { CLONE_NEWNS, "CLONE_NEWNS" },
526 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
527 { CLONE_SETTLS, "CLONE_SETTLS" },
528 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
529 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
530 { CLONE_DETACHED, "CLONE_DETACHED" },
531 { CLONE_UNTRACED, "CLONE_UNTRACED" },
532 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000533 { 0, NULL },
534};
535
Roland McGrath909875b2002-12-22 03:34:36 +0000536# ifdef I386
537# include <asm/ldt.h>
Roland McGrath7decfb22004-03-01 22:10:52 +0000538# ifdef HAVE_STRUCT_USER_DESC
539# define modify_ldt_ldt_s user_desc
540# endif
Roland McGrath909875b2002-12-22 03:34:36 +0000541extern void print_ldt_entry();
542# endif
543
Roland McGrath9677b3a2003-03-12 09:54:36 +0000544# if defined IA64
545# define ARG_FLAGS 0
546# define ARG_STACK 1
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000547# define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
548# define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
549# define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
550# define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000551# elif defined S390 || defined S390X
Roland McGrath9677b3a2003-03-12 09:54:36 +0000552# define ARG_STACK 0
553# define ARG_FLAGS 1
554# define ARG_PTID 2
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000555# define ARG_CTID 3
556# define ARG_TLS 4
Roland McGrath9c555e72003-07-09 09:47:59 +0000557# elif defined X86_64 || defined ALPHA
Roland McGrath361aac52003-03-18 07:43:42 +0000558# define ARG_FLAGS 0
559# define ARG_STACK 1
560# define ARG_PTID 2
561# define ARG_CTID 3
562# define ARG_TLS 4
Roland McGrath9677b3a2003-03-12 09:54:36 +0000563# else
564# define ARG_FLAGS 0
565# define ARG_STACK 1
566# define ARG_PTID 2
567# define ARG_TLS 3
568# define ARG_CTID 4
569# endif
570
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000571int
572sys_clone(tcp)
573struct tcb *tcp;
574{
575 if (exiting(tcp)) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000576 unsigned long flags = tcp->u_arg[ARG_FLAGS];
577 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
578# ifdef ARG_STACKSIZE
579 if (ARG_STACKSIZE != -1)
580 tprintf("stack_size=%#lx, ",
581 tcp->u_arg[ARG_STACKSIZE]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000582# endif
Roland McGrath9677b3a2003-03-12 09:54:36 +0000583 tprintf("flags=");
Roland McGrathb2dee132005-06-01 19:02:36 +0000584 printflags(clone_flags, flags &~ CSIGNAL, NULL);
Roland McGrath984154d2003-05-23 01:08:42 +0000585 if ((flags & CSIGNAL) != 0)
586 tprintf("|%s", signame(flags & CSIGNAL));
Roland McGrathb4968be2003-01-20 09:04:33 +0000587 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
Roland McGrath9677b3a2003-03-12 09:54:36 +0000588 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
Roland McGrath909875b2002-12-22 03:34:36 +0000589 return 0;
Roland McGrath6f67a982003-03-21 07:33:15 +0000590 if (flags & CLONE_PARENT_SETTID)
591 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000592 if (flags & CLONE_SETTLS) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000593# ifdef I386
Roland McGrath909875b2002-12-22 03:34:36 +0000594 struct modify_ldt_ldt_s copy;
Roland McGrath9677b3a2003-03-12 09:54:36 +0000595 if (umove(tcp, tcp->u_arg[ARG_TLS], &copy) != -1) {
Roland McGrath909875b2002-12-22 03:34:36 +0000596 tprintf(", {entry_number:%d, ",
597 copy.entry_number);
598 if (!verbose(tcp))
599 tprintf("...}");
600 else
601 print_ldt_entry(&copy);
602 }
603 else
Roland McGrath9677b3a2003-03-12 09:54:36 +0000604# endif
Roland McGrath43f2c842003-03-12 09:58:14 +0000605 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
Roland McGrath909875b2002-12-22 03:34:36 +0000606 }
Roland McGrath9677b3a2003-03-12 09:54:36 +0000607 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
608 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000609 }
610 return 0;
611}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000612
613int
614sys_unshare(struct tcb *tcp)
615{
616 if (entering(tcp))
617 printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
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;
Roland McGrath6d1a65c2004-07-12 07:44:08 +0000661#elif defined(SPARC) || defined(SPARC64)
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;
Roland McGrathf691bd22006-04-25 07:34:41 +0000707#elif defined(ARM)
708 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
709# ifndef PTRACE_SET_SYSCALL
710# define PTRACE_SET_SYSCALL 23
711# endif
712
713 if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new) != 0)
714 return -1;
715
716 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000717#else
718#warning Do not know how to handle change_syscall for this architecture
719#endif /* architecture */
720#endif /* LINUX */
721 return -1;
722}
723
Roland McGratha4d48532005-06-08 20:45:28 +0000724#if 0
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000725int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000726setarg(tcp, argnum)
727 struct tcb *tcp;
728 int argnum;
729{
730#if defined (IA64)
731 {
732 unsigned long *bsp, *ap;
733
734 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
735 return -1;
736
737 ap = ia64_rse_skip_regs(bsp, argnum);
738 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000739 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000740 if (errno)
741 return -1;
742
743 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000744#elif defined(I386)
745 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000746 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000747 if (errno)
748 return -1;
749 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000750#elif defined(X86_64)
751 {
752 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
753 if (errno)
754 return -1;
755 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000756#elif defined(POWERPC)
757#ifndef PT_ORIG_R3
758#define PT_ORIG_R3 34
759#endif
760 {
761 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000762 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000763 tcp->u_arg[argnum]);
764 if (errno)
765 return -1;
766 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000767#elif defined(MIPS)
768 {
769 errno = 0;
770 if (argnum < 4)
771 ptrace(PTRACE_POKEUSER, tcp->pid,
772 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
773 else {
774 unsigned long *sp;
775
776 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
777 return -1;
778
779 ptrace(PTRACE_POKEDATA, tcp->pid,
780 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
781 }
782 if (errno)
783 return -1;
784 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000785#elif defined(S390) || defined(S390X)
786 {
787 if(argnum <= 5)
788 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000789 (char *) (argnum==0 ? PT_ORIGGPR2 :
790 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000791 tcp->u_arg[argnum]);
792 else
793 return -E2BIG;
794 if (errno)
795 return -1;
796 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000797#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000798# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000799#endif
800 return 0;
801}
Roland McGratha4d48532005-06-08 20:45:28 +0000802#endif
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000803
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000804#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000805int
806internal_clone(tcp)
807struct tcb *tcp;
808{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000809 struct tcb *tcpchild;
810 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000811 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000812 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000813 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000814 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000815 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000816 if (setbpt(tcp) < 0)
817 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000818 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000819 int bpt = tcp->flags & TCB_BPTSET;
820
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000821 if (!(tcp->flags & TCB_FOLLOWFORK))
822 return 0;
823
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000824 if (syserror(tcp)) {
825 if (bpt)
826 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000827 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000828 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000829
830 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000831
832#ifdef CLONE_PTRACE /* See new setbpt code. */
833 tcpchild = pid2tcb(pid);
834 if (tcpchild != NULL) {
835 /* The child already reported its startup trap
836 before the parent reported its syscall return. */
837 if ((tcpchild->flags
838 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
839 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
840 fprintf(stderr, "\
841[preattached child %d of %d in weird state!]\n",
842 pid, tcp->pid);
843 }
844 else
845#endif
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000846 if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000847 if (bpt)
848 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000849 kill(pid, SIGKILL); /* XXX */
850 return 0;
851 }
852
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000853#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000854 /* Attach to the new child */
855 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000856 if (bpt)
857 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000858 perror("PTRACE_ATTACH");
859 fprintf(stderr, "Too late?\n");
860 droptcb(tcpchild);
861 return 0;
862 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000863#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000864
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000865 if (bpt)
866 clearbpt(tcp);
867
Ulrich Drepper90512f01999-12-24 07:22:25 +0000868 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000869 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000870 if (bpt) {
871 tcpchild->flags |= TCB_BPTSET;
872 tcpchild->baddr = tcp->baddr;
873 memcpy(tcpchild->inst, tcp->inst,
874 sizeof tcpchild->inst);
875 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000876 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000877 tcp->nchildren++;
878 if (tcpchild->flags & TCB_SUSPENDED) {
879 /* The child was born suspended, due to our having
880 forced CLONE_PTRACE. */
881 if (bpt)
882 clearbpt(tcpchild);
883
884 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
885 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
886 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
887 return -1;
888 }
889
890 if (!qflag)
891 fprintf(stderr, "\
892Process %u resumed (parent %d ready)\n",
893 pid, tcp->pid);
894 }
895 else {
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000896 if (!qflag)
897 fprintf(stderr, "Process %d attached\n", pid);
898 }
899
900#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000901 {
902 /*
903 * Save the flags used in this call,
904 * in case we point TCP to our parent below.
905 */
906 int call_flags = tcp->u_arg[ARG_FLAGS];
907 if ((tcp->flags & TCB_CLONE_THREAD) &&
908 tcp->parent != NULL) {
909 /* The parent in this clone is itself a
910 thread belonging to another process.
911 There is no meaning to the parentage
912 relationship of the new child with the
913 thread, only with the process. We
914 associate the new thread with our
915 parent. Since this is done for every
916 new thread, there will never be a
917 TCB_CLONE_THREAD process that has
918 children. */
919 --tcp->nchildren;
920 tcp = tcp->parent;
921 tcpchild->parent = tcp;
922 ++tcp->nchildren;
923 }
924 if (call_flags & CLONE_THREAD) {
925 tcpchild->flags |= TCB_CLONE_THREAD;
926 ++tcp->nclone_threads;
927 }
928 if (call_flags & CLONE_DETACHED) {
929 tcpchild->flags |= TCB_CLONE_DETACHED;
930 ++tcp->nclone_detached;
931 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000932 }
933#endif
934
935 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000936 return 0;
937}
938#endif
939
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000940int
941internal_fork(tcp)
942struct tcb *tcp;
943{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000944#ifdef LINUX
945 /* We do special magic with clone for any clone or fork. */
946 return internal_clone(tcp);
947#else
948
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000949 struct tcb *tcpchild;
950 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000951 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000952
953#ifdef SYS_vfork
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000954 if (known_scno(tcp) == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000955 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000956 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000957 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000958 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000959 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000960#endif
961 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000962 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000963 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000964 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000965 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000966 if (setbpt(tcp) < 0)
967 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000968 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000969 else {
970 int bpt = tcp->flags & TCB_BPTSET;
971
972 if (!(tcp->flags & TCB_FOLLOWFORK))
973 return 0;
974 if (bpt)
975 clearbpt(tcp);
976
977 if (syserror(tcp))
978 return 0;
979
980 pid = tcp->u_rval;
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000981 if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000982 kill(pid, SIGKILL); /* XXX */
983 return 0;
984 }
985#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000986#ifdef HPPA
987 /* The child must have run before it can be attached. */
988 /* This must be a bug in the parisc kernel, but I havn't
989 * identified it yet. Seems to be an issue associated
990 * with attaching to a process (which sends it a signal)
991 * before that process has ever been scheduled. When
992 * debugging, I started seeing crashes in
993 * arch/parisc/kernel/signal.c:do_signal(), apparently
994 * caused by r8 getting corrupt over the dequeue_signal()
995 * call. Didn't make much sense though...
996 */
997 {
998 struct timeval tv;
999 tv.tv_sec = 0;
1000 tv.tv_usec = 10000;
1001 select(0, NULL, NULL, NULL, &tv);
1002 }
1003#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001004 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
1005 perror("PTRACE_ATTACH");
1006 fprintf(stderr, "Too late?\n");
1007 droptcb(tcpchild);
1008 return 0;
1009 }
1010#endif /* LINUX */
1011#ifdef SUNOS4
1012#ifdef oldway
1013 /* The child must have run before it can be attached. */
1014 {
1015 struct timeval tv;
1016 tv.tv_sec = 0;
1017 tv.tv_usec = 10000;
1018 select(0, NULL, NULL, NULL, &tv);
1019 }
1020 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1021 perror("PTRACE_ATTACH");
1022 fprintf(stderr, "Too late?\n");
1023 droptcb(tcpchild);
1024 return 0;
1025 }
1026#else /* !oldway */
1027 /* Try to catch the new process as soon as possible. */
1028 {
1029 int i;
1030 for (i = 0; i < 1024; i++)
1031 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1032 break;
1033 if (i == 1024) {
1034 perror("PTRACE_ATTACH");
1035 fprintf(stderr, "Too late?\n");
1036 droptcb(tcpchild);
1037 return 0;
1038 }
1039 }
1040#endif /* !oldway */
1041#endif /* SUNOS4 */
1042 tcpchild->flags |= TCB_ATTACHED;
1043 /* Child has BPT too, must be removed on first occasion */
1044 if (bpt) {
1045 tcpchild->flags |= TCB_BPTSET;
1046 tcpchild->baddr = tcp->baddr;
1047 memcpy(tcpchild->inst, tcp->inst,
1048 sizeof tcpchild->inst);
1049 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001050 tcpchild->parent = tcp;
1051 tcp->nchildren++;
1052 if (!qflag)
1053 fprintf(stderr, "Process %d attached\n", pid);
1054 }
1055 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001056#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001057}
1058
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001059#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001060
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001061#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001062
1063int
1064sys_vfork(tcp)
1065struct tcb *tcp;
1066{
1067 if (exiting(tcp))
1068 return RVAL_UDECIMAL;
1069 return 0;
1070}
1071
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001072#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001073
1074#ifndef LINUX
1075
1076static char idstr[16];
1077
1078int
1079sys_getpid(tcp)
1080struct tcb *tcp;
1081{
1082 if (exiting(tcp)) {
1083 sprintf(idstr, "ppid %lu", getrval2(tcp));
1084 tcp->auxstr = idstr;
1085 return RVAL_STR;
1086 }
1087 return 0;
1088}
1089
1090int
1091sys_getuid(tcp)
1092struct tcb *tcp;
1093{
1094 if (exiting(tcp)) {
1095 sprintf(idstr, "euid %lu", getrval2(tcp));
1096 tcp->auxstr = idstr;
1097 return RVAL_STR;
1098 }
1099 return 0;
1100}
1101
1102int
1103sys_getgid(tcp)
1104struct tcb *tcp;
1105{
1106 if (exiting(tcp)) {
1107 sprintf(idstr, "egid %lu", getrval2(tcp));
1108 tcp->auxstr = idstr;
1109 return RVAL_STR;
1110 }
1111 return 0;
1112}
1113
1114#endif /* !LINUX */
1115
1116#ifdef LINUX
1117
1118int
1119sys_setuid(tcp)
1120struct tcb *tcp;
1121{
1122 if (entering(tcp)) {
1123 tprintf("%u", (uid_t) tcp->u_arg[0]);
1124 }
1125 return 0;
1126}
1127
1128int
1129sys_setgid(tcp)
1130struct tcb *tcp;
1131{
1132 if (entering(tcp)) {
1133 tprintf("%u", (gid_t) tcp->u_arg[0]);
1134 }
1135 return 0;
1136}
1137
1138int
1139sys_getresuid(tcp)
1140 struct tcb *tcp;
1141{
1142 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001143 __kernel_uid_t uid;
1144 if (syserror(tcp))
1145 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1146 tcp->u_arg[1], tcp->u_arg[2]);
1147 else {
1148 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1149 tprintf("%#lx, ", tcp->u_arg[0]);
1150 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001151 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001152 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1153 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001154 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001155 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001156 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1157 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001158 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001159 tprintf("[%lu]", (unsigned long) uid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001160 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001161 }
1162 return 0;
1163}
1164
1165int
1166sys_getresgid(tcp)
1167struct tcb *tcp;
1168{
1169 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001170 __kernel_gid_t gid;
1171 if (syserror(tcp))
1172 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1173 tcp->u_arg[1], tcp->u_arg[2]);
1174 else {
1175 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1176 tprintf("%#lx, ", tcp->u_arg[0]);
1177 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001178 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001179 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1180 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001181 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001182 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001183 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1184 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001185 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001186 tprintf("[%lu]", (unsigned long) gid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001187 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001188 }
1189 return 0;
1190}
1191
1192#endif /* LINUX */
1193
1194int
1195sys_setreuid(tcp)
1196struct tcb *tcp;
1197{
1198 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001199 printuid("", tcp->u_arg[0]);
1200 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001201 }
1202 return 0;
1203}
1204
1205int
1206sys_setregid(tcp)
1207struct tcb *tcp;
1208{
1209 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001210 printuid("", tcp->u_arg[0]);
1211 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001212 }
1213 return 0;
1214}
1215
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001216#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001217int
1218sys_setresuid(tcp)
1219 struct tcb *tcp;
1220{
1221 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001222 printuid("", tcp->u_arg[0]);
1223 printuid(", ", tcp->u_arg[1]);
1224 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001225 }
1226 return 0;
1227}
1228int
1229sys_setresgid(tcp)
1230 struct tcb *tcp;
1231{
1232 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001233 printuid("", tcp->u_arg[0]);
1234 printuid(", ", tcp->u_arg[1]);
1235 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001236 }
1237 return 0;
1238}
1239
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001240#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001241
1242int
1243sys_setgroups(tcp)
1244struct tcb *tcp;
1245{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001246 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001247 unsigned long len, size, start, cur, end, abbrev_end;
1248 GETGROUPS_T gid;
1249 int failed = 0;
1250
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001251 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001252 tprintf("%lu, ", len);
1253 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001254 tprintf("[]");
1255 return 0;
1256 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001257 start = tcp->u_arg[1];
1258 if (start == 0) {
1259 tprintf("NULL");
1260 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001261 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001262 size = len * sizeof(gid);
1263 end = start + size;
1264 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1265 tprintf("%#lx", start);
1266 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001267 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001268 if (abbrev(tcp)) {
1269 abbrev_end = start + max_strlen * sizeof(gid);
1270 if (abbrev_end < start)
1271 abbrev_end = end;
1272 } else {
1273 abbrev_end = end;
1274 }
1275 tprintf("[");
1276 for (cur = start; cur < end; cur += sizeof(gid)) {
1277 if (cur > start)
1278 tprintf(", ");
1279 if (cur >= abbrev_end) {
1280 tprintf("...");
1281 break;
1282 }
1283 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1284 tprintf("?");
1285 failed = 1;
1286 break;
1287 }
1288 tprintf("%lu", (unsigned long) gid);
1289 }
1290 tprintf("]");
1291 if (failed)
1292 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001293 }
1294 return 0;
1295}
1296
1297int
1298sys_getgroups(tcp)
1299struct tcb *tcp;
1300{
Roland McGrathaa524c82005-06-01 19:22:06 +00001301 unsigned long len;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001302
1303 if (entering(tcp)) {
1304 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001305 tprintf("%lu, ", len);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001306 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001307 unsigned long size, start, cur, end, abbrev_end;
1308 GETGROUPS_T gid;
1309 int failed = 0;
1310
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001311 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001312 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001313 tprintf("[]");
1314 return 0;
1315 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001316 start = tcp->u_arg[1];
1317 if (start == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001318 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001319 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001320 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001321 if (tcp->u_arg[0] == 0) {
1322 tprintf("%#lx", start);
1323 return 0;
1324 }
1325 size = len * sizeof(gid);
1326 end = start + size;
1327 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1328 size / sizeof(gid) != len || end < start) {
1329 tprintf("%#lx", start);
1330 return 0;
1331 }
1332 if (abbrev(tcp)) {
1333 abbrev_end = start + max_strlen * sizeof(gid);
1334 if (abbrev_end < start)
1335 abbrev_end = end;
1336 } else {
1337 abbrev_end = end;
1338 }
1339 tprintf("[");
1340 for (cur = start; cur < end; cur += sizeof(gid)) {
1341 if (cur > start)
1342 tprintf(", ");
1343 if (cur >= abbrev_end) {
1344 tprintf("...");
1345 break;
1346 }
1347 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1348 tprintf("?");
1349 failed = 1;
1350 break;
1351 }
1352 tprintf("%lu", (unsigned long) gid);
1353 }
1354 tprintf("]");
1355 if (failed)
1356 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001357 }
1358 return 0;
1359}
1360
Roland McGrath83bd47a2003-11-13 22:32:26 +00001361#ifdef LINUX
1362int
1363sys_setgroups32(tcp)
1364struct tcb *tcp;
1365{
Roland McGrath83bd47a2003-11-13 22:32:26 +00001366 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001367 unsigned long len, size, start, cur, end, abbrev_end;
1368 GETGROUPS32_T gid;
1369 int failed = 0;
1370
Roland McGrath83bd47a2003-11-13 22:32:26 +00001371 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001372 tprintf("%lu, ", len);
1373 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001374 tprintf("[]");
1375 return 0;
1376 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001377 start = tcp->u_arg[1];
1378 if (start == 0) {
1379 tprintf("NULL");
1380 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001381 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001382 size = len * sizeof(gid);
1383 end = start + size;
1384 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1385 tprintf("%#lx", start);
1386 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001387 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001388 if (abbrev(tcp)) {
1389 abbrev_end = start + max_strlen * sizeof(gid);
1390 if (abbrev_end < start)
1391 abbrev_end = end;
1392 } else {
1393 abbrev_end = end;
1394 }
1395 tprintf("[");
1396 for (cur = start; cur < end; cur += sizeof(gid)) {
1397 if (cur > start)
1398 tprintf(", ");
1399 if (cur >= abbrev_end) {
1400 tprintf("...");
1401 break;
1402 }
1403 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1404 tprintf("?");
1405 failed = 1;
1406 break;
1407 }
1408 tprintf("%lu", (unsigned long) gid);
1409 }
1410 tprintf("]");
1411 if (failed)
1412 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001413 }
1414 return 0;
1415}
1416
1417int
1418sys_getgroups32(tcp)
1419struct tcb *tcp;
1420{
Roland McGrathaa524c82005-06-01 19:22:06 +00001421 unsigned long len;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001422
1423 if (entering(tcp)) {
1424 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001425 tprintf("%lu, ", len);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001426 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001427 unsigned long size, start, cur, end, abbrev_end;
1428 GETGROUPS32_T gid;
1429 int failed = 0;
1430
Roland McGrath83bd47a2003-11-13 22:32:26 +00001431 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001432 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001433 tprintf("[]");
1434 return 0;
1435 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001436 start = tcp->u_arg[1];
1437 if (start == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001438 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001439 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001440 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001441 size = len * sizeof(gid);
1442 end = start + size;
1443 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1444 size / sizeof(gid) != len || end < start) {
1445 tprintf("%#lx", start);
1446 return 0;
1447 }
1448 if (abbrev(tcp)) {
1449 abbrev_end = start + max_strlen * sizeof(gid);
1450 if (abbrev_end < start)
1451 abbrev_end = end;
1452 } else {
1453 abbrev_end = end;
1454 }
1455 tprintf("[");
1456 for (cur = start; cur < end; cur += sizeof(gid)) {
1457 if (cur > start)
1458 tprintf(", ");
1459 if (cur >= abbrev_end) {
1460 tprintf("...");
1461 break;
1462 }
1463 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1464 tprintf("?");
1465 failed = 1;
1466 break;
1467 }
1468 tprintf("%lu", (unsigned long) gid);
1469 }
1470 tprintf("]");
1471 if (failed)
1472 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001473 }
1474 return 0;
1475}
1476#endif /* LINUX */
1477
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001478#if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001479int
1480sys_setpgrp(tcp)
1481struct tcb *tcp;
1482{
1483 if (entering(tcp)) {
1484#ifndef SVR4
1485 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1486#endif /* !SVR4 */
1487 }
1488 return 0;
1489}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001490#endif /* ALPHA || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001491
1492int
1493sys_getpgrp(tcp)
1494struct tcb *tcp;
1495{
1496 if (entering(tcp)) {
1497#ifndef SVR4
1498 tprintf("%lu", tcp->u_arg[0]);
1499#endif /* !SVR4 */
1500 }
1501 return 0;
1502}
1503
1504int
1505sys_getsid(tcp)
1506struct tcb *tcp;
1507{
1508 if (entering(tcp)) {
1509 tprintf("%lu", tcp->u_arg[0]);
1510 }
1511 return 0;
1512}
1513
1514int
1515sys_setsid(tcp)
1516struct tcb *tcp;
1517{
1518 return 0;
1519}
1520
1521int
1522sys_getpgid(tcp)
1523struct tcb *tcp;
1524{
1525 if (entering(tcp)) {
1526 tprintf("%lu", tcp->u_arg[0]);
1527 }
1528 return 0;
1529}
1530
1531int
1532sys_setpgid(tcp)
1533struct tcb *tcp;
1534{
1535 if (entering(tcp)) {
1536 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1537 }
1538 return 0;
1539}
1540
John Hughesc61eb3d2002-05-17 11:37:50 +00001541#if UNIXWARE >= 2
1542
1543#include <sys/privilege.h>
1544
1545
Roland McGrathd9f816f2004-09-04 03:39:20 +00001546static const struct xlat procpriv_cmds [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001547 { SETPRV, "SETPRV" },
1548 { CLRPRV, "CLRPRV" },
1549 { PUTPRV, "PUTPRV" },
1550 { GETPRV, "GETPRV" },
1551 { CNTPRV, "CNTPRV" },
1552 { 0, NULL },
1553};
1554
1555
Roland McGrathd9f816f2004-09-04 03:39:20 +00001556static const struct xlat procpriv_priv [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001557 { P_OWNER, "P_OWNER" },
1558 { P_AUDIT, "P_AUDIT" },
1559 { P_COMPAT, "P_COMPAT" },
1560 { P_DACREAD, "P_DACREAD" },
1561 { P_DACWRITE, "P_DACWRITE" },
1562 { P_DEV, "P_DEV" },
1563 { P_FILESYS, "P_FILESYS" },
1564 { P_MACREAD, "P_MACREAD" },
1565 { P_MACWRITE, "P_MACWRITE" },
1566 { P_MOUNT, "P_MOUNT" },
1567 { P_MULTIDIR, "P_MULTIDIR" },
1568 { P_SETPLEVEL, "P_SETPLEVEL" },
1569 { P_SETSPRIV, "P_SETSPRIV" },
1570 { P_SETUID, "P_SETUID" },
1571 { P_SYSOPS, "P_SYSOPS" },
1572 { P_SETUPRIV, "P_SETUPRIV" },
1573 { P_DRIVER, "P_DRIVER" },
1574 { P_RTIME, "P_RTIME" },
1575 { P_MACUPGRADE, "P_MACUPGRADE" },
1576 { P_FSYSRANGE, "P_FSYSRANGE" },
1577 { P_SETFLEVEL, "P_SETFLEVEL" },
1578 { P_AUDITWR, "P_AUDITWR" },
1579 { P_TSHAR, "P_TSHAR" },
1580 { P_PLOCK, "P_PLOCK" },
1581 { P_CORE, "P_CORE" },
1582 { P_LOADMOD, "P_LOADMOD" },
1583 { P_BIND, "P_BIND" },
1584 { P_ALLPRIVS, "P_ALLPRIVS" },
1585 { 0, NULL },
1586};
1587
1588
Roland McGrathd9f816f2004-09-04 03:39:20 +00001589static const struct xlat procpriv_type [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001590 { PS_FIX, "PS_FIX" },
1591 { PS_INH, "PS_INH" },
1592 { PS_MAX, "PS_MAX" },
1593 { PS_WKG, "PS_WKG" },
1594 { 0, NULL },
1595};
1596
1597
1598static void
Dmitry V. Levinab9008b2007-01-11 22:05:04 +00001599printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
John Hughesc61eb3d2002-05-17 11:37:50 +00001600{
1601 priv_t buf [128];
1602 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1603 int dots = len > max;
1604 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001605
John Hughesc61eb3d2002-05-17 11:37:50 +00001606 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001607
John Hughesc61eb3d2002-05-17 11:37:50 +00001608 if (len <= 0 ||
1609 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1610 {
1611 tprintf ("%#lx", addr);
1612 return;
1613 }
1614
1615 tprintf ("[");
1616
1617 for (i = 0; i < len; ++i) {
Dmitry V. Levinab9008b2007-01-11 22:05:04 +00001618 const char *t, *p;
John Hughesc61eb3d2002-05-17 11:37:50 +00001619
1620 if (i) tprintf (", ");
1621
1622 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1623 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1624 {
1625 tprintf ("%s|%s", t, p);
1626 }
1627 else {
1628 tprintf ("%#lx", buf [i]);
1629 }
1630 }
1631
1632 if (dots) tprintf (" ...");
1633
1634 tprintf ("]");
1635}
1636
1637
1638int
1639sys_procpriv(tcp)
1640struct tcb *tcp;
1641{
1642 if (entering(tcp)) {
1643 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1644 switch (tcp->u_arg[0]) {
1645 case CNTPRV:
1646 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1647 break;
1648
1649 case GETPRV:
1650 break;
1651
1652 default:
1653 tprintf (", ");
1654 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1655 tprintf (", %ld", tcp->u_arg[2]);
1656 }
1657 }
1658 else if (tcp->u_arg[0] == GETPRV) {
1659 if (syserror (tcp)) {
1660 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1661 }
1662 else {
1663 tprintf (", ");
1664 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1665 tprintf (", %ld", tcp->u_arg[2]);
1666 }
1667 }
Roland McGrath5a223472002-12-15 23:58:26 +00001668
John Hughesc61eb3d2002-05-17 11:37:50 +00001669 return 0;
1670}
1671
1672#endif
1673
1674
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001675static void
1676printargv(tcp, addr)
1677struct tcb *tcp;
1678long addr;
1679{
1680 char *cp;
1681 char *sep;
1682 int max = max_strlen / 2;
1683
1684 for (sep = ""; --max >= 0; sep = ", ") {
1685 if (!abbrev(tcp))
1686 max++;
1687 if (umove(tcp, addr, &cp) < 0) {
1688 tprintf("%#lx", addr);
1689 return;
1690 }
1691 if (cp == 0)
1692 break;
1693 tprintf(sep);
1694 printstr(tcp, (long) cp, -1);
1695 addr += sizeof(char *);
1696 }
1697 if (cp)
1698 tprintf(", ...");
1699}
1700
1701static void
1702printargc(fmt, tcp, addr)
1703char *fmt;
1704struct tcb *tcp;
1705long addr;
1706{
1707 int count;
1708 char *cp;
1709
1710 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1711 addr += sizeof(char *);
1712 }
1713 tprintf(fmt, count, count == 1 ? "" : "s");
1714}
1715
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001716#if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001717int
1718sys_execv(tcp)
1719struct tcb *tcp;
1720{
1721 if (entering(tcp)) {
1722 printpath(tcp, tcp->u_arg[0]);
1723 if (!verbose(tcp))
1724 tprintf(", %#lx", tcp->u_arg[1]);
1725#if 0
1726 else if (abbrev(tcp))
1727 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1728#endif
1729 else {
1730 tprintf(", [");
1731 printargv(tcp, tcp->u_arg[1]);
1732 tprintf("]");
1733 }
1734 }
1735 return 0;
1736}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001737#endif /* SPARC || SPARC64 || SUNOS4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001738
1739int
1740sys_execve(tcp)
1741struct tcb *tcp;
1742{
1743 if (entering(tcp)) {
1744 printpath(tcp, tcp->u_arg[0]);
1745 if (!verbose(tcp))
1746 tprintf(", %#lx", tcp->u_arg[1]);
1747#if 0
1748 else if (abbrev(tcp))
1749 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1750#endif
1751 else {
1752 tprintf(", [");
1753 printargv(tcp, tcp->u_arg[1]);
1754 tprintf("]");
1755 }
1756 if (!verbose(tcp))
1757 tprintf(", %#lx", tcp->u_arg[2]);
1758 else if (abbrev(tcp))
1759 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1760 else {
1761 tprintf(", [");
1762 printargv(tcp, tcp->u_arg[2]);
1763 tprintf("]");
1764 }
1765 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001766 return 0;
1767}
1768
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001769#if UNIXWARE > 2
John Hughes4e36a812001-04-18 15:11:51 +00001770
1771int sys_rexecve(tcp)
1772struct tcb *tcp;
1773{
1774 if (entering (tcp)) {
1775 sys_execve (tcp);
1776 tprintf (", %ld", tcp->u_arg[3]);
1777 }
1778 return 0;
1779}
1780
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001781#endif
John Hughes4e36a812001-04-18 15:11:51 +00001782
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001783int
1784internal_exec(tcp)
1785struct tcb *tcp;
1786{
1787#ifdef SUNOS4
1788 if (exiting(tcp) && !syserror(tcp) && followfork)
1789 fixvfork(tcp);
1790#endif /* SUNOS4 */
Roland McGrathfdb097f2004-07-12 07:38:55 +00001791#if defined LINUX && defined TCB_WAITEXECVE
1792 if (exiting(tcp) && syserror(tcp))
1793 tcp->flags &= ~TCB_WAITEXECVE;
1794 else
1795 tcp->flags |= TCB_WAITEXECVE;
1796#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001797 return 0;
1798}
1799
1800#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001801#ifndef __WNOTHREAD
1802#define __WNOTHREAD 0x20000000
1803#endif
1804#ifndef __WALL
1805#define __WALL 0x40000000
1806#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001807#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001808#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001809#endif
1810#endif /* LINUX */
1811
Roland McGrathd9f816f2004-09-04 03:39:20 +00001812static const struct xlat wait4_options[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001813 { WNOHANG, "WNOHANG" },
1814#ifndef WSTOPPED
1815 { WUNTRACED, "WUNTRACED" },
1816#endif
1817#ifdef WEXITED
1818 { WEXITED, "WEXITED" },
1819#endif
1820#ifdef WTRAPPED
1821 { WTRAPPED, "WTRAPPED" },
1822#endif
1823#ifdef WSTOPPED
1824 { WSTOPPED, "WSTOPPED" },
1825#endif
1826#ifdef WCONTINUED
1827 { WCONTINUED, "WCONTINUED" },
1828#endif
1829#ifdef WNOWAIT
1830 { WNOWAIT, "WNOWAIT" },
1831#endif
1832#ifdef __WCLONE
1833 { __WCLONE, "__WCLONE" },
1834#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001835#ifdef __WALL
1836 { __WALL, "__WALL" },
1837#endif
1838#ifdef __WNOTHREAD
1839 { __WNOTHREAD, "__WNOTHREAD" },
1840#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001841 { 0, NULL },
1842};
1843
Roland McGrath5e02a572004-10-19 23:33:47 +00001844#if !defined WCOREFLAG && defined WCOREFLG
1845# define WCOREFLAG WCOREFLG
1846#endif
1847#ifndef WCOREFLAG
1848#define WCOREFLAG 0x80
1849#endif
1850
1851#ifndef W_STOPCODE
1852#define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1853#endif
1854#ifndef W_EXITCODE
1855#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1856#endif
1857
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001858static int
1859printstatus(status)
1860int status;
1861{
1862 int exited = 0;
1863
1864 /*
1865 * Here is a tricky presentation problem. This solution
1866 * is still not entirely satisfactory but since there
1867 * are no wait status constructors it will have to do.
1868 */
Roland McGrath79fbda52004-04-14 02:45:55 +00001869 if (WIFSTOPPED(status)) {
1870 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001871 signame(WSTOPSIG(status)));
Roland McGrath79fbda52004-04-14 02:45:55 +00001872 status &= ~W_STOPCODE(WSTOPSIG(status));
1873 }
1874 else if (WIFSIGNALED(status)) {
1875 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001876 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001877 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
Roland McGrath79fbda52004-04-14 02:45:55 +00001878 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1879 }
1880 else if (WIFEXITED(status)) {
1881 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001882 WEXITSTATUS(status));
1883 exited = 1;
Roland McGrath79fbda52004-04-14 02:45:55 +00001884 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001885 }
Roland McGrath79fbda52004-04-14 02:45:55 +00001886 else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001887 tprintf("[%#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001888 return 0;
1889 }
1890
1891 if (status == 0)
1892 tprintf("]");
1893 else
Roland McGrathf8cc83c2004-06-04 01:24:07 +00001894 tprintf(" | %#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001895
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001896 return exited;
1897}
1898
1899static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001900printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001901struct tcb *tcp;
1902int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001903int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001904{
1905 int status;
1906 int exited = 0;
1907
1908 if (entering(tcp)) {
1909 tprintf("%ld, ", tcp->u_arg[0]);
1910 } else {
1911 /* status */
1912 if (!tcp->u_arg[1])
1913 tprintf("NULL");
1914 else if (syserror(tcp) || tcp->u_rval == 0)
1915 tprintf("%#lx", tcp->u_arg[1]);
1916 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1917 tprintf("[?]");
1918 else
1919 exited = printstatus(status);
1920 /* options */
1921 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00001922 printflags(wait4_options, tcp->u_arg[2], "W???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001923 if (n == 4) {
1924 tprintf(", ");
1925 /* usage */
1926 if (!tcp->u_arg[3])
1927 tprintf("NULL");
1928#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001929 else if (tcp->u_rval > 0) {
1930#ifdef LINUX_64BIT
1931 if (bitness)
1932 printrusage32(tcp, tcp->u_arg[3]);
1933 else
1934#endif
1935 printrusage(tcp, tcp->u_arg[3]);
1936 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001937#endif /* LINUX */
1938#ifdef SUNOS4
1939 else if (tcp->u_rval > 0 && exited)
1940 printrusage(tcp, tcp->u_arg[3]);
1941#endif /* SUNOS4 */
1942 else
1943 tprintf("%#lx", tcp->u_arg[3]);
1944 }
1945 }
1946 return 0;
1947}
1948
1949int
Roland McGrathc74c0b72004-09-01 19:39:46 +00001950internal_wait(tcp, flagarg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001951struct tcb *tcp;
Roland McGrathc74c0b72004-09-01 19:39:46 +00001952int flagarg;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001953{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001954 int got_kids;
1955
1956#ifdef TCB_CLONE_THREAD
1957 if (tcp->flags & TCB_CLONE_THREAD)
1958 /* The children we wait for are our parent's children. */
1959 got_kids = (tcp->parent->nchildren
1960 > tcp->parent->nclone_detached);
1961 else
1962 got_kids = (tcp->nchildren > tcp->nclone_detached);
1963#else
1964 got_kids = tcp->nchildren > 0;
1965#endif
1966
1967 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001968 /* There are children that this parent should block for.
1969 But ptrace made us the parent of the traced children
1970 and the real parent will get ECHILD from the wait call.
1971
1972 XXX If we attached with strace -f -p PID, then there
1973 may be untraced dead children the parent could be reaping
1974 now, but we make him block. */
1975
1976 /* ??? WTA: fix bug with hanging children */
1977
Roland McGrathc74c0b72004-09-01 19:39:46 +00001978 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00001979 /*
1980 * There are traced children. We'll make the parent
1981 * block to avoid a false ECHILD error due to our
1982 * ptrace having stolen the children. However,
1983 * we shouldn't block if there are zombies to reap.
1984 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1985 */
Roland McGrathfccfb942003-10-01 21:59:44 +00001986 struct tcb *child = NULL;
Roland McGrath09623452003-05-23 02:27:13 +00001987 if (tcp->nzombies > 0 &&
1988 (tcp->u_arg[0] == -1 ||
Roland McGrathfccfb942003-10-01 21:59:44 +00001989 (child = pid2tcb(tcp->u_arg[0])) == NULL))
Roland McGrath09623452003-05-23 02:27:13 +00001990 return 0;
Roland McGrathfccfb942003-10-01 21:59:44 +00001991 if (tcp->u_arg[0] > 0) {
1992 /*
1993 * If the parent waits for a specified child
1994 * PID, then it must get ECHILD right away
1995 * if that PID is not one of its children.
1996 * Make sure that the requested PID matches
1997 * one of the parent's children that we are
1998 * tracing, and don't suspend it otherwise.
1999 */
2000 if (child == NULL)
2001 child = pid2tcb(tcp->u_arg[0]);
2002 if (child == NULL || child->parent != (
2003#ifdef TCB_CLONE_THREAD
2004 (tcp->flags & TCB_CLONE_THREAD)
2005 ? tcp->parent :
2006#endif
Roland McGrathd56a6562005-08-03 11:23:43 +00002007 tcp) ||
2008 (child->flags & TCB_EXITING))
Roland McGrathfccfb942003-10-01 21:59:44 +00002009 return 0;
2010 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002011 tcp->flags |= TCB_SUSPENDED;
2012 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002013#ifdef TCB_CLONE_THREAD
2014 if (tcp->flags & TCB_CLONE_THREAD)
2015 tcp->parent->nclone_waiting++;
2016#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002017 }
2018 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002019 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathc74c0b72004-09-01 19:39:46 +00002020 if (tcp->u_arg[flagarg] & WNOHANG) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00002021 /* We must force a fake result of 0 instead of
2022 the ECHILD error. */
2023 extern int force_result();
2024 return force_result(tcp, 0, 0);
2025 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00002026 }
Roland McGrath09623452003-05-23 02:27:13 +00002027 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2028 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2029 /*
2030 * We just reaped a child we don't know about,
2031 * presumably a zombie we already droptcb'd.
2032 */
2033 tcp->nzombies--;
2034 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002035 return 0;
2036}
2037
2038#ifdef SVR4
2039
2040int
2041sys_wait(tcp)
2042struct tcb *tcp;
2043{
2044 if (exiting(tcp)) {
2045 /* The library wrapper stuffs this into the user variable. */
2046 if (!syserror(tcp))
2047 printstatus(getrval2(tcp));
2048 }
2049 return 0;
2050}
2051
2052#endif /* SVR4 */
2053
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002054#ifdef FREEBSD
2055int
2056sys_wait(tcp)
2057struct tcb *tcp;
2058{
2059 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00002060
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002061 if (exiting(tcp)) {
2062 if (!syserror(tcp)) {
2063 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2064 tprintf("%#lx", tcp->u_arg[0]);
2065 else
2066 printstatus(status);
2067 }
2068 }
2069 return 0;
2070}
2071#endif
2072
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002073int
2074sys_waitpid(tcp)
2075struct tcb *tcp;
2076{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002077 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002078}
2079
2080int
2081sys_wait4(tcp)
2082struct tcb *tcp;
2083{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002084 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002085}
2086
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002087#ifdef ALPHA
2088int
2089sys_osf_wait4(tcp)
2090struct tcb *tcp;
2091{
2092 return printwaitn(tcp, 4, 1);
2093}
2094#endif
2095
Roland McGrathc74c0b72004-09-01 19:39:46 +00002096#if defined SVR4 || defined LINUX
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002097
Roland McGrathd9f816f2004-09-04 03:39:20 +00002098static const struct xlat waitid_types[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002099 { P_PID, "P_PID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002100#ifdef P_PPID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002101 { P_PPID, "P_PPID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002102#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002103 { P_PGID, "P_PGID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002104#ifdef P_SID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002105 { P_SID, "P_SID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002106#endif
2107#ifdef P_CID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002108 { P_CID, "P_CID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002109#endif
2110#ifdef P_UID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002111 { P_UID, "P_UID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002112#endif
2113#ifdef P_GID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002114 { P_GID, "P_GID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002115#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002116 { P_ALL, "P_ALL" },
2117#ifdef P_LWPID
2118 { P_LWPID, "P_LWPID" },
2119#endif
2120 { 0, NULL },
2121};
2122
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002123int
2124sys_waitid(tcp)
2125struct tcb *tcp;
2126{
2127 siginfo_t si;
2128 int exited;
2129
2130 if (entering(tcp)) {
2131 printxval(waitid_types, tcp->u_arg[0], "P_???");
2132 tprintf(", %ld, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002133 }
2134 else {
2135 /* siginfo */
2136 exited = 0;
2137 if (!tcp->u_arg[2])
2138 tprintf("NULL");
2139 else if (syserror(tcp))
2140 tprintf("%#lx", tcp->u_arg[2]);
2141 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2142 tprintf("{???}");
2143 else
John Hughes58265892001-10-18 15:13:53 +00002144 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002145 /* options */
2146 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00002147 printflags(wait4_options, tcp->u_arg[3], "W???");
Roland McGrath39426a32004-10-06 22:02:59 +00002148 if (tcp->u_nargs > 4) {
2149 /* usage */
2150 tprintf(", ");
2151 if (!tcp->u_arg[4])
2152 tprintf("NULL");
2153 else if (tcp->u_error)
2154 tprintf("%#lx", tcp->u_arg[4]);
2155 else
2156 printrusage(tcp, tcp->u_arg[4]);
2157 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002158 }
2159 return 0;
2160}
2161
Roland McGrathc74c0b72004-09-01 19:39:46 +00002162#endif /* SVR4 or LINUX */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002163
2164int
2165sys_alarm(tcp)
2166struct tcb *tcp;
2167{
2168 if (entering(tcp))
2169 tprintf("%lu", tcp->u_arg[0]);
2170 return 0;
2171}
2172
2173int
2174sys_uname(tcp)
2175struct tcb *tcp;
2176{
2177 struct utsname uname;
2178
2179 if (exiting(tcp)) {
2180 if (syserror(tcp) || !verbose(tcp))
2181 tprintf("%#lx", tcp->u_arg[0]);
2182 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2183 tprintf("{...}");
2184 else if (!abbrev(tcp)) {
2185
2186 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2187 uname.sysname, uname.nodename);
2188 tprintf("release=\"%s\", version=\"%s\", ",
2189 uname.release, uname.version);
2190 tprintf("machine=\"%s\"", uname.machine);
2191#ifdef LINUX
2192#ifndef __GLIBC__
2193 tprintf(", domainname=\"%s\"", uname.domainname);
2194#endif /* __GLIBC__ */
2195#endif /* LINUX */
2196 tprintf("}");
2197 }
2198 else
2199 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2200 uname.sysname, uname.nodename);
2201 }
2202 return 0;
2203}
2204
2205#ifndef SVR4
2206
Roland McGrathd9f816f2004-09-04 03:39:20 +00002207static const struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002208#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002209 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2210 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2211 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2212 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2213 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2214 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2215 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2216 { PTRACE_CONT, "PTRACE_CONT" },
2217 { PTRACE_KILL, "PTRACE_KILL" },
2218 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2219 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2220 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002221#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002222 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002223#endif
2224#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002225 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002226#endif
2227#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002228 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002229#endif
2230#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002231 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002232#endif
2233#ifdef PTRACE_GETFPXREGS
2234 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2235#endif
2236#ifdef PTRACE_SETFPXREGS
2237 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2238#endif
Roland McGrathf04bb482005-05-09 07:45:33 +00002239#ifdef PTRACE_GETVRREGS
2240 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2241#endif
2242#ifdef PTRACE_SETVRREGS
2243 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2244#endif
Roland McGrathbf621d42003-01-14 09:46:21 +00002245#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002246 { PTRACE_READDATA, "PTRACE_READDATA" },
2247 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2248 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2249 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2250 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2251 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2252#ifdef SPARC
2253 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2254 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2255#else /* !SPARC */
2256 { PTRACE_22, "PTRACE_PTRACE_22" },
2257 { PTRACE_23, "PTRACE_PTRACE_23" },
2258#endif /* !SPARC */
2259#endif /* SUNOS4 */
2260 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2261#ifdef SUNOS4
2262 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2263#ifdef I386
2264 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2265 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2266 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2267#else /* !I386 */
2268 { PTRACE_26, "PTRACE_26" },
2269 { PTRACE_27, "PTRACE_27" },
2270 { PTRACE_28, "PTRACE_28" },
2271#endif /* !I386 */
2272 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2273#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002274#else /* FREEBSD */
2275 { PT_TRACE_ME, "PT_TRACE_ME" },
2276 { PT_READ_I, "PT_READ_I" },
2277 { PT_READ_D, "PT_READ_D" },
2278 { PT_WRITE_I, "PT_WRITE_I" },
2279 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002280#ifdef PT_READ_U
2281 { PT_READ_U, "PT_READ_U" },
2282#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002283 { PT_CONTINUE, "PT_CONTINUE" },
2284 { PT_KILL, "PT_KILL" },
2285 { PT_STEP, "PT_STEP" },
2286 { PT_ATTACH, "PT_ATTACH" },
2287 { PT_DETACH, "PT_DETACH" },
2288 { PT_GETREGS, "PT_GETREGS" },
2289 { PT_SETREGS, "PT_SETREGS" },
2290 { PT_GETFPREGS, "PT_GETFPREGS" },
2291 { PT_SETFPREGS, "PT_SETFPREGS" },
2292 { PT_GETDBREGS, "PT_GETDBREGS" },
2293 { PT_SETDBREGS, "PT_SETDBREGS" },
2294#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002295 { 0, NULL },
2296};
2297
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002298#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002299#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2300static
2301#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
Roland McGrathd9f816f2004-09-04 03:39:20 +00002302const struct xlat struct_user_offsets[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002303#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002304#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002305 { PT_PSWMASK, "psw_mask" },
2306 { PT_PSWADDR, "psw_addr" },
2307 { PT_GPR0, "gpr0" },
2308 { PT_GPR1, "gpr1" },
2309 { PT_GPR2, "gpr2" },
2310 { PT_GPR3, "gpr3" },
2311 { PT_GPR4, "gpr4" },
2312 { PT_GPR5, "gpr5" },
2313 { PT_GPR6, "gpr6" },
2314 { PT_GPR7, "gpr7" },
2315 { PT_GPR8, "gpr8" },
2316 { PT_GPR9, "gpr9" },
2317 { PT_GPR10, "gpr10" },
2318 { PT_GPR11, "gpr11" },
2319 { PT_GPR12, "gpr12" },
2320 { PT_GPR13, "gpr13" },
2321 { PT_GPR14, "gpr14" },
2322 { PT_GPR15, "gpr15" },
2323 { PT_ACR0, "acr0" },
2324 { PT_ACR1, "acr1" },
2325 { PT_ACR2, "acr2" },
2326 { PT_ACR3, "acr3" },
2327 { PT_ACR4, "acr4" },
2328 { PT_ACR5, "acr5" },
2329 { PT_ACR6, "acr6" },
2330 { PT_ACR7, "acr7" },
2331 { PT_ACR8, "acr8" },
2332 { PT_ACR9, "acr9" },
2333 { PT_ACR10, "acr10" },
2334 { PT_ACR11, "acr11" },
2335 { PT_ACR12, "acr12" },
2336 { PT_ACR13, "acr13" },
2337 { PT_ACR14, "acr14" },
2338 { PT_ACR15, "acr15" },
2339 { PT_ORIGGPR2, "orig_gpr2" },
2340 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002341#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002342 { PT_FPR0_HI, "fpr0.hi" },
2343 { PT_FPR0_LO, "fpr0.lo" },
2344 { PT_FPR1_HI, "fpr1.hi" },
2345 { PT_FPR1_LO, "fpr1.lo" },
2346 { PT_FPR2_HI, "fpr2.hi" },
2347 { PT_FPR2_LO, "fpr2.lo" },
2348 { PT_FPR3_HI, "fpr3.hi" },
2349 { PT_FPR3_LO, "fpr3.lo" },
2350 { PT_FPR4_HI, "fpr4.hi" },
2351 { PT_FPR4_LO, "fpr4.lo" },
2352 { PT_FPR5_HI, "fpr5.hi" },
2353 { PT_FPR5_LO, "fpr5.lo" },
2354 { PT_FPR6_HI, "fpr6.hi" },
2355 { PT_FPR6_LO, "fpr6.lo" },
2356 { PT_FPR7_HI, "fpr7.hi" },
2357 { PT_FPR7_LO, "fpr7.lo" },
2358 { PT_FPR8_HI, "fpr8.hi" },
2359 { PT_FPR8_LO, "fpr8.lo" },
2360 { PT_FPR9_HI, "fpr9.hi" },
2361 { PT_FPR9_LO, "fpr9.lo" },
2362 { PT_FPR10_HI, "fpr10.hi" },
2363 { PT_FPR10_LO, "fpr10.lo" },
2364 { PT_FPR11_HI, "fpr11.hi" },
2365 { PT_FPR11_LO, "fpr11.lo" },
2366 { PT_FPR12_HI, "fpr12.hi" },
2367 { PT_FPR12_LO, "fpr12.lo" },
2368 { PT_FPR13_HI, "fpr13.hi" },
2369 { PT_FPR13_LO, "fpr13.lo" },
2370 { PT_FPR14_HI, "fpr14.hi" },
2371 { PT_FPR14_LO, "fpr14.lo" },
2372 { PT_FPR15_HI, "fpr15.hi" },
2373 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002374#endif
2375#if defined(S390X)
2376 { PT_FPR0, "fpr0" },
2377 { PT_FPR1, "fpr1" },
2378 { PT_FPR2, "fpr2" },
2379 { PT_FPR3, "fpr3" },
2380 { PT_FPR4, "fpr4" },
2381 { PT_FPR5, "fpr5" },
2382 { PT_FPR6, "fpr6" },
2383 { PT_FPR7, "fpr7" },
2384 { PT_FPR8, "fpr8" },
2385 { PT_FPR9, "fpr9" },
2386 { PT_FPR10, "fpr10" },
2387 { PT_FPR11, "fpr11" },
2388 { PT_FPR12, "fpr12" },
2389 { PT_FPR13, "fpr13" },
2390 { PT_FPR14, "fpr14" },
2391 { PT_FPR15, "fpr15" },
2392#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002393 { PT_CR_9, "cr9" },
2394 { PT_CR_10, "cr10" },
2395 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002396 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002397#endif
2398#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002399 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002400#elif defined(HPPA)
2401 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002402#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002403#ifndef PT_ORIG_R3
2404#define PT_ORIG_R3 34
2405#endif
Roland McGratheb285352003-01-14 09:59:00 +00002406#define REGSIZE (sizeof(unsigned long))
2407 { REGSIZE*PT_R0, "r0" },
2408 { REGSIZE*PT_R1, "r1" },
2409 { REGSIZE*PT_R2, "r2" },
2410 { REGSIZE*PT_R3, "r3" },
2411 { REGSIZE*PT_R4, "r4" },
2412 { REGSIZE*PT_R5, "r5" },
2413 { REGSIZE*PT_R6, "r6" },
2414 { REGSIZE*PT_R7, "r7" },
2415 { REGSIZE*PT_R8, "r8" },
2416 { REGSIZE*PT_R9, "r9" },
2417 { REGSIZE*PT_R10, "r10" },
2418 { REGSIZE*PT_R11, "r11" },
2419 { REGSIZE*PT_R12, "r12" },
2420 { REGSIZE*PT_R13, "r13" },
2421 { REGSIZE*PT_R14, "r14" },
2422 { REGSIZE*PT_R15, "r15" },
2423 { REGSIZE*PT_R16, "r16" },
2424 { REGSIZE*PT_R17, "r17" },
2425 { REGSIZE*PT_R18, "r18" },
2426 { REGSIZE*PT_R19, "r19" },
2427 { REGSIZE*PT_R20, "r20" },
2428 { REGSIZE*PT_R21, "r21" },
2429 { REGSIZE*PT_R22, "r22" },
2430 { REGSIZE*PT_R23, "r23" },
2431 { REGSIZE*PT_R24, "r24" },
2432 { REGSIZE*PT_R25, "r25" },
2433 { REGSIZE*PT_R26, "r26" },
2434 { REGSIZE*PT_R27, "r27" },
2435 { REGSIZE*PT_R28, "r28" },
2436 { REGSIZE*PT_R29, "r29" },
2437 { REGSIZE*PT_R30, "r30" },
2438 { REGSIZE*PT_R31, "r31" },
2439 { REGSIZE*PT_NIP, "NIP" },
2440 { REGSIZE*PT_MSR, "MSR" },
2441 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2442 { REGSIZE*PT_CTR, "CTR" },
2443 { REGSIZE*PT_LNK, "LNK" },
2444 { REGSIZE*PT_XER, "XER" },
2445 { REGSIZE*PT_CCR, "CCR" },
2446 { REGSIZE*PT_FPR0, "FPR0" },
2447#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002448#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002449#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002450 { 0, "r0" },
2451 { 1, "r1" },
2452 { 2, "r2" },
2453 { 3, "r3" },
2454 { 4, "r4" },
2455 { 5, "r5" },
2456 { 6, "r6" },
2457 { 7, "r7" },
2458 { 8, "r8" },
2459 { 9, "r9" },
2460 { 10, "r10" },
2461 { 11, "r11" },
2462 { 12, "r12" },
2463 { 13, "r13" },
2464 { 14, "r14" },
2465 { 15, "r15" },
2466 { 16, "r16" },
2467 { 17, "r17" },
2468 { 18, "r18" },
2469 { 19, "r19" },
2470 { 20, "r20" },
2471 { 21, "r21" },
2472 { 22, "r22" },
2473 { 23, "r23" },
2474 { 24, "r24" },
2475 { 25, "r25" },
2476 { 26, "r26" },
2477 { 27, "r27" },
2478 { 28, "r28" },
2479 { 29, "gp" },
2480 { 30, "fp" },
2481 { 31, "zero" },
2482 { 32, "fp0" },
2483 { 33, "fp" },
2484 { 34, "fp2" },
2485 { 35, "fp3" },
2486 { 36, "fp4" },
2487 { 37, "fp5" },
2488 { 38, "fp6" },
2489 { 39, "fp7" },
2490 { 40, "fp8" },
2491 { 41, "fp9" },
2492 { 42, "fp10" },
2493 { 43, "fp11" },
2494 { 44, "fp12" },
2495 { 45, "fp13" },
2496 { 46, "fp14" },
2497 { 47, "fp15" },
2498 { 48, "fp16" },
2499 { 49, "fp17" },
2500 { 50, "fp18" },
2501 { 51, "fp19" },
2502 { 52, "fp20" },
2503 { 53, "fp21" },
2504 { 54, "fp22" },
2505 { 55, "fp23" },
2506 { 56, "fp24" },
2507 { 57, "fp25" },
2508 { 58, "fp26" },
2509 { 59, "fp27" },
2510 { 60, "fp28" },
2511 { 61, "fp29" },
2512 { 62, "fp30" },
2513 { 63, "fp31" },
2514 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002515#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002516#ifdef IA64
2517 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2518 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2519 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2520 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2521 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2522 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2523 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2524 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2525 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2526 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2527 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2528 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2529 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2530 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2531 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2532 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2533 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2534 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2535 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2536 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2537 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2538 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2539 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2540 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2541 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2542 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2543 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2544 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2545 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2546 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2547 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2548 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2549 /* switch stack: */
2550 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2551 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2552 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2553 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2554 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2555 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2556 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2557 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2558 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2559 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002560 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2561 { PT_B4, "b4" }, { PT_B5, "b5" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002562 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002563 /* pt_regs */
Roland McGrathca4e10c2004-01-13 10:13:20 +00002564 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2565 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002566 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2567 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2568 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2569 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2570 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2571 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2572 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2573 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2574 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2575 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2576 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2577 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2578 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2579 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2580 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
Roland McGrathfb1bc072004-03-01 21:29:24 +00002581# ifdef PT_AR_CSD
2582 { PT_AR_CSD, "ar.csd" },
2583# endif
2584# ifdef PT_AR_SSD
2585 { PT_AR_SSD, "ar.ssd" },
2586# endif
Roland McGrathca4e10c2004-01-13 10:13:20 +00002587 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002588#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002589#ifdef I386
2590 { 4*EBX, "4*EBX" },
2591 { 4*ECX, "4*ECX" },
2592 { 4*EDX, "4*EDX" },
2593 { 4*ESI, "4*ESI" },
2594 { 4*EDI, "4*EDI" },
2595 { 4*EBP, "4*EBP" },
2596 { 4*EAX, "4*EAX" },
2597 { 4*DS, "4*DS" },
2598 { 4*ES, "4*ES" },
2599 { 4*FS, "4*FS" },
2600 { 4*GS, "4*GS" },
2601 { 4*ORIG_EAX, "4*ORIG_EAX" },
2602 { 4*EIP, "4*EIP" },
2603 { 4*CS, "4*CS" },
2604 { 4*EFL, "4*EFL" },
2605 { 4*UESP, "4*UESP" },
2606 { 4*SS, "4*SS" },
2607#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002608#ifdef X86_64
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002609 { 8*R15, "8*R15" },
2610 { 8*R14, "8*R14" },
2611 { 8*R13, "8*R13" },
2612 { 8*R12, "8*R12" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002613 { 8*RBP, "8*RBP" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002614 { 8*RBX, "8*RBX" },
2615 { 8*R11, "8*R11" },
2616 { 8*R10, "8*R10" },
2617 { 8*R9, "8*R9" },
2618 { 8*R8, "8*R8" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002619 { 8*RAX, "8*RAX" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002620 { 8*RCX, "8*RCX" },
2621 { 8*RDX, "8*RDX" },
2622 { 8*RSI, "8*RSI" },
2623 { 8*RDI, "8*RDI" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002624#if 0
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002625 { DS, "DS" },
2626 { ES, "ES" },
2627 { FS, "FS" },
2628 { GS, "GS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002629#endif
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002630 { 8*ORIG_RAX, "8*ORIG_RAX" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002631 { 8*RIP, "8*RIP" },
2632 { 8*CS, "8*CS" },
2633 { 8*EFLAGS, "8*EFL" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002634 { 8*RSP, "8*RSP" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002635 { 8*SS, "8*SS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002636#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002637#ifdef M68K
2638 { 4*PT_D1, "4*PT_D1" },
2639 { 4*PT_D2, "4*PT_D2" },
2640 { 4*PT_D3, "4*PT_D3" },
2641 { 4*PT_D4, "4*PT_D4" },
2642 { 4*PT_D5, "4*PT_D5" },
2643 { 4*PT_D6, "4*PT_D6" },
2644 { 4*PT_D7, "4*PT_D7" },
2645 { 4*PT_A0, "4*PT_A0" },
2646 { 4*PT_A1, "4*PT_A1" },
2647 { 4*PT_A2, "4*PT_A2" },
2648 { 4*PT_A3, "4*PT_A3" },
2649 { 4*PT_A4, "4*PT_A4" },
2650 { 4*PT_A5, "4*PT_A5" },
2651 { 4*PT_A6, "4*PT_A6" },
2652 { 4*PT_D0, "4*PT_D0" },
2653 { 4*PT_USP, "4*PT_USP" },
2654 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2655 { 4*PT_SR, "4*PT_SR" },
2656 { 4*PT_PC, "4*PT_PC" },
2657#endif /* M68K */
2658#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002659#ifdef SH
2660 { 4*REG_REG0, "4*REG_REG0" },
2661 { 4*(REG_REG0+1), "4*REG_REG1" },
2662 { 4*(REG_REG0+2), "4*REG_REG2" },
2663 { 4*(REG_REG0+3), "4*REG_REG3" },
2664 { 4*(REG_REG0+4), "4*REG_REG4" },
2665 { 4*(REG_REG0+5), "4*REG_REG5" },
2666 { 4*(REG_REG0+6), "4*REG_REG6" },
2667 { 4*(REG_REG0+7), "4*REG_REG7" },
2668 { 4*(REG_REG0+8), "4*REG_REG8" },
2669 { 4*(REG_REG0+9), "4*REG_REG9" },
2670 { 4*(REG_REG0+10), "4*REG_REG10" },
2671 { 4*(REG_REG0+11), "4*REG_REG11" },
2672 { 4*(REG_REG0+12), "4*REG_REG12" },
2673 { 4*(REG_REG0+13), "4*REG_REG13" },
2674 { 4*(REG_REG0+14), "4*REG_REG14" },
2675 { 4*REG_REG15, "4*REG_REG15" },
2676 { 4*REG_PC, "4*REG_PC" },
2677 { 4*REG_PR, "4*REG_PR" },
2678 { 4*REG_SR, "4*REG_SR" },
2679 { 4*REG_GBR, "4*REG_GBR" },
2680 { 4*REG_MACH, "4*REG_MACH" },
2681 { 4*REG_MACL, "4*REG_MACL" },
2682 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2683 { 4*REG_FPUL, "4*REG_FPUL" },
2684 { 4*REG_FPREG0, "4*REG_FPREG0" },
2685 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2686 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2687 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2688 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2689 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2690 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2691 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2692 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2693 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2694 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2695 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2696 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2697 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2698 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2699 { 4*REG_FPREG15, "4*REG_FPREG15" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002700#ifdef REG_XDREG0
Wichert Akkermanccef6372002-05-01 16:39:22 +00002701 { 4*REG_XDREG0, "4*REG_XDREG0" },
2702 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2703 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2704 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2705 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2706 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2707 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2708 { 4*REG_XDREG14, "4*REG_XDREG14" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002709#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002710 { 4*REG_FPSCR, "4*REG_FPSCR" },
2711#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002712#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002713 { 0, "PC(L)" },
2714 { 4, "PC(U)" },
2715 { 8, "SR(L)" },
2716 { 12, "SR(U)" },
2717 { 16, "syscall no.(L)" },
2718 { 20, "syscall_no.(U)" },
2719 { 24, "R0(L)" },
2720 { 28, "R0(U)" },
2721 { 32, "R1(L)" },
2722 { 36, "R1(U)" },
2723 { 40, "R2(L)" },
2724 { 44, "R2(U)" },
2725 { 48, "R3(L)" },
2726 { 52, "R3(U)" },
2727 { 56, "R4(L)" },
2728 { 60, "R4(U)" },
2729 { 64, "R5(L)" },
2730 { 68, "R5(U)" },
2731 { 72, "R6(L)" },
2732 { 76, "R6(U)" },
2733 { 80, "R7(L)" },
2734 { 84, "R7(U)" },
2735 { 88, "R8(L)" },
2736 { 92, "R8(U)" },
2737 { 96, "R9(L)" },
2738 { 100, "R9(U)" },
2739 { 104, "R10(L)" },
2740 { 108, "R10(U)" },
2741 { 112, "R11(L)" },
2742 { 116, "R11(U)" },
2743 { 120, "R12(L)" },
2744 { 124, "R12(U)" },
2745 { 128, "R13(L)" },
2746 { 132, "R13(U)" },
2747 { 136, "R14(L)" },
2748 { 140, "R14(U)" },
2749 { 144, "R15(L)" },
2750 { 148, "R15(U)" },
2751 { 152, "R16(L)" },
2752 { 156, "R16(U)" },
2753 { 160, "R17(L)" },
2754 { 164, "R17(U)" },
2755 { 168, "R18(L)" },
2756 { 172, "R18(U)" },
2757 { 176, "R19(L)" },
2758 { 180, "R19(U)" },
2759 { 184, "R20(L)" },
2760 { 188, "R20(U)" },
2761 { 192, "R21(L)" },
2762 { 196, "R21(U)" },
2763 { 200, "R22(L)" },
2764 { 204, "R22(U)" },
2765 { 208, "R23(L)" },
2766 { 212, "R23(U)" },
2767 { 216, "R24(L)" },
2768 { 220, "R24(U)" },
2769 { 224, "R25(L)" },
2770 { 228, "R25(U)" },
2771 { 232, "R26(L)" },
2772 { 236, "R26(U)" },
2773 { 240, "R27(L)" },
2774 { 244, "R27(U)" },
2775 { 248, "R28(L)" },
2776 { 252, "R28(U)" },
2777 { 256, "R29(L)" },
2778 { 260, "R29(U)" },
2779 { 264, "R30(L)" },
2780 { 268, "R30(U)" },
2781 { 272, "R31(L)" },
2782 { 276, "R31(U)" },
2783 { 280, "R32(L)" },
2784 { 284, "R32(U)" },
2785 { 288, "R33(L)" },
2786 { 292, "R33(U)" },
2787 { 296, "R34(L)" },
2788 { 300, "R34(U)" },
2789 { 304, "R35(L)" },
2790 { 308, "R35(U)" },
2791 { 312, "R36(L)" },
2792 { 316, "R36(U)" },
2793 { 320, "R37(L)" },
2794 { 324, "R37(U)" },
2795 { 328, "R38(L)" },
2796 { 332, "R38(U)" },
2797 { 336, "R39(L)" },
2798 { 340, "R39(U)" },
2799 { 344, "R40(L)" },
2800 { 348, "R40(U)" },
2801 { 352, "R41(L)" },
2802 { 356, "R41(U)" },
2803 { 360, "R42(L)" },
2804 { 364, "R42(U)" },
2805 { 368, "R43(L)" },
2806 { 372, "R43(U)" },
2807 { 376, "R44(L)" },
2808 { 380, "R44(U)" },
2809 { 384, "R45(L)" },
2810 { 388, "R45(U)" },
2811 { 392, "R46(L)" },
2812 { 396, "R46(U)" },
2813 { 400, "R47(L)" },
2814 { 404, "R47(U)" },
2815 { 408, "R48(L)" },
2816 { 412, "R48(U)" },
2817 { 416, "R49(L)" },
2818 { 420, "R49(U)" },
2819 { 424, "R50(L)" },
2820 { 428, "R50(U)" },
2821 { 432, "R51(L)" },
2822 { 436, "R51(U)" },
2823 { 440, "R52(L)" },
2824 { 444, "R52(U)" },
2825 { 448, "R53(L)" },
2826 { 452, "R53(U)" },
2827 { 456, "R54(L)" },
2828 { 460, "R54(U)" },
2829 { 464, "R55(L)" },
2830 { 468, "R55(U)" },
2831 { 472, "R56(L)" },
2832 { 476, "R56(U)" },
2833 { 480, "R57(L)" },
2834 { 484, "R57(U)" },
2835 { 488, "R58(L)" },
2836 { 492, "R58(U)" },
2837 { 496, "R59(L)" },
2838 { 500, "R59(U)" },
2839 { 504, "R60(L)" },
2840 { 508, "R60(U)" },
2841 { 512, "R61(L)" },
2842 { 516, "R61(U)" },
2843 { 520, "R62(L)" },
2844 { 524, "R62(U)" },
2845 { 528, "TR0(L)" },
2846 { 532, "TR0(U)" },
2847 { 536, "TR1(L)" },
2848 { 540, "TR1(U)" },
2849 { 544, "TR2(L)" },
2850 { 548, "TR2(U)" },
2851 { 552, "TR3(L)" },
2852 { 556, "TR3(U)" },
2853 { 560, "TR4(L)" },
2854 { 564, "TR4(U)" },
2855 { 568, "TR5(L)" },
2856 { 572, "TR5(U)" },
2857 { 576, "TR6(L)" },
2858 { 580, "TR6(U)" },
2859 { 584, "TR7(L)" },
2860 { 588, "TR7(U)" },
2861 /* This entry is in case pt_regs contains dregs (depends on
2862 the kernel build options). */
2863 { uoff(regs), "offsetof(struct user, regs)" },
2864 { uoff(fpu), "offsetof(struct user, fpu)" },
2865#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002866#ifdef ARM
2867 { uoff(regs.ARM_r0), "r0" },
2868 { uoff(regs.ARM_r1), "r1" },
2869 { uoff(regs.ARM_r2), "r2" },
2870 { uoff(regs.ARM_r3), "r3" },
2871 { uoff(regs.ARM_r4), "r4" },
2872 { uoff(regs.ARM_r5), "r5" },
2873 { uoff(regs.ARM_r6), "r6" },
2874 { uoff(regs.ARM_r7), "r7" },
2875 { uoff(regs.ARM_r8), "r8" },
2876 { uoff(regs.ARM_r9), "r9" },
2877 { uoff(regs.ARM_r10), "r10" },
2878 { uoff(regs.ARM_fp), "fp" },
2879 { uoff(regs.ARM_ip), "ip" },
2880 { uoff(regs.ARM_sp), "sp" },
2881 { uoff(regs.ARM_lr), "lr" },
2882 { uoff(regs.ARM_pc), "pc" },
2883 { uoff(regs.ARM_cpsr), "cpsr" },
2884#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002885
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002886#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002887 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002888#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002889#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002890 { uoff(i387), "offsetof(struct user, i387)" },
2891#else /* !I386 */
2892#ifdef M68K
2893 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2894#endif /* M68K */
2895#endif /* !I386 */
2896 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2897 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2898 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002899#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002900 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002901#endif
Roland McGrathf5a47772003-06-26 22:40:42 +00002902#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002903 { uoff(start_data), "offsetof(struct user, start_data)" },
2904#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002905#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002906 { uoff(start_stack), "offsetof(struct user, start_stack)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002907#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002908 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002909#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002910 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002911#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002912#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002913 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002914#endif
2915#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002916 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2917#endif
2918 { uoff(magic), "offsetof(struct user, magic)" },
2919 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002920#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002921 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2922#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002923#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002924#endif /* !ALPHA */
2925#endif /* !POWERPC/!SPARC */
2926#endif /* LINUX */
2927#ifdef SUNOS4
2928 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2929 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2930 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2931 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2932 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2933 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2934 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2935 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2936 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2937 { uoff(u_error), "offsetof(struct user, u_error)" },
2938 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2939 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2940 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2941 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2942 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2943 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2944 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2945 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2946 { uoff(u_code), "offsetof(struct user, u_code)" },
2947 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2948 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2949 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2950 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2951 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2952 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2953 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2954 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2955 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2956 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2957 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2958 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2959 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2960 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2961 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2962 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2963 { uoff(u_start), "offsetof(struct user, u_start)" },
2964 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2965 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2966 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2967 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2968 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2969 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2970 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2971 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2972 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2973#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002974#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002975 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002976#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002977 { 0, NULL },
2978};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002979#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002980
2981int
2982sys_ptrace(tcp)
2983struct tcb *tcp;
2984{
Roland McGrathd9f816f2004-09-04 03:39:20 +00002985 const struct xlat *x;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002986 long addr;
2987
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002988 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002989 printxval(ptrace_cmds, tcp->u_arg[0],
2990#ifndef FREEBSD
2991 "PTRACE_???"
2992#else
2993 "PT_???"
2994#endif
2995 );
2996 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002997 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002998#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002999 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3000 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3001 for (x = struct_user_offsets; x->str; x++) {
3002 if (x->val >= addr)
3003 break;
3004 }
3005 if (!x->str)
3006 tprintf("%#lx, ", addr);
3007 else if (x->val > addr && x != struct_user_offsets) {
3008 x--;
3009 tprintf("%s + %ld, ", x->str, addr - x->val);
3010 }
3011 else
3012 tprintf("%s, ", x->str);
3013 }
3014 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003015#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003016 tprintf("%#lx, ", tcp->u_arg[2]);
3017#ifdef LINUX
3018 switch (tcp->u_arg[0]) {
3019 case PTRACE_PEEKDATA:
3020 case PTRACE_PEEKTEXT:
3021 case PTRACE_PEEKUSER:
3022 break;
3023 case PTRACE_CONT:
3024 case PTRACE_SINGLESTEP:
3025 case PTRACE_SYSCALL:
3026 case PTRACE_DETACH:
3027 printsignal(tcp->u_arg[3]);
3028 break;
3029 default:
3030 tprintf("%#lx", tcp->u_arg[3]);
3031 break;
3032 }
3033 } else {
3034 switch (tcp->u_arg[0]) {
3035 case PTRACE_PEEKDATA:
3036 case PTRACE_PEEKTEXT:
3037 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00003038 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003039 break;
3040 }
3041 }
3042#endif /* LINUX */
3043#ifdef SUNOS4
3044 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3045 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3046 tprintf("%lu, ", tcp->u_arg[3]);
3047 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3048 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3049 tcp->u_arg[0] != PTRACE_READTEXT) {
3050 tprintf("%#lx", tcp->u_arg[3]);
3051 }
3052 } else {
3053 if (tcp->u_arg[0] == PTRACE_READDATA ||
3054 tcp->u_arg[0] == PTRACE_READTEXT) {
3055 tprintf("%lu, ", tcp->u_arg[3]);
3056 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3057 }
3058 }
3059#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003060#ifdef FREEBSD
3061 tprintf("%lu", tcp->u_arg[3]);
3062 }
3063#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003064 return 0;
3065}
3066
3067#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00003068
3069#ifdef LINUX
Roland McGrathd9f816f2004-09-04 03:39:20 +00003070static const struct xlat futexops[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00003071 { FUTEX_WAIT, "FUTEX_WAIT" },
3072 { FUTEX_WAKE, "FUTEX_WAKE" },
3073 { FUTEX_FD, "FUTEX_FD" },
Roland McGrath88812d62003-06-26 22:27:23 +00003074 { FUTEX_REQUEUE,"FUTEX_REQUEUE" },
Roland McGrath5a223472002-12-15 23:58:26 +00003075 { 0, NULL }
3076};
3077
3078int
3079sys_futex(tcp)
3080struct tcb *tcp;
3081{
3082 if (entering(tcp)) {
3083 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00003084 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003085 tprintf(", %ld", tcp->u_arg[2]);
3086 if (tcp->u_arg[1] == FUTEX_WAIT) {
3087 tprintf(", ");
3088 printtv(tcp, tcp->u_arg[3]);
Roland McGrath88812d62003-06-26 22:27:23 +00003089 } else if (tcp->u_arg[1] == FUTEX_REQUEUE)
3090 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath5a223472002-12-15 23:58:26 +00003091 }
3092 return 0;
3093}
3094
3095static void
Roland McGrath79fbda52004-04-14 02:45:55 +00003096print_affinitylist(tcp, list, len)
3097struct tcb *tcp;
3098long list;
Roland McGrath5a223472002-12-15 23:58:26 +00003099unsigned int len;
3100{
3101 int first = 1;
3102 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00003103 while (len >= sizeof (unsigned long)) {
Roland McGrath79fbda52004-04-14 02:45:55 +00003104 unsigned long w;
3105 umove(tcp, list, &w);
3106 tprintf("%s %lx", first ? "" : ",", w);
Roland McGrath5a223472002-12-15 23:58:26 +00003107 first = 0;
3108 len -= sizeof (unsigned long);
Roland McGrath79fbda52004-04-14 02:45:55 +00003109 list += sizeof(unsigned long);
Roland McGrath5a223472002-12-15 23:58:26 +00003110 }
3111 tprintf(" }");
3112}
3113
3114int
3115sys_sched_setaffinity(tcp)
3116struct tcb *tcp;
3117{
3118 if (entering(tcp)) {
3119 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath79fbda52004-04-14 02:45:55 +00003120 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
Roland McGrath5a223472002-12-15 23:58:26 +00003121 }
3122 return 0;
3123}
3124
3125int
3126sys_sched_getaffinity(tcp)
3127struct tcb *tcp;
3128{
3129 if (entering(tcp)) {
3130 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3131 } else {
Roland McGrath79fbda52004-04-14 02:45:55 +00003132 if (tcp->u_rval == -1)
3133 tprintf("%#lx", tcp->u_arg[2]);
3134 else
3135 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
Roland McGrath5a223472002-12-15 23:58:26 +00003136 }
3137 return 0;
3138}
Roland McGrath279d3782004-03-01 20:27:37 +00003139
Roland McGrathd9f816f2004-09-04 03:39:20 +00003140static const struct xlat schedulers[] = {
Roland McGrath279d3782004-03-01 20:27:37 +00003141 { SCHED_OTHER, "SCHED_OTHER" },
3142 { SCHED_RR, "SCHED_RR" },
3143 { SCHED_FIFO, "SCHED_FIFO" },
3144 { 0, NULL }
3145};
3146
3147int
3148sys_sched_getscheduler(tcp)
3149struct tcb *tcp;
3150{
3151 if (entering(tcp)) {
3152 tprintf("%d", (int) tcp->u_arg[0]);
3153 } else if (! syserror(tcp)) {
3154 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3155 if (tcp->auxstr != NULL)
3156 return RVAL_STR;
3157 }
3158 return 0;
3159}
3160
3161int
3162sys_sched_setscheduler(tcp)
3163struct tcb *tcp;
3164{
3165 if (entering(tcp)) {
3166 struct sched_param p;
3167 tprintf("%d, ", (int) tcp->u_arg[0]);
3168 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3169 if (umove(tcp, tcp->u_arg[2], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003170 tprintf(", %#lx", tcp->u_arg[2]);
Roland McGrath279d3782004-03-01 20:27:37 +00003171 else
3172 tprintf(", { %d }", p.__sched_priority);
3173 }
3174 return 0;
3175}
3176
3177int
3178sys_sched_getparam(tcp)
3179struct tcb *tcp;
3180{
3181 if (entering(tcp)) {
3182 tprintf("%d, ", (int) tcp->u_arg[0]);
3183 } else {
3184 struct sched_param p;
3185 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003186 tprintf("%#lx", tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003187 else
3188 tprintf("{ %d }", p.__sched_priority);
3189 }
3190 return 0;
3191}
3192
3193int
3194sys_sched_setparam(tcp)
3195struct tcb *tcp;
3196{
3197 if (entering(tcp)) {
3198 struct sched_param p;
3199 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003200 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003201 else
3202 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3203 }
3204 return 0;
3205}
3206
3207int
3208sys_sched_get_priority_min(tcp)
3209struct tcb *tcp;
3210{
3211 if (entering(tcp)) {
3212 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3213 }
3214 return 0;
3215}
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003216
3217#ifdef X86_64
3218#include <asm/prctl.h>
3219
3220static const struct xlat archvals[] = {
3221 { ARCH_SET_GS, "ARCH_SET_GS" },
3222 { ARCH_SET_FS, "ARCH_SET_FS" },
3223 { ARCH_GET_FS, "ARCH_GET_FS" },
3224 { ARCH_GET_GS, "ARCH_GET_GS" },
3225 { 0, NULL },
3226};
3227
3228int
3229sys_arch_prctl(tcp)
3230struct tcb *tcp;
3231{
3232 if (entering(tcp)) {
3233 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3234 if (tcp->u_arg[0] == ARCH_SET_GS
3235 || tcp->u_arg[0] == ARCH_SET_FS)
3236 tprintf(", %#lx", tcp->u_arg[1]);
3237 } else {
3238 if (tcp->u_arg[0] == ARCH_GET_GS
3239 || tcp->u_arg[0] == ARCH_GET_FS) {
3240 long int v;
3241 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3242 tprintf(", [%#lx]", v);
3243 else
3244 tprintf(", %#lx", tcp->u_arg[1]);
3245 }
3246 }
3247 return 0;
3248}
3249#endif
3250
Roland McGrath5a223472002-12-15 23:58:26 +00003251#endif