blob: 06eb76e8d1f93b97e71c4d6f706fd6d205cd81df [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 {
896 newoutf(tcpchild);
897 if (!qflag)
898 fprintf(stderr, "Process %d attached\n", pid);
899 }
900
901#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000902 {
903 /*
904 * Save the flags used in this call,
905 * in case we point TCP to our parent below.
906 */
907 int call_flags = tcp->u_arg[ARG_FLAGS];
908 if ((tcp->flags & TCB_CLONE_THREAD) &&
909 tcp->parent != NULL) {
910 /* The parent in this clone is itself a
911 thread belonging to another process.
912 There is no meaning to the parentage
913 relationship of the new child with the
914 thread, only with the process. We
915 associate the new thread with our
916 parent. Since this is done for every
917 new thread, there will never be a
918 TCB_CLONE_THREAD process that has
919 children. */
920 --tcp->nchildren;
921 tcp = tcp->parent;
922 tcpchild->parent = tcp;
923 ++tcp->nchildren;
924 }
925 if (call_flags & CLONE_THREAD) {
926 tcpchild->flags |= TCB_CLONE_THREAD;
927 ++tcp->nclone_threads;
928 }
929 if (call_flags & CLONE_DETACHED) {
930 tcpchild->flags |= TCB_CLONE_DETACHED;
931 ++tcp->nclone_detached;
932 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000933 }
934#endif
935
936 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000937 return 0;
938}
939#endif
940
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000941int
942internal_fork(tcp)
943struct tcb *tcp;
944{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000945#ifdef LINUX
946 /* We do special magic with clone for any clone or fork. */
947 return internal_clone(tcp);
948#else
949
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000950 struct tcb *tcpchild;
951 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000952 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000953
954#ifdef SYS_vfork
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000955 if (known_scno(tcp) == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000956 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000957 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000958 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000959 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000960 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000961#endif
962 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000963 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000964 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000965 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000966 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000967 if (setbpt(tcp) < 0)
968 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000969 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000970 else {
971 int bpt = tcp->flags & TCB_BPTSET;
972
973 if (!(tcp->flags & TCB_FOLLOWFORK))
974 return 0;
975 if (bpt)
976 clearbpt(tcp);
977
978 if (syserror(tcp))
979 return 0;
980
981 pid = tcp->u_rval;
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000982 if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000983 kill(pid, SIGKILL); /* XXX */
984 return 0;
985 }
986#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000987#ifdef HPPA
988 /* The child must have run before it can be attached. */
989 /* This must be a bug in the parisc kernel, but I havn't
990 * identified it yet. Seems to be an issue associated
991 * with attaching to a process (which sends it a signal)
992 * before that process has ever been scheduled. When
993 * debugging, I started seeing crashes in
994 * arch/parisc/kernel/signal.c:do_signal(), apparently
995 * caused by r8 getting corrupt over the dequeue_signal()
996 * call. Didn't make much sense though...
997 */
998 {
999 struct timeval tv;
1000 tv.tv_sec = 0;
1001 tv.tv_usec = 10000;
1002 select(0, NULL, NULL, NULL, &tv);
1003 }
1004#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001005 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
1006 perror("PTRACE_ATTACH");
1007 fprintf(stderr, "Too late?\n");
1008 droptcb(tcpchild);
1009 return 0;
1010 }
1011#endif /* LINUX */
1012#ifdef SUNOS4
1013#ifdef oldway
1014 /* The child must have run before it can be attached. */
1015 {
1016 struct timeval tv;
1017 tv.tv_sec = 0;
1018 tv.tv_usec = 10000;
1019 select(0, NULL, NULL, NULL, &tv);
1020 }
1021 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1022 perror("PTRACE_ATTACH");
1023 fprintf(stderr, "Too late?\n");
1024 droptcb(tcpchild);
1025 return 0;
1026 }
1027#else /* !oldway */
1028 /* Try to catch the new process as soon as possible. */
1029 {
1030 int i;
1031 for (i = 0; i < 1024; i++)
1032 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1033 break;
1034 if (i == 1024) {
1035 perror("PTRACE_ATTACH");
1036 fprintf(stderr, "Too late?\n");
1037 droptcb(tcpchild);
1038 return 0;
1039 }
1040 }
1041#endif /* !oldway */
1042#endif /* SUNOS4 */
1043 tcpchild->flags |= TCB_ATTACHED;
1044 /* Child has BPT too, must be removed on first occasion */
1045 if (bpt) {
1046 tcpchild->flags |= TCB_BPTSET;
1047 tcpchild->baddr = tcp->baddr;
1048 memcpy(tcpchild->inst, tcp->inst,
1049 sizeof tcpchild->inst);
1050 }
1051 newoutf(tcpchild);
1052 tcpchild->parent = tcp;
1053 tcp->nchildren++;
1054 if (!qflag)
1055 fprintf(stderr, "Process %d attached\n", pid);
1056 }
1057 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001058#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001059}
1060
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001061#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001062
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001063#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001064
1065int
1066sys_vfork(tcp)
1067struct tcb *tcp;
1068{
1069 if (exiting(tcp))
1070 return RVAL_UDECIMAL;
1071 return 0;
1072}
1073
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001074#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001075
1076#ifndef LINUX
1077
1078static char idstr[16];
1079
1080int
1081sys_getpid(tcp)
1082struct tcb *tcp;
1083{
1084 if (exiting(tcp)) {
1085 sprintf(idstr, "ppid %lu", getrval2(tcp));
1086 tcp->auxstr = idstr;
1087 return RVAL_STR;
1088 }
1089 return 0;
1090}
1091
1092int
1093sys_getuid(tcp)
1094struct tcb *tcp;
1095{
1096 if (exiting(tcp)) {
1097 sprintf(idstr, "euid %lu", getrval2(tcp));
1098 tcp->auxstr = idstr;
1099 return RVAL_STR;
1100 }
1101 return 0;
1102}
1103
1104int
1105sys_getgid(tcp)
1106struct tcb *tcp;
1107{
1108 if (exiting(tcp)) {
1109 sprintf(idstr, "egid %lu", getrval2(tcp));
1110 tcp->auxstr = idstr;
1111 return RVAL_STR;
1112 }
1113 return 0;
1114}
1115
1116#endif /* !LINUX */
1117
1118#ifdef LINUX
1119
1120int
1121sys_setuid(tcp)
1122struct tcb *tcp;
1123{
1124 if (entering(tcp)) {
1125 tprintf("%u", (uid_t) tcp->u_arg[0]);
1126 }
1127 return 0;
1128}
1129
1130int
1131sys_setgid(tcp)
1132struct tcb *tcp;
1133{
1134 if (entering(tcp)) {
1135 tprintf("%u", (gid_t) tcp->u_arg[0]);
1136 }
1137 return 0;
1138}
1139
1140int
1141sys_getresuid(tcp)
1142 struct tcb *tcp;
1143{
1144 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001145 __kernel_uid_t uid;
1146 if (syserror(tcp))
1147 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1148 tcp->u_arg[1], tcp->u_arg[2]);
1149 else {
1150 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1151 tprintf("%#lx, ", tcp->u_arg[0]);
1152 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001153 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001154 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1155 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001156 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001157 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001158 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1159 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001160 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001161 tprintf("[%lu]", (unsigned long) uid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001162 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001163 }
1164 return 0;
1165}
1166
1167int
1168sys_getresgid(tcp)
1169struct tcb *tcp;
1170{
1171 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001172 __kernel_gid_t gid;
1173 if (syserror(tcp))
1174 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1175 tcp->u_arg[1], tcp->u_arg[2]);
1176 else {
1177 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1178 tprintf("%#lx, ", tcp->u_arg[0]);
1179 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001180 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001181 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1182 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001183 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001184 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001185 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1186 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001187 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001188 tprintf("[%lu]", (unsigned long) gid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001189 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001190 }
1191 return 0;
1192}
1193
1194#endif /* LINUX */
1195
1196int
1197sys_setreuid(tcp)
1198struct tcb *tcp;
1199{
1200 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001201 printuid("", tcp->u_arg[0]);
1202 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001203 }
1204 return 0;
1205}
1206
1207int
1208sys_setregid(tcp)
1209struct tcb *tcp;
1210{
1211 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001212 printuid("", tcp->u_arg[0]);
1213 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001214 }
1215 return 0;
1216}
1217
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001218#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001219int
1220sys_setresuid(tcp)
1221 struct tcb *tcp;
1222{
1223 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001224 printuid("", tcp->u_arg[0]);
1225 printuid(", ", tcp->u_arg[1]);
1226 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001227 }
1228 return 0;
1229}
1230int
1231sys_setresgid(tcp)
1232 struct tcb *tcp;
1233{
1234 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001235 printuid("", tcp->u_arg[0]);
1236 printuid(", ", tcp->u_arg[1]);
1237 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001238 }
1239 return 0;
1240}
1241
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001242#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001243
1244int
1245sys_setgroups(tcp)
1246struct tcb *tcp;
1247{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001248 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001249 unsigned long len, size, start, cur, end, abbrev_end;
1250 GETGROUPS_T gid;
1251 int failed = 0;
1252
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001253 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001254 tprintf("%lu, ", len);
1255 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001256 tprintf("[]");
1257 return 0;
1258 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001259 start = tcp->u_arg[1];
1260 if (start == 0) {
1261 tprintf("NULL");
1262 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001263 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001264 size = len * sizeof(gid);
1265 end = start + size;
1266 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1267 tprintf("%#lx", start);
1268 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001269 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001270 if (abbrev(tcp)) {
1271 abbrev_end = start + max_strlen * sizeof(gid);
1272 if (abbrev_end < start)
1273 abbrev_end = end;
1274 } else {
1275 abbrev_end = end;
1276 }
1277 tprintf("[");
1278 for (cur = start; cur < end; cur += sizeof(gid)) {
1279 if (cur > start)
1280 tprintf(", ");
1281 if (cur >= abbrev_end) {
1282 tprintf("...");
1283 break;
1284 }
1285 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1286 tprintf("?");
1287 failed = 1;
1288 break;
1289 }
1290 tprintf("%lu", (unsigned long) gid);
1291 }
1292 tprintf("]");
1293 if (failed)
1294 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001295 }
1296 return 0;
1297}
1298
1299int
1300sys_getgroups(tcp)
1301struct tcb *tcp;
1302{
Roland McGrathaa524c82005-06-01 19:22:06 +00001303 unsigned long len;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001304
1305 if (entering(tcp)) {
1306 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001307 tprintf("%lu, ", len);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001308 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001309 unsigned long size, start, cur, end, abbrev_end;
1310 GETGROUPS_T gid;
1311 int failed = 0;
1312
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001313 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001314 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001315 tprintf("[]");
1316 return 0;
1317 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001318 start = tcp->u_arg[1];
1319 if (start == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001320 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001321 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001322 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001323 if (tcp->u_arg[0] == 0) {
1324 tprintf("%#lx", start);
1325 return 0;
1326 }
1327 size = len * sizeof(gid);
1328 end = start + size;
1329 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1330 size / sizeof(gid) != len || end < start) {
1331 tprintf("%#lx", start);
1332 return 0;
1333 }
1334 if (abbrev(tcp)) {
1335 abbrev_end = start + max_strlen * sizeof(gid);
1336 if (abbrev_end < start)
1337 abbrev_end = end;
1338 } else {
1339 abbrev_end = end;
1340 }
1341 tprintf("[");
1342 for (cur = start; cur < end; cur += sizeof(gid)) {
1343 if (cur > start)
1344 tprintf(", ");
1345 if (cur >= abbrev_end) {
1346 tprintf("...");
1347 break;
1348 }
1349 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1350 tprintf("?");
1351 failed = 1;
1352 break;
1353 }
1354 tprintf("%lu", (unsigned long) gid);
1355 }
1356 tprintf("]");
1357 if (failed)
1358 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001359 }
1360 return 0;
1361}
1362
Roland McGrath83bd47a2003-11-13 22:32:26 +00001363#ifdef LINUX
1364int
1365sys_setgroups32(tcp)
1366struct tcb *tcp;
1367{
Roland McGrath83bd47a2003-11-13 22:32:26 +00001368 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001369 unsigned long len, size, start, cur, end, abbrev_end;
1370 GETGROUPS32_T gid;
1371 int failed = 0;
1372
Roland McGrath83bd47a2003-11-13 22:32:26 +00001373 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001374 tprintf("%lu, ", len);
1375 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001376 tprintf("[]");
1377 return 0;
1378 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001379 start = tcp->u_arg[1];
1380 if (start == 0) {
1381 tprintf("NULL");
1382 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001383 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001384 size = len * sizeof(gid);
1385 end = start + size;
1386 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1387 tprintf("%#lx", start);
1388 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001389 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001390 if (abbrev(tcp)) {
1391 abbrev_end = start + max_strlen * sizeof(gid);
1392 if (abbrev_end < start)
1393 abbrev_end = end;
1394 } else {
1395 abbrev_end = end;
1396 }
1397 tprintf("[");
1398 for (cur = start; cur < end; cur += sizeof(gid)) {
1399 if (cur > start)
1400 tprintf(", ");
1401 if (cur >= abbrev_end) {
1402 tprintf("...");
1403 break;
1404 }
1405 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1406 tprintf("?");
1407 failed = 1;
1408 break;
1409 }
1410 tprintf("%lu", (unsigned long) gid);
1411 }
1412 tprintf("]");
1413 if (failed)
1414 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001415 }
1416 return 0;
1417}
1418
1419int
1420sys_getgroups32(tcp)
1421struct tcb *tcp;
1422{
Roland McGrathaa524c82005-06-01 19:22:06 +00001423 unsigned long len;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001424
1425 if (entering(tcp)) {
1426 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001427 tprintf("%lu, ", len);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001428 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001429 unsigned long size, start, cur, end, abbrev_end;
1430 GETGROUPS32_T gid;
1431 int failed = 0;
1432
Roland McGrath83bd47a2003-11-13 22:32:26 +00001433 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001434 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001435 tprintf("[]");
1436 return 0;
1437 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001438 start = tcp->u_arg[1];
1439 if (start == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001440 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001441 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001442 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001443 size = len * sizeof(gid);
1444 end = start + size;
1445 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1446 size / sizeof(gid) != len || end < start) {
1447 tprintf("%#lx", start);
1448 return 0;
1449 }
1450 if (abbrev(tcp)) {
1451 abbrev_end = start + max_strlen * sizeof(gid);
1452 if (abbrev_end < start)
1453 abbrev_end = end;
1454 } else {
1455 abbrev_end = end;
1456 }
1457 tprintf("[");
1458 for (cur = start; cur < end; cur += sizeof(gid)) {
1459 if (cur > start)
1460 tprintf(", ");
1461 if (cur >= abbrev_end) {
1462 tprintf("...");
1463 break;
1464 }
1465 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1466 tprintf("?");
1467 failed = 1;
1468 break;
1469 }
1470 tprintf("%lu", (unsigned long) gid);
1471 }
1472 tprintf("]");
1473 if (failed)
1474 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001475 }
1476 return 0;
1477}
1478#endif /* LINUX */
1479
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001480#if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001481int
1482sys_setpgrp(tcp)
1483struct tcb *tcp;
1484{
1485 if (entering(tcp)) {
1486#ifndef SVR4
1487 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1488#endif /* !SVR4 */
1489 }
1490 return 0;
1491}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001492#endif /* ALPHA || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001493
1494int
1495sys_getpgrp(tcp)
1496struct tcb *tcp;
1497{
1498 if (entering(tcp)) {
1499#ifndef SVR4
1500 tprintf("%lu", tcp->u_arg[0]);
1501#endif /* !SVR4 */
1502 }
1503 return 0;
1504}
1505
1506int
1507sys_getsid(tcp)
1508struct tcb *tcp;
1509{
1510 if (entering(tcp)) {
1511 tprintf("%lu", tcp->u_arg[0]);
1512 }
1513 return 0;
1514}
1515
1516int
1517sys_setsid(tcp)
1518struct tcb *tcp;
1519{
1520 return 0;
1521}
1522
1523int
1524sys_getpgid(tcp)
1525struct tcb *tcp;
1526{
1527 if (entering(tcp)) {
1528 tprintf("%lu", tcp->u_arg[0]);
1529 }
1530 return 0;
1531}
1532
1533int
1534sys_setpgid(tcp)
1535struct tcb *tcp;
1536{
1537 if (entering(tcp)) {
1538 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1539 }
1540 return 0;
1541}
1542
John Hughesc61eb3d2002-05-17 11:37:50 +00001543#if UNIXWARE >= 2
1544
1545#include <sys/privilege.h>
1546
1547
Roland McGrathd9f816f2004-09-04 03:39:20 +00001548static const struct xlat procpriv_cmds [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001549 { SETPRV, "SETPRV" },
1550 { CLRPRV, "CLRPRV" },
1551 { PUTPRV, "PUTPRV" },
1552 { GETPRV, "GETPRV" },
1553 { CNTPRV, "CNTPRV" },
1554 { 0, NULL },
1555};
1556
1557
Roland McGrathd9f816f2004-09-04 03:39:20 +00001558static const struct xlat procpriv_priv [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001559 { P_OWNER, "P_OWNER" },
1560 { P_AUDIT, "P_AUDIT" },
1561 { P_COMPAT, "P_COMPAT" },
1562 { P_DACREAD, "P_DACREAD" },
1563 { P_DACWRITE, "P_DACWRITE" },
1564 { P_DEV, "P_DEV" },
1565 { P_FILESYS, "P_FILESYS" },
1566 { P_MACREAD, "P_MACREAD" },
1567 { P_MACWRITE, "P_MACWRITE" },
1568 { P_MOUNT, "P_MOUNT" },
1569 { P_MULTIDIR, "P_MULTIDIR" },
1570 { P_SETPLEVEL, "P_SETPLEVEL" },
1571 { P_SETSPRIV, "P_SETSPRIV" },
1572 { P_SETUID, "P_SETUID" },
1573 { P_SYSOPS, "P_SYSOPS" },
1574 { P_SETUPRIV, "P_SETUPRIV" },
1575 { P_DRIVER, "P_DRIVER" },
1576 { P_RTIME, "P_RTIME" },
1577 { P_MACUPGRADE, "P_MACUPGRADE" },
1578 { P_FSYSRANGE, "P_FSYSRANGE" },
1579 { P_SETFLEVEL, "P_SETFLEVEL" },
1580 { P_AUDITWR, "P_AUDITWR" },
1581 { P_TSHAR, "P_TSHAR" },
1582 { P_PLOCK, "P_PLOCK" },
1583 { P_CORE, "P_CORE" },
1584 { P_LOADMOD, "P_LOADMOD" },
1585 { P_BIND, "P_BIND" },
1586 { P_ALLPRIVS, "P_ALLPRIVS" },
1587 { 0, NULL },
1588};
1589
1590
Roland McGrathd9f816f2004-09-04 03:39:20 +00001591static const struct xlat procpriv_type [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001592 { PS_FIX, "PS_FIX" },
1593 { PS_INH, "PS_INH" },
1594 { PS_MAX, "PS_MAX" },
1595 { PS_WKG, "PS_WKG" },
1596 { 0, NULL },
1597};
1598
1599
1600static void
1601printpriv(tcp, addr, len, opt)
1602struct tcb *tcp;
1603long addr;
1604int len;
Roland McGrathd9f816f2004-09-04 03:39:20 +00001605const struct xlat *opt;
John Hughesc61eb3d2002-05-17 11:37:50 +00001606{
1607 priv_t buf [128];
1608 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1609 int dots = len > max;
1610 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001611
John Hughesc61eb3d2002-05-17 11:37:50 +00001612 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001613
John Hughesc61eb3d2002-05-17 11:37:50 +00001614 if (len <= 0 ||
1615 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1616 {
1617 tprintf ("%#lx", addr);
1618 return;
1619 }
1620
1621 tprintf ("[");
1622
1623 for (i = 0; i < len; ++i) {
1624 char *t, *p;
1625
1626 if (i) tprintf (", ");
1627
1628 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1629 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1630 {
1631 tprintf ("%s|%s", t, p);
1632 }
1633 else {
1634 tprintf ("%#lx", buf [i]);
1635 }
1636 }
1637
1638 if (dots) tprintf (" ...");
1639
1640 tprintf ("]");
1641}
1642
1643
1644int
1645sys_procpriv(tcp)
1646struct tcb *tcp;
1647{
1648 if (entering(tcp)) {
1649 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1650 switch (tcp->u_arg[0]) {
1651 case CNTPRV:
1652 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1653 break;
1654
1655 case GETPRV:
1656 break;
1657
1658 default:
1659 tprintf (", ");
1660 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1661 tprintf (", %ld", tcp->u_arg[2]);
1662 }
1663 }
1664 else if (tcp->u_arg[0] == GETPRV) {
1665 if (syserror (tcp)) {
1666 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1667 }
1668 else {
1669 tprintf (", ");
1670 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1671 tprintf (", %ld", tcp->u_arg[2]);
1672 }
1673 }
Roland McGrath5a223472002-12-15 23:58:26 +00001674
John Hughesc61eb3d2002-05-17 11:37:50 +00001675 return 0;
1676}
1677
1678#endif
1679
1680
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001681static void
1682printargv(tcp, addr)
1683struct tcb *tcp;
1684long addr;
1685{
1686 char *cp;
1687 char *sep;
1688 int max = max_strlen / 2;
1689
1690 for (sep = ""; --max >= 0; sep = ", ") {
1691 if (!abbrev(tcp))
1692 max++;
1693 if (umove(tcp, addr, &cp) < 0) {
1694 tprintf("%#lx", addr);
1695 return;
1696 }
1697 if (cp == 0)
1698 break;
1699 tprintf(sep);
1700 printstr(tcp, (long) cp, -1);
1701 addr += sizeof(char *);
1702 }
1703 if (cp)
1704 tprintf(", ...");
1705}
1706
1707static void
1708printargc(fmt, tcp, addr)
1709char *fmt;
1710struct tcb *tcp;
1711long addr;
1712{
1713 int count;
1714 char *cp;
1715
1716 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1717 addr += sizeof(char *);
1718 }
1719 tprintf(fmt, count, count == 1 ? "" : "s");
1720}
1721
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001722#if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001723int
1724sys_execv(tcp)
1725struct tcb *tcp;
1726{
1727 if (entering(tcp)) {
1728 printpath(tcp, tcp->u_arg[0]);
1729 if (!verbose(tcp))
1730 tprintf(", %#lx", tcp->u_arg[1]);
1731#if 0
1732 else if (abbrev(tcp))
1733 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1734#endif
1735 else {
1736 tprintf(", [");
1737 printargv(tcp, tcp->u_arg[1]);
1738 tprintf("]");
1739 }
1740 }
1741 return 0;
1742}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001743#endif /* SPARC || SPARC64 || SUNOS4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001744
1745int
1746sys_execve(tcp)
1747struct tcb *tcp;
1748{
1749 if (entering(tcp)) {
1750 printpath(tcp, tcp->u_arg[0]);
1751 if (!verbose(tcp))
1752 tprintf(", %#lx", tcp->u_arg[1]);
1753#if 0
1754 else if (abbrev(tcp))
1755 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1756#endif
1757 else {
1758 tprintf(", [");
1759 printargv(tcp, tcp->u_arg[1]);
1760 tprintf("]");
1761 }
1762 if (!verbose(tcp))
1763 tprintf(", %#lx", tcp->u_arg[2]);
1764 else if (abbrev(tcp))
1765 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1766 else {
1767 tprintf(", [");
1768 printargv(tcp, tcp->u_arg[2]);
1769 tprintf("]");
1770 }
1771 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001772 return 0;
1773}
1774
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001775#if UNIXWARE > 2
John Hughes4e36a812001-04-18 15:11:51 +00001776
1777int sys_rexecve(tcp)
1778struct tcb *tcp;
1779{
1780 if (entering (tcp)) {
1781 sys_execve (tcp);
1782 tprintf (", %ld", tcp->u_arg[3]);
1783 }
1784 return 0;
1785}
1786
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001787#endif
John Hughes4e36a812001-04-18 15:11:51 +00001788
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001789int
1790internal_exec(tcp)
1791struct tcb *tcp;
1792{
1793#ifdef SUNOS4
1794 if (exiting(tcp) && !syserror(tcp) && followfork)
1795 fixvfork(tcp);
1796#endif /* SUNOS4 */
Roland McGrathfdb097f2004-07-12 07:38:55 +00001797#if defined LINUX && defined TCB_WAITEXECVE
1798 if (exiting(tcp) && syserror(tcp))
1799 tcp->flags &= ~TCB_WAITEXECVE;
1800 else
1801 tcp->flags |= TCB_WAITEXECVE;
1802#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001803 return 0;
1804}
1805
1806#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001807#ifndef __WNOTHREAD
1808#define __WNOTHREAD 0x20000000
1809#endif
1810#ifndef __WALL
1811#define __WALL 0x40000000
1812#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001813#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001814#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001815#endif
1816#endif /* LINUX */
1817
Roland McGrathd9f816f2004-09-04 03:39:20 +00001818static const struct xlat wait4_options[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001819 { WNOHANG, "WNOHANG" },
1820#ifndef WSTOPPED
1821 { WUNTRACED, "WUNTRACED" },
1822#endif
1823#ifdef WEXITED
1824 { WEXITED, "WEXITED" },
1825#endif
1826#ifdef WTRAPPED
1827 { WTRAPPED, "WTRAPPED" },
1828#endif
1829#ifdef WSTOPPED
1830 { WSTOPPED, "WSTOPPED" },
1831#endif
1832#ifdef WCONTINUED
1833 { WCONTINUED, "WCONTINUED" },
1834#endif
1835#ifdef WNOWAIT
1836 { WNOWAIT, "WNOWAIT" },
1837#endif
1838#ifdef __WCLONE
1839 { __WCLONE, "__WCLONE" },
1840#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001841#ifdef __WALL
1842 { __WALL, "__WALL" },
1843#endif
1844#ifdef __WNOTHREAD
1845 { __WNOTHREAD, "__WNOTHREAD" },
1846#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001847 { 0, NULL },
1848};
1849
Roland McGrath5e02a572004-10-19 23:33:47 +00001850#if !defined WCOREFLAG && defined WCOREFLG
1851# define WCOREFLAG WCOREFLG
1852#endif
1853#ifndef WCOREFLAG
1854#define WCOREFLAG 0x80
1855#endif
1856
1857#ifndef W_STOPCODE
1858#define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1859#endif
1860#ifndef W_EXITCODE
1861#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1862#endif
1863
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001864static int
1865printstatus(status)
1866int status;
1867{
1868 int exited = 0;
1869
1870 /*
1871 * Here is a tricky presentation problem. This solution
1872 * is still not entirely satisfactory but since there
1873 * are no wait status constructors it will have to do.
1874 */
Roland McGrath79fbda52004-04-14 02:45:55 +00001875 if (WIFSTOPPED(status)) {
1876 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001877 signame(WSTOPSIG(status)));
Roland McGrath79fbda52004-04-14 02:45:55 +00001878 status &= ~W_STOPCODE(WSTOPSIG(status));
1879 }
1880 else if (WIFSIGNALED(status)) {
1881 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001882 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001883 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
Roland McGrath79fbda52004-04-14 02:45:55 +00001884 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1885 }
1886 else if (WIFEXITED(status)) {
1887 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001888 WEXITSTATUS(status));
1889 exited = 1;
Roland McGrath79fbda52004-04-14 02:45:55 +00001890 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001891 }
Roland McGrath79fbda52004-04-14 02:45:55 +00001892 else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001893 tprintf("[%#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001894 return 0;
1895 }
1896
1897 if (status == 0)
1898 tprintf("]");
1899 else
Roland McGrathf8cc83c2004-06-04 01:24:07 +00001900 tprintf(" | %#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001901
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001902 return exited;
1903}
1904
1905static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001906printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001907struct tcb *tcp;
1908int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001909int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001910{
1911 int status;
1912 int exited = 0;
1913
1914 if (entering(tcp)) {
1915 tprintf("%ld, ", tcp->u_arg[0]);
1916 } else {
1917 /* status */
1918 if (!tcp->u_arg[1])
1919 tprintf("NULL");
1920 else if (syserror(tcp) || tcp->u_rval == 0)
1921 tprintf("%#lx", tcp->u_arg[1]);
1922 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1923 tprintf("[?]");
1924 else
1925 exited = printstatus(status);
1926 /* options */
1927 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00001928 printflags(wait4_options, tcp->u_arg[2], "W???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001929 if (n == 4) {
1930 tprintf(", ");
1931 /* usage */
1932 if (!tcp->u_arg[3])
1933 tprintf("NULL");
1934#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001935 else if (tcp->u_rval > 0) {
1936#ifdef LINUX_64BIT
1937 if (bitness)
1938 printrusage32(tcp, tcp->u_arg[3]);
1939 else
1940#endif
1941 printrusage(tcp, tcp->u_arg[3]);
1942 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001943#endif /* LINUX */
1944#ifdef SUNOS4
1945 else if (tcp->u_rval > 0 && exited)
1946 printrusage(tcp, tcp->u_arg[3]);
1947#endif /* SUNOS4 */
1948 else
1949 tprintf("%#lx", tcp->u_arg[3]);
1950 }
1951 }
1952 return 0;
1953}
1954
1955int
Roland McGrathc74c0b72004-09-01 19:39:46 +00001956internal_wait(tcp, flagarg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001957struct tcb *tcp;
Roland McGrathc74c0b72004-09-01 19:39:46 +00001958int flagarg;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001959{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001960 int got_kids;
1961
1962#ifdef TCB_CLONE_THREAD
1963 if (tcp->flags & TCB_CLONE_THREAD)
1964 /* The children we wait for are our parent's children. */
1965 got_kids = (tcp->parent->nchildren
1966 > tcp->parent->nclone_detached);
1967 else
1968 got_kids = (tcp->nchildren > tcp->nclone_detached);
1969#else
1970 got_kids = tcp->nchildren > 0;
1971#endif
1972
1973 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001974 /* There are children that this parent should block for.
1975 But ptrace made us the parent of the traced children
1976 and the real parent will get ECHILD from the wait call.
1977
1978 XXX If we attached with strace -f -p PID, then there
1979 may be untraced dead children the parent could be reaping
1980 now, but we make him block. */
1981
1982 /* ??? WTA: fix bug with hanging children */
1983
Roland McGrathc74c0b72004-09-01 19:39:46 +00001984 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00001985 /*
1986 * There are traced children. We'll make the parent
1987 * block to avoid a false ECHILD error due to our
1988 * ptrace having stolen the children. However,
1989 * we shouldn't block if there are zombies to reap.
1990 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1991 */
Roland McGrathfccfb942003-10-01 21:59:44 +00001992 struct tcb *child = NULL;
Roland McGrath09623452003-05-23 02:27:13 +00001993 if (tcp->nzombies > 0 &&
1994 (tcp->u_arg[0] == -1 ||
Roland McGrathfccfb942003-10-01 21:59:44 +00001995 (child = pid2tcb(tcp->u_arg[0])) == NULL))
Roland McGrath09623452003-05-23 02:27:13 +00001996 return 0;
Roland McGrathfccfb942003-10-01 21:59:44 +00001997 if (tcp->u_arg[0] > 0) {
1998 /*
1999 * If the parent waits for a specified child
2000 * PID, then it must get ECHILD right away
2001 * if that PID is not one of its children.
2002 * Make sure that the requested PID matches
2003 * one of the parent's children that we are
2004 * tracing, and don't suspend it otherwise.
2005 */
2006 if (child == NULL)
2007 child = pid2tcb(tcp->u_arg[0]);
2008 if (child == NULL || child->parent != (
2009#ifdef TCB_CLONE_THREAD
2010 (tcp->flags & TCB_CLONE_THREAD)
2011 ? tcp->parent :
2012#endif
Roland McGrathd56a6562005-08-03 11:23:43 +00002013 tcp) ||
2014 (child->flags & TCB_EXITING))
Roland McGrathfccfb942003-10-01 21:59:44 +00002015 return 0;
2016 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002017 tcp->flags |= TCB_SUSPENDED;
2018 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002019#ifdef TCB_CLONE_THREAD
2020 if (tcp->flags & TCB_CLONE_THREAD)
2021 tcp->parent->nclone_waiting++;
2022#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002023 }
2024 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002025 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathc74c0b72004-09-01 19:39:46 +00002026 if (tcp->u_arg[flagarg] & WNOHANG) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00002027 /* We must force a fake result of 0 instead of
2028 the ECHILD error. */
2029 extern int force_result();
2030 return force_result(tcp, 0, 0);
2031 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00002032 }
Roland McGrath09623452003-05-23 02:27:13 +00002033 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2034 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2035 /*
2036 * We just reaped a child we don't know about,
2037 * presumably a zombie we already droptcb'd.
2038 */
2039 tcp->nzombies--;
2040 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002041 return 0;
2042}
2043
2044#ifdef SVR4
2045
2046int
2047sys_wait(tcp)
2048struct tcb *tcp;
2049{
2050 if (exiting(tcp)) {
2051 /* The library wrapper stuffs this into the user variable. */
2052 if (!syserror(tcp))
2053 printstatus(getrval2(tcp));
2054 }
2055 return 0;
2056}
2057
2058#endif /* SVR4 */
2059
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002060#ifdef FREEBSD
2061int
2062sys_wait(tcp)
2063struct tcb *tcp;
2064{
2065 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00002066
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002067 if (exiting(tcp)) {
2068 if (!syserror(tcp)) {
2069 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2070 tprintf("%#lx", tcp->u_arg[0]);
2071 else
2072 printstatus(status);
2073 }
2074 }
2075 return 0;
2076}
2077#endif
2078
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002079int
2080sys_waitpid(tcp)
2081struct tcb *tcp;
2082{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002083 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002084}
2085
2086int
2087sys_wait4(tcp)
2088struct tcb *tcp;
2089{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002090 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002091}
2092
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002093#ifdef ALPHA
2094int
2095sys_osf_wait4(tcp)
2096struct tcb *tcp;
2097{
2098 return printwaitn(tcp, 4, 1);
2099}
2100#endif
2101
Roland McGrathc74c0b72004-09-01 19:39:46 +00002102#if defined SVR4 || defined LINUX
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002103
Roland McGrathd9f816f2004-09-04 03:39:20 +00002104static const struct xlat waitid_types[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002105 { P_PID, "P_PID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002106#ifdef P_PPID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002107 { P_PPID, "P_PPID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002108#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002109 { P_PGID, "P_PGID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002110#ifdef P_SID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002111 { P_SID, "P_SID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002112#endif
2113#ifdef P_CID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002114 { P_CID, "P_CID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002115#endif
2116#ifdef P_UID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002117 { P_UID, "P_UID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002118#endif
2119#ifdef P_GID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002120 { P_GID, "P_GID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002121#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002122 { P_ALL, "P_ALL" },
2123#ifdef P_LWPID
2124 { P_LWPID, "P_LWPID" },
2125#endif
2126 { 0, NULL },
2127};
2128
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002129int
2130sys_waitid(tcp)
2131struct tcb *tcp;
2132{
2133 siginfo_t si;
2134 int exited;
2135
2136 if (entering(tcp)) {
2137 printxval(waitid_types, tcp->u_arg[0], "P_???");
2138 tprintf(", %ld, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002139 }
2140 else {
2141 /* siginfo */
2142 exited = 0;
2143 if (!tcp->u_arg[2])
2144 tprintf("NULL");
2145 else if (syserror(tcp))
2146 tprintf("%#lx", tcp->u_arg[2]);
2147 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2148 tprintf("{???}");
2149 else
John Hughes58265892001-10-18 15:13:53 +00002150 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002151 /* options */
2152 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00002153 printflags(wait4_options, tcp->u_arg[3], "W???");
Roland McGrath39426a32004-10-06 22:02:59 +00002154 if (tcp->u_nargs > 4) {
2155 /* usage */
2156 tprintf(", ");
2157 if (!tcp->u_arg[4])
2158 tprintf("NULL");
2159 else if (tcp->u_error)
2160 tprintf("%#lx", tcp->u_arg[4]);
2161 else
2162 printrusage(tcp, tcp->u_arg[4]);
2163 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002164 }
2165 return 0;
2166}
2167
Roland McGrathc74c0b72004-09-01 19:39:46 +00002168#endif /* SVR4 or LINUX */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002169
2170int
2171sys_alarm(tcp)
2172struct tcb *tcp;
2173{
2174 if (entering(tcp))
2175 tprintf("%lu", tcp->u_arg[0]);
2176 return 0;
2177}
2178
2179int
2180sys_uname(tcp)
2181struct tcb *tcp;
2182{
2183 struct utsname uname;
2184
2185 if (exiting(tcp)) {
2186 if (syserror(tcp) || !verbose(tcp))
2187 tprintf("%#lx", tcp->u_arg[0]);
2188 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2189 tprintf("{...}");
2190 else if (!abbrev(tcp)) {
2191
2192 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2193 uname.sysname, uname.nodename);
2194 tprintf("release=\"%s\", version=\"%s\", ",
2195 uname.release, uname.version);
2196 tprintf("machine=\"%s\"", uname.machine);
2197#ifdef LINUX
2198#ifndef __GLIBC__
2199 tprintf(", domainname=\"%s\"", uname.domainname);
2200#endif /* __GLIBC__ */
2201#endif /* LINUX */
2202 tprintf("}");
2203 }
2204 else
2205 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2206 uname.sysname, uname.nodename);
2207 }
2208 return 0;
2209}
2210
2211#ifndef SVR4
2212
Roland McGrathd9f816f2004-09-04 03:39:20 +00002213static const struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002214#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002215 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2216 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2217 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2218 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2219 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2220 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2221 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2222 { PTRACE_CONT, "PTRACE_CONT" },
2223 { PTRACE_KILL, "PTRACE_KILL" },
2224 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2225 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2226 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002227#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002228 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002229#endif
2230#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002231 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002232#endif
2233#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002234 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002235#endif
2236#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002237 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002238#endif
2239#ifdef PTRACE_GETFPXREGS
2240 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2241#endif
2242#ifdef PTRACE_SETFPXREGS
2243 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2244#endif
Roland McGrathf04bb482005-05-09 07:45:33 +00002245#ifdef PTRACE_GETVRREGS
2246 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2247#endif
2248#ifdef PTRACE_SETVRREGS
2249 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2250#endif
Roland McGrathbf621d42003-01-14 09:46:21 +00002251#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002252 { PTRACE_READDATA, "PTRACE_READDATA" },
2253 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2254 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2255 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2256 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2257 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2258#ifdef SPARC
2259 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2260 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2261#else /* !SPARC */
2262 { PTRACE_22, "PTRACE_PTRACE_22" },
2263 { PTRACE_23, "PTRACE_PTRACE_23" },
2264#endif /* !SPARC */
2265#endif /* SUNOS4 */
2266 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2267#ifdef SUNOS4
2268 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2269#ifdef I386
2270 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2271 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2272 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2273#else /* !I386 */
2274 { PTRACE_26, "PTRACE_26" },
2275 { PTRACE_27, "PTRACE_27" },
2276 { PTRACE_28, "PTRACE_28" },
2277#endif /* !I386 */
2278 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2279#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002280#else /* FREEBSD */
2281 { PT_TRACE_ME, "PT_TRACE_ME" },
2282 { PT_READ_I, "PT_READ_I" },
2283 { PT_READ_D, "PT_READ_D" },
2284 { PT_WRITE_I, "PT_WRITE_I" },
2285 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002286#ifdef PT_READ_U
2287 { PT_READ_U, "PT_READ_U" },
2288#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002289 { PT_CONTINUE, "PT_CONTINUE" },
2290 { PT_KILL, "PT_KILL" },
2291 { PT_STEP, "PT_STEP" },
2292 { PT_ATTACH, "PT_ATTACH" },
2293 { PT_DETACH, "PT_DETACH" },
2294 { PT_GETREGS, "PT_GETREGS" },
2295 { PT_SETREGS, "PT_SETREGS" },
2296 { PT_GETFPREGS, "PT_GETFPREGS" },
2297 { PT_SETFPREGS, "PT_SETFPREGS" },
2298 { PT_GETDBREGS, "PT_GETDBREGS" },
2299 { PT_SETDBREGS, "PT_SETDBREGS" },
2300#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002301 { 0, NULL },
2302};
2303
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002304#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002305#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2306static
2307#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
Roland McGrathd9f816f2004-09-04 03:39:20 +00002308const struct xlat struct_user_offsets[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002309#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002310#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002311 { PT_PSWMASK, "psw_mask" },
2312 { PT_PSWADDR, "psw_addr" },
2313 { PT_GPR0, "gpr0" },
2314 { PT_GPR1, "gpr1" },
2315 { PT_GPR2, "gpr2" },
2316 { PT_GPR3, "gpr3" },
2317 { PT_GPR4, "gpr4" },
2318 { PT_GPR5, "gpr5" },
2319 { PT_GPR6, "gpr6" },
2320 { PT_GPR7, "gpr7" },
2321 { PT_GPR8, "gpr8" },
2322 { PT_GPR9, "gpr9" },
2323 { PT_GPR10, "gpr10" },
2324 { PT_GPR11, "gpr11" },
2325 { PT_GPR12, "gpr12" },
2326 { PT_GPR13, "gpr13" },
2327 { PT_GPR14, "gpr14" },
2328 { PT_GPR15, "gpr15" },
2329 { PT_ACR0, "acr0" },
2330 { PT_ACR1, "acr1" },
2331 { PT_ACR2, "acr2" },
2332 { PT_ACR3, "acr3" },
2333 { PT_ACR4, "acr4" },
2334 { PT_ACR5, "acr5" },
2335 { PT_ACR6, "acr6" },
2336 { PT_ACR7, "acr7" },
2337 { PT_ACR8, "acr8" },
2338 { PT_ACR9, "acr9" },
2339 { PT_ACR10, "acr10" },
2340 { PT_ACR11, "acr11" },
2341 { PT_ACR12, "acr12" },
2342 { PT_ACR13, "acr13" },
2343 { PT_ACR14, "acr14" },
2344 { PT_ACR15, "acr15" },
2345 { PT_ORIGGPR2, "orig_gpr2" },
2346 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002347#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002348 { PT_FPR0_HI, "fpr0.hi" },
2349 { PT_FPR0_LO, "fpr0.lo" },
2350 { PT_FPR1_HI, "fpr1.hi" },
2351 { PT_FPR1_LO, "fpr1.lo" },
2352 { PT_FPR2_HI, "fpr2.hi" },
2353 { PT_FPR2_LO, "fpr2.lo" },
2354 { PT_FPR3_HI, "fpr3.hi" },
2355 { PT_FPR3_LO, "fpr3.lo" },
2356 { PT_FPR4_HI, "fpr4.hi" },
2357 { PT_FPR4_LO, "fpr4.lo" },
2358 { PT_FPR5_HI, "fpr5.hi" },
2359 { PT_FPR5_LO, "fpr5.lo" },
2360 { PT_FPR6_HI, "fpr6.hi" },
2361 { PT_FPR6_LO, "fpr6.lo" },
2362 { PT_FPR7_HI, "fpr7.hi" },
2363 { PT_FPR7_LO, "fpr7.lo" },
2364 { PT_FPR8_HI, "fpr8.hi" },
2365 { PT_FPR8_LO, "fpr8.lo" },
2366 { PT_FPR9_HI, "fpr9.hi" },
2367 { PT_FPR9_LO, "fpr9.lo" },
2368 { PT_FPR10_HI, "fpr10.hi" },
2369 { PT_FPR10_LO, "fpr10.lo" },
2370 { PT_FPR11_HI, "fpr11.hi" },
2371 { PT_FPR11_LO, "fpr11.lo" },
2372 { PT_FPR12_HI, "fpr12.hi" },
2373 { PT_FPR12_LO, "fpr12.lo" },
2374 { PT_FPR13_HI, "fpr13.hi" },
2375 { PT_FPR13_LO, "fpr13.lo" },
2376 { PT_FPR14_HI, "fpr14.hi" },
2377 { PT_FPR14_LO, "fpr14.lo" },
2378 { PT_FPR15_HI, "fpr15.hi" },
2379 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002380#endif
2381#if defined(S390X)
2382 { PT_FPR0, "fpr0" },
2383 { PT_FPR1, "fpr1" },
2384 { PT_FPR2, "fpr2" },
2385 { PT_FPR3, "fpr3" },
2386 { PT_FPR4, "fpr4" },
2387 { PT_FPR5, "fpr5" },
2388 { PT_FPR6, "fpr6" },
2389 { PT_FPR7, "fpr7" },
2390 { PT_FPR8, "fpr8" },
2391 { PT_FPR9, "fpr9" },
2392 { PT_FPR10, "fpr10" },
2393 { PT_FPR11, "fpr11" },
2394 { PT_FPR12, "fpr12" },
2395 { PT_FPR13, "fpr13" },
2396 { PT_FPR14, "fpr14" },
2397 { PT_FPR15, "fpr15" },
2398#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002399 { PT_CR_9, "cr9" },
2400 { PT_CR_10, "cr10" },
2401 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002402 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002403#endif
2404#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002405 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002406#elif defined(HPPA)
2407 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002408#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002409#ifndef PT_ORIG_R3
2410#define PT_ORIG_R3 34
2411#endif
Roland McGratheb285352003-01-14 09:59:00 +00002412#define REGSIZE (sizeof(unsigned long))
2413 { REGSIZE*PT_R0, "r0" },
2414 { REGSIZE*PT_R1, "r1" },
2415 { REGSIZE*PT_R2, "r2" },
2416 { REGSIZE*PT_R3, "r3" },
2417 { REGSIZE*PT_R4, "r4" },
2418 { REGSIZE*PT_R5, "r5" },
2419 { REGSIZE*PT_R6, "r6" },
2420 { REGSIZE*PT_R7, "r7" },
2421 { REGSIZE*PT_R8, "r8" },
2422 { REGSIZE*PT_R9, "r9" },
2423 { REGSIZE*PT_R10, "r10" },
2424 { REGSIZE*PT_R11, "r11" },
2425 { REGSIZE*PT_R12, "r12" },
2426 { REGSIZE*PT_R13, "r13" },
2427 { REGSIZE*PT_R14, "r14" },
2428 { REGSIZE*PT_R15, "r15" },
2429 { REGSIZE*PT_R16, "r16" },
2430 { REGSIZE*PT_R17, "r17" },
2431 { REGSIZE*PT_R18, "r18" },
2432 { REGSIZE*PT_R19, "r19" },
2433 { REGSIZE*PT_R20, "r20" },
2434 { REGSIZE*PT_R21, "r21" },
2435 { REGSIZE*PT_R22, "r22" },
2436 { REGSIZE*PT_R23, "r23" },
2437 { REGSIZE*PT_R24, "r24" },
2438 { REGSIZE*PT_R25, "r25" },
2439 { REGSIZE*PT_R26, "r26" },
2440 { REGSIZE*PT_R27, "r27" },
2441 { REGSIZE*PT_R28, "r28" },
2442 { REGSIZE*PT_R29, "r29" },
2443 { REGSIZE*PT_R30, "r30" },
2444 { REGSIZE*PT_R31, "r31" },
2445 { REGSIZE*PT_NIP, "NIP" },
2446 { REGSIZE*PT_MSR, "MSR" },
2447 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2448 { REGSIZE*PT_CTR, "CTR" },
2449 { REGSIZE*PT_LNK, "LNK" },
2450 { REGSIZE*PT_XER, "XER" },
2451 { REGSIZE*PT_CCR, "CCR" },
2452 { REGSIZE*PT_FPR0, "FPR0" },
2453#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002454#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002455#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002456 { 0, "r0" },
2457 { 1, "r1" },
2458 { 2, "r2" },
2459 { 3, "r3" },
2460 { 4, "r4" },
2461 { 5, "r5" },
2462 { 6, "r6" },
2463 { 7, "r7" },
2464 { 8, "r8" },
2465 { 9, "r9" },
2466 { 10, "r10" },
2467 { 11, "r11" },
2468 { 12, "r12" },
2469 { 13, "r13" },
2470 { 14, "r14" },
2471 { 15, "r15" },
2472 { 16, "r16" },
2473 { 17, "r17" },
2474 { 18, "r18" },
2475 { 19, "r19" },
2476 { 20, "r20" },
2477 { 21, "r21" },
2478 { 22, "r22" },
2479 { 23, "r23" },
2480 { 24, "r24" },
2481 { 25, "r25" },
2482 { 26, "r26" },
2483 { 27, "r27" },
2484 { 28, "r28" },
2485 { 29, "gp" },
2486 { 30, "fp" },
2487 { 31, "zero" },
2488 { 32, "fp0" },
2489 { 33, "fp" },
2490 { 34, "fp2" },
2491 { 35, "fp3" },
2492 { 36, "fp4" },
2493 { 37, "fp5" },
2494 { 38, "fp6" },
2495 { 39, "fp7" },
2496 { 40, "fp8" },
2497 { 41, "fp9" },
2498 { 42, "fp10" },
2499 { 43, "fp11" },
2500 { 44, "fp12" },
2501 { 45, "fp13" },
2502 { 46, "fp14" },
2503 { 47, "fp15" },
2504 { 48, "fp16" },
2505 { 49, "fp17" },
2506 { 50, "fp18" },
2507 { 51, "fp19" },
2508 { 52, "fp20" },
2509 { 53, "fp21" },
2510 { 54, "fp22" },
2511 { 55, "fp23" },
2512 { 56, "fp24" },
2513 { 57, "fp25" },
2514 { 58, "fp26" },
2515 { 59, "fp27" },
2516 { 60, "fp28" },
2517 { 61, "fp29" },
2518 { 62, "fp30" },
2519 { 63, "fp31" },
2520 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002521#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002522#ifdef IA64
2523 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2524 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2525 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2526 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2527 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2528 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2529 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2530 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2531 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2532 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2533 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2534 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2535 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2536 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2537 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2538 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2539 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2540 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2541 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2542 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2543 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2544 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2545 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2546 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2547 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2548 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2549 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2550 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2551 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2552 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2553 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2554 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2555 /* switch stack: */
2556 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2557 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2558 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2559 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2560 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2561 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2562 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2563 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2564 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2565 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002566 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2567 { PT_B4, "b4" }, { PT_B5, "b5" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002568 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002569 /* pt_regs */
Roland McGrathca4e10c2004-01-13 10:13:20 +00002570 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2571 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002572 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2573 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2574 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2575 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2576 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2577 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2578 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2579 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2580 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2581 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2582 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2583 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2584 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2585 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2586 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
Roland McGrathfb1bc072004-03-01 21:29:24 +00002587# ifdef PT_AR_CSD
2588 { PT_AR_CSD, "ar.csd" },
2589# endif
2590# ifdef PT_AR_SSD
2591 { PT_AR_SSD, "ar.ssd" },
2592# endif
Roland McGrathca4e10c2004-01-13 10:13:20 +00002593 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002594#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002595#ifdef I386
2596 { 4*EBX, "4*EBX" },
2597 { 4*ECX, "4*ECX" },
2598 { 4*EDX, "4*EDX" },
2599 { 4*ESI, "4*ESI" },
2600 { 4*EDI, "4*EDI" },
2601 { 4*EBP, "4*EBP" },
2602 { 4*EAX, "4*EAX" },
2603 { 4*DS, "4*DS" },
2604 { 4*ES, "4*ES" },
2605 { 4*FS, "4*FS" },
2606 { 4*GS, "4*GS" },
2607 { 4*ORIG_EAX, "4*ORIG_EAX" },
2608 { 4*EIP, "4*EIP" },
2609 { 4*CS, "4*CS" },
2610 { 4*EFL, "4*EFL" },
2611 { 4*UESP, "4*UESP" },
2612 { 4*SS, "4*SS" },
2613#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002614#ifdef X86_64
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002615 { 8*R15, "8*R15" },
2616 { 8*R14, "8*R14" },
2617 { 8*R13, "8*R13" },
2618 { 8*R12, "8*R12" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002619 { 8*RBP, "8*RBP" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002620 { 8*RBX, "8*RBX" },
2621 { 8*R11, "8*R11" },
2622 { 8*R10, "8*R10" },
2623 { 8*R9, "8*R9" },
2624 { 8*R8, "8*R8" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002625 { 8*RAX, "8*RAX" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002626 { 8*RCX, "8*RCX" },
2627 { 8*RDX, "8*RDX" },
2628 { 8*RSI, "8*RSI" },
2629 { 8*RDI, "8*RDI" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002630#if 0
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002631 { DS, "DS" },
2632 { ES, "ES" },
2633 { FS, "FS" },
2634 { GS, "GS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002635#endif
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002636 { 8*ORIG_RAX, "8*ORIG_RAX" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002637 { 8*RIP, "8*RIP" },
2638 { 8*CS, "8*CS" },
2639 { 8*EFLAGS, "8*EFL" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002640 { 8*RSP, "8*RSP" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002641 { 8*SS, "8*SS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002642#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002643#ifdef M68K
2644 { 4*PT_D1, "4*PT_D1" },
2645 { 4*PT_D2, "4*PT_D2" },
2646 { 4*PT_D3, "4*PT_D3" },
2647 { 4*PT_D4, "4*PT_D4" },
2648 { 4*PT_D5, "4*PT_D5" },
2649 { 4*PT_D6, "4*PT_D6" },
2650 { 4*PT_D7, "4*PT_D7" },
2651 { 4*PT_A0, "4*PT_A0" },
2652 { 4*PT_A1, "4*PT_A1" },
2653 { 4*PT_A2, "4*PT_A2" },
2654 { 4*PT_A3, "4*PT_A3" },
2655 { 4*PT_A4, "4*PT_A4" },
2656 { 4*PT_A5, "4*PT_A5" },
2657 { 4*PT_A6, "4*PT_A6" },
2658 { 4*PT_D0, "4*PT_D0" },
2659 { 4*PT_USP, "4*PT_USP" },
2660 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2661 { 4*PT_SR, "4*PT_SR" },
2662 { 4*PT_PC, "4*PT_PC" },
2663#endif /* M68K */
2664#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002665#ifdef SH
2666 { 4*REG_REG0, "4*REG_REG0" },
2667 { 4*(REG_REG0+1), "4*REG_REG1" },
2668 { 4*(REG_REG0+2), "4*REG_REG2" },
2669 { 4*(REG_REG0+3), "4*REG_REG3" },
2670 { 4*(REG_REG0+4), "4*REG_REG4" },
2671 { 4*(REG_REG0+5), "4*REG_REG5" },
2672 { 4*(REG_REG0+6), "4*REG_REG6" },
2673 { 4*(REG_REG0+7), "4*REG_REG7" },
2674 { 4*(REG_REG0+8), "4*REG_REG8" },
2675 { 4*(REG_REG0+9), "4*REG_REG9" },
2676 { 4*(REG_REG0+10), "4*REG_REG10" },
2677 { 4*(REG_REG0+11), "4*REG_REG11" },
2678 { 4*(REG_REG0+12), "4*REG_REG12" },
2679 { 4*(REG_REG0+13), "4*REG_REG13" },
2680 { 4*(REG_REG0+14), "4*REG_REG14" },
2681 { 4*REG_REG15, "4*REG_REG15" },
2682 { 4*REG_PC, "4*REG_PC" },
2683 { 4*REG_PR, "4*REG_PR" },
2684 { 4*REG_SR, "4*REG_SR" },
2685 { 4*REG_GBR, "4*REG_GBR" },
2686 { 4*REG_MACH, "4*REG_MACH" },
2687 { 4*REG_MACL, "4*REG_MACL" },
2688 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2689 { 4*REG_FPUL, "4*REG_FPUL" },
2690 { 4*REG_FPREG0, "4*REG_FPREG0" },
2691 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2692 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2693 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2694 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2695 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2696 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2697 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2698 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2699 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2700 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2701 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2702 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2703 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2704 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2705 { 4*REG_FPREG15, "4*REG_FPREG15" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002706#ifdef REG_XDREG0
Wichert Akkermanccef6372002-05-01 16:39:22 +00002707 { 4*REG_XDREG0, "4*REG_XDREG0" },
2708 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2709 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2710 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2711 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2712 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2713 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2714 { 4*REG_XDREG14, "4*REG_XDREG14" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002715#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002716 { 4*REG_FPSCR, "4*REG_FPSCR" },
2717#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002718#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002719 { 0, "PC(L)" },
2720 { 4, "PC(U)" },
2721 { 8, "SR(L)" },
2722 { 12, "SR(U)" },
2723 { 16, "syscall no.(L)" },
2724 { 20, "syscall_no.(U)" },
2725 { 24, "R0(L)" },
2726 { 28, "R0(U)" },
2727 { 32, "R1(L)" },
2728 { 36, "R1(U)" },
2729 { 40, "R2(L)" },
2730 { 44, "R2(U)" },
2731 { 48, "R3(L)" },
2732 { 52, "R3(U)" },
2733 { 56, "R4(L)" },
2734 { 60, "R4(U)" },
2735 { 64, "R5(L)" },
2736 { 68, "R5(U)" },
2737 { 72, "R6(L)" },
2738 { 76, "R6(U)" },
2739 { 80, "R7(L)" },
2740 { 84, "R7(U)" },
2741 { 88, "R8(L)" },
2742 { 92, "R8(U)" },
2743 { 96, "R9(L)" },
2744 { 100, "R9(U)" },
2745 { 104, "R10(L)" },
2746 { 108, "R10(U)" },
2747 { 112, "R11(L)" },
2748 { 116, "R11(U)" },
2749 { 120, "R12(L)" },
2750 { 124, "R12(U)" },
2751 { 128, "R13(L)" },
2752 { 132, "R13(U)" },
2753 { 136, "R14(L)" },
2754 { 140, "R14(U)" },
2755 { 144, "R15(L)" },
2756 { 148, "R15(U)" },
2757 { 152, "R16(L)" },
2758 { 156, "R16(U)" },
2759 { 160, "R17(L)" },
2760 { 164, "R17(U)" },
2761 { 168, "R18(L)" },
2762 { 172, "R18(U)" },
2763 { 176, "R19(L)" },
2764 { 180, "R19(U)" },
2765 { 184, "R20(L)" },
2766 { 188, "R20(U)" },
2767 { 192, "R21(L)" },
2768 { 196, "R21(U)" },
2769 { 200, "R22(L)" },
2770 { 204, "R22(U)" },
2771 { 208, "R23(L)" },
2772 { 212, "R23(U)" },
2773 { 216, "R24(L)" },
2774 { 220, "R24(U)" },
2775 { 224, "R25(L)" },
2776 { 228, "R25(U)" },
2777 { 232, "R26(L)" },
2778 { 236, "R26(U)" },
2779 { 240, "R27(L)" },
2780 { 244, "R27(U)" },
2781 { 248, "R28(L)" },
2782 { 252, "R28(U)" },
2783 { 256, "R29(L)" },
2784 { 260, "R29(U)" },
2785 { 264, "R30(L)" },
2786 { 268, "R30(U)" },
2787 { 272, "R31(L)" },
2788 { 276, "R31(U)" },
2789 { 280, "R32(L)" },
2790 { 284, "R32(U)" },
2791 { 288, "R33(L)" },
2792 { 292, "R33(U)" },
2793 { 296, "R34(L)" },
2794 { 300, "R34(U)" },
2795 { 304, "R35(L)" },
2796 { 308, "R35(U)" },
2797 { 312, "R36(L)" },
2798 { 316, "R36(U)" },
2799 { 320, "R37(L)" },
2800 { 324, "R37(U)" },
2801 { 328, "R38(L)" },
2802 { 332, "R38(U)" },
2803 { 336, "R39(L)" },
2804 { 340, "R39(U)" },
2805 { 344, "R40(L)" },
2806 { 348, "R40(U)" },
2807 { 352, "R41(L)" },
2808 { 356, "R41(U)" },
2809 { 360, "R42(L)" },
2810 { 364, "R42(U)" },
2811 { 368, "R43(L)" },
2812 { 372, "R43(U)" },
2813 { 376, "R44(L)" },
2814 { 380, "R44(U)" },
2815 { 384, "R45(L)" },
2816 { 388, "R45(U)" },
2817 { 392, "R46(L)" },
2818 { 396, "R46(U)" },
2819 { 400, "R47(L)" },
2820 { 404, "R47(U)" },
2821 { 408, "R48(L)" },
2822 { 412, "R48(U)" },
2823 { 416, "R49(L)" },
2824 { 420, "R49(U)" },
2825 { 424, "R50(L)" },
2826 { 428, "R50(U)" },
2827 { 432, "R51(L)" },
2828 { 436, "R51(U)" },
2829 { 440, "R52(L)" },
2830 { 444, "R52(U)" },
2831 { 448, "R53(L)" },
2832 { 452, "R53(U)" },
2833 { 456, "R54(L)" },
2834 { 460, "R54(U)" },
2835 { 464, "R55(L)" },
2836 { 468, "R55(U)" },
2837 { 472, "R56(L)" },
2838 { 476, "R56(U)" },
2839 { 480, "R57(L)" },
2840 { 484, "R57(U)" },
2841 { 488, "R58(L)" },
2842 { 492, "R58(U)" },
2843 { 496, "R59(L)" },
2844 { 500, "R59(U)" },
2845 { 504, "R60(L)" },
2846 { 508, "R60(U)" },
2847 { 512, "R61(L)" },
2848 { 516, "R61(U)" },
2849 { 520, "R62(L)" },
2850 { 524, "R62(U)" },
2851 { 528, "TR0(L)" },
2852 { 532, "TR0(U)" },
2853 { 536, "TR1(L)" },
2854 { 540, "TR1(U)" },
2855 { 544, "TR2(L)" },
2856 { 548, "TR2(U)" },
2857 { 552, "TR3(L)" },
2858 { 556, "TR3(U)" },
2859 { 560, "TR4(L)" },
2860 { 564, "TR4(U)" },
2861 { 568, "TR5(L)" },
2862 { 572, "TR5(U)" },
2863 { 576, "TR6(L)" },
2864 { 580, "TR6(U)" },
2865 { 584, "TR7(L)" },
2866 { 588, "TR7(U)" },
2867 /* This entry is in case pt_regs contains dregs (depends on
2868 the kernel build options). */
2869 { uoff(regs), "offsetof(struct user, regs)" },
2870 { uoff(fpu), "offsetof(struct user, fpu)" },
2871#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002872#ifdef ARM
2873 { uoff(regs.ARM_r0), "r0" },
2874 { uoff(regs.ARM_r1), "r1" },
2875 { uoff(regs.ARM_r2), "r2" },
2876 { uoff(regs.ARM_r3), "r3" },
2877 { uoff(regs.ARM_r4), "r4" },
2878 { uoff(regs.ARM_r5), "r5" },
2879 { uoff(regs.ARM_r6), "r6" },
2880 { uoff(regs.ARM_r7), "r7" },
2881 { uoff(regs.ARM_r8), "r8" },
2882 { uoff(regs.ARM_r9), "r9" },
2883 { uoff(regs.ARM_r10), "r10" },
2884 { uoff(regs.ARM_fp), "fp" },
2885 { uoff(regs.ARM_ip), "ip" },
2886 { uoff(regs.ARM_sp), "sp" },
2887 { uoff(regs.ARM_lr), "lr" },
2888 { uoff(regs.ARM_pc), "pc" },
2889 { uoff(regs.ARM_cpsr), "cpsr" },
2890#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002891
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002892#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002893 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002894#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002895#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002896 { uoff(i387), "offsetof(struct user, i387)" },
2897#else /* !I386 */
2898#ifdef M68K
2899 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2900#endif /* M68K */
2901#endif /* !I386 */
2902 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2903 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2904 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002905#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002906 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002907#endif
Roland McGrathf5a47772003-06-26 22:40:42 +00002908#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002909 { uoff(start_data), "offsetof(struct user, start_data)" },
2910#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002911#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002912 { uoff(start_stack), "offsetof(struct user, start_stack)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002913#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002914 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002915#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002916 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002917#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002918#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002919 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002920#endif
2921#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002922 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2923#endif
2924 { uoff(magic), "offsetof(struct user, magic)" },
2925 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002926#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002927 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2928#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002929#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002930#endif /* !ALPHA */
2931#endif /* !POWERPC/!SPARC */
2932#endif /* LINUX */
2933#ifdef SUNOS4
2934 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2935 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2936 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2937 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2938 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2939 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2940 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2941 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2942 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2943 { uoff(u_error), "offsetof(struct user, u_error)" },
2944 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2945 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2946 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2947 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2948 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2949 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2950 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2951 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2952 { uoff(u_code), "offsetof(struct user, u_code)" },
2953 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2954 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2955 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2956 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2957 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2958 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2959 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2960 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2961 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2962 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2963 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2964 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2965 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2966 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2967 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2968 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2969 { uoff(u_start), "offsetof(struct user, u_start)" },
2970 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2971 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2972 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2973 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2974 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2975 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2976 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2977 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2978 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2979#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002980#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002981 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002982#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002983 { 0, NULL },
2984};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002985#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002986
2987int
2988sys_ptrace(tcp)
2989struct tcb *tcp;
2990{
Roland McGrathd9f816f2004-09-04 03:39:20 +00002991 const struct xlat *x;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002992 long addr;
2993
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002994 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002995 printxval(ptrace_cmds, tcp->u_arg[0],
2996#ifndef FREEBSD
2997 "PTRACE_???"
2998#else
2999 "PT_???"
3000#endif
3001 );
3002 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003003 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003004#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003005 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3006 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3007 for (x = struct_user_offsets; x->str; x++) {
3008 if (x->val >= addr)
3009 break;
3010 }
3011 if (!x->str)
3012 tprintf("%#lx, ", addr);
3013 else if (x->val > addr && x != struct_user_offsets) {
3014 x--;
3015 tprintf("%s + %ld, ", x->str, addr - x->val);
3016 }
3017 else
3018 tprintf("%s, ", x->str);
3019 }
3020 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003021#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003022 tprintf("%#lx, ", tcp->u_arg[2]);
3023#ifdef LINUX
3024 switch (tcp->u_arg[0]) {
3025 case PTRACE_PEEKDATA:
3026 case PTRACE_PEEKTEXT:
3027 case PTRACE_PEEKUSER:
3028 break;
3029 case PTRACE_CONT:
3030 case PTRACE_SINGLESTEP:
3031 case PTRACE_SYSCALL:
3032 case PTRACE_DETACH:
3033 printsignal(tcp->u_arg[3]);
3034 break;
3035 default:
3036 tprintf("%#lx", tcp->u_arg[3]);
3037 break;
3038 }
3039 } else {
3040 switch (tcp->u_arg[0]) {
3041 case PTRACE_PEEKDATA:
3042 case PTRACE_PEEKTEXT:
3043 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00003044 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003045 break;
3046 }
3047 }
3048#endif /* LINUX */
3049#ifdef SUNOS4
3050 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3051 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3052 tprintf("%lu, ", tcp->u_arg[3]);
3053 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3054 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3055 tcp->u_arg[0] != PTRACE_READTEXT) {
3056 tprintf("%#lx", tcp->u_arg[3]);
3057 }
3058 } else {
3059 if (tcp->u_arg[0] == PTRACE_READDATA ||
3060 tcp->u_arg[0] == PTRACE_READTEXT) {
3061 tprintf("%lu, ", tcp->u_arg[3]);
3062 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3063 }
3064 }
3065#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003066#ifdef FREEBSD
3067 tprintf("%lu", tcp->u_arg[3]);
3068 }
3069#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003070 return 0;
3071}
3072
3073#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00003074
3075#ifdef LINUX
Roland McGrathd9f816f2004-09-04 03:39:20 +00003076static const struct xlat futexops[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00003077 { FUTEX_WAIT, "FUTEX_WAIT" },
3078 { FUTEX_WAKE, "FUTEX_WAKE" },
3079 { FUTEX_FD, "FUTEX_FD" },
Roland McGrath88812d62003-06-26 22:27:23 +00003080 { FUTEX_REQUEUE,"FUTEX_REQUEUE" },
Roland McGrath5a223472002-12-15 23:58:26 +00003081 { 0, NULL }
3082};
3083
3084int
3085sys_futex(tcp)
3086struct tcb *tcp;
3087{
3088 if (entering(tcp)) {
3089 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00003090 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003091 tprintf(", %ld", tcp->u_arg[2]);
3092 if (tcp->u_arg[1] == FUTEX_WAIT) {
3093 tprintf(", ");
3094 printtv(tcp, tcp->u_arg[3]);
Roland McGrath88812d62003-06-26 22:27:23 +00003095 } else if (tcp->u_arg[1] == FUTEX_REQUEUE)
3096 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath5a223472002-12-15 23:58:26 +00003097 }
3098 return 0;
3099}
3100
3101static void
Roland McGrath79fbda52004-04-14 02:45:55 +00003102print_affinitylist(tcp, list, len)
3103struct tcb *tcp;
3104long list;
Roland McGrath5a223472002-12-15 23:58:26 +00003105unsigned int len;
3106{
3107 int first = 1;
3108 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00003109 while (len >= sizeof (unsigned long)) {
Roland McGrath79fbda52004-04-14 02:45:55 +00003110 unsigned long w;
3111 umove(tcp, list, &w);
3112 tprintf("%s %lx", first ? "" : ",", w);
Roland McGrath5a223472002-12-15 23:58:26 +00003113 first = 0;
3114 len -= sizeof (unsigned long);
Roland McGrath79fbda52004-04-14 02:45:55 +00003115 list += sizeof(unsigned long);
Roland McGrath5a223472002-12-15 23:58:26 +00003116 }
3117 tprintf(" }");
3118}
3119
3120int
3121sys_sched_setaffinity(tcp)
3122struct tcb *tcp;
3123{
3124 if (entering(tcp)) {
3125 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath79fbda52004-04-14 02:45:55 +00003126 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
Roland McGrath5a223472002-12-15 23:58:26 +00003127 }
3128 return 0;
3129}
3130
3131int
3132sys_sched_getaffinity(tcp)
3133struct tcb *tcp;
3134{
3135 if (entering(tcp)) {
3136 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3137 } else {
Roland McGrath79fbda52004-04-14 02:45:55 +00003138 if (tcp->u_rval == -1)
3139 tprintf("%#lx", tcp->u_arg[2]);
3140 else
3141 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
Roland McGrath5a223472002-12-15 23:58:26 +00003142 }
3143 return 0;
3144}
Roland McGrath279d3782004-03-01 20:27:37 +00003145
Roland McGrathd9f816f2004-09-04 03:39:20 +00003146static const struct xlat schedulers[] = {
Roland McGrath279d3782004-03-01 20:27:37 +00003147 { SCHED_OTHER, "SCHED_OTHER" },
3148 { SCHED_RR, "SCHED_RR" },
3149 { SCHED_FIFO, "SCHED_FIFO" },
3150 { 0, NULL }
3151};
3152
3153int
3154sys_sched_getscheduler(tcp)
3155struct tcb *tcp;
3156{
3157 if (entering(tcp)) {
3158 tprintf("%d", (int) tcp->u_arg[0]);
3159 } else if (! syserror(tcp)) {
3160 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3161 if (tcp->auxstr != NULL)
3162 return RVAL_STR;
3163 }
3164 return 0;
3165}
3166
3167int
3168sys_sched_setscheduler(tcp)
3169struct tcb *tcp;
3170{
3171 if (entering(tcp)) {
3172 struct sched_param p;
3173 tprintf("%d, ", (int) tcp->u_arg[0]);
3174 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3175 if (umove(tcp, tcp->u_arg[2], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003176 tprintf(", %#lx", tcp->u_arg[2]);
Roland McGrath279d3782004-03-01 20:27:37 +00003177 else
3178 tprintf(", { %d }", p.__sched_priority);
3179 }
3180 return 0;
3181}
3182
3183int
3184sys_sched_getparam(tcp)
3185struct tcb *tcp;
3186{
3187 if (entering(tcp)) {
3188 tprintf("%d, ", (int) tcp->u_arg[0]);
3189 } else {
3190 struct sched_param p;
3191 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003192 tprintf("%#lx", tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003193 else
3194 tprintf("{ %d }", p.__sched_priority);
3195 }
3196 return 0;
3197}
3198
3199int
3200sys_sched_setparam(tcp)
3201struct tcb *tcp;
3202{
3203 if (entering(tcp)) {
3204 struct sched_param p;
3205 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003206 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003207 else
3208 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3209 }
3210 return 0;
3211}
3212
3213int
3214sys_sched_get_priority_min(tcp)
3215struct tcb *tcp;
3216{
3217 if (entering(tcp)) {
3218 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3219 }
3220 return 0;
3221}
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003222
3223#ifdef X86_64
3224#include <asm/prctl.h>
3225
3226static const struct xlat archvals[] = {
3227 { ARCH_SET_GS, "ARCH_SET_GS" },
3228 { ARCH_SET_FS, "ARCH_SET_FS" },
3229 { ARCH_GET_FS, "ARCH_GET_FS" },
3230 { ARCH_GET_GS, "ARCH_GET_GS" },
3231 { 0, NULL },
3232};
3233
3234int
3235sys_arch_prctl(tcp)
3236struct tcb *tcp;
3237{
3238 if (entering(tcp)) {
3239 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3240 if (tcp->u_arg[0] == ARCH_SET_GS
3241 || tcp->u_arg[0] == ARCH_SET_FS)
3242 tprintf(", %#lx", tcp->u_arg[1]);
3243 } else {
3244 if (tcp->u_arg[0] == ARCH_GET_GS
3245 || tcp->u_arg[0] == ARCH_GET_FS) {
3246 long int v;
3247 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3248 tprintf(", [%#lx]", v);
3249 else
3250 tprintf(", %#lx", tcp->u_arg[1]);
3251 }
3252 }
3253 return 0;
3254}
3255#endif
3256
Roland McGrath5a223472002-12-15 23:58:26 +00003257#endif