blob: ff1960c9c71fe0c2cb07d159d3e54db345d1021c [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
Dmitry V. Levinf02cf212008-09-03 00:54:40 +0000207#ifdef PR_GET_DUMPABLE
208 { PR_GET_DUMPABLE, "PR_GET_DUMPABLE" },
209#endif
210#ifdef PR_SET_DUMPABLE
211 { PR_SET_DUMPABLE, "PR_SET_DUMPABLE" },
212#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000213#ifdef PR_GET_UNALIGN
214 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
215#endif
216#ifdef PR_SET_UNALIGN
217 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
218#endif
219#ifdef PR_GET_KEEPCAPS
220 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" },
221#endif
222#ifdef PR_SET_KEEPCAPS
223 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" },
224#endif
Roland McGrathe5039fb2007-11-03 23:58:07 +0000225#ifdef PR_GET_FPEMU
226 { PR_GET_FPEMU, "PR_GET_FPEMU" },
227#endif
228#ifdef PR_SET_FPEMU
229 { PR_SET_FPEMU, "PR_SET_FPEMU" },
230#endif
231#ifdef PR_GET_FPEXC
232 { PR_GET_FPEXC, "PR_GET_FPEXC" },
233#endif
234#ifdef PR_SET_FPEXC
235 { PR_SET_FPEXC, "PR_SET_FPEXC" },
236#endif
237#ifdef PR_GET_TIMING
238 { PR_GET_TIMING, "PR_GET_TIMING" },
239#endif
240#ifdef PR_SET_TIMING
241 { PR_SET_TIMING, "PR_SET_TIMING" },
242#endif
243#ifdef PR_SET_NAME
244 { PR_SET_NAME, "PR_SET_NAME" },
245#endif
246#ifdef PR_GET_NAME
247 { PR_GET_NAME, "PR_GET_NAME" },
248#endif
249#ifdef PR_GET_ENDIAN
250 { PR_GET_ENDIAN, "PR_GET_ENDIAN" },
251#endif
252#ifdef PR_SET_ENDIAN
253 { PR_SET_ENDIAN, "PR_SET_ENDIAN" },
254#endif
255#ifdef PR_GET_SECCOMP
256 { PR_GET_SECCOMP, "PR_GET_SECCOMP" },
257#endif
258#ifdef PR_SET_SECCOMP
259 { PR_SET_SECCOMP, "PR_SET_SECCOMP" },
260#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000261 { 0, NULL },
262};
263
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000264
Roland McGratha4d48532005-06-08 20:45:28 +0000265static const char *
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000266unalignctl_string (unsigned int ctl)
267{
268 static char buf[16];
269
270 switch (ctl) {
271#ifdef PR_UNALIGN_NOPRINT
272 case PR_UNALIGN_NOPRINT:
273 return "NOPRINT";
274#endif
275#ifdef PR_UNALIGN_SIGBUS
276 case PR_UNALIGN_SIGBUS:
277 return "SIGBUS";
278#endif
279 default:
280 break;
281 }
282 sprintf(buf, "%x", ctl);
283 return buf;
284}
285
286
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000287int
288sys_prctl(tcp)
289struct tcb *tcp;
290{
291 int i;
292
293 if (entering(tcp)) {
294 printxval(prctl_options, tcp->u_arg[0], "PR_???");
295 switch (tcp->u_arg[0]) {
296#ifdef PR_GETNSHARE
297 case PR_GETNSHARE:
298 break;
299#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000300#ifdef PR_SET_DEATHSIG
301 case PR_GET_PDEATHSIG:
302 break;
303#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000304#ifdef PR_SET_UNALIGN
305 case PR_SET_UNALIGN:
306 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
307 break;
308#endif
309#ifdef PR_GET_UNALIGN
310 case PR_GET_UNALIGN:
311 tprintf(", %#lx", tcp->u_arg[1]);
312 break;
313#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000314 default:
315 for (i = 1; i < tcp->u_nargs; i++)
316 tprintf(", %#lx", tcp->u_arg[i]);
317 break;
318 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000319 } else {
320 switch (tcp->u_arg[0]) {
321#ifdef PR_GET_PDEATHSIG
322 case PR_GET_PDEATHSIG:
323 for (i=1; i<tcp->u_nargs; i++)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000324 tprintf(", %#lx", tcp->u_arg[i]);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000325 break;
326#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000327#ifdef PR_SET_UNALIGN
328 case PR_SET_UNALIGN:
329 break;
330#endif
331#ifdef PR_GET_UNALIGN
332 case PR_GET_UNALIGN:
333 {
334 int ctl;
335
336 umove(tcp, tcp->u_arg[1], &ctl);
337 tcp->auxstr = unalignctl_string(ctl);
338 return RVAL_STR;
339 }
340#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000341 default:
342 break;
343 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000344 }
345 return 0;
346}
347
348#endif /* HAVE_PRCTL */
349
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000350#if defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000351int
352sys_gethostid(tcp)
353struct tcb *tcp;
354{
355 if (exiting(tcp))
356 return RVAL_HEX;
357 return 0;
358}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000359#endif /* FREEBSD || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000360
361int
362sys_sethostname(tcp)
363struct tcb *tcp;
364{
365 if (entering(tcp)) {
366 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
367 tprintf(", %lu", tcp->u_arg[1]);
368 }
369 return 0;
370}
371
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000372#if defined(ALPHA) || defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000373int
374sys_gethostname(tcp)
375struct tcb *tcp;
376{
377 if (exiting(tcp)) {
378 if (syserror(tcp))
379 tprintf("%#lx", tcp->u_arg[0]);
380 else
381 printpath(tcp, tcp->u_arg[0]);
382 tprintf(", %lu", tcp->u_arg[1]);
383 }
384 return 0;
385}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000386#endif /* ALPHA || FREEBSD || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000387
388int
389sys_setdomainname(tcp)
390struct tcb *tcp;
391{
392 if (entering(tcp)) {
393 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
394 tprintf(", %lu", tcp->u_arg[1]);
395 }
396 return 0;
397}
398
Wichert Akkerman5daa0281999-03-15 19:49:42 +0000399#if !defined(LINUX)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000400
401int
402sys_getdomainname(tcp)
403struct tcb *tcp;
404{
405 if (exiting(tcp)) {
406 if (syserror(tcp))
407 tprintf("%#lx", tcp->u_arg[0]);
408 else
409 printpath(tcp, tcp->u_arg[0]);
410 tprintf(", %lu", tcp->u_arg[1]);
411 }
412 return 0;
413}
414#endif /* !LINUX */
415
416int
417sys_exit(tcp)
418struct tcb *tcp;
419{
420 if (exiting(tcp)) {
421 fprintf(stderr, "_exit returned!\n");
422 return -1;
423 }
424 /* special case: we stop tracing this process, finish line now */
425 tprintf("%ld) ", tcp->u_arg[0]);
426 tabto(acolumn);
427 tprintf("= ?");
428 printtrailer(tcp);
429 return 0;
430}
431
432int
433internal_exit(tcp)
434struct tcb *tcp;
435{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000436 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000437 tcp->flags |= TCB_EXITING;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000438#ifdef __NR_exit_group
Roland McGrath08267b82004-02-20 22:56:43 +0000439# ifdef IA64
440 if (ia32) {
441 if (tcp->scno == 252)
442 tcp->flags |= TCB_GROUP_EXITING;
443 } else
444# endif
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000445 if (known_scno(tcp) == __NR_exit_group)
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000446 tcp->flags |= TCB_GROUP_EXITING;
447#endif
448 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000449 return 0;
450}
451
Roland McGrathee9d4352002-12-18 04:16:10 +0000452/* TCP is creating a child we want to follow.
453 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
454 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
455static int
456fork_tcb(struct tcb *tcp)
457{
458 if (nprocs == tcbtabsize) {
Roland McGrath7b54a7a2004-06-04 01:50:45 +0000459 if (expand_tcbtab()) {
Roland McGrathee9d4352002-12-18 04:16:10 +0000460 tcp->flags &= ~TCB_FOLLOWFORK;
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000461 return 1;
Roland McGrathee9d4352002-12-18 04:16:10 +0000462 }
Roland McGrathee9d4352002-12-18 04:16:10 +0000463 }
464
465 tcp->flags |= TCB_FOLLOWFORK;
466 return 0;
467}
468
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000469#ifdef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000470
471int
472sys_fork(tcp)
473struct tcb *tcp;
474{
475 if (exiting(tcp)) {
476 if (getrval2(tcp)) {
477 tcp->auxstr = "child process";
478 return RVAL_UDECIMAL | RVAL_STR;
479 }
480 }
481 return 0;
482}
483
John Hughes4e36a812001-04-18 15:11:51 +0000484#if UNIXWARE > 2
485
486int
487sys_rfork(tcp)
488struct tcb *tcp;
489{
490 if (entering(tcp)) {
491 tprintf ("%ld", tcp->u_arg[0]);
492 }
493 else {
494 if (getrval2(tcp)) {
495 tcp->auxstr = "child process";
496 return RVAL_UDECIMAL | RVAL_STR;
497 }
498 }
499 return 0;
500}
501
502#endif
503
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000504int
505internal_fork(tcp)
506struct tcb *tcp;
507{
508 struct tcb *tcpchild;
509
510 if (exiting(tcp)) {
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000511#ifdef SYS_rfork
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000512 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000513 return 0;
514#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000515 if (getrval2(tcp))
516 return 0;
517 if (!followfork)
518 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000519 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000520 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000521 if (syserror(tcp))
522 return 0;
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000523 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000524 return 0;
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000525 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000526 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000527 }
528 return 0;
529}
530
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000531#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000532
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000533#ifdef LINUX
534
535/* defines copied from linux/sched.h since we can't include that
536 * ourselves (it conflicts with *lots* of libc includes)
537 */
538#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
539#define CLONE_VM 0x00000100 /* set if VM shared between processes */
540#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
541#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
542#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000543#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000544#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
545#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
546#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000547#define CLONE_THREAD 0x00010000 /* Same thread group? */
548#define CLONE_NEWNS 0x00020000 /* New namespace group? */
549#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
550#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
551#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
552#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
553#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
554#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
555#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000556
Roland McGrathd9f816f2004-09-04 03:39:20 +0000557static const struct xlat clone_flags[] = {
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000558 { CLONE_VM, "CLONE_VM" },
559 { CLONE_FS, "CLONE_FS" },
560 { CLONE_FILES, "CLONE_FILES" },
561 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000562 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000563 { CLONE_PTRACE, "CLONE_PTRACE" },
564 { CLONE_VFORK, "CLONE_VFORK" },
565 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000566 { CLONE_THREAD, "CLONE_THREAD" },
567 { CLONE_NEWNS, "CLONE_NEWNS" },
568 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
569 { CLONE_SETTLS, "CLONE_SETTLS" },
570 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
571 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
572 { CLONE_DETACHED, "CLONE_DETACHED" },
573 { CLONE_UNTRACED, "CLONE_UNTRACED" },
574 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000575 { 0, NULL },
576};
577
Roland McGrath909875b2002-12-22 03:34:36 +0000578# ifdef I386
579# include <asm/ldt.h>
Roland McGrath7decfb22004-03-01 22:10:52 +0000580# ifdef HAVE_STRUCT_USER_DESC
581# define modify_ldt_ldt_s user_desc
582# endif
Roland McGrath909875b2002-12-22 03:34:36 +0000583extern void print_ldt_entry();
584# endif
585
Roland McGrath9677b3a2003-03-12 09:54:36 +0000586# if defined IA64
587# define ARG_FLAGS 0
588# define ARG_STACK 1
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000589# define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
590# define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
591# define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
592# define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000593# elif defined S390 || defined S390X
Roland McGrath9677b3a2003-03-12 09:54:36 +0000594# define ARG_STACK 0
595# define ARG_FLAGS 1
596# define ARG_PTID 2
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000597# define ARG_CTID 3
598# define ARG_TLS 4
Roland McGrath9c555e72003-07-09 09:47:59 +0000599# elif defined X86_64 || defined ALPHA
Roland McGrath361aac52003-03-18 07:43:42 +0000600# define ARG_FLAGS 0
601# define ARG_STACK 1
602# define ARG_PTID 2
603# define ARG_CTID 3
604# define ARG_TLS 4
Roland McGrath9677b3a2003-03-12 09:54:36 +0000605# else
606# define ARG_FLAGS 0
607# define ARG_STACK 1
608# define ARG_PTID 2
609# define ARG_TLS 3
610# define ARG_CTID 4
611# endif
612
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000613int
614sys_clone(tcp)
615struct tcb *tcp;
616{
617 if (exiting(tcp)) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000618 unsigned long flags = tcp->u_arg[ARG_FLAGS];
619 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
620# ifdef ARG_STACKSIZE
621 if (ARG_STACKSIZE != -1)
622 tprintf("stack_size=%#lx, ",
623 tcp->u_arg[ARG_STACKSIZE]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000624# endif
Roland McGrath9677b3a2003-03-12 09:54:36 +0000625 tprintf("flags=");
Roland McGrathb2dee132005-06-01 19:02:36 +0000626 printflags(clone_flags, flags &~ CSIGNAL, NULL);
Roland McGrath984154d2003-05-23 01:08:42 +0000627 if ((flags & CSIGNAL) != 0)
628 tprintf("|%s", signame(flags & CSIGNAL));
Roland McGrathb4968be2003-01-20 09:04:33 +0000629 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
Roland McGrath9677b3a2003-03-12 09:54:36 +0000630 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
Roland McGrath909875b2002-12-22 03:34:36 +0000631 return 0;
Roland McGrath6f67a982003-03-21 07:33:15 +0000632 if (flags & CLONE_PARENT_SETTID)
633 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000634 if (flags & CLONE_SETTLS) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000635# ifdef I386
Roland McGrath909875b2002-12-22 03:34:36 +0000636 struct modify_ldt_ldt_s copy;
Roland McGrath9677b3a2003-03-12 09:54:36 +0000637 if (umove(tcp, tcp->u_arg[ARG_TLS], &copy) != -1) {
Roland McGrath909875b2002-12-22 03:34:36 +0000638 tprintf(", {entry_number:%d, ",
639 copy.entry_number);
640 if (!verbose(tcp))
641 tprintf("...}");
642 else
643 print_ldt_entry(&copy);
644 }
645 else
Roland McGrath9677b3a2003-03-12 09:54:36 +0000646# endif
Roland McGrath43f2c842003-03-12 09:58:14 +0000647 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
Roland McGrath909875b2002-12-22 03:34:36 +0000648 }
Roland McGrath9677b3a2003-03-12 09:54:36 +0000649 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
650 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000651 }
652 return 0;
653}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000654
655int
656sys_unshare(struct tcb *tcp)
657{
658 if (entering(tcp))
659 printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
660 return 0;
661}
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000662#endif
663
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000664int
665sys_fork(tcp)
666struct tcb *tcp;
667{
668 if (exiting(tcp))
669 return RVAL_UDECIMAL;
670 return 0;
671}
672
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000673int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000674change_syscall(tcp, new)
675struct tcb *tcp;
676int new;
677{
678#if defined(LINUX)
679#if defined(I386)
680 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000681 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000682 return -1;
683 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000684#elif defined(X86_64)
685 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000686 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000687 return -1;
688 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000689#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000690 if (ptrace(PTRACE_POKEUSER, tcp->pid,
691 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000692 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000693 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000694#elif defined(S390) || defined(S390X)
695 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
696 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
697 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000698 return 0;
699#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000700 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000701 return -1;
702 return 0;
Roland McGrath6d1a65c2004-07-12 07:44:08 +0000703#elif defined(SPARC) || defined(SPARC64)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000704 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000705 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
706 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000707 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000708 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
709 return -1;
710 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000711#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000712 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000713 return -1;
714 return 0;
715#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000716 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000717 return -1;
718 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000719#elif defined(IA64)
Roland McGrath08267b82004-02-20 22:56:43 +0000720 if (ia32) {
721 switch (new) {
722 case 2: break; /* x86 SYS_fork */
723 case SYS_clone: new = 120; break;
724 default:
725 fprintf(stderr, "%s: unexpected syscall %d\n",
726 __FUNCTION__, new);
727 return -1;
728 }
729 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
730 return -1;
731 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000732 return -1;
733 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000734#elif defined(HPPA)
735 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
736 return -1;
737 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000738#elif defined(SH)
Roland McGrathac971c22003-03-31 01:03:33 +0000739 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
Wichert Akkermanccef6372002-05-01 16:39:22 +0000740 return -1;
741 return 0;
Roland McGrathf5a47772003-06-26 22:40:42 +0000742#elif defined(SH64)
Roland McGrathe1e584b2003-06-02 19:18:58 +0000743 /* Top half of reg encodes the no. of args n as 0x1n.
744 Assume 0 args as kernel never actually checks... */
745 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
746 0x100000 | new) < 0)
747 return -1;
748 return 0;
Roland McGrathf691bd22006-04-25 07:34:41 +0000749#elif defined(ARM)
750 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
751# ifndef PTRACE_SET_SYSCALL
752# define PTRACE_SET_SYSCALL 23
753# endif
754
755 if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new) != 0)
756 return -1;
757
758 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000759#else
760#warning Do not know how to handle change_syscall for this architecture
761#endif /* architecture */
762#endif /* LINUX */
763 return -1;
764}
765
Roland McGratha4d48532005-06-08 20:45:28 +0000766#if 0
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000767int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000768setarg(tcp, argnum)
769 struct tcb *tcp;
770 int argnum;
771{
772#if defined (IA64)
773 {
774 unsigned long *bsp, *ap;
775
776 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
777 return -1;
778
779 ap = ia64_rse_skip_regs(bsp, argnum);
780 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000781 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000782 if (errno)
783 return -1;
784
785 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000786#elif defined(I386)
787 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000788 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000789 if (errno)
790 return -1;
791 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000792#elif defined(X86_64)
793 {
794 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
795 if (errno)
796 return -1;
797 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000798#elif defined(POWERPC)
799#ifndef PT_ORIG_R3
800#define PT_ORIG_R3 34
801#endif
802 {
803 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000804 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000805 tcp->u_arg[argnum]);
806 if (errno)
807 return -1;
808 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000809#elif defined(MIPS)
810 {
811 errno = 0;
812 if (argnum < 4)
813 ptrace(PTRACE_POKEUSER, tcp->pid,
814 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
815 else {
816 unsigned long *sp;
817
818 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
819 return -1;
820
821 ptrace(PTRACE_POKEDATA, tcp->pid,
822 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
823 }
824 if (errno)
825 return -1;
826 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000827#elif defined(S390) || defined(S390X)
828 {
829 if(argnum <= 5)
830 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000831 (char *) (argnum==0 ? PT_ORIGGPR2 :
832 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000833 tcp->u_arg[argnum]);
834 else
835 return -E2BIG;
836 if (errno)
837 return -1;
838 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000839#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000840# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000841#endif
842 return 0;
843}
Roland McGratha4d48532005-06-08 20:45:28 +0000844#endif
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000845
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000846#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000847int
848internal_clone(tcp)
849struct tcb *tcp;
850{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000851 struct tcb *tcpchild;
852 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000853 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000854 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000855 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000856 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000857 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000858 if (setbpt(tcp) < 0)
859 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000860 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000861 int bpt = tcp->flags & TCB_BPTSET;
862
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000863 if (!(tcp->flags & TCB_FOLLOWFORK))
864 return 0;
865
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000866 if (syserror(tcp)) {
867 if (bpt)
868 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000869 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000870 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000871
872 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000873
874#ifdef CLONE_PTRACE /* See new setbpt code. */
875 tcpchild = pid2tcb(pid);
876 if (tcpchild != NULL) {
877 /* The child already reported its startup trap
878 before the parent reported its syscall return. */
879 if ((tcpchild->flags
880 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
881 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
882 fprintf(stderr, "\
883[preattached child %d of %d in weird state!]\n",
884 pid, tcp->pid);
885 }
886 else
887#endif
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000888 if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000889 if (bpt)
890 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000891 kill(pid, SIGKILL); /* XXX */
892 return 0;
893 }
894
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000895#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000896 /* Attach to the new child */
897 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000898 if (bpt)
899 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000900 perror("PTRACE_ATTACH");
901 fprintf(stderr, "Too late?\n");
902 droptcb(tcpchild);
903 return 0;
904 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000905#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000906
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000907 if (bpt)
908 clearbpt(tcp);
909
Ulrich Drepper90512f01999-12-24 07:22:25 +0000910 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000911 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000912 if (bpt) {
913 tcpchild->flags |= TCB_BPTSET;
914 tcpchild->baddr = tcp->baddr;
915 memcpy(tcpchild->inst, tcp->inst,
916 sizeof tcpchild->inst);
917 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000918 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000919 tcp->nchildren++;
920 if (tcpchild->flags & TCB_SUSPENDED) {
921 /* The child was born suspended, due to our having
922 forced CLONE_PTRACE. */
923 if (bpt)
924 clearbpt(tcpchild);
925
926 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
927 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
928 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
929 return -1;
930 }
931
932 if (!qflag)
933 fprintf(stderr, "\
934Process %u resumed (parent %d ready)\n",
935 pid, tcp->pid);
936 }
937 else {
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000938 if (!qflag)
939 fprintf(stderr, "Process %d attached\n", pid);
940 }
941
942#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000943 {
944 /*
945 * Save the flags used in this call,
946 * in case we point TCP to our parent below.
947 */
948 int call_flags = tcp->u_arg[ARG_FLAGS];
949 if ((tcp->flags & TCB_CLONE_THREAD) &&
950 tcp->parent != NULL) {
951 /* The parent in this clone is itself a
952 thread belonging to another process.
953 There is no meaning to the parentage
954 relationship of the new child with the
955 thread, only with the process. We
956 associate the new thread with our
957 parent. Since this is done for every
958 new thread, there will never be a
959 TCB_CLONE_THREAD process that has
960 children. */
961 --tcp->nchildren;
962 tcp = tcp->parent;
963 tcpchild->parent = tcp;
964 ++tcp->nchildren;
965 }
966 if (call_flags & CLONE_THREAD) {
967 tcpchild->flags |= TCB_CLONE_THREAD;
968 ++tcp->nclone_threads;
969 }
970 if (call_flags & CLONE_DETACHED) {
971 tcpchild->flags |= TCB_CLONE_DETACHED;
972 ++tcp->nclone_detached;
973 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000974 }
975#endif
976
977 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000978 return 0;
979}
980#endif
981
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000982int
983internal_fork(tcp)
984struct tcb *tcp;
985{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000986#ifdef LINUX
987 /* We do special magic with clone for any clone or fork. */
988 return internal_clone(tcp);
989#else
990
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000991 struct tcb *tcpchild;
992 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000993 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000994
995#ifdef SYS_vfork
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000996 if (known_scno(tcp) == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000997 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath41c48222008-07-18 00:25:10 +0000998 if (change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000999 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +00001000 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001001#endif
1002 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +00001003 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001004 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +00001005 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001006 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001007 if (setbpt(tcp) < 0)
1008 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +00001009 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001010 else {
1011 int bpt = tcp->flags & TCB_BPTSET;
1012
1013 if (!(tcp->flags & TCB_FOLLOWFORK))
1014 return 0;
1015 if (bpt)
1016 clearbpt(tcp);
1017
1018 if (syserror(tcp))
1019 return 0;
1020
1021 pid = tcp->u_rval;
Dmitry V. Levin76860f62006-10-11 22:55:25 +00001022 if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001023 kill(pid, SIGKILL); /* XXX */
1024 return 0;
1025 }
1026#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +00001027#ifdef HPPA
1028 /* The child must have run before it can be attached. */
1029 /* This must be a bug in the parisc kernel, but I havn't
1030 * identified it yet. Seems to be an issue associated
1031 * with attaching to a process (which sends it a signal)
1032 * before that process has ever been scheduled. When
1033 * debugging, I started seeing crashes in
1034 * arch/parisc/kernel/signal.c:do_signal(), apparently
1035 * caused by r8 getting corrupt over the dequeue_signal()
1036 * call. Didn't make much sense though...
1037 */
1038 {
1039 struct timeval tv;
1040 tv.tv_sec = 0;
1041 tv.tv_usec = 10000;
1042 select(0, NULL, NULL, NULL, &tv);
1043 }
1044#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001045 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
1046 perror("PTRACE_ATTACH");
1047 fprintf(stderr, "Too late?\n");
1048 droptcb(tcpchild);
1049 return 0;
1050 }
1051#endif /* LINUX */
1052#ifdef SUNOS4
1053#ifdef oldway
1054 /* The child must have run before it can be attached. */
1055 {
1056 struct timeval tv;
1057 tv.tv_sec = 0;
1058 tv.tv_usec = 10000;
1059 select(0, NULL, NULL, NULL, &tv);
1060 }
1061 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1062 perror("PTRACE_ATTACH");
1063 fprintf(stderr, "Too late?\n");
1064 droptcb(tcpchild);
1065 return 0;
1066 }
1067#else /* !oldway */
1068 /* Try to catch the new process as soon as possible. */
1069 {
1070 int i;
1071 for (i = 0; i < 1024; i++)
1072 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1073 break;
1074 if (i == 1024) {
1075 perror("PTRACE_ATTACH");
1076 fprintf(stderr, "Too late?\n");
1077 droptcb(tcpchild);
1078 return 0;
1079 }
1080 }
1081#endif /* !oldway */
1082#endif /* SUNOS4 */
1083 tcpchild->flags |= TCB_ATTACHED;
1084 /* Child has BPT too, must be removed on first occasion */
1085 if (bpt) {
1086 tcpchild->flags |= TCB_BPTSET;
1087 tcpchild->baddr = tcp->baddr;
1088 memcpy(tcpchild->inst, tcp->inst,
1089 sizeof tcpchild->inst);
1090 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001091 tcpchild->parent = tcp;
1092 tcp->nchildren++;
1093 if (!qflag)
1094 fprintf(stderr, "Process %d attached\n", pid);
1095 }
1096 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001097#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001098}
1099
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001100#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001101
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001102#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001103
1104int
1105sys_vfork(tcp)
1106struct tcb *tcp;
1107{
1108 if (exiting(tcp))
1109 return RVAL_UDECIMAL;
1110 return 0;
1111}
1112
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001113#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001114
1115#ifndef LINUX
1116
1117static char idstr[16];
1118
1119int
1120sys_getpid(tcp)
1121struct tcb *tcp;
1122{
1123 if (exiting(tcp)) {
1124 sprintf(idstr, "ppid %lu", getrval2(tcp));
1125 tcp->auxstr = idstr;
1126 return RVAL_STR;
1127 }
1128 return 0;
1129}
1130
1131int
1132sys_getuid(tcp)
1133struct tcb *tcp;
1134{
1135 if (exiting(tcp)) {
1136 sprintf(idstr, "euid %lu", getrval2(tcp));
1137 tcp->auxstr = idstr;
1138 return RVAL_STR;
1139 }
1140 return 0;
1141}
1142
1143int
1144sys_getgid(tcp)
1145struct tcb *tcp;
1146{
1147 if (exiting(tcp)) {
1148 sprintf(idstr, "egid %lu", getrval2(tcp));
1149 tcp->auxstr = idstr;
1150 return RVAL_STR;
1151 }
1152 return 0;
1153}
1154
1155#endif /* !LINUX */
1156
1157#ifdef LINUX
1158
1159int
1160sys_setuid(tcp)
1161struct tcb *tcp;
1162{
1163 if (entering(tcp)) {
1164 tprintf("%u", (uid_t) tcp->u_arg[0]);
1165 }
1166 return 0;
1167}
1168
1169int
1170sys_setgid(tcp)
1171struct tcb *tcp;
1172{
1173 if (entering(tcp)) {
1174 tprintf("%u", (gid_t) tcp->u_arg[0]);
1175 }
1176 return 0;
1177}
1178
1179int
1180sys_getresuid(tcp)
1181 struct tcb *tcp;
1182{
1183 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001184 __kernel_uid_t uid;
1185 if (syserror(tcp))
1186 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1187 tcp->u_arg[1], tcp->u_arg[2]);
1188 else {
1189 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1190 tprintf("%#lx, ", tcp->u_arg[0]);
1191 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001192 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001193 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1194 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001195 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001196 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001197 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1198 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001199 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001200 tprintf("[%lu]", (unsigned long) uid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001201 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001202 }
1203 return 0;
1204}
1205
1206int
1207sys_getresgid(tcp)
1208struct tcb *tcp;
1209{
1210 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001211 __kernel_gid_t gid;
1212 if (syserror(tcp))
1213 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1214 tcp->u_arg[1], tcp->u_arg[2]);
1215 else {
1216 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1217 tprintf("%#lx, ", tcp->u_arg[0]);
1218 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001219 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001220 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1221 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001222 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001223 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001224 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1225 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001226 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001227 tprintf("[%lu]", (unsigned long) gid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001228 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001229 }
1230 return 0;
1231}
1232
1233#endif /* LINUX */
1234
1235int
1236sys_setreuid(tcp)
1237struct tcb *tcp;
1238{
1239 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001240 printuid("", tcp->u_arg[0]);
1241 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001242 }
1243 return 0;
1244}
1245
1246int
1247sys_setregid(tcp)
1248struct tcb *tcp;
1249{
1250 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001251 printuid("", tcp->u_arg[0]);
1252 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001253 }
1254 return 0;
1255}
1256
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001257#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001258int
1259sys_setresuid(tcp)
1260 struct tcb *tcp;
1261{
1262 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001263 printuid("", tcp->u_arg[0]);
1264 printuid(", ", tcp->u_arg[1]);
1265 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001266 }
1267 return 0;
1268}
1269int
1270sys_setresgid(tcp)
1271 struct tcb *tcp;
1272{
1273 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001274 printuid("", tcp->u_arg[0]);
1275 printuid(", ", tcp->u_arg[1]);
1276 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001277 }
1278 return 0;
1279}
1280
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001281#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001282
1283int
1284sys_setgroups(tcp)
1285struct tcb *tcp;
1286{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001287 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001288 unsigned long len, size, start, cur, end, abbrev_end;
1289 GETGROUPS_T gid;
1290 int failed = 0;
1291
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001292 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001293 tprintf("%lu, ", len);
1294 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001295 tprintf("[]");
1296 return 0;
1297 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001298 start = tcp->u_arg[1];
1299 if (start == 0) {
1300 tprintf("NULL");
1301 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001302 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001303 size = len * sizeof(gid);
1304 end = start + size;
1305 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1306 tprintf("%#lx", start);
1307 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001308 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001309 if (abbrev(tcp)) {
1310 abbrev_end = start + max_strlen * sizeof(gid);
1311 if (abbrev_end < start)
1312 abbrev_end = end;
1313 } else {
1314 abbrev_end = end;
1315 }
1316 tprintf("[");
1317 for (cur = start; cur < end; cur += sizeof(gid)) {
1318 if (cur > start)
1319 tprintf(", ");
1320 if (cur >= abbrev_end) {
1321 tprintf("...");
1322 break;
1323 }
1324 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1325 tprintf("?");
1326 failed = 1;
1327 break;
1328 }
1329 tprintf("%lu", (unsigned long) gid);
1330 }
1331 tprintf("]");
1332 if (failed)
1333 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001334 }
1335 return 0;
1336}
1337
1338int
1339sys_getgroups(tcp)
1340struct tcb *tcp;
1341{
Roland McGrathaa524c82005-06-01 19:22:06 +00001342 unsigned long len;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001343
1344 if (entering(tcp)) {
1345 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001346 tprintf("%lu, ", len);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001347 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001348 unsigned long size, start, cur, end, abbrev_end;
1349 GETGROUPS_T gid;
1350 int failed = 0;
1351
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001352 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001353 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001354 tprintf("[]");
1355 return 0;
1356 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001357 start = tcp->u_arg[1];
1358 if (start == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001359 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001360 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001361 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001362 if (tcp->u_arg[0] == 0) {
1363 tprintf("%#lx", start);
1364 return 0;
1365 }
1366 size = len * sizeof(gid);
1367 end = start + size;
1368 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1369 size / sizeof(gid) != len || end < start) {
1370 tprintf("%#lx", start);
1371 return 0;
1372 }
1373 if (abbrev(tcp)) {
1374 abbrev_end = start + max_strlen * sizeof(gid);
1375 if (abbrev_end < start)
1376 abbrev_end = end;
1377 } else {
1378 abbrev_end = end;
1379 }
1380 tprintf("[");
1381 for (cur = start; cur < end; cur += sizeof(gid)) {
1382 if (cur > start)
1383 tprintf(", ");
1384 if (cur >= abbrev_end) {
1385 tprintf("...");
1386 break;
1387 }
1388 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1389 tprintf("?");
1390 failed = 1;
1391 break;
1392 }
1393 tprintf("%lu", (unsigned long) gid);
1394 }
1395 tprintf("]");
1396 if (failed)
1397 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001398 }
1399 return 0;
1400}
1401
Roland McGrath83bd47a2003-11-13 22:32:26 +00001402#ifdef LINUX
1403int
1404sys_setgroups32(tcp)
1405struct tcb *tcp;
1406{
Roland McGrath83bd47a2003-11-13 22:32:26 +00001407 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001408 unsigned long len, size, start, cur, end, abbrev_end;
1409 GETGROUPS32_T gid;
1410 int failed = 0;
1411
Roland McGrath83bd47a2003-11-13 22:32:26 +00001412 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001413 tprintf("%lu, ", len);
1414 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001415 tprintf("[]");
1416 return 0;
1417 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001418 start = tcp->u_arg[1];
1419 if (start == 0) {
1420 tprintf("NULL");
1421 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001422 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001423 size = len * sizeof(gid);
1424 end = start + size;
1425 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1426 tprintf("%#lx", start);
1427 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001428 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001429 if (abbrev(tcp)) {
1430 abbrev_end = start + max_strlen * sizeof(gid);
1431 if (abbrev_end < start)
1432 abbrev_end = end;
1433 } else {
1434 abbrev_end = end;
1435 }
1436 tprintf("[");
1437 for (cur = start; cur < end; cur += sizeof(gid)) {
1438 if (cur > start)
1439 tprintf(", ");
1440 if (cur >= abbrev_end) {
1441 tprintf("...");
1442 break;
1443 }
1444 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1445 tprintf("?");
1446 failed = 1;
1447 break;
1448 }
1449 tprintf("%lu", (unsigned long) gid);
1450 }
1451 tprintf("]");
1452 if (failed)
1453 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001454 }
1455 return 0;
1456}
1457
1458int
1459sys_getgroups32(tcp)
1460struct tcb *tcp;
1461{
Roland McGrathaa524c82005-06-01 19:22:06 +00001462 unsigned long len;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001463
1464 if (entering(tcp)) {
1465 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001466 tprintf("%lu, ", len);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001467 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001468 unsigned long size, start, cur, end, abbrev_end;
1469 GETGROUPS32_T gid;
1470 int failed = 0;
1471
Roland McGrath83bd47a2003-11-13 22:32:26 +00001472 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001473 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001474 tprintf("[]");
1475 return 0;
1476 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001477 start = tcp->u_arg[1];
1478 if (start == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001479 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001480 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001481 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001482 size = len * sizeof(gid);
1483 end = start + size;
1484 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1485 size / sizeof(gid) != len || end < start) {
1486 tprintf("%#lx", start);
1487 return 0;
1488 }
1489 if (abbrev(tcp)) {
1490 abbrev_end = start + max_strlen * sizeof(gid);
1491 if (abbrev_end < start)
1492 abbrev_end = end;
1493 } else {
1494 abbrev_end = end;
1495 }
1496 tprintf("[");
1497 for (cur = start; cur < end; cur += sizeof(gid)) {
1498 if (cur > start)
1499 tprintf(", ");
1500 if (cur >= abbrev_end) {
1501 tprintf("...");
1502 break;
1503 }
1504 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1505 tprintf("?");
1506 failed = 1;
1507 break;
1508 }
1509 tprintf("%lu", (unsigned long) gid);
1510 }
1511 tprintf("]");
1512 if (failed)
1513 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001514 }
1515 return 0;
1516}
1517#endif /* LINUX */
1518
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001519#if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001520int
1521sys_setpgrp(tcp)
1522struct tcb *tcp;
1523{
1524 if (entering(tcp)) {
1525#ifndef SVR4
1526 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1527#endif /* !SVR4 */
1528 }
1529 return 0;
1530}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001531#endif /* ALPHA || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001532
1533int
1534sys_getpgrp(tcp)
1535struct tcb *tcp;
1536{
1537 if (entering(tcp)) {
1538#ifndef SVR4
1539 tprintf("%lu", tcp->u_arg[0]);
1540#endif /* !SVR4 */
1541 }
1542 return 0;
1543}
1544
1545int
1546sys_getsid(tcp)
1547struct tcb *tcp;
1548{
1549 if (entering(tcp)) {
1550 tprintf("%lu", tcp->u_arg[0]);
1551 }
1552 return 0;
1553}
1554
1555int
1556sys_setsid(tcp)
1557struct tcb *tcp;
1558{
1559 return 0;
1560}
1561
1562int
1563sys_getpgid(tcp)
1564struct tcb *tcp;
1565{
1566 if (entering(tcp)) {
1567 tprintf("%lu", tcp->u_arg[0]);
1568 }
1569 return 0;
1570}
1571
1572int
1573sys_setpgid(tcp)
1574struct tcb *tcp;
1575{
1576 if (entering(tcp)) {
1577 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1578 }
1579 return 0;
1580}
1581
John Hughesc61eb3d2002-05-17 11:37:50 +00001582#if UNIXWARE >= 2
1583
1584#include <sys/privilege.h>
1585
1586
Roland McGrathd9f816f2004-09-04 03:39:20 +00001587static const struct xlat procpriv_cmds [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001588 { SETPRV, "SETPRV" },
1589 { CLRPRV, "CLRPRV" },
1590 { PUTPRV, "PUTPRV" },
1591 { GETPRV, "GETPRV" },
1592 { CNTPRV, "CNTPRV" },
1593 { 0, NULL },
1594};
1595
1596
Roland McGrathd9f816f2004-09-04 03:39:20 +00001597static const struct xlat procpriv_priv [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001598 { P_OWNER, "P_OWNER" },
1599 { P_AUDIT, "P_AUDIT" },
1600 { P_COMPAT, "P_COMPAT" },
1601 { P_DACREAD, "P_DACREAD" },
1602 { P_DACWRITE, "P_DACWRITE" },
1603 { P_DEV, "P_DEV" },
1604 { P_FILESYS, "P_FILESYS" },
1605 { P_MACREAD, "P_MACREAD" },
1606 { P_MACWRITE, "P_MACWRITE" },
1607 { P_MOUNT, "P_MOUNT" },
1608 { P_MULTIDIR, "P_MULTIDIR" },
1609 { P_SETPLEVEL, "P_SETPLEVEL" },
1610 { P_SETSPRIV, "P_SETSPRIV" },
1611 { P_SETUID, "P_SETUID" },
1612 { P_SYSOPS, "P_SYSOPS" },
1613 { P_SETUPRIV, "P_SETUPRIV" },
1614 { P_DRIVER, "P_DRIVER" },
1615 { P_RTIME, "P_RTIME" },
1616 { P_MACUPGRADE, "P_MACUPGRADE" },
1617 { P_FSYSRANGE, "P_FSYSRANGE" },
1618 { P_SETFLEVEL, "P_SETFLEVEL" },
1619 { P_AUDITWR, "P_AUDITWR" },
1620 { P_TSHAR, "P_TSHAR" },
1621 { P_PLOCK, "P_PLOCK" },
1622 { P_CORE, "P_CORE" },
1623 { P_LOADMOD, "P_LOADMOD" },
1624 { P_BIND, "P_BIND" },
1625 { P_ALLPRIVS, "P_ALLPRIVS" },
1626 { 0, NULL },
1627};
1628
1629
Roland McGrathd9f816f2004-09-04 03:39:20 +00001630static const struct xlat procpriv_type [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001631 { PS_FIX, "PS_FIX" },
1632 { PS_INH, "PS_INH" },
1633 { PS_MAX, "PS_MAX" },
1634 { PS_WKG, "PS_WKG" },
1635 { 0, NULL },
1636};
1637
1638
1639static void
Dmitry V. Levinab9008b2007-01-11 22:05:04 +00001640printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
John Hughesc61eb3d2002-05-17 11:37:50 +00001641{
1642 priv_t buf [128];
1643 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1644 int dots = len > max;
1645 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001646
John Hughesc61eb3d2002-05-17 11:37:50 +00001647 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001648
John Hughesc61eb3d2002-05-17 11:37:50 +00001649 if (len <= 0 ||
1650 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1651 {
1652 tprintf ("%#lx", addr);
1653 return;
1654 }
1655
1656 tprintf ("[");
1657
1658 for (i = 0; i < len; ++i) {
Dmitry V. Levinab9008b2007-01-11 22:05:04 +00001659 const char *t, *p;
John Hughesc61eb3d2002-05-17 11:37:50 +00001660
1661 if (i) tprintf (", ");
1662
1663 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1664 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1665 {
1666 tprintf ("%s|%s", t, p);
1667 }
1668 else {
1669 tprintf ("%#lx", buf [i]);
1670 }
1671 }
1672
1673 if (dots) tprintf (" ...");
1674
1675 tprintf ("]");
1676}
1677
1678
1679int
1680sys_procpriv(tcp)
1681struct tcb *tcp;
1682{
1683 if (entering(tcp)) {
1684 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1685 switch (tcp->u_arg[0]) {
1686 case CNTPRV:
1687 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1688 break;
1689
1690 case GETPRV:
1691 break;
1692
1693 default:
1694 tprintf (", ");
1695 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1696 tprintf (", %ld", tcp->u_arg[2]);
1697 }
1698 }
1699 else if (tcp->u_arg[0] == GETPRV) {
1700 if (syserror (tcp)) {
1701 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1702 }
1703 else {
1704 tprintf (", ");
1705 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1706 tprintf (", %ld", tcp->u_arg[2]);
1707 }
1708 }
Roland McGrath5a223472002-12-15 23:58:26 +00001709
John Hughesc61eb3d2002-05-17 11:37:50 +00001710 return 0;
1711}
1712
1713#endif
1714
1715
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001716static void
1717printargv(tcp, addr)
1718struct tcb *tcp;
1719long addr;
1720{
Roland McGrath85a3bc42007-08-02 02:13:05 +00001721 union {
1722 int p32;
1723 long p64;
1724 char data[sizeof(long)];
1725 } cp;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001726 char *sep;
Roland McGrath85a3bc42007-08-02 02:13:05 +00001727 int n = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001728
Roland McGrath85a3bc42007-08-02 02:13:05 +00001729 cp.p64 = 1;
1730 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1731 if (umoven(tcp, addr, personality_wordsize[current_personality],
1732 cp.data) < 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001733 tprintf("%#lx", addr);
1734 return;
1735 }
Roland McGrath85a3bc42007-08-02 02:13:05 +00001736 if (personality_wordsize[current_personality] == 4)
1737 cp.p64 = cp.p32;
1738 if (cp.p64 == 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001739 break;
1740 tprintf(sep);
Roland McGrath85a3bc42007-08-02 02:13:05 +00001741 printstr(tcp, cp.p64, -1);
1742 addr += personality_wordsize[current_personality];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001743 }
Roland McGrath85a3bc42007-08-02 02:13:05 +00001744 if (cp.p64)
1745 tprintf("%s...", sep);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001746}
1747
1748static void
1749printargc(fmt, tcp, addr)
1750char *fmt;
1751struct tcb *tcp;
1752long addr;
1753{
1754 int count;
1755 char *cp;
1756
1757 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1758 addr += sizeof(char *);
1759 }
1760 tprintf(fmt, count, count == 1 ? "" : "s");
1761}
1762
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001763#if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001764int
1765sys_execv(tcp)
1766struct tcb *tcp;
1767{
1768 if (entering(tcp)) {
1769 printpath(tcp, tcp->u_arg[0]);
1770 if (!verbose(tcp))
1771 tprintf(", %#lx", tcp->u_arg[1]);
1772#if 0
1773 else if (abbrev(tcp))
1774 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1775#endif
1776 else {
1777 tprintf(", [");
1778 printargv(tcp, tcp->u_arg[1]);
1779 tprintf("]");
1780 }
1781 }
1782 return 0;
1783}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001784#endif /* SPARC || SPARC64 || SUNOS4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001785
1786int
1787sys_execve(tcp)
1788struct tcb *tcp;
1789{
1790 if (entering(tcp)) {
1791 printpath(tcp, tcp->u_arg[0]);
1792 if (!verbose(tcp))
1793 tprintf(", %#lx", tcp->u_arg[1]);
1794#if 0
1795 else if (abbrev(tcp))
1796 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1797#endif
1798 else {
1799 tprintf(", [");
1800 printargv(tcp, tcp->u_arg[1]);
1801 tprintf("]");
1802 }
1803 if (!verbose(tcp))
1804 tprintf(", %#lx", tcp->u_arg[2]);
1805 else if (abbrev(tcp))
1806 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1807 else {
1808 tprintf(", [");
1809 printargv(tcp, tcp->u_arg[2]);
1810 tprintf("]");
1811 }
1812 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001813 return 0;
1814}
1815
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001816#if UNIXWARE > 2
John Hughes4e36a812001-04-18 15:11:51 +00001817
1818int sys_rexecve(tcp)
1819struct tcb *tcp;
1820{
1821 if (entering (tcp)) {
1822 sys_execve (tcp);
1823 tprintf (", %ld", tcp->u_arg[3]);
1824 }
1825 return 0;
1826}
1827
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001828#endif
John Hughes4e36a812001-04-18 15:11:51 +00001829
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001830int
1831internal_exec(tcp)
1832struct tcb *tcp;
1833{
1834#ifdef SUNOS4
1835 if (exiting(tcp) && !syserror(tcp) && followfork)
1836 fixvfork(tcp);
1837#endif /* SUNOS4 */
Roland McGrathfdb097f2004-07-12 07:38:55 +00001838#if defined LINUX && defined TCB_WAITEXECVE
1839 if (exiting(tcp) && syserror(tcp))
1840 tcp->flags &= ~TCB_WAITEXECVE;
1841 else
1842 tcp->flags |= TCB_WAITEXECVE;
1843#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001844 return 0;
1845}
1846
1847#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001848#ifndef __WNOTHREAD
1849#define __WNOTHREAD 0x20000000
1850#endif
1851#ifndef __WALL
1852#define __WALL 0x40000000
1853#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001854#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001855#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001856#endif
1857#endif /* LINUX */
1858
Roland McGrathd9f816f2004-09-04 03:39:20 +00001859static const struct xlat wait4_options[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001860 { WNOHANG, "WNOHANG" },
1861#ifndef WSTOPPED
1862 { WUNTRACED, "WUNTRACED" },
1863#endif
1864#ifdef WEXITED
1865 { WEXITED, "WEXITED" },
1866#endif
1867#ifdef WTRAPPED
1868 { WTRAPPED, "WTRAPPED" },
1869#endif
1870#ifdef WSTOPPED
1871 { WSTOPPED, "WSTOPPED" },
1872#endif
1873#ifdef WCONTINUED
1874 { WCONTINUED, "WCONTINUED" },
1875#endif
1876#ifdef WNOWAIT
1877 { WNOWAIT, "WNOWAIT" },
1878#endif
1879#ifdef __WCLONE
1880 { __WCLONE, "__WCLONE" },
1881#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001882#ifdef __WALL
1883 { __WALL, "__WALL" },
1884#endif
1885#ifdef __WNOTHREAD
1886 { __WNOTHREAD, "__WNOTHREAD" },
1887#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001888 { 0, NULL },
1889};
1890
Roland McGrath5e02a572004-10-19 23:33:47 +00001891#if !defined WCOREFLAG && defined WCOREFLG
1892# define WCOREFLAG WCOREFLG
1893#endif
1894#ifndef WCOREFLAG
1895#define WCOREFLAG 0x80
1896#endif
1897
1898#ifndef W_STOPCODE
1899#define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1900#endif
1901#ifndef W_EXITCODE
1902#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1903#endif
1904
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001905static int
1906printstatus(status)
1907int status;
1908{
1909 int exited = 0;
1910
1911 /*
1912 * Here is a tricky presentation problem. This solution
1913 * is still not entirely satisfactory but since there
1914 * are no wait status constructors it will have to do.
1915 */
Roland McGrath79fbda52004-04-14 02:45:55 +00001916 if (WIFSTOPPED(status)) {
1917 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001918 signame(WSTOPSIG(status)));
Roland McGrath79fbda52004-04-14 02:45:55 +00001919 status &= ~W_STOPCODE(WSTOPSIG(status));
1920 }
1921 else if (WIFSIGNALED(status)) {
1922 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001923 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001924 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
Roland McGrath79fbda52004-04-14 02:45:55 +00001925 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1926 }
1927 else if (WIFEXITED(status)) {
1928 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001929 WEXITSTATUS(status));
1930 exited = 1;
Roland McGrath79fbda52004-04-14 02:45:55 +00001931 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001932 }
Roland McGrath79fbda52004-04-14 02:45:55 +00001933 else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001934 tprintf("[%#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001935 return 0;
1936 }
1937
1938 if (status == 0)
1939 tprintf("]");
1940 else
Roland McGrathf8cc83c2004-06-04 01:24:07 +00001941 tprintf(" | %#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001942
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001943 return exited;
1944}
1945
1946static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001947printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001948struct tcb *tcp;
1949int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001950int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001951{
1952 int status;
1953 int exited = 0;
1954
1955 if (entering(tcp)) {
Roland McGrath5b63d962008-07-18 02:16:47 +00001956 /*
1957 * Sign-extend a 32-bit value when that's what it is.
1958 */
1959 long pid = tcp->u_arg[0];
1960 if (personality_wordsize[current_personality] < sizeof pid)
1961 pid = (long) (int) pid;
1962 tprintf("%ld, ", pid);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001963 } else {
1964 /* status */
1965 if (!tcp->u_arg[1])
1966 tprintf("NULL");
1967 else if (syserror(tcp) || tcp->u_rval == 0)
1968 tprintf("%#lx", tcp->u_arg[1]);
1969 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1970 tprintf("[?]");
1971 else
1972 exited = printstatus(status);
1973 /* options */
1974 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00001975 printflags(wait4_options, tcp->u_arg[2], "W???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001976 if (n == 4) {
1977 tprintf(", ");
1978 /* usage */
1979 if (!tcp->u_arg[3])
1980 tprintf("NULL");
1981#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001982 else if (tcp->u_rval > 0) {
1983#ifdef LINUX_64BIT
1984 if (bitness)
1985 printrusage32(tcp, tcp->u_arg[3]);
1986 else
1987#endif
1988 printrusage(tcp, tcp->u_arg[3]);
1989 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001990#endif /* LINUX */
1991#ifdef SUNOS4
1992 else if (tcp->u_rval > 0 && exited)
1993 printrusage(tcp, tcp->u_arg[3]);
1994#endif /* SUNOS4 */
1995 else
1996 tprintf("%#lx", tcp->u_arg[3]);
1997 }
1998 }
1999 return 0;
2000}
2001
2002int
Roland McGrathc74c0b72004-09-01 19:39:46 +00002003internal_wait(tcp, flagarg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002004struct tcb *tcp;
Roland McGrathc74c0b72004-09-01 19:39:46 +00002005int flagarg;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002006{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002007 int got_kids;
2008
2009#ifdef TCB_CLONE_THREAD
2010 if (tcp->flags & TCB_CLONE_THREAD)
2011 /* The children we wait for are our parent's children. */
2012 got_kids = (tcp->parent->nchildren
2013 > tcp->parent->nclone_detached);
2014 else
2015 got_kids = (tcp->nchildren > tcp->nclone_detached);
2016#else
2017 got_kids = tcp->nchildren > 0;
2018#endif
2019
2020 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00002021 /* There are children that this parent should block for.
2022 But ptrace made us the parent of the traced children
2023 and the real parent will get ECHILD from the wait call.
2024
2025 XXX If we attached with strace -f -p PID, then there
2026 may be untraced dead children the parent could be reaping
2027 now, but we make him block. */
2028
2029 /* ??? WTA: fix bug with hanging children */
2030
Roland McGrathc74c0b72004-09-01 19:39:46 +00002031 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00002032 /*
2033 * There are traced children. We'll make the parent
2034 * block to avoid a false ECHILD error due to our
2035 * ptrace having stolen the children. However,
2036 * we shouldn't block if there are zombies to reap.
2037 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
2038 */
Roland McGrathfccfb942003-10-01 21:59:44 +00002039 struct tcb *child = NULL;
Roland McGrath09623452003-05-23 02:27:13 +00002040 if (tcp->nzombies > 0 &&
2041 (tcp->u_arg[0] == -1 ||
Roland McGrathfccfb942003-10-01 21:59:44 +00002042 (child = pid2tcb(tcp->u_arg[0])) == NULL))
Roland McGrath09623452003-05-23 02:27:13 +00002043 return 0;
Roland McGrathfccfb942003-10-01 21:59:44 +00002044 if (tcp->u_arg[0] > 0) {
2045 /*
2046 * If the parent waits for a specified child
2047 * PID, then it must get ECHILD right away
2048 * if that PID is not one of its children.
2049 * Make sure that the requested PID matches
2050 * one of the parent's children that we are
2051 * tracing, and don't suspend it otherwise.
2052 */
2053 if (child == NULL)
2054 child = pid2tcb(tcp->u_arg[0]);
2055 if (child == NULL || child->parent != (
2056#ifdef TCB_CLONE_THREAD
2057 (tcp->flags & TCB_CLONE_THREAD)
2058 ? tcp->parent :
2059#endif
Roland McGrathd56a6562005-08-03 11:23:43 +00002060 tcp) ||
2061 (child->flags & TCB_EXITING))
Roland McGrathfccfb942003-10-01 21:59:44 +00002062 return 0;
2063 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002064 tcp->flags |= TCB_SUSPENDED;
2065 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002066#ifdef TCB_CLONE_THREAD
2067 if (tcp->flags & TCB_CLONE_THREAD)
2068 tcp->parent->nclone_waiting++;
2069#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002070 }
2071 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002072 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathc74c0b72004-09-01 19:39:46 +00002073 if (tcp->u_arg[flagarg] & WNOHANG) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00002074 /* We must force a fake result of 0 instead of
2075 the ECHILD error. */
2076 extern int force_result();
2077 return force_result(tcp, 0, 0);
2078 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00002079 }
Roland McGrath09623452003-05-23 02:27:13 +00002080 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2081 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2082 /*
2083 * We just reaped a child we don't know about,
2084 * presumably a zombie we already droptcb'd.
2085 */
2086 tcp->nzombies--;
2087 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002088 return 0;
2089}
2090
2091#ifdef SVR4
2092
2093int
2094sys_wait(tcp)
2095struct tcb *tcp;
2096{
2097 if (exiting(tcp)) {
2098 /* The library wrapper stuffs this into the user variable. */
2099 if (!syserror(tcp))
2100 printstatus(getrval2(tcp));
2101 }
2102 return 0;
2103}
2104
2105#endif /* SVR4 */
2106
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002107#ifdef FREEBSD
2108int
2109sys_wait(tcp)
2110struct tcb *tcp;
2111{
2112 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00002113
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002114 if (exiting(tcp)) {
2115 if (!syserror(tcp)) {
2116 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2117 tprintf("%#lx", tcp->u_arg[0]);
2118 else
2119 printstatus(status);
2120 }
2121 }
2122 return 0;
2123}
2124#endif
2125
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002126int
2127sys_waitpid(tcp)
2128struct tcb *tcp;
2129{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002130 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002131}
2132
2133int
2134sys_wait4(tcp)
2135struct tcb *tcp;
2136{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002137 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002138}
2139
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002140#ifdef ALPHA
2141int
2142sys_osf_wait4(tcp)
2143struct tcb *tcp;
2144{
2145 return printwaitn(tcp, 4, 1);
2146}
2147#endif
2148
Roland McGrathc74c0b72004-09-01 19:39:46 +00002149#if defined SVR4 || defined LINUX
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002150
Roland McGrathd9f816f2004-09-04 03:39:20 +00002151static const struct xlat waitid_types[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002152 { P_PID, "P_PID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002153#ifdef P_PPID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002154 { P_PPID, "P_PPID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002155#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002156 { P_PGID, "P_PGID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002157#ifdef P_SID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002158 { P_SID, "P_SID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002159#endif
2160#ifdef P_CID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002161 { P_CID, "P_CID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002162#endif
2163#ifdef P_UID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002164 { P_UID, "P_UID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002165#endif
2166#ifdef P_GID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002167 { P_GID, "P_GID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002168#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002169 { P_ALL, "P_ALL" },
2170#ifdef P_LWPID
2171 { P_LWPID, "P_LWPID" },
2172#endif
2173 { 0, NULL },
2174};
2175
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002176int
2177sys_waitid(tcp)
2178struct tcb *tcp;
2179{
2180 siginfo_t si;
2181 int exited;
2182
2183 if (entering(tcp)) {
2184 printxval(waitid_types, tcp->u_arg[0], "P_???");
2185 tprintf(", %ld, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002186 }
2187 else {
2188 /* siginfo */
2189 exited = 0;
2190 if (!tcp->u_arg[2])
2191 tprintf("NULL");
2192 else if (syserror(tcp))
2193 tprintf("%#lx", tcp->u_arg[2]);
2194 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2195 tprintf("{???}");
2196 else
John Hughes58265892001-10-18 15:13:53 +00002197 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002198 /* options */
2199 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00002200 printflags(wait4_options, tcp->u_arg[3], "W???");
Roland McGrath39426a32004-10-06 22:02:59 +00002201 if (tcp->u_nargs > 4) {
2202 /* usage */
2203 tprintf(", ");
2204 if (!tcp->u_arg[4])
2205 tprintf("NULL");
2206 else if (tcp->u_error)
2207 tprintf("%#lx", tcp->u_arg[4]);
2208 else
2209 printrusage(tcp, tcp->u_arg[4]);
2210 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002211 }
2212 return 0;
2213}
2214
Roland McGrathc74c0b72004-09-01 19:39:46 +00002215#endif /* SVR4 or LINUX */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002216
2217int
2218sys_alarm(tcp)
2219struct tcb *tcp;
2220{
2221 if (entering(tcp))
2222 tprintf("%lu", tcp->u_arg[0]);
2223 return 0;
2224}
2225
2226int
2227sys_uname(tcp)
2228struct tcb *tcp;
2229{
2230 struct utsname uname;
2231
2232 if (exiting(tcp)) {
2233 if (syserror(tcp) || !verbose(tcp))
2234 tprintf("%#lx", tcp->u_arg[0]);
2235 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2236 tprintf("{...}");
2237 else if (!abbrev(tcp)) {
2238
2239 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2240 uname.sysname, uname.nodename);
2241 tprintf("release=\"%s\", version=\"%s\", ",
2242 uname.release, uname.version);
2243 tprintf("machine=\"%s\"", uname.machine);
2244#ifdef LINUX
2245#ifndef __GLIBC__
2246 tprintf(", domainname=\"%s\"", uname.domainname);
2247#endif /* __GLIBC__ */
2248#endif /* LINUX */
2249 tprintf("}");
2250 }
2251 else
2252 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2253 uname.sysname, uname.nodename);
2254 }
2255 return 0;
2256}
2257
2258#ifndef SVR4
2259
Roland McGrathd9f816f2004-09-04 03:39:20 +00002260static const struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002261#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002262 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2263 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2264 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2265 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2266 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2267 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2268 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2269 { PTRACE_CONT, "PTRACE_CONT" },
2270 { PTRACE_KILL, "PTRACE_KILL" },
2271 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2272 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2273 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002274#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002275 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002276#endif
2277#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002278 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002279#endif
2280#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002281 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002282#endif
2283#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002284 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002285#endif
2286#ifdef PTRACE_GETFPXREGS
2287 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2288#endif
2289#ifdef PTRACE_SETFPXREGS
2290 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2291#endif
Roland McGrathf04bb482005-05-09 07:45:33 +00002292#ifdef PTRACE_GETVRREGS
2293 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2294#endif
2295#ifdef PTRACE_SETVRREGS
2296 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2297#endif
Roland McGrathbf621d42003-01-14 09:46:21 +00002298#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002299 { PTRACE_READDATA, "PTRACE_READDATA" },
2300 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2301 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2302 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2303 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2304 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2305#ifdef SPARC
2306 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2307 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2308#else /* !SPARC */
2309 { PTRACE_22, "PTRACE_PTRACE_22" },
2310 { PTRACE_23, "PTRACE_PTRACE_23" },
2311#endif /* !SPARC */
2312#endif /* SUNOS4 */
2313 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2314#ifdef SUNOS4
2315 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2316#ifdef I386
2317 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2318 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2319 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2320#else /* !I386 */
2321 { PTRACE_26, "PTRACE_26" },
2322 { PTRACE_27, "PTRACE_27" },
2323 { PTRACE_28, "PTRACE_28" },
2324#endif /* !I386 */
2325 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2326#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002327#else /* FREEBSD */
2328 { PT_TRACE_ME, "PT_TRACE_ME" },
2329 { PT_READ_I, "PT_READ_I" },
2330 { PT_READ_D, "PT_READ_D" },
2331 { PT_WRITE_I, "PT_WRITE_I" },
2332 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002333#ifdef PT_READ_U
2334 { PT_READ_U, "PT_READ_U" },
2335#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002336 { PT_CONTINUE, "PT_CONTINUE" },
2337 { PT_KILL, "PT_KILL" },
2338 { PT_STEP, "PT_STEP" },
2339 { PT_ATTACH, "PT_ATTACH" },
2340 { PT_DETACH, "PT_DETACH" },
2341 { PT_GETREGS, "PT_GETREGS" },
2342 { PT_SETREGS, "PT_SETREGS" },
2343 { PT_GETFPREGS, "PT_GETFPREGS" },
2344 { PT_SETFPREGS, "PT_SETFPREGS" },
2345 { PT_GETDBREGS, "PT_GETDBREGS" },
2346 { PT_SETDBREGS, "PT_SETDBREGS" },
2347#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002348 { 0, NULL },
2349};
2350
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002351#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002352#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2353static
2354#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
Roland McGrathd9f816f2004-09-04 03:39:20 +00002355const struct xlat struct_user_offsets[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002356#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002357#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002358 { PT_PSWMASK, "psw_mask" },
2359 { PT_PSWADDR, "psw_addr" },
2360 { PT_GPR0, "gpr0" },
2361 { PT_GPR1, "gpr1" },
2362 { PT_GPR2, "gpr2" },
2363 { PT_GPR3, "gpr3" },
2364 { PT_GPR4, "gpr4" },
2365 { PT_GPR5, "gpr5" },
2366 { PT_GPR6, "gpr6" },
2367 { PT_GPR7, "gpr7" },
2368 { PT_GPR8, "gpr8" },
2369 { PT_GPR9, "gpr9" },
2370 { PT_GPR10, "gpr10" },
2371 { PT_GPR11, "gpr11" },
2372 { PT_GPR12, "gpr12" },
2373 { PT_GPR13, "gpr13" },
2374 { PT_GPR14, "gpr14" },
2375 { PT_GPR15, "gpr15" },
2376 { PT_ACR0, "acr0" },
2377 { PT_ACR1, "acr1" },
2378 { PT_ACR2, "acr2" },
2379 { PT_ACR3, "acr3" },
2380 { PT_ACR4, "acr4" },
2381 { PT_ACR5, "acr5" },
2382 { PT_ACR6, "acr6" },
2383 { PT_ACR7, "acr7" },
2384 { PT_ACR8, "acr8" },
2385 { PT_ACR9, "acr9" },
2386 { PT_ACR10, "acr10" },
2387 { PT_ACR11, "acr11" },
2388 { PT_ACR12, "acr12" },
2389 { PT_ACR13, "acr13" },
2390 { PT_ACR14, "acr14" },
2391 { PT_ACR15, "acr15" },
2392 { PT_ORIGGPR2, "orig_gpr2" },
2393 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002394#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002395 { PT_FPR0_HI, "fpr0.hi" },
2396 { PT_FPR0_LO, "fpr0.lo" },
2397 { PT_FPR1_HI, "fpr1.hi" },
2398 { PT_FPR1_LO, "fpr1.lo" },
2399 { PT_FPR2_HI, "fpr2.hi" },
2400 { PT_FPR2_LO, "fpr2.lo" },
2401 { PT_FPR3_HI, "fpr3.hi" },
2402 { PT_FPR3_LO, "fpr3.lo" },
2403 { PT_FPR4_HI, "fpr4.hi" },
2404 { PT_FPR4_LO, "fpr4.lo" },
2405 { PT_FPR5_HI, "fpr5.hi" },
2406 { PT_FPR5_LO, "fpr5.lo" },
2407 { PT_FPR6_HI, "fpr6.hi" },
2408 { PT_FPR6_LO, "fpr6.lo" },
2409 { PT_FPR7_HI, "fpr7.hi" },
2410 { PT_FPR7_LO, "fpr7.lo" },
2411 { PT_FPR8_HI, "fpr8.hi" },
2412 { PT_FPR8_LO, "fpr8.lo" },
2413 { PT_FPR9_HI, "fpr9.hi" },
2414 { PT_FPR9_LO, "fpr9.lo" },
2415 { PT_FPR10_HI, "fpr10.hi" },
2416 { PT_FPR10_LO, "fpr10.lo" },
2417 { PT_FPR11_HI, "fpr11.hi" },
2418 { PT_FPR11_LO, "fpr11.lo" },
2419 { PT_FPR12_HI, "fpr12.hi" },
2420 { PT_FPR12_LO, "fpr12.lo" },
2421 { PT_FPR13_HI, "fpr13.hi" },
2422 { PT_FPR13_LO, "fpr13.lo" },
2423 { PT_FPR14_HI, "fpr14.hi" },
2424 { PT_FPR14_LO, "fpr14.lo" },
2425 { PT_FPR15_HI, "fpr15.hi" },
2426 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002427#endif
2428#if defined(S390X)
2429 { PT_FPR0, "fpr0" },
2430 { PT_FPR1, "fpr1" },
2431 { PT_FPR2, "fpr2" },
2432 { PT_FPR3, "fpr3" },
2433 { PT_FPR4, "fpr4" },
2434 { PT_FPR5, "fpr5" },
2435 { PT_FPR6, "fpr6" },
2436 { PT_FPR7, "fpr7" },
2437 { PT_FPR8, "fpr8" },
2438 { PT_FPR9, "fpr9" },
2439 { PT_FPR10, "fpr10" },
2440 { PT_FPR11, "fpr11" },
2441 { PT_FPR12, "fpr12" },
2442 { PT_FPR13, "fpr13" },
2443 { PT_FPR14, "fpr14" },
2444 { PT_FPR15, "fpr15" },
2445#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002446 { PT_CR_9, "cr9" },
2447 { PT_CR_10, "cr10" },
2448 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002449 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002450#endif
2451#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002452 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002453#elif defined(HPPA)
2454 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002455#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002456#ifndef PT_ORIG_R3
2457#define PT_ORIG_R3 34
2458#endif
Roland McGratheb285352003-01-14 09:59:00 +00002459#define REGSIZE (sizeof(unsigned long))
2460 { REGSIZE*PT_R0, "r0" },
2461 { REGSIZE*PT_R1, "r1" },
2462 { REGSIZE*PT_R2, "r2" },
2463 { REGSIZE*PT_R3, "r3" },
2464 { REGSIZE*PT_R4, "r4" },
2465 { REGSIZE*PT_R5, "r5" },
2466 { REGSIZE*PT_R6, "r6" },
2467 { REGSIZE*PT_R7, "r7" },
2468 { REGSIZE*PT_R8, "r8" },
2469 { REGSIZE*PT_R9, "r9" },
2470 { REGSIZE*PT_R10, "r10" },
2471 { REGSIZE*PT_R11, "r11" },
2472 { REGSIZE*PT_R12, "r12" },
2473 { REGSIZE*PT_R13, "r13" },
2474 { REGSIZE*PT_R14, "r14" },
2475 { REGSIZE*PT_R15, "r15" },
2476 { REGSIZE*PT_R16, "r16" },
2477 { REGSIZE*PT_R17, "r17" },
2478 { REGSIZE*PT_R18, "r18" },
2479 { REGSIZE*PT_R19, "r19" },
2480 { REGSIZE*PT_R20, "r20" },
2481 { REGSIZE*PT_R21, "r21" },
2482 { REGSIZE*PT_R22, "r22" },
2483 { REGSIZE*PT_R23, "r23" },
2484 { REGSIZE*PT_R24, "r24" },
2485 { REGSIZE*PT_R25, "r25" },
2486 { REGSIZE*PT_R26, "r26" },
2487 { REGSIZE*PT_R27, "r27" },
2488 { REGSIZE*PT_R28, "r28" },
2489 { REGSIZE*PT_R29, "r29" },
2490 { REGSIZE*PT_R30, "r30" },
2491 { REGSIZE*PT_R31, "r31" },
2492 { REGSIZE*PT_NIP, "NIP" },
2493 { REGSIZE*PT_MSR, "MSR" },
2494 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2495 { REGSIZE*PT_CTR, "CTR" },
2496 { REGSIZE*PT_LNK, "LNK" },
2497 { REGSIZE*PT_XER, "XER" },
2498 { REGSIZE*PT_CCR, "CCR" },
2499 { REGSIZE*PT_FPR0, "FPR0" },
2500#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002501#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002502#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002503 { 0, "r0" },
2504 { 1, "r1" },
2505 { 2, "r2" },
2506 { 3, "r3" },
2507 { 4, "r4" },
2508 { 5, "r5" },
2509 { 6, "r6" },
2510 { 7, "r7" },
2511 { 8, "r8" },
2512 { 9, "r9" },
2513 { 10, "r10" },
2514 { 11, "r11" },
2515 { 12, "r12" },
2516 { 13, "r13" },
2517 { 14, "r14" },
2518 { 15, "r15" },
2519 { 16, "r16" },
2520 { 17, "r17" },
2521 { 18, "r18" },
2522 { 19, "r19" },
2523 { 20, "r20" },
2524 { 21, "r21" },
2525 { 22, "r22" },
2526 { 23, "r23" },
2527 { 24, "r24" },
2528 { 25, "r25" },
2529 { 26, "r26" },
2530 { 27, "r27" },
2531 { 28, "r28" },
2532 { 29, "gp" },
2533 { 30, "fp" },
2534 { 31, "zero" },
2535 { 32, "fp0" },
2536 { 33, "fp" },
2537 { 34, "fp2" },
2538 { 35, "fp3" },
2539 { 36, "fp4" },
2540 { 37, "fp5" },
2541 { 38, "fp6" },
2542 { 39, "fp7" },
2543 { 40, "fp8" },
2544 { 41, "fp9" },
2545 { 42, "fp10" },
2546 { 43, "fp11" },
2547 { 44, "fp12" },
2548 { 45, "fp13" },
2549 { 46, "fp14" },
2550 { 47, "fp15" },
2551 { 48, "fp16" },
2552 { 49, "fp17" },
2553 { 50, "fp18" },
2554 { 51, "fp19" },
2555 { 52, "fp20" },
2556 { 53, "fp21" },
2557 { 54, "fp22" },
2558 { 55, "fp23" },
2559 { 56, "fp24" },
2560 { 57, "fp25" },
2561 { 58, "fp26" },
2562 { 59, "fp27" },
2563 { 60, "fp28" },
2564 { 61, "fp29" },
2565 { 62, "fp30" },
2566 { 63, "fp31" },
2567 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002568#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002569#ifdef IA64
2570 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2571 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2572 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2573 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2574 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2575 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2576 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2577 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2578 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2579 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2580 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2581 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2582 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2583 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2584 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2585 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2586 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2587 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2588 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2589 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2590 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2591 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2592 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2593 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2594 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2595 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2596 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2597 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2598 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2599 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2600 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2601 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2602 /* switch stack: */
2603 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2604 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2605 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2606 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2607 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2608 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2609 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2610 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2611 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2612 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002613 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2614 { PT_B4, "b4" }, { PT_B5, "b5" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002615 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002616 /* pt_regs */
Roland McGrathca4e10c2004-01-13 10:13:20 +00002617 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2618 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002619 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2620 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2621 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2622 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2623 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2624 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2625 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2626 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2627 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2628 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2629 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2630 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2631 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2632 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2633 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
Roland McGrathfb1bc072004-03-01 21:29:24 +00002634# ifdef PT_AR_CSD
2635 { PT_AR_CSD, "ar.csd" },
2636# endif
2637# ifdef PT_AR_SSD
2638 { PT_AR_SSD, "ar.ssd" },
2639# endif
Roland McGrathca4e10c2004-01-13 10:13:20 +00002640 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002641#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002642#ifdef I386
2643 { 4*EBX, "4*EBX" },
2644 { 4*ECX, "4*ECX" },
2645 { 4*EDX, "4*EDX" },
2646 { 4*ESI, "4*ESI" },
2647 { 4*EDI, "4*EDI" },
2648 { 4*EBP, "4*EBP" },
2649 { 4*EAX, "4*EAX" },
2650 { 4*DS, "4*DS" },
2651 { 4*ES, "4*ES" },
2652 { 4*FS, "4*FS" },
2653 { 4*GS, "4*GS" },
2654 { 4*ORIG_EAX, "4*ORIG_EAX" },
2655 { 4*EIP, "4*EIP" },
2656 { 4*CS, "4*CS" },
2657 { 4*EFL, "4*EFL" },
2658 { 4*UESP, "4*UESP" },
2659 { 4*SS, "4*SS" },
2660#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002661#ifdef X86_64
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002662 { 8*R15, "8*R15" },
2663 { 8*R14, "8*R14" },
2664 { 8*R13, "8*R13" },
2665 { 8*R12, "8*R12" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002666 { 8*RBP, "8*RBP" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002667 { 8*RBX, "8*RBX" },
2668 { 8*R11, "8*R11" },
2669 { 8*R10, "8*R10" },
2670 { 8*R9, "8*R9" },
2671 { 8*R8, "8*R8" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002672 { 8*RAX, "8*RAX" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002673 { 8*RCX, "8*RCX" },
2674 { 8*RDX, "8*RDX" },
2675 { 8*RSI, "8*RSI" },
2676 { 8*RDI, "8*RDI" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002677#if 0
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002678 { DS, "DS" },
2679 { ES, "ES" },
2680 { FS, "FS" },
2681 { GS, "GS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002682#endif
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002683 { 8*ORIG_RAX, "8*ORIG_RAX" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002684 { 8*RIP, "8*RIP" },
2685 { 8*CS, "8*CS" },
2686 { 8*EFLAGS, "8*EFL" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002687 { 8*RSP, "8*RSP" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002688 { 8*SS, "8*SS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002689#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002690#ifdef M68K
2691 { 4*PT_D1, "4*PT_D1" },
2692 { 4*PT_D2, "4*PT_D2" },
2693 { 4*PT_D3, "4*PT_D3" },
2694 { 4*PT_D4, "4*PT_D4" },
2695 { 4*PT_D5, "4*PT_D5" },
2696 { 4*PT_D6, "4*PT_D6" },
2697 { 4*PT_D7, "4*PT_D7" },
2698 { 4*PT_A0, "4*PT_A0" },
2699 { 4*PT_A1, "4*PT_A1" },
2700 { 4*PT_A2, "4*PT_A2" },
2701 { 4*PT_A3, "4*PT_A3" },
2702 { 4*PT_A4, "4*PT_A4" },
2703 { 4*PT_A5, "4*PT_A5" },
2704 { 4*PT_A6, "4*PT_A6" },
2705 { 4*PT_D0, "4*PT_D0" },
2706 { 4*PT_USP, "4*PT_USP" },
2707 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2708 { 4*PT_SR, "4*PT_SR" },
2709 { 4*PT_PC, "4*PT_PC" },
2710#endif /* M68K */
2711#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002712#ifdef SH
2713 { 4*REG_REG0, "4*REG_REG0" },
2714 { 4*(REG_REG0+1), "4*REG_REG1" },
2715 { 4*(REG_REG0+2), "4*REG_REG2" },
2716 { 4*(REG_REG0+3), "4*REG_REG3" },
2717 { 4*(REG_REG0+4), "4*REG_REG4" },
2718 { 4*(REG_REG0+5), "4*REG_REG5" },
2719 { 4*(REG_REG0+6), "4*REG_REG6" },
2720 { 4*(REG_REG0+7), "4*REG_REG7" },
2721 { 4*(REG_REG0+8), "4*REG_REG8" },
2722 { 4*(REG_REG0+9), "4*REG_REG9" },
2723 { 4*(REG_REG0+10), "4*REG_REG10" },
2724 { 4*(REG_REG0+11), "4*REG_REG11" },
2725 { 4*(REG_REG0+12), "4*REG_REG12" },
2726 { 4*(REG_REG0+13), "4*REG_REG13" },
2727 { 4*(REG_REG0+14), "4*REG_REG14" },
2728 { 4*REG_REG15, "4*REG_REG15" },
2729 { 4*REG_PC, "4*REG_PC" },
2730 { 4*REG_PR, "4*REG_PR" },
2731 { 4*REG_SR, "4*REG_SR" },
2732 { 4*REG_GBR, "4*REG_GBR" },
2733 { 4*REG_MACH, "4*REG_MACH" },
2734 { 4*REG_MACL, "4*REG_MACL" },
2735 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2736 { 4*REG_FPUL, "4*REG_FPUL" },
2737 { 4*REG_FPREG0, "4*REG_FPREG0" },
2738 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2739 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2740 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2741 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2742 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2743 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2744 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2745 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2746 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2747 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2748 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2749 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2750 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2751 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2752 { 4*REG_FPREG15, "4*REG_FPREG15" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002753#ifdef REG_XDREG0
Wichert Akkermanccef6372002-05-01 16:39:22 +00002754 { 4*REG_XDREG0, "4*REG_XDREG0" },
2755 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2756 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2757 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2758 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2759 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2760 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2761 { 4*REG_XDREG14, "4*REG_XDREG14" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002762#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002763 { 4*REG_FPSCR, "4*REG_FPSCR" },
2764#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002765#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002766 { 0, "PC(L)" },
2767 { 4, "PC(U)" },
2768 { 8, "SR(L)" },
2769 { 12, "SR(U)" },
2770 { 16, "syscall no.(L)" },
2771 { 20, "syscall_no.(U)" },
2772 { 24, "R0(L)" },
2773 { 28, "R0(U)" },
2774 { 32, "R1(L)" },
2775 { 36, "R1(U)" },
2776 { 40, "R2(L)" },
2777 { 44, "R2(U)" },
2778 { 48, "R3(L)" },
2779 { 52, "R3(U)" },
2780 { 56, "R4(L)" },
2781 { 60, "R4(U)" },
2782 { 64, "R5(L)" },
2783 { 68, "R5(U)" },
2784 { 72, "R6(L)" },
2785 { 76, "R6(U)" },
2786 { 80, "R7(L)" },
2787 { 84, "R7(U)" },
2788 { 88, "R8(L)" },
2789 { 92, "R8(U)" },
2790 { 96, "R9(L)" },
2791 { 100, "R9(U)" },
2792 { 104, "R10(L)" },
2793 { 108, "R10(U)" },
2794 { 112, "R11(L)" },
2795 { 116, "R11(U)" },
2796 { 120, "R12(L)" },
2797 { 124, "R12(U)" },
2798 { 128, "R13(L)" },
2799 { 132, "R13(U)" },
2800 { 136, "R14(L)" },
2801 { 140, "R14(U)" },
2802 { 144, "R15(L)" },
2803 { 148, "R15(U)" },
2804 { 152, "R16(L)" },
2805 { 156, "R16(U)" },
2806 { 160, "R17(L)" },
2807 { 164, "R17(U)" },
2808 { 168, "R18(L)" },
2809 { 172, "R18(U)" },
2810 { 176, "R19(L)" },
2811 { 180, "R19(U)" },
2812 { 184, "R20(L)" },
2813 { 188, "R20(U)" },
2814 { 192, "R21(L)" },
2815 { 196, "R21(U)" },
2816 { 200, "R22(L)" },
2817 { 204, "R22(U)" },
2818 { 208, "R23(L)" },
2819 { 212, "R23(U)" },
2820 { 216, "R24(L)" },
2821 { 220, "R24(U)" },
2822 { 224, "R25(L)" },
2823 { 228, "R25(U)" },
2824 { 232, "R26(L)" },
2825 { 236, "R26(U)" },
2826 { 240, "R27(L)" },
2827 { 244, "R27(U)" },
2828 { 248, "R28(L)" },
2829 { 252, "R28(U)" },
2830 { 256, "R29(L)" },
2831 { 260, "R29(U)" },
2832 { 264, "R30(L)" },
2833 { 268, "R30(U)" },
2834 { 272, "R31(L)" },
2835 { 276, "R31(U)" },
2836 { 280, "R32(L)" },
2837 { 284, "R32(U)" },
2838 { 288, "R33(L)" },
2839 { 292, "R33(U)" },
2840 { 296, "R34(L)" },
2841 { 300, "R34(U)" },
2842 { 304, "R35(L)" },
2843 { 308, "R35(U)" },
2844 { 312, "R36(L)" },
2845 { 316, "R36(U)" },
2846 { 320, "R37(L)" },
2847 { 324, "R37(U)" },
2848 { 328, "R38(L)" },
2849 { 332, "R38(U)" },
2850 { 336, "R39(L)" },
2851 { 340, "R39(U)" },
2852 { 344, "R40(L)" },
2853 { 348, "R40(U)" },
2854 { 352, "R41(L)" },
2855 { 356, "R41(U)" },
2856 { 360, "R42(L)" },
2857 { 364, "R42(U)" },
2858 { 368, "R43(L)" },
2859 { 372, "R43(U)" },
2860 { 376, "R44(L)" },
2861 { 380, "R44(U)" },
2862 { 384, "R45(L)" },
2863 { 388, "R45(U)" },
2864 { 392, "R46(L)" },
2865 { 396, "R46(U)" },
2866 { 400, "R47(L)" },
2867 { 404, "R47(U)" },
2868 { 408, "R48(L)" },
2869 { 412, "R48(U)" },
2870 { 416, "R49(L)" },
2871 { 420, "R49(U)" },
2872 { 424, "R50(L)" },
2873 { 428, "R50(U)" },
2874 { 432, "R51(L)" },
2875 { 436, "R51(U)" },
2876 { 440, "R52(L)" },
2877 { 444, "R52(U)" },
2878 { 448, "R53(L)" },
2879 { 452, "R53(U)" },
2880 { 456, "R54(L)" },
2881 { 460, "R54(U)" },
2882 { 464, "R55(L)" },
2883 { 468, "R55(U)" },
2884 { 472, "R56(L)" },
2885 { 476, "R56(U)" },
2886 { 480, "R57(L)" },
2887 { 484, "R57(U)" },
2888 { 488, "R58(L)" },
2889 { 492, "R58(U)" },
2890 { 496, "R59(L)" },
2891 { 500, "R59(U)" },
2892 { 504, "R60(L)" },
2893 { 508, "R60(U)" },
2894 { 512, "R61(L)" },
2895 { 516, "R61(U)" },
2896 { 520, "R62(L)" },
2897 { 524, "R62(U)" },
2898 { 528, "TR0(L)" },
2899 { 532, "TR0(U)" },
2900 { 536, "TR1(L)" },
2901 { 540, "TR1(U)" },
2902 { 544, "TR2(L)" },
2903 { 548, "TR2(U)" },
2904 { 552, "TR3(L)" },
2905 { 556, "TR3(U)" },
2906 { 560, "TR4(L)" },
2907 { 564, "TR4(U)" },
2908 { 568, "TR5(L)" },
2909 { 572, "TR5(U)" },
2910 { 576, "TR6(L)" },
2911 { 580, "TR6(U)" },
2912 { 584, "TR7(L)" },
2913 { 588, "TR7(U)" },
2914 /* This entry is in case pt_regs contains dregs (depends on
2915 the kernel build options). */
2916 { uoff(regs), "offsetof(struct user, regs)" },
2917 { uoff(fpu), "offsetof(struct user, fpu)" },
2918#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002919#ifdef ARM
2920 { uoff(regs.ARM_r0), "r0" },
2921 { uoff(regs.ARM_r1), "r1" },
2922 { uoff(regs.ARM_r2), "r2" },
2923 { uoff(regs.ARM_r3), "r3" },
2924 { uoff(regs.ARM_r4), "r4" },
2925 { uoff(regs.ARM_r5), "r5" },
2926 { uoff(regs.ARM_r6), "r6" },
2927 { uoff(regs.ARM_r7), "r7" },
2928 { uoff(regs.ARM_r8), "r8" },
2929 { uoff(regs.ARM_r9), "r9" },
2930 { uoff(regs.ARM_r10), "r10" },
2931 { uoff(regs.ARM_fp), "fp" },
2932 { uoff(regs.ARM_ip), "ip" },
2933 { uoff(regs.ARM_sp), "sp" },
2934 { uoff(regs.ARM_lr), "lr" },
2935 { uoff(regs.ARM_pc), "pc" },
2936 { uoff(regs.ARM_cpsr), "cpsr" },
2937#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002938
Roland McGrath542c2c62008-05-20 01:11:56 +00002939#ifdef MIPS
2940 { 0, "r0" },
2941 { 1, "r1" },
2942 { 2, "r2" },
2943 { 3, "r3" },
2944 { 4, "r4" },
2945 { 5, "r5" },
2946 { 6, "r6" },
2947 { 7, "r7" },
2948 { 8, "r8" },
2949 { 9, "r9" },
2950 { 10, "r10" },
2951 { 11, "r11" },
2952 { 12, "r12" },
2953 { 13, "r13" },
2954 { 14, "r14" },
2955 { 15, "r15" },
2956 { 16, "r16" },
2957 { 17, "r17" },
2958 { 18, "r18" },
2959 { 19, "r19" },
2960 { 20, "r20" },
2961 { 21, "r21" },
2962 { 22, "r22" },
2963 { 23, "r23" },
2964 { 24, "r24" },
2965 { 25, "r25" },
2966 { 26, "r26" },
2967 { 27, "r27" },
2968 { 28, "r28" },
2969 { 29, "r29" },
2970 { 30, "r30" },
2971 { 31, "r31" },
2972 { 32, "f0" },
2973 { 33, "f1" },
2974 { 34, "f2" },
2975 { 35, "f3" },
2976 { 36, "f4" },
2977 { 37, "f5" },
2978 { 38, "f6" },
2979 { 39, "f7" },
2980 { 40, "f8" },
2981 { 41, "f9" },
2982 { 42, "f10" },
2983 { 43, "f11" },
2984 { 44, "f12" },
2985 { 45, "f13" },
2986 { 46, "f14" },
2987 { 47, "f15" },
2988 { 48, "f16" },
2989 { 49, "f17" },
2990 { 50, "f18" },
2991 { 51, "f19" },
2992 { 52, "f20" },
2993 { 53, "f21" },
2994 { 54, "f22" },
2995 { 55, "f23" },
2996 { 56, "f24" },
2997 { 57, "f25" },
2998 { 58, "f26" },
2999 { 59, "f27" },
3000 { 60, "f28" },
3001 { 61, "f29" },
3002 { 62, "f30" },
3003 { 63, "f31" },
3004 { 64, "pc" },
3005 { 65, "cause" },
3006 { 66, "badvaddr" },
3007 { 67, "mmhi" },
3008 { 68, "mmlo" },
3009 { 69, "fpcsr" },
3010 { 70, "fpeir" },
3011#endif
3012
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003013#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003014 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00003015#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00003016#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003017 { uoff(i387), "offsetof(struct user, i387)" },
3018#else /* !I386 */
3019#ifdef M68K
3020 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3021#endif /* M68K */
3022#endif /* !I386 */
3023 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3024 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3025 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003026#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003027 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003028#endif
Roland McGrathf5a47772003-06-26 22:40:42 +00003029#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00003030 { uoff(start_data), "offsetof(struct user, start_data)" },
3031#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003032#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003033 { uoff(start_stack), "offsetof(struct user, start_stack)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003034#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003035 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003036#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003037 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00003038#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003039#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003040 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003041#endif
3042#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003043 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3044#endif
3045 { uoff(magic), "offsetof(struct user, magic)" },
3046 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00003047#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003048 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3049#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00003050#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003051#endif /* !ALPHA */
3052#endif /* !POWERPC/!SPARC */
3053#endif /* LINUX */
3054#ifdef SUNOS4
3055 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3056 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3057 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3058 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3059 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3060 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3061 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3062 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3063 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3064 { uoff(u_error), "offsetof(struct user, u_error)" },
3065 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3066 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3067 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3068 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3069 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3070 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3071 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3072 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3073 { uoff(u_code), "offsetof(struct user, u_code)" },
3074 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3075 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3076 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3077 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3078 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3079 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3080 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3081 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3082 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3083 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3084 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3085 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3086 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3087 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3088 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3089 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3090 { uoff(u_start), "offsetof(struct user, u_start)" },
3091 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3092 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3093 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3094 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3095 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3096 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3097 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3098 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3099 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3100#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00003101#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003102 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00003103#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003104 { 0, NULL },
3105};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003106#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003107
3108int
3109sys_ptrace(tcp)
3110struct tcb *tcp;
3111{
Roland McGrathd9f816f2004-09-04 03:39:20 +00003112 const struct xlat *x;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003113 long addr;
3114
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003115 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00003116 printxval(ptrace_cmds, tcp->u_arg[0],
3117#ifndef FREEBSD
3118 "PTRACE_???"
3119#else
3120 "PT_???"
3121#endif
3122 );
3123 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003124 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003125#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003126 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3127 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3128 for (x = struct_user_offsets; x->str; x++) {
3129 if (x->val >= addr)
3130 break;
3131 }
3132 if (!x->str)
3133 tprintf("%#lx, ", addr);
3134 else if (x->val > addr && x != struct_user_offsets) {
3135 x--;
3136 tprintf("%s + %ld, ", x->str, addr - x->val);
3137 }
3138 else
3139 tprintf("%s, ", x->str);
3140 }
3141 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003142#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003143 tprintf("%#lx, ", tcp->u_arg[2]);
3144#ifdef LINUX
3145 switch (tcp->u_arg[0]) {
Roland McGrath1e868062007-11-19 22:11:45 +00003146#ifndef IA64
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003147 case PTRACE_PEEKDATA:
3148 case PTRACE_PEEKTEXT:
3149 case PTRACE_PEEKUSER:
3150 break;
Roland McGrath1e868062007-11-19 22:11:45 +00003151#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003152 case PTRACE_CONT:
3153 case PTRACE_SINGLESTEP:
3154 case PTRACE_SYSCALL:
3155 case PTRACE_DETACH:
3156 printsignal(tcp->u_arg[3]);
3157 break;
3158 default:
3159 tprintf("%#lx", tcp->u_arg[3]);
3160 break;
3161 }
3162 } else {
3163 switch (tcp->u_arg[0]) {
3164 case PTRACE_PEEKDATA:
3165 case PTRACE_PEEKTEXT:
3166 case PTRACE_PEEKUSER:
Roland McGrath1e868062007-11-19 22:11:45 +00003167#ifdef IA64
3168 return RVAL_HEX;
3169#else
Roland McGratheb285352003-01-14 09:59:00 +00003170 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003171 break;
Roland McGrath1e868062007-11-19 22:11:45 +00003172#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003173 }
3174 }
3175#endif /* LINUX */
3176#ifdef SUNOS4
3177 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3178 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3179 tprintf("%lu, ", tcp->u_arg[3]);
3180 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3181 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3182 tcp->u_arg[0] != PTRACE_READTEXT) {
3183 tprintf("%#lx", tcp->u_arg[3]);
3184 }
3185 } else {
3186 if (tcp->u_arg[0] == PTRACE_READDATA ||
3187 tcp->u_arg[0] == PTRACE_READTEXT) {
3188 tprintf("%lu, ", tcp->u_arg[3]);
3189 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3190 }
3191 }
3192#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003193#ifdef FREEBSD
3194 tprintf("%lu", tcp->u_arg[3]);
3195 }
3196#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003197 return 0;
3198}
3199
3200#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00003201
3202#ifdef LINUX
Roland McGrath51942a92007-07-05 18:59:11 +00003203# ifndef FUTEX_CMP_REQUEUE
3204# define FUTEX_CMP_REQUEUE 4
3205# endif
3206# ifndef FUTEX_WAKE_OP
3207# define FUTEX_WAKE_OP 5
3208# endif
3209# ifndef FUTEX_LOCK_PI
3210# define FUTEX_LOCK_PI 6
3211# define FUTEX_UNLOCK_PI 7
3212# define FUTEX_TRYLOCK_PI 8
3213# endif
Roland McGrath1aeaf742008-07-18 01:27:39 +00003214# ifndef FUTEX_WAIT_BITSET
3215# define FUTEX_WAIT_BITSET 9
3216# endif
3217# ifndef FUTEX_WAKE_BITSET
3218# define FUTEX_WAKE_BITSET 10
Roland McGrath51942a92007-07-05 18:59:11 +00003219# endif
3220# ifndef FUTEX_PRIVATE_FLAG
3221# define FUTEX_PRIVATE_FLAG 128
3222# endif
Roland McGrathd9f816f2004-09-04 03:39:20 +00003223static const struct xlat futexops[] = {
Roland McGrath51942a92007-07-05 18:59:11 +00003224 { FUTEX_WAIT, "FUTEX_WAIT" },
3225 { FUTEX_WAKE, "FUTEX_WAKE" },
3226 { FUTEX_FD, "FUTEX_FD" },
3227 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3228 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3229 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3230 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3231 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3232 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
Roland McGrath1aeaf742008-07-18 01:27:39 +00003233 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3234 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
Roland McGrath51942a92007-07-05 18:59:11 +00003235 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3236 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3237 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3238 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3239 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3240 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3241 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3242 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3243 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
Roland McGrath1aeaf742008-07-18 01:27:39 +00003244 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3245 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
Roland McGrath51942a92007-07-05 18:59:11 +00003246 { 0, NULL }
3247};
3248#ifndef FUTEX_OP_SET
3249# define FUTEX_OP_SET 0
3250# define FUTEX_OP_ADD 1
3251# define FUTEX_OP_OR 2
3252# define FUTEX_OP_ANDN 3
3253# define FUTEX_OP_XOR 4
3254# define FUTEX_OP_CMP_EQ 0
3255# define FUTEX_OP_CMP_NE 1
3256# define FUTEX_OP_CMP_LT 2
3257# define FUTEX_OP_CMP_LE 3
3258# define FUTEX_OP_CMP_GT 4
3259# define FUTEX_OP_CMP_GE 5
3260#endif
3261static const struct xlat futexwakeops[] = {
3262 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3263 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3264 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3265 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3266 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3267 { 0, NULL }
3268};
3269static const struct xlat futexwakecmps[] = {
3270 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3271 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3272 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3273 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3274 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3275 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3276 { 0, NULL }
Roland McGrath5a223472002-12-15 23:58:26 +00003277};
3278
3279int
3280sys_futex(tcp)
3281struct tcb *tcp;
3282{
3283 if (entering(tcp)) {
Roland McGrath1aeaf742008-07-18 01:27:39 +00003284 long int cmd = tcp->u_arg[1] & 127;
Roland McGrath5a223472002-12-15 23:58:26 +00003285 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00003286 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003287 tprintf(", %ld", tcp->u_arg[2]);
Roland McGrath1aeaf742008-07-18 01:27:39 +00003288 if (cmd == FUTEX_WAKE_BITSET)
3289 tprintf(", %lx", tcp->u_arg[5]);
3290 else if (cmd == FUTEX_WAIT) {
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003291 tprintf(", ");
3292 printtv(tcp, tcp->u_arg[3]);
Roland McGrath1aeaf742008-07-18 01:27:39 +00003293 } else if (cmd == FUTEX_WAIT_BITSET) {
3294 tprintf(", ");
3295 printtv(tcp, tcp->u_arg[3]);
3296 tprintf(", %lx", tcp->u_arg[5]);
Roland McGrath51942a92007-07-05 18:59:11 +00003297 } else if (cmd == FUTEX_REQUEUE)
Roland McGrath88812d62003-06-26 22:27:23 +00003298 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath51942a92007-07-05 18:59:11 +00003299 else if (cmd == FUTEX_CMP_REQUEUE)
3300 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3301 else if (cmd == FUTEX_WAKE_OP) {
3302 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3303 if ((tcp->u_arg[5] >> 28) & 8)
3304 tprintf("FUTEX_OP_OPARG_SHIFT|");
3305 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3306 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3307 if ((tcp->u_arg[5] >> 24) & 8)
3308 tprintf("FUTEX_OP_OPARG_SHIFT|");
3309 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3310 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3311 }
Roland McGrath5a223472002-12-15 23:58:26 +00003312 }
3313 return 0;
3314}
3315
3316static void
Roland McGrath79fbda52004-04-14 02:45:55 +00003317print_affinitylist(tcp, list, len)
3318struct tcb *tcp;
3319long list;
Roland McGrath5a223472002-12-15 23:58:26 +00003320unsigned int len;
3321{
3322 int first = 1;
3323 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00003324 while (len >= sizeof (unsigned long)) {
Roland McGrath79fbda52004-04-14 02:45:55 +00003325 unsigned long w;
3326 umove(tcp, list, &w);
3327 tprintf("%s %lx", first ? "" : ",", w);
Roland McGrath5a223472002-12-15 23:58:26 +00003328 first = 0;
3329 len -= sizeof (unsigned long);
Roland McGrath79fbda52004-04-14 02:45:55 +00003330 list += sizeof(unsigned long);
Roland McGrath5a223472002-12-15 23:58:26 +00003331 }
3332 tprintf(" }");
3333}
3334
3335int
3336sys_sched_setaffinity(tcp)
3337struct tcb *tcp;
3338{
3339 if (entering(tcp)) {
3340 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath79fbda52004-04-14 02:45:55 +00003341 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
Roland McGrath5a223472002-12-15 23:58:26 +00003342 }
3343 return 0;
3344}
3345
3346int
3347sys_sched_getaffinity(tcp)
3348struct tcb *tcp;
3349{
3350 if (entering(tcp)) {
3351 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3352 } else {
Roland McGrath79fbda52004-04-14 02:45:55 +00003353 if (tcp->u_rval == -1)
3354 tprintf("%#lx", tcp->u_arg[2]);
3355 else
3356 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
Roland McGrath5a223472002-12-15 23:58:26 +00003357 }
3358 return 0;
3359}
Roland McGrath279d3782004-03-01 20:27:37 +00003360
Roland McGrathd9f816f2004-09-04 03:39:20 +00003361static const struct xlat schedulers[] = {
Roland McGrath279d3782004-03-01 20:27:37 +00003362 { SCHED_OTHER, "SCHED_OTHER" },
3363 { SCHED_RR, "SCHED_RR" },
3364 { SCHED_FIFO, "SCHED_FIFO" },
3365 { 0, NULL }
3366};
3367
3368int
3369sys_sched_getscheduler(tcp)
3370struct tcb *tcp;
3371{
3372 if (entering(tcp)) {
3373 tprintf("%d", (int) tcp->u_arg[0]);
3374 } else if (! syserror(tcp)) {
3375 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3376 if (tcp->auxstr != NULL)
3377 return RVAL_STR;
3378 }
3379 return 0;
3380}
3381
3382int
3383sys_sched_setscheduler(tcp)
3384struct tcb *tcp;
3385{
3386 if (entering(tcp)) {
3387 struct sched_param p;
3388 tprintf("%d, ", (int) tcp->u_arg[0]);
3389 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3390 if (umove(tcp, tcp->u_arg[2], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003391 tprintf(", %#lx", tcp->u_arg[2]);
Roland McGrath279d3782004-03-01 20:27:37 +00003392 else
3393 tprintf(", { %d }", p.__sched_priority);
3394 }
3395 return 0;
3396}
3397
3398int
3399sys_sched_getparam(tcp)
3400struct tcb *tcp;
3401{
3402 if (entering(tcp)) {
3403 tprintf("%d, ", (int) tcp->u_arg[0]);
3404 } else {
3405 struct sched_param p;
3406 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003407 tprintf("%#lx", tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003408 else
3409 tprintf("{ %d }", p.__sched_priority);
3410 }
3411 return 0;
3412}
3413
3414int
3415sys_sched_setparam(tcp)
3416struct tcb *tcp;
3417{
3418 if (entering(tcp)) {
3419 struct sched_param p;
3420 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003421 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003422 else
3423 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3424 }
3425 return 0;
3426}
3427
3428int
3429sys_sched_get_priority_min(tcp)
3430struct tcb *tcp;
3431{
3432 if (entering(tcp)) {
3433 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3434 }
3435 return 0;
3436}
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003437
3438#ifdef X86_64
3439#include <asm/prctl.h>
3440
3441static const struct xlat archvals[] = {
3442 { ARCH_SET_GS, "ARCH_SET_GS" },
3443 { ARCH_SET_FS, "ARCH_SET_FS" },
3444 { ARCH_GET_FS, "ARCH_GET_FS" },
3445 { ARCH_GET_GS, "ARCH_GET_GS" },
3446 { 0, NULL },
3447};
3448
3449int
3450sys_arch_prctl(tcp)
3451struct tcb *tcp;
3452{
3453 if (entering(tcp)) {
3454 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3455 if (tcp->u_arg[0] == ARCH_SET_GS
3456 || tcp->u_arg[0] == ARCH_SET_FS)
3457 tprintf(", %#lx", tcp->u_arg[1]);
3458 } else {
3459 if (tcp->u_arg[0] == ARCH_GET_GS
3460 || tcp->u_arg[0] == ARCH_GET_FS) {
3461 long int v;
3462 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3463 tprintf(", [%#lx]", v);
3464 else
3465 tprintf(", %#lx", tcp->u_arg[1]);
3466 }
3467 }
3468 return 0;
3469}
3470#endif
3471
Roland McGrathdb8319f2007-08-02 01:37:55 +00003472
3473int
3474sys_getcpu(tcp)
3475struct tcb *tcp;
3476{
3477 if (exiting(tcp)) {
3478 unsigned u;
3479 if (tcp->u_arg[0] == 0)
3480 tprintf("NULL, ");
3481 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3482 tprintf("%#lx, ", tcp->u_arg[0]);
3483 else
3484 tprintf("[%u], ", u);
3485 if (tcp->u_arg[1] == 0)
3486 tprintf("NULL, ");
3487 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3488 tprintf("%#lx, ", tcp->u_arg[1]);
3489 else
3490 tprintf("[%u], ", u);
3491 tprintf("%#lx", tcp->u_arg[2]);
3492 }
3493 return 0;
3494}
3495
Roland McGrath5a223472002-12-15 23:58:26 +00003496#endif