blob: ec41b499896afd16dc56a2759439717582ce3eaa [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00005 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Linux for s390 port by D.J. Barrow
8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
Wichert Akkermanccef6372002-05-01 16:39:22 +00009 * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH
10 * port by Greg Banks <gbanks@pocketpenguins.com>
11
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +000012 *
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000013 * All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * $Id$
38 */
39
40#include "defs.h"
41
42#include <fcntl.h>
43#include <sys/stat.h>
44#include <sys/time.h>
45#include <sys/wait.h>
46#include <sys/resource.h>
47#include <sys/utsname.h>
48#include <sys/user.h>
49#include <sys/syscall.h>
50#include <signal.h>
51#ifdef SUNOS4
52#include <machine/reg.h>
53#endif /* SUNOS4 */
54
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +000055#ifdef FREEBSD
56#include <sys/ptrace.h>
57#endif
58
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000059#if HAVE_ASM_REG_H
Roland McGrath6d1a65c2004-07-12 07:44:08 +000060#if defined (SPARC) || defined (SPARC64)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000061# define fpq kernel_fpq
62# define fq kernel_fq
63# define fpu kernel_fpu
Roland McGrath6d1a65c2004-07-12 07:44:08 +000064#endif /* SPARC || SPARC64 */
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000065#include <asm/reg.h>
Roland McGrath6d1a65c2004-07-12 07:44:08 +000066#if defined (SPARC) || defined (SPARC64)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000067# undef fpq
68# undef fq
Roland McGrath5a223472002-12-15 23:58:26 +000069# undef fpu
Roland McGrath6d1a65c2004-07-12 07:44:08 +000070#endif /* SPARC || SPARC64 */
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000071#endif /* HAVE_ASM_REG_H */
72
Wichert Akkerman36915a11999-07-13 15:45:02 +000073#ifdef HAVE_SYS_REG_H
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000074# include <sys/reg.h>
Wichert Akkerman15dea971999-10-06 13:06:34 +000075#ifndef PTRACE_PEEKUSR
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000076# define PTRACE_PEEKUSR PTRACE_PEEKUSER
Wichert Akkerman15dea971999-10-06 13:06:34 +000077#endif
78#ifndef PTRACE_POKEUSR
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000079# define PTRACE_POKEUSR PTRACE_POKEUSER
80#endif
Wichert Akkerman15dea971999-10-06 13:06:34 +000081#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000082
Roland McGrath5bd7cf82003-01-24 04:31:18 +000083#ifdef HAVE_LINUX_PTRACE_H
84#undef PTRACE_SYSCALL
Roland McGrathfb1bc072004-03-01 21:29:24 +000085# ifdef HAVE_STRUCT_IA64_FPREG
86# define ia64_fpreg XXX_ia64_fpreg
87# endif
88# ifdef HAVE_STRUCT_PT_ALL_USER_REGS
89# define pt_all_user_regs XXX_pt_all_user_regs
90# endif
Roland McGrath5bd7cf82003-01-24 04:31:18 +000091#include <linux/ptrace.h>
Roland McGrathfb1bc072004-03-01 21:29:24 +000092# undef ia64_fpreg
93# undef pt_all_user_regs
Roland McGrath5bd7cf82003-01-24 04:31:18 +000094#endif
95
Roland McGrath6d1a65c2004-07-12 07:44:08 +000096#if defined (LINUX) && defined (SPARC64)
97# define r_pc r_tpc
98# undef PTRACE_GETREGS
99# define PTRACE_GETREGS PTRACE_GETREGS64
100# undef PTRACE_SETREGS
101# define PTRACE_SETREGS PTRACE_SETREGS64
102#endif /* LINUX && SPARC64 */
103
Roland McGrath5a223472002-12-15 23:58:26 +0000104#ifdef HAVE_LINUX_FUTEX_H
105#include <linux/futex.h>
106#endif
107#if defined LINUX
108# ifndef FUTEX_WAIT
109# define FUTEX_WAIT 0
110# endif
111# ifndef FUTEX_WAKE
112# define FUTEX_WAKE 1
113# endif
114# ifndef FUTEX_FD
115# define FUTEX_FD 2
116# endif
Roland McGrath88812d62003-06-26 22:27:23 +0000117# ifndef FUTEX_REQUEUE
118# define FUTEX_REQUEUE 3
119# endif
Roland McGrath5a223472002-12-15 23:58:26 +0000120#endif
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000121
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000122#ifdef LINUX
Roland McGrath279d3782004-03-01 20:27:37 +0000123#include <sched.h>
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000124#include <asm/posix_types.h>
125#undef GETGROUPS_T
126#define GETGROUPS_T __kernel_gid_t
Roland McGrath83bd47a2003-11-13 22:32:26 +0000127#undef GETGROUPS32_T
128#define GETGROUPS32_T __kernel_gid32_t
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000129#endif /* LINUX */
130
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000131#if defined(LINUX) && defined(IA64)
132# include <asm/ptrace_offsets.h>
133# include <asm/rse.h>
134#endif
135
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000136#ifdef HAVE_PRCTL
137#include <sys/prctl.h>
138#endif
139
140#ifndef WCOREDUMP
141#define WCOREDUMP(status) ((status) & 0200)
142#endif
143
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000144/* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000145#if defined(HAVE_PRCTL)
Roland McGrathd9f816f2004-09-04 03:39:20 +0000146static const struct xlat prctl_options[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000147#ifdef PR_MAXPROCS
148 { PR_MAXPROCS, "PR_MAXPROCS" },
149#endif
150#ifdef PR_ISBLOCKED
151 { PR_ISBLOCKED, "PR_ISBLOCKED" },
152#endif
153#ifdef PR_SETSTACKSIZE
154 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
155#endif
156#ifdef PR_GETSTACKSIZE
157 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
158#endif
159#ifdef PR_MAXPPROCS
160 { PR_MAXPPROCS, "PR_MAXPPROCS" },
161#endif
162#ifdef PR_UNBLKONEXEC
163 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
164#endif
165#ifdef PR_ATOMICSIM
166 { PR_ATOMICSIM, "PR_ATOMICSIM" },
167#endif
168#ifdef PR_SETEXITSIG
169 { PR_SETEXITSIG, "PR_SETEXITSIG" },
170#endif
171#ifdef PR_RESIDENT
172 { PR_RESIDENT, "PR_RESIDENT" },
173#endif
174#ifdef PR_ATTACHADDR
175 { PR_ATTACHADDR, "PR_ATTACHADDR" },
176#endif
177#ifdef PR_DETACHADDR
178 { PR_DETACHADDR, "PR_DETACHADDR" },
179#endif
180#ifdef PR_TERMCHILD
181 { PR_TERMCHILD, "PR_TERMCHILD" },
182#endif
183#ifdef PR_GETSHMASK
184 { PR_GETSHMASK, "PR_GETSHMASK" },
185#endif
186#ifdef PR_GETNSHARE
187 { PR_GETNSHARE, "PR_GETNSHARE" },
188#endif
189#if defined(PR_SET_PDEATHSIG)
190 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
191#endif
Wichert Akkerman8829a551999-06-11 13:18:40 +0000192#ifdef PR_COREPID
193 { PR_COREPID, "PR_COREPID" },
194#endif
195#ifdef PR_ATTACHADDRPERM
196 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
197#endif
198#ifdef PR_PTHREADEXIT
199 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
200#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000201#ifdef PR_SET_PDEATHSIG
202 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
203#endif
204#ifdef PR_GET_PDEATHSIG
205 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
206#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000207#ifdef PR_GET_UNALIGN
208 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
209#endif
210#ifdef PR_SET_UNALIGN
211 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
212#endif
213#ifdef PR_GET_KEEPCAPS
214 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" },
215#endif
216#ifdef PR_SET_KEEPCAPS
217 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" },
218#endif
Roland McGrathe5039fb2007-11-03 23:58:07 +0000219#ifdef PR_GET_FPEMU
220 { PR_GET_FPEMU, "PR_GET_FPEMU" },
221#endif
222#ifdef PR_SET_FPEMU
223 { PR_SET_FPEMU, "PR_SET_FPEMU" },
224#endif
225#ifdef PR_GET_FPEXC
226 { PR_GET_FPEXC, "PR_GET_FPEXC" },
227#endif
228#ifdef PR_SET_FPEXC
229 { PR_SET_FPEXC, "PR_SET_FPEXC" },
230#endif
231#ifdef PR_GET_TIMING
232 { PR_GET_TIMING, "PR_GET_TIMING" },
233#endif
234#ifdef PR_SET_TIMING
235 { PR_SET_TIMING, "PR_SET_TIMING" },
236#endif
237#ifdef PR_SET_NAME
238 { PR_SET_NAME, "PR_SET_NAME" },
239#endif
240#ifdef PR_GET_NAME
241 { PR_GET_NAME, "PR_GET_NAME" },
242#endif
243#ifdef PR_GET_ENDIAN
244 { PR_GET_ENDIAN, "PR_GET_ENDIAN" },
245#endif
246#ifdef PR_SET_ENDIAN
247 { PR_SET_ENDIAN, "PR_SET_ENDIAN" },
248#endif
249#ifdef PR_GET_SECCOMP
250 { PR_GET_SECCOMP, "PR_GET_SECCOMP" },
251#endif
252#ifdef PR_SET_SECCOMP
253 { PR_SET_SECCOMP, "PR_SET_SECCOMP" },
254#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000255 { 0, NULL },
256};
257
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000258
Roland McGratha4d48532005-06-08 20:45:28 +0000259static const char *
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000260unalignctl_string (unsigned int ctl)
261{
262 static char buf[16];
263
264 switch (ctl) {
265#ifdef PR_UNALIGN_NOPRINT
266 case PR_UNALIGN_NOPRINT:
267 return "NOPRINT";
268#endif
269#ifdef PR_UNALIGN_SIGBUS
270 case PR_UNALIGN_SIGBUS:
271 return "SIGBUS";
272#endif
273 default:
274 break;
275 }
276 sprintf(buf, "%x", ctl);
277 return buf;
278}
279
280
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000281int
282sys_prctl(tcp)
283struct tcb *tcp;
284{
285 int i;
286
287 if (entering(tcp)) {
288 printxval(prctl_options, tcp->u_arg[0], "PR_???");
289 switch (tcp->u_arg[0]) {
290#ifdef PR_GETNSHARE
291 case PR_GETNSHARE:
292 break;
293#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000294#ifdef PR_SET_DEATHSIG
295 case PR_GET_PDEATHSIG:
296 break;
297#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000298#ifdef PR_SET_UNALIGN
299 case PR_SET_UNALIGN:
300 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
301 break;
302#endif
303#ifdef PR_GET_UNALIGN
304 case PR_GET_UNALIGN:
305 tprintf(", %#lx", tcp->u_arg[1]);
306 break;
307#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000308 default:
309 for (i = 1; i < tcp->u_nargs; i++)
310 tprintf(", %#lx", tcp->u_arg[i]);
311 break;
312 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000313 } else {
314 switch (tcp->u_arg[0]) {
315#ifdef PR_GET_PDEATHSIG
316 case PR_GET_PDEATHSIG:
317 for (i=1; i<tcp->u_nargs; i++)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000318 tprintf(", %#lx", tcp->u_arg[i]);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000319 break;
320#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000321#ifdef PR_SET_UNALIGN
322 case PR_SET_UNALIGN:
323 break;
324#endif
325#ifdef PR_GET_UNALIGN
326 case PR_GET_UNALIGN:
327 {
328 int ctl;
329
330 umove(tcp, tcp->u_arg[1], &ctl);
331 tcp->auxstr = unalignctl_string(ctl);
332 return RVAL_STR;
333 }
334#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000335 default:
336 break;
337 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000338 }
339 return 0;
340}
341
342#endif /* HAVE_PRCTL */
343
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000344#if defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000345int
346sys_gethostid(tcp)
347struct tcb *tcp;
348{
349 if (exiting(tcp))
350 return RVAL_HEX;
351 return 0;
352}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000353#endif /* FREEBSD || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000354
355int
356sys_sethostname(tcp)
357struct tcb *tcp;
358{
359 if (entering(tcp)) {
360 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
361 tprintf(", %lu", tcp->u_arg[1]);
362 }
363 return 0;
364}
365
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000366#if defined(ALPHA) || defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000367int
368sys_gethostname(tcp)
369struct tcb *tcp;
370{
371 if (exiting(tcp)) {
372 if (syserror(tcp))
373 tprintf("%#lx", tcp->u_arg[0]);
374 else
375 printpath(tcp, tcp->u_arg[0]);
376 tprintf(", %lu", tcp->u_arg[1]);
377 }
378 return 0;
379}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000380#endif /* ALPHA || FREEBSD || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000381
382int
383sys_setdomainname(tcp)
384struct tcb *tcp;
385{
386 if (entering(tcp)) {
387 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
388 tprintf(", %lu", tcp->u_arg[1]);
389 }
390 return 0;
391}
392
Wichert Akkerman5daa0281999-03-15 19:49:42 +0000393#if !defined(LINUX)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000394
395int
396sys_getdomainname(tcp)
397struct tcb *tcp;
398{
399 if (exiting(tcp)) {
400 if (syserror(tcp))
401 tprintf("%#lx", tcp->u_arg[0]);
402 else
403 printpath(tcp, tcp->u_arg[0]);
404 tprintf(", %lu", tcp->u_arg[1]);
405 }
406 return 0;
407}
408#endif /* !LINUX */
409
410int
411sys_exit(tcp)
412struct tcb *tcp;
413{
414 if (exiting(tcp)) {
415 fprintf(stderr, "_exit returned!\n");
416 return -1;
417 }
418 /* special case: we stop tracing this process, finish line now */
419 tprintf("%ld) ", tcp->u_arg[0]);
420 tabto(acolumn);
421 tprintf("= ?");
422 printtrailer(tcp);
423 return 0;
424}
425
426int
427internal_exit(tcp)
428struct tcb *tcp;
429{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000430 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000431 tcp->flags |= TCB_EXITING;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000432#ifdef __NR_exit_group
Roland McGrath08267b82004-02-20 22:56:43 +0000433# ifdef IA64
434 if (ia32) {
435 if (tcp->scno == 252)
436 tcp->flags |= TCB_GROUP_EXITING;
437 } else
438# endif
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000439 if (known_scno(tcp) == __NR_exit_group)
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000440 tcp->flags |= TCB_GROUP_EXITING;
441#endif
442 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000443 return 0;
444}
445
Roland McGrathee9d4352002-12-18 04:16:10 +0000446/* TCP is creating a child we want to follow.
447 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
448 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
449static int
450fork_tcb(struct tcb *tcp)
451{
452 if (nprocs == tcbtabsize) {
Roland McGrath7b54a7a2004-06-04 01:50:45 +0000453 if (expand_tcbtab()) {
Roland McGrathee9d4352002-12-18 04:16:10 +0000454 tcp->flags &= ~TCB_FOLLOWFORK;
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000455 return 1;
Roland McGrathee9d4352002-12-18 04:16:10 +0000456 }
Roland McGrathee9d4352002-12-18 04:16:10 +0000457 }
458
459 tcp->flags |= TCB_FOLLOWFORK;
460 return 0;
461}
462
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000463#ifdef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000464
465int
466sys_fork(tcp)
467struct tcb *tcp;
468{
469 if (exiting(tcp)) {
470 if (getrval2(tcp)) {
471 tcp->auxstr = "child process";
472 return RVAL_UDECIMAL | RVAL_STR;
473 }
474 }
475 return 0;
476}
477
John Hughes4e36a812001-04-18 15:11:51 +0000478#if UNIXWARE > 2
479
480int
481sys_rfork(tcp)
482struct tcb *tcp;
483{
484 if (entering(tcp)) {
485 tprintf ("%ld", tcp->u_arg[0]);
486 }
487 else {
488 if (getrval2(tcp)) {
489 tcp->auxstr = "child process";
490 return RVAL_UDECIMAL | RVAL_STR;
491 }
492 }
493 return 0;
494}
495
496#endif
497
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000498int
499internal_fork(tcp)
500struct tcb *tcp;
501{
502 struct tcb *tcpchild;
503
504 if (exiting(tcp)) {
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000505#ifdef SYS_rfork
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000506 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000507 return 0;
508#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000509 if (getrval2(tcp))
510 return 0;
511 if (!followfork)
512 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000513 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000514 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000515 if (syserror(tcp))
516 return 0;
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000517 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000518 return 0;
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000519 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000520 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000521 }
522 return 0;
523}
524
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000525#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000526
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000527#ifdef LINUX
528
529/* defines copied from linux/sched.h since we can't include that
530 * ourselves (it conflicts with *lots* of libc includes)
531 */
532#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
533#define CLONE_VM 0x00000100 /* set if VM shared between processes */
534#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
535#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
536#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000537#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000538#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
539#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
540#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000541#define CLONE_THREAD 0x00010000 /* Same thread group? */
542#define CLONE_NEWNS 0x00020000 /* New namespace group? */
543#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
544#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
545#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
546#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
547#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
548#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
549#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000550
Roland McGrathd9f816f2004-09-04 03:39:20 +0000551static const struct xlat clone_flags[] = {
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000552 { CLONE_VM, "CLONE_VM" },
553 { CLONE_FS, "CLONE_FS" },
554 { CLONE_FILES, "CLONE_FILES" },
555 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000556 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000557 { CLONE_PTRACE, "CLONE_PTRACE" },
558 { CLONE_VFORK, "CLONE_VFORK" },
559 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000560 { CLONE_THREAD, "CLONE_THREAD" },
561 { CLONE_NEWNS, "CLONE_NEWNS" },
562 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
563 { CLONE_SETTLS, "CLONE_SETTLS" },
564 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
565 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
566 { CLONE_DETACHED, "CLONE_DETACHED" },
567 { CLONE_UNTRACED, "CLONE_UNTRACED" },
568 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000569 { 0, NULL },
570};
571
Roland McGrath909875b2002-12-22 03:34:36 +0000572# ifdef I386
573# include <asm/ldt.h>
Roland McGrath7decfb22004-03-01 22:10:52 +0000574# ifdef HAVE_STRUCT_USER_DESC
575# define modify_ldt_ldt_s user_desc
576# endif
Roland McGrath909875b2002-12-22 03:34:36 +0000577extern void print_ldt_entry();
578# endif
579
Roland McGrath9677b3a2003-03-12 09:54:36 +0000580# if defined IA64
581# define ARG_FLAGS 0
582# define ARG_STACK 1
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000583# define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
584# define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
585# define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
586# define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000587# elif defined S390 || defined S390X
Roland McGrath9677b3a2003-03-12 09:54:36 +0000588# define ARG_STACK 0
589# define ARG_FLAGS 1
590# define ARG_PTID 2
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000591# define ARG_CTID 3
592# define ARG_TLS 4
Roland McGrath9c555e72003-07-09 09:47:59 +0000593# elif defined X86_64 || defined ALPHA
Roland McGrath361aac52003-03-18 07:43:42 +0000594# define ARG_FLAGS 0
595# define ARG_STACK 1
596# define ARG_PTID 2
597# define ARG_CTID 3
598# define ARG_TLS 4
Roland McGrath9677b3a2003-03-12 09:54:36 +0000599# else
600# define ARG_FLAGS 0
601# define ARG_STACK 1
602# define ARG_PTID 2
603# define ARG_TLS 3
604# define ARG_CTID 4
605# endif
606
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000607int
608sys_clone(tcp)
609struct tcb *tcp;
610{
611 if (exiting(tcp)) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000612 unsigned long flags = tcp->u_arg[ARG_FLAGS];
613 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
614# ifdef ARG_STACKSIZE
615 if (ARG_STACKSIZE != -1)
616 tprintf("stack_size=%#lx, ",
617 tcp->u_arg[ARG_STACKSIZE]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000618# endif
Roland McGrath9677b3a2003-03-12 09:54:36 +0000619 tprintf("flags=");
Roland McGrathb2dee132005-06-01 19:02:36 +0000620 printflags(clone_flags, flags &~ CSIGNAL, NULL);
Roland McGrath984154d2003-05-23 01:08:42 +0000621 if ((flags & CSIGNAL) != 0)
622 tprintf("|%s", signame(flags & CSIGNAL));
Roland McGrathb4968be2003-01-20 09:04:33 +0000623 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
Roland McGrath9677b3a2003-03-12 09:54:36 +0000624 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
Roland McGrath909875b2002-12-22 03:34:36 +0000625 return 0;
Roland McGrath6f67a982003-03-21 07:33:15 +0000626 if (flags & CLONE_PARENT_SETTID)
627 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000628 if (flags & CLONE_SETTLS) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000629# ifdef I386
Roland McGrath909875b2002-12-22 03:34:36 +0000630 struct modify_ldt_ldt_s copy;
Roland McGrath9677b3a2003-03-12 09:54:36 +0000631 if (umove(tcp, tcp->u_arg[ARG_TLS], &copy) != -1) {
Roland McGrath909875b2002-12-22 03:34:36 +0000632 tprintf(", {entry_number:%d, ",
633 copy.entry_number);
634 if (!verbose(tcp))
635 tprintf("...}");
636 else
637 print_ldt_entry(&copy);
638 }
639 else
Roland McGrath9677b3a2003-03-12 09:54:36 +0000640# endif
Roland McGrath43f2c842003-03-12 09:58:14 +0000641 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
Roland McGrath909875b2002-12-22 03:34:36 +0000642 }
Roland McGrath9677b3a2003-03-12 09:54:36 +0000643 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
644 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000645 }
646 return 0;
647}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000648
649int
650sys_unshare(struct tcb *tcp)
651{
652 if (entering(tcp))
653 printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
654 return 0;
655}
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000656#endif
657
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000658int
659sys_fork(tcp)
660struct tcb *tcp;
661{
662 if (exiting(tcp))
663 return RVAL_UDECIMAL;
664 return 0;
665}
666
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000667int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000668change_syscall(tcp, new)
669struct tcb *tcp;
670int new;
671{
672#if defined(LINUX)
673#if defined(I386)
674 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000675 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000676 return -1;
677 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000678#elif defined(X86_64)
679 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000680 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000681 return -1;
682 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000683#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000684 if (ptrace(PTRACE_POKEUSER, tcp->pid,
685 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000686 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000687 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000688#elif defined(S390) || defined(S390X)
689 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
690 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
691 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000692 return 0;
693#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000694 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000695 return -1;
696 return 0;
Roland McGrath6d1a65c2004-07-12 07:44:08 +0000697#elif defined(SPARC) || defined(SPARC64)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000698 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000699 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
700 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000701 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000702 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
703 return -1;
704 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000705#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000706 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000707 return -1;
708 return 0;
709#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000710 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000711 return -1;
712 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000713#elif defined(IA64)
Roland McGrath08267b82004-02-20 22:56:43 +0000714 if (ia32) {
715 switch (new) {
716 case 2: break; /* x86 SYS_fork */
717 case SYS_clone: new = 120; break;
718 default:
719 fprintf(stderr, "%s: unexpected syscall %d\n",
720 __FUNCTION__, new);
721 return -1;
722 }
723 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
724 return -1;
725 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000726 return -1;
727 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000728#elif defined(HPPA)
729 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
730 return -1;
731 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000732#elif defined(SH)
Roland McGrathac971c22003-03-31 01:03:33 +0000733 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
Wichert Akkermanccef6372002-05-01 16:39:22 +0000734 return -1;
735 return 0;
Roland McGrathf5a47772003-06-26 22:40:42 +0000736#elif defined(SH64)
Roland McGrathe1e584b2003-06-02 19:18:58 +0000737 /* Top half of reg encodes the no. of args n as 0x1n.
738 Assume 0 args as kernel never actually checks... */
739 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
740 0x100000 | new) < 0)
741 return -1;
742 return 0;
Roland McGrathf691bd22006-04-25 07:34:41 +0000743#elif defined(ARM)
744 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
745# ifndef PTRACE_SET_SYSCALL
746# define PTRACE_SET_SYSCALL 23
747# endif
748
749 if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new) != 0)
750 return -1;
751
752 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000753#else
754#warning Do not know how to handle change_syscall for this architecture
755#endif /* architecture */
756#endif /* LINUX */
757 return -1;
758}
759
Roland McGratha4d48532005-06-08 20:45:28 +0000760#if 0
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000761int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000762setarg(tcp, argnum)
763 struct tcb *tcp;
764 int argnum;
765{
766#if defined (IA64)
767 {
768 unsigned long *bsp, *ap;
769
770 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
771 return -1;
772
773 ap = ia64_rse_skip_regs(bsp, argnum);
774 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000775 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000776 if (errno)
777 return -1;
778
779 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000780#elif defined(I386)
781 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000782 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000783 if (errno)
784 return -1;
785 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000786#elif defined(X86_64)
787 {
788 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
789 if (errno)
790 return -1;
791 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000792#elif defined(POWERPC)
793#ifndef PT_ORIG_R3
794#define PT_ORIG_R3 34
795#endif
796 {
797 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000798 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000799 tcp->u_arg[argnum]);
800 if (errno)
801 return -1;
802 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000803#elif defined(MIPS)
804 {
805 errno = 0;
806 if (argnum < 4)
807 ptrace(PTRACE_POKEUSER, tcp->pid,
808 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
809 else {
810 unsigned long *sp;
811
812 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
813 return -1;
814
815 ptrace(PTRACE_POKEDATA, tcp->pid,
816 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
817 }
818 if (errno)
819 return -1;
820 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000821#elif defined(S390) || defined(S390X)
822 {
823 if(argnum <= 5)
824 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000825 (char *) (argnum==0 ? PT_ORIGGPR2 :
826 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000827 tcp->u_arg[argnum]);
828 else
829 return -E2BIG;
830 if (errno)
831 return -1;
832 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000833#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000834# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000835#endif
836 return 0;
837}
Roland McGratha4d48532005-06-08 20:45:28 +0000838#endif
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000839
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000840#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000841int
842internal_clone(tcp)
843struct tcb *tcp;
844{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000845 struct tcb *tcpchild;
846 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000847 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000848 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000849 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000850 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000851 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000852 if (setbpt(tcp) < 0)
853 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000854 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000855 int bpt = tcp->flags & TCB_BPTSET;
856
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000857 if (!(tcp->flags & TCB_FOLLOWFORK))
858 return 0;
859
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000860 if (syserror(tcp)) {
861 if (bpt)
862 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000863 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000864 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000865
866 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000867
868#ifdef CLONE_PTRACE /* See new setbpt code. */
869 tcpchild = pid2tcb(pid);
870 if (tcpchild != NULL) {
871 /* The child already reported its startup trap
872 before the parent reported its syscall return. */
873 if ((tcpchild->flags
874 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
875 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
876 fprintf(stderr, "\
877[preattached child %d of %d in weird state!]\n",
878 pid, tcp->pid);
879 }
880 else
881#endif
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000882 if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000883 if (bpt)
884 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000885 kill(pid, SIGKILL); /* XXX */
886 return 0;
887 }
888
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000889#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000890 /* Attach to the new child */
891 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000892 if (bpt)
893 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000894 perror("PTRACE_ATTACH");
895 fprintf(stderr, "Too late?\n");
896 droptcb(tcpchild);
897 return 0;
898 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000899#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000900
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000901 if (bpt)
902 clearbpt(tcp);
903
Ulrich Drepper90512f01999-12-24 07:22:25 +0000904 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000905 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000906 if (bpt) {
907 tcpchild->flags |= TCB_BPTSET;
908 tcpchild->baddr = tcp->baddr;
909 memcpy(tcpchild->inst, tcp->inst,
910 sizeof tcpchild->inst);
911 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000912 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000913 tcp->nchildren++;
914 if (tcpchild->flags & TCB_SUSPENDED) {
915 /* The child was born suspended, due to our having
916 forced CLONE_PTRACE. */
917 if (bpt)
918 clearbpt(tcpchild);
919
920 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
921 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
922 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
923 return -1;
924 }
925
926 if (!qflag)
927 fprintf(stderr, "\
928Process %u resumed (parent %d ready)\n",
929 pid, tcp->pid);
930 }
931 else {
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000932 if (!qflag)
933 fprintf(stderr, "Process %d attached\n", pid);
934 }
935
936#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000937 {
938 /*
939 * Save the flags used in this call,
940 * in case we point TCP to our parent below.
941 */
942 int call_flags = tcp->u_arg[ARG_FLAGS];
943 if ((tcp->flags & TCB_CLONE_THREAD) &&
944 tcp->parent != NULL) {
945 /* The parent in this clone is itself a
946 thread belonging to another process.
947 There is no meaning to the parentage
948 relationship of the new child with the
949 thread, only with the process. We
950 associate the new thread with our
951 parent. Since this is done for every
952 new thread, there will never be a
953 TCB_CLONE_THREAD process that has
954 children. */
955 --tcp->nchildren;
956 tcp = tcp->parent;
957 tcpchild->parent = tcp;
958 ++tcp->nchildren;
959 }
960 if (call_flags & CLONE_THREAD) {
961 tcpchild->flags |= TCB_CLONE_THREAD;
962 ++tcp->nclone_threads;
963 }
964 if (call_flags & CLONE_DETACHED) {
965 tcpchild->flags |= TCB_CLONE_DETACHED;
966 ++tcp->nclone_detached;
967 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000968 }
969#endif
970
971 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000972 return 0;
973}
974#endif
975
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000976int
977internal_fork(tcp)
978struct tcb *tcp;
979{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000980#ifdef LINUX
981 /* We do special magic with clone for any clone or fork. */
982 return internal_clone(tcp);
983#else
984
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000985 struct tcb *tcpchild;
986 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000987 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000988
989#ifdef SYS_vfork
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000990 if (known_scno(tcp) == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000991 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath41c48222008-07-18 00:25:10 +0000992 if (change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000993 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000994 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000995#endif
996 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000997 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000998 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000999 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001000 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001001 if (setbpt(tcp) < 0)
1002 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +00001003 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001004 else {
1005 int bpt = tcp->flags & TCB_BPTSET;
1006
1007 if (!(tcp->flags & TCB_FOLLOWFORK))
1008 return 0;
1009 if (bpt)
1010 clearbpt(tcp);
1011
1012 if (syserror(tcp))
1013 return 0;
1014
1015 pid = tcp->u_rval;
Dmitry V. Levin76860f62006-10-11 22:55:25 +00001016 if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001017 kill(pid, SIGKILL); /* XXX */
1018 return 0;
1019 }
1020#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +00001021#ifdef HPPA
1022 /* The child must have run before it can be attached. */
1023 /* This must be a bug in the parisc kernel, but I havn't
1024 * identified it yet. Seems to be an issue associated
1025 * with attaching to a process (which sends it a signal)
1026 * before that process has ever been scheduled. When
1027 * debugging, I started seeing crashes in
1028 * arch/parisc/kernel/signal.c:do_signal(), apparently
1029 * caused by r8 getting corrupt over the dequeue_signal()
1030 * call. Didn't make much sense though...
1031 */
1032 {
1033 struct timeval tv;
1034 tv.tv_sec = 0;
1035 tv.tv_usec = 10000;
1036 select(0, NULL, NULL, NULL, &tv);
1037 }
1038#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001039 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
1040 perror("PTRACE_ATTACH");
1041 fprintf(stderr, "Too late?\n");
1042 droptcb(tcpchild);
1043 return 0;
1044 }
1045#endif /* LINUX */
1046#ifdef SUNOS4
1047#ifdef oldway
1048 /* The child must have run before it can be attached. */
1049 {
1050 struct timeval tv;
1051 tv.tv_sec = 0;
1052 tv.tv_usec = 10000;
1053 select(0, NULL, NULL, NULL, &tv);
1054 }
1055 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1056 perror("PTRACE_ATTACH");
1057 fprintf(stderr, "Too late?\n");
1058 droptcb(tcpchild);
1059 return 0;
1060 }
1061#else /* !oldway */
1062 /* Try to catch the new process as soon as possible. */
1063 {
1064 int i;
1065 for (i = 0; i < 1024; i++)
1066 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1067 break;
1068 if (i == 1024) {
1069 perror("PTRACE_ATTACH");
1070 fprintf(stderr, "Too late?\n");
1071 droptcb(tcpchild);
1072 return 0;
1073 }
1074 }
1075#endif /* !oldway */
1076#endif /* SUNOS4 */
1077 tcpchild->flags |= TCB_ATTACHED;
1078 /* Child has BPT too, must be removed on first occasion */
1079 if (bpt) {
1080 tcpchild->flags |= TCB_BPTSET;
1081 tcpchild->baddr = tcp->baddr;
1082 memcpy(tcpchild->inst, tcp->inst,
1083 sizeof tcpchild->inst);
1084 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001085 tcpchild->parent = tcp;
1086 tcp->nchildren++;
1087 if (!qflag)
1088 fprintf(stderr, "Process %d attached\n", pid);
1089 }
1090 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001091#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001092}
1093
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001094#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001095
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001096#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001097
1098int
1099sys_vfork(tcp)
1100struct tcb *tcp;
1101{
1102 if (exiting(tcp))
1103 return RVAL_UDECIMAL;
1104 return 0;
1105}
1106
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001107#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001108
1109#ifndef LINUX
1110
1111static char idstr[16];
1112
1113int
1114sys_getpid(tcp)
1115struct tcb *tcp;
1116{
1117 if (exiting(tcp)) {
1118 sprintf(idstr, "ppid %lu", getrval2(tcp));
1119 tcp->auxstr = idstr;
1120 return RVAL_STR;
1121 }
1122 return 0;
1123}
1124
1125int
1126sys_getuid(tcp)
1127struct tcb *tcp;
1128{
1129 if (exiting(tcp)) {
1130 sprintf(idstr, "euid %lu", getrval2(tcp));
1131 tcp->auxstr = idstr;
1132 return RVAL_STR;
1133 }
1134 return 0;
1135}
1136
1137int
1138sys_getgid(tcp)
1139struct tcb *tcp;
1140{
1141 if (exiting(tcp)) {
1142 sprintf(idstr, "egid %lu", getrval2(tcp));
1143 tcp->auxstr = idstr;
1144 return RVAL_STR;
1145 }
1146 return 0;
1147}
1148
1149#endif /* !LINUX */
1150
1151#ifdef LINUX
1152
1153int
1154sys_setuid(tcp)
1155struct tcb *tcp;
1156{
1157 if (entering(tcp)) {
1158 tprintf("%u", (uid_t) tcp->u_arg[0]);
1159 }
1160 return 0;
1161}
1162
1163int
1164sys_setgid(tcp)
1165struct tcb *tcp;
1166{
1167 if (entering(tcp)) {
1168 tprintf("%u", (gid_t) tcp->u_arg[0]);
1169 }
1170 return 0;
1171}
1172
1173int
1174sys_getresuid(tcp)
1175 struct tcb *tcp;
1176{
1177 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001178 __kernel_uid_t uid;
1179 if (syserror(tcp))
1180 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1181 tcp->u_arg[1], tcp->u_arg[2]);
1182 else {
1183 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1184 tprintf("%#lx, ", tcp->u_arg[0]);
1185 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001186 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001187 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1188 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001189 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001190 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001191 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1192 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001193 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001194 tprintf("[%lu]", (unsigned long) uid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001195 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001196 }
1197 return 0;
1198}
1199
1200int
1201sys_getresgid(tcp)
1202struct tcb *tcp;
1203{
1204 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001205 __kernel_gid_t gid;
1206 if (syserror(tcp))
1207 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1208 tcp->u_arg[1], tcp->u_arg[2]);
1209 else {
1210 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1211 tprintf("%#lx, ", tcp->u_arg[0]);
1212 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001213 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001214 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1215 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001216 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001217 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001218 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1219 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001220 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001221 tprintf("[%lu]", (unsigned long) gid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001222 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001223 }
1224 return 0;
1225}
1226
1227#endif /* LINUX */
1228
1229int
1230sys_setreuid(tcp)
1231struct tcb *tcp;
1232{
1233 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001234 printuid("", tcp->u_arg[0]);
1235 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001236 }
1237 return 0;
1238}
1239
1240int
1241sys_setregid(tcp)
1242struct tcb *tcp;
1243{
1244 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001245 printuid("", tcp->u_arg[0]);
1246 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001247 }
1248 return 0;
1249}
1250
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001251#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001252int
1253sys_setresuid(tcp)
1254 struct tcb *tcp;
1255{
1256 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001257 printuid("", tcp->u_arg[0]);
1258 printuid(", ", tcp->u_arg[1]);
1259 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001260 }
1261 return 0;
1262}
1263int
1264sys_setresgid(tcp)
1265 struct tcb *tcp;
1266{
1267 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001268 printuid("", tcp->u_arg[0]);
1269 printuid(", ", tcp->u_arg[1]);
1270 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001271 }
1272 return 0;
1273}
1274
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001275#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001276
1277int
1278sys_setgroups(tcp)
1279struct tcb *tcp;
1280{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001281 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001282 unsigned long len, size, start, cur, end, abbrev_end;
1283 GETGROUPS_T gid;
1284 int failed = 0;
1285
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001286 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001287 tprintf("%lu, ", len);
1288 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001289 tprintf("[]");
1290 return 0;
1291 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001292 start = tcp->u_arg[1];
1293 if (start == 0) {
1294 tprintf("NULL");
1295 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001296 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001297 size = len * sizeof(gid);
1298 end = start + size;
1299 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1300 tprintf("%#lx", start);
1301 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001302 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001303 if (abbrev(tcp)) {
1304 abbrev_end = start + max_strlen * sizeof(gid);
1305 if (abbrev_end < start)
1306 abbrev_end = end;
1307 } else {
1308 abbrev_end = end;
1309 }
1310 tprintf("[");
1311 for (cur = start; cur < end; cur += sizeof(gid)) {
1312 if (cur > start)
1313 tprintf(", ");
1314 if (cur >= abbrev_end) {
1315 tprintf("...");
1316 break;
1317 }
1318 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1319 tprintf("?");
1320 failed = 1;
1321 break;
1322 }
1323 tprintf("%lu", (unsigned long) gid);
1324 }
1325 tprintf("]");
1326 if (failed)
1327 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001328 }
1329 return 0;
1330}
1331
1332int
1333sys_getgroups(tcp)
1334struct tcb *tcp;
1335{
Roland McGrathaa524c82005-06-01 19:22:06 +00001336 unsigned long len;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001337
1338 if (entering(tcp)) {
1339 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001340 tprintf("%lu, ", len);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001341 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001342 unsigned long size, start, cur, end, abbrev_end;
1343 GETGROUPS_T gid;
1344 int failed = 0;
1345
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001346 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001347 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001348 tprintf("[]");
1349 return 0;
1350 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001351 start = tcp->u_arg[1];
1352 if (start == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001353 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001354 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001355 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001356 if (tcp->u_arg[0] == 0) {
1357 tprintf("%#lx", start);
1358 return 0;
1359 }
1360 size = len * sizeof(gid);
1361 end = start + size;
1362 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1363 size / sizeof(gid) != len || end < start) {
1364 tprintf("%#lx", start);
1365 return 0;
1366 }
1367 if (abbrev(tcp)) {
1368 abbrev_end = start + max_strlen * sizeof(gid);
1369 if (abbrev_end < start)
1370 abbrev_end = end;
1371 } else {
1372 abbrev_end = end;
1373 }
1374 tprintf("[");
1375 for (cur = start; cur < end; cur += sizeof(gid)) {
1376 if (cur > start)
1377 tprintf(", ");
1378 if (cur >= abbrev_end) {
1379 tprintf("...");
1380 break;
1381 }
1382 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1383 tprintf("?");
1384 failed = 1;
1385 break;
1386 }
1387 tprintf("%lu", (unsigned long) gid);
1388 }
1389 tprintf("]");
1390 if (failed)
1391 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001392 }
1393 return 0;
1394}
1395
Roland McGrath83bd47a2003-11-13 22:32:26 +00001396#ifdef LINUX
1397int
1398sys_setgroups32(tcp)
1399struct tcb *tcp;
1400{
Roland McGrath83bd47a2003-11-13 22:32:26 +00001401 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001402 unsigned long len, size, start, cur, end, abbrev_end;
1403 GETGROUPS32_T gid;
1404 int failed = 0;
1405
Roland McGrath83bd47a2003-11-13 22:32:26 +00001406 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001407 tprintf("%lu, ", len);
1408 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001409 tprintf("[]");
1410 return 0;
1411 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001412 start = tcp->u_arg[1];
1413 if (start == 0) {
1414 tprintf("NULL");
1415 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001416 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001417 size = len * sizeof(gid);
1418 end = start + size;
1419 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1420 tprintf("%#lx", start);
1421 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001422 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001423 if (abbrev(tcp)) {
1424 abbrev_end = start + max_strlen * sizeof(gid);
1425 if (abbrev_end < start)
1426 abbrev_end = end;
1427 } else {
1428 abbrev_end = end;
1429 }
1430 tprintf("[");
1431 for (cur = start; cur < end; cur += sizeof(gid)) {
1432 if (cur > start)
1433 tprintf(", ");
1434 if (cur >= abbrev_end) {
1435 tprintf("...");
1436 break;
1437 }
1438 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1439 tprintf("?");
1440 failed = 1;
1441 break;
1442 }
1443 tprintf("%lu", (unsigned long) gid);
1444 }
1445 tprintf("]");
1446 if (failed)
1447 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001448 }
1449 return 0;
1450}
1451
1452int
1453sys_getgroups32(tcp)
1454struct tcb *tcp;
1455{
Roland McGrathaa524c82005-06-01 19:22:06 +00001456 unsigned long len;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001457
1458 if (entering(tcp)) {
1459 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001460 tprintf("%lu, ", len);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001461 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001462 unsigned long size, start, cur, end, abbrev_end;
1463 GETGROUPS32_T gid;
1464 int failed = 0;
1465
Roland McGrath83bd47a2003-11-13 22:32:26 +00001466 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001467 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001468 tprintf("[]");
1469 return 0;
1470 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001471 start = tcp->u_arg[1];
1472 if (start == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001473 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001474 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001475 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001476 size = len * sizeof(gid);
1477 end = start + size;
1478 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1479 size / sizeof(gid) != len || end < start) {
1480 tprintf("%#lx", start);
1481 return 0;
1482 }
1483 if (abbrev(tcp)) {
1484 abbrev_end = start + max_strlen * sizeof(gid);
1485 if (abbrev_end < start)
1486 abbrev_end = end;
1487 } else {
1488 abbrev_end = end;
1489 }
1490 tprintf("[");
1491 for (cur = start; cur < end; cur += sizeof(gid)) {
1492 if (cur > start)
1493 tprintf(", ");
1494 if (cur >= abbrev_end) {
1495 tprintf("...");
1496 break;
1497 }
1498 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1499 tprintf("?");
1500 failed = 1;
1501 break;
1502 }
1503 tprintf("%lu", (unsigned long) gid);
1504 }
1505 tprintf("]");
1506 if (failed)
1507 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001508 }
1509 return 0;
1510}
1511#endif /* LINUX */
1512
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001513#if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001514int
1515sys_setpgrp(tcp)
1516struct tcb *tcp;
1517{
1518 if (entering(tcp)) {
1519#ifndef SVR4
1520 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1521#endif /* !SVR4 */
1522 }
1523 return 0;
1524}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001525#endif /* ALPHA || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001526
1527int
1528sys_getpgrp(tcp)
1529struct tcb *tcp;
1530{
1531 if (entering(tcp)) {
1532#ifndef SVR4
1533 tprintf("%lu", tcp->u_arg[0]);
1534#endif /* !SVR4 */
1535 }
1536 return 0;
1537}
1538
1539int
1540sys_getsid(tcp)
1541struct tcb *tcp;
1542{
1543 if (entering(tcp)) {
1544 tprintf("%lu", tcp->u_arg[0]);
1545 }
1546 return 0;
1547}
1548
1549int
1550sys_setsid(tcp)
1551struct tcb *tcp;
1552{
1553 return 0;
1554}
1555
1556int
1557sys_getpgid(tcp)
1558struct tcb *tcp;
1559{
1560 if (entering(tcp)) {
1561 tprintf("%lu", tcp->u_arg[0]);
1562 }
1563 return 0;
1564}
1565
1566int
1567sys_setpgid(tcp)
1568struct tcb *tcp;
1569{
1570 if (entering(tcp)) {
1571 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1572 }
1573 return 0;
1574}
1575
John Hughesc61eb3d2002-05-17 11:37:50 +00001576#if UNIXWARE >= 2
1577
1578#include <sys/privilege.h>
1579
1580
Roland McGrathd9f816f2004-09-04 03:39:20 +00001581static const struct xlat procpriv_cmds [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001582 { SETPRV, "SETPRV" },
1583 { CLRPRV, "CLRPRV" },
1584 { PUTPRV, "PUTPRV" },
1585 { GETPRV, "GETPRV" },
1586 { CNTPRV, "CNTPRV" },
1587 { 0, NULL },
1588};
1589
1590
Roland McGrathd9f816f2004-09-04 03:39:20 +00001591static const struct xlat procpriv_priv [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001592 { P_OWNER, "P_OWNER" },
1593 { P_AUDIT, "P_AUDIT" },
1594 { P_COMPAT, "P_COMPAT" },
1595 { P_DACREAD, "P_DACREAD" },
1596 { P_DACWRITE, "P_DACWRITE" },
1597 { P_DEV, "P_DEV" },
1598 { P_FILESYS, "P_FILESYS" },
1599 { P_MACREAD, "P_MACREAD" },
1600 { P_MACWRITE, "P_MACWRITE" },
1601 { P_MOUNT, "P_MOUNT" },
1602 { P_MULTIDIR, "P_MULTIDIR" },
1603 { P_SETPLEVEL, "P_SETPLEVEL" },
1604 { P_SETSPRIV, "P_SETSPRIV" },
1605 { P_SETUID, "P_SETUID" },
1606 { P_SYSOPS, "P_SYSOPS" },
1607 { P_SETUPRIV, "P_SETUPRIV" },
1608 { P_DRIVER, "P_DRIVER" },
1609 { P_RTIME, "P_RTIME" },
1610 { P_MACUPGRADE, "P_MACUPGRADE" },
1611 { P_FSYSRANGE, "P_FSYSRANGE" },
1612 { P_SETFLEVEL, "P_SETFLEVEL" },
1613 { P_AUDITWR, "P_AUDITWR" },
1614 { P_TSHAR, "P_TSHAR" },
1615 { P_PLOCK, "P_PLOCK" },
1616 { P_CORE, "P_CORE" },
1617 { P_LOADMOD, "P_LOADMOD" },
1618 { P_BIND, "P_BIND" },
1619 { P_ALLPRIVS, "P_ALLPRIVS" },
1620 { 0, NULL },
1621};
1622
1623
Roland McGrathd9f816f2004-09-04 03:39:20 +00001624static const struct xlat procpriv_type [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001625 { PS_FIX, "PS_FIX" },
1626 { PS_INH, "PS_INH" },
1627 { PS_MAX, "PS_MAX" },
1628 { PS_WKG, "PS_WKG" },
1629 { 0, NULL },
1630};
1631
1632
1633static void
Dmitry V. Levinab9008b2007-01-11 22:05:04 +00001634printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
John Hughesc61eb3d2002-05-17 11:37:50 +00001635{
1636 priv_t buf [128];
1637 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1638 int dots = len > max;
1639 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001640
John Hughesc61eb3d2002-05-17 11:37:50 +00001641 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001642
John Hughesc61eb3d2002-05-17 11:37:50 +00001643 if (len <= 0 ||
1644 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1645 {
1646 tprintf ("%#lx", addr);
1647 return;
1648 }
1649
1650 tprintf ("[");
1651
1652 for (i = 0; i < len; ++i) {
Dmitry V. Levinab9008b2007-01-11 22:05:04 +00001653 const char *t, *p;
John Hughesc61eb3d2002-05-17 11:37:50 +00001654
1655 if (i) tprintf (", ");
1656
1657 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1658 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1659 {
1660 tprintf ("%s|%s", t, p);
1661 }
1662 else {
1663 tprintf ("%#lx", buf [i]);
1664 }
1665 }
1666
1667 if (dots) tprintf (" ...");
1668
1669 tprintf ("]");
1670}
1671
1672
1673int
1674sys_procpriv(tcp)
1675struct tcb *tcp;
1676{
1677 if (entering(tcp)) {
1678 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1679 switch (tcp->u_arg[0]) {
1680 case CNTPRV:
1681 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1682 break;
1683
1684 case GETPRV:
1685 break;
1686
1687 default:
1688 tprintf (", ");
1689 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1690 tprintf (", %ld", tcp->u_arg[2]);
1691 }
1692 }
1693 else if (tcp->u_arg[0] == GETPRV) {
1694 if (syserror (tcp)) {
1695 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1696 }
1697 else {
1698 tprintf (", ");
1699 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1700 tprintf (", %ld", tcp->u_arg[2]);
1701 }
1702 }
Roland McGrath5a223472002-12-15 23:58:26 +00001703
John Hughesc61eb3d2002-05-17 11:37:50 +00001704 return 0;
1705}
1706
1707#endif
1708
1709
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001710static void
1711printargv(tcp, addr)
1712struct tcb *tcp;
1713long addr;
1714{
Roland McGrath85a3bc42007-08-02 02:13:05 +00001715 union {
1716 int p32;
1717 long p64;
1718 char data[sizeof(long)];
1719 } cp;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001720 char *sep;
Roland McGrath85a3bc42007-08-02 02:13:05 +00001721 int n = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001722
Roland McGrath85a3bc42007-08-02 02:13:05 +00001723 cp.p64 = 1;
1724 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1725 if (umoven(tcp, addr, personality_wordsize[current_personality],
1726 cp.data) < 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001727 tprintf("%#lx", addr);
1728 return;
1729 }
Roland McGrath85a3bc42007-08-02 02:13:05 +00001730 if (personality_wordsize[current_personality] == 4)
1731 cp.p64 = cp.p32;
1732 if (cp.p64 == 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001733 break;
1734 tprintf(sep);
Roland McGrath85a3bc42007-08-02 02:13:05 +00001735 printstr(tcp, cp.p64, -1);
1736 addr += personality_wordsize[current_personality];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001737 }
Roland McGrath85a3bc42007-08-02 02:13:05 +00001738 if (cp.p64)
1739 tprintf("%s...", sep);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001740}
1741
1742static void
1743printargc(fmt, tcp, addr)
1744char *fmt;
1745struct tcb *tcp;
1746long addr;
1747{
1748 int count;
1749 char *cp;
1750
1751 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1752 addr += sizeof(char *);
1753 }
1754 tprintf(fmt, count, count == 1 ? "" : "s");
1755}
1756
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001757#if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001758int
1759sys_execv(tcp)
1760struct tcb *tcp;
1761{
1762 if (entering(tcp)) {
1763 printpath(tcp, tcp->u_arg[0]);
1764 if (!verbose(tcp))
1765 tprintf(", %#lx", tcp->u_arg[1]);
1766#if 0
1767 else if (abbrev(tcp))
1768 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1769#endif
1770 else {
1771 tprintf(", [");
1772 printargv(tcp, tcp->u_arg[1]);
1773 tprintf("]");
1774 }
1775 }
1776 return 0;
1777}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001778#endif /* SPARC || SPARC64 || SUNOS4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001779
1780int
1781sys_execve(tcp)
1782struct tcb *tcp;
1783{
1784 if (entering(tcp)) {
1785 printpath(tcp, tcp->u_arg[0]);
1786 if (!verbose(tcp))
1787 tprintf(", %#lx", tcp->u_arg[1]);
1788#if 0
1789 else if (abbrev(tcp))
1790 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1791#endif
1792 else {
1793 tprintf(", [");
1794 printargv(tcp, tcp->u_arg[1]);
1795 tprintf("]");
1796 }
1797 if (!verbose(tcp))
1798 tprintf(", %#lx", tcp->u_arg[2]);
1799 else if (abbrev(tcp))
1800 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1801 else {
1802 tprintf(", [");
1803 printargv(tcp, tcp->u_arg[2]);
1804 tprintf("]");
1805 }
1806 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001807 return 0;
1808}
1809
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001810#if UNIXWARE > 2
John Hughes4e36a812001-04-18 15:11:51 +00001811
1812int sys_rexecve(tcp)
1813struct tcb *tcp;
1814{
1815 if (entering (tcp)) {
1816 sys_execve (tcp);
1817 tprintf (", %ld", tcp->u_arg[3]);
1818 }
1819 return 0;
1820}
1821
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001822#endif
John Hughes4e36a812001-04-18 15:11:51 +00001823
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001824int
1825internal_exec(tcp)
1826struct tcb *tcp;
1827{
1828#ifdef SUNOS4
1829 if (exiting(tcp) && !syserror(tcp) && followfork)
1830 fixvfork(tcp);
1831#endif /* SUNOS4 */
Roland McGrathfdb097f2004-07-12 07:38:55 +00001832#if defined LINUX && defined TCB_WAITEXECVE
1833 if (exiting(tcp) && syserror(tcp))
1834 tcp->flags &= ~TCB_WAITEXECVE;
1835 else
1836 tcp->flags |= TCB_WAITEXECVE;
1837#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001838 return 0;
1839}
1840
1841#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001842#ifndef __WNOTHREAD
1843#define __WNOTHREAD 0x20000000
1844#endif
1845#ifndef __WALL
1846#define __WALL 0x40000000
1847#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001848#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001849#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001850#endif
1851#endif /* LINUX */
1852
Roland McGrathd9f816f2004-09-04 03:39:20 +00001853static const struct xlat wait4_options[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001854 { WNOHANG, "WNOHANG" },
1855#ifndef WSTOPPED
1856 { WUNTRACED, "WUNTRACED" },
1857#endif
1858#ifdef WEXITED
1859 { WEXITED, "WEXITED" },
1860#endif
1861#ifdef WTRAPPED
1862 { WTRAPPED, "WTRAPPED" },
1863#endif
1864#ifdef WSTOPPED
1865 { WSTOPPED, "WSTOPPED" },
1866#endif
1867#ifdef WCONTINUED
1868 { WCONTINUED, "WCONTINUED" },
1869#endif
1870#ifdef WNOWAIT
1871 { WNOWAIT, "WNOWAIT" },
1872#endif
1873#ifdef __WCLONE
1874 { __WCLONE, "__WCLONE" },
1875#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001876#ifdef __WALL
1877 { __WALL, "__WALL" },
1878#endif
1879#ifdef __WNOTHREAD
1880 { __WNOTHREAD, "__WNOTHREAD" },
1881#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001882 { 0, NULL },
1883};
1884
Roland McGrath5e02a572004-10-19 23:33:47 +00001885#if !defined WCOREFLAG && defined WCOREFLG
1886# define WCOREFLAG WCOREFLG
1887#endif
1888#ifndef WCOREFLAG
1889#define WCOREFLAG 0x80
1890#endif
1891
1892#ifndef W_STOPCODE
1893#define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1894#endif
1895#ifndef W_EXITCODE
1896#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1897#endif
1898
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001899static int
1900printstatus(status)
1901int status;
1902{
1903 int exited = 0;
1904
1905 /*
1906 * Here is a tricky presentation problem. This solution
1907 * is still not entirely satisfactory but since there
1908 * are no wait status constructors it will have to do.
1909 */
Roland McGrath79fbda52004-04-14 02:45:55 +00001910 if (WIFSTOPPED(status)) {
1911 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001912 signame(WSTOPSIG(status)));
Roland McGrath79fbda52004-04-14 02:45:55 +00001913 status &= ~W_STOPCODE(WSTOPSIG(status));
1914 }
1915 else if (WIFSIGNALED(status)) {
1916 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001917 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001918 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
Roland McGrath79fbda52004-04-14 02:45:55 +00001919 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1920 }
1921 else if (WIFEXITED(status)) {
1922 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001923 WEXITSTATUS(status));
1924 exited = 1;
Roland McGrath79fbda52004-04-14 02:45:55 +00001925 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001926 }
Roland McGrath79fbda52004-04-14 02:45:55 +00001927 else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001928 tprintf("[%#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001929 return 0;
1930 }
1931
1932 if (status == 0)
1933 tprintf("]");
1934 else
Roland McGrathf8cc83c2004-06-04 01:24:07 +00001935 tprintf(" | %#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001936
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001937 return exited;
1938}
1939
1940static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001941printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001942struct tcb *tcp;
1943int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001944int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001945{
1946 int status;
1947 int exited = 0;
1948
1949 if (entering(tcp)) {
1950 tprintf("%ld, ", tcp->u_arg[0]);
1951 } else {
1952 /* status */
1953 if (!tcp->u_arg[1])
1954 tprintf("NULL");
1955 else if (syserror(tcp) || tcp->u_rval == 0)
1956 tprintf("%#lx", tcp->u_arg[1]);
1957 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1958 tprintf("[?]");
1959 else
1960 exited = printstatus(status);
1961 /* options */
1962 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00001963 printflags(wait4_options, tcp->u_arg[2], "W???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001964 if (n == 4) {
1965 tprintf(", ");
1966 /* usage */
1967 if (!tcp->u_arg[3])
1968 tprintf("NULL");
1969#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001970 else if (tcp->u_rval > 0) {
1971#ifdef LINUX_64BIT
1972 if (bitness)
1973 printrusage32(tcp, tcp->u_arg[3]);
1974 else
1975#endif
1976 printrusage(tcp, tcp->u_arg[3]);
1977 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001978#endif /* LINUX */
1979#ifdef SUNOS4
1980 else if (tcp->u_rval > 0 && exited)
1981 printrusage(tcp, tcp->u_arg[3]);
1982#endif /* SUNOS4 */
1983 else
1984 tprintf("%#lx", tcp->u_arg[3]);
1985 }
1986 }
1987 return 0;
1988}
1989
1990int
Roland McGrathc74c0b72004-09-01 19:39:46 +00001991internal_wait(tcp, flagarg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001992struct tcb *tcp;
Roland McGrathc74c0b72004-09-01 19:39:46 +00001993int flagarg;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001994{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001995 int got_kids;
1996
1997#ifdef TCB_CLONE_THREAD
1998 if (tcp->flags & TCB_CLONE_THREAD)
1999 /* The children we wait for are our parent's children. */
2000 got_kids = (tcp->parent->nchildren
2001 > tcp->parent->nclone_detached);
2002 else
2003 got_kids = (tcp->nchildren > tcp->nclone_detached);
2004#else
2005 got_kids = tcp->nchildren > 0;
2006#endif
2007
2008 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00002009 /* There are children that this parent should block for.
2010 But ptrace made us the parent of the traced children
2011 and the real parent will get ECHILD from the wait call.
2012
2013 XXX If we attached with strace -f -p PID, then there
2014 may be untraced dead children the parent could be reaping
2015 now, but we make him block. */
2016
2017 /* ??? WTA: fix bug with hanging children */
2018
Roland McGrathc74c0b72004-09-01 19:39:46 +00002019 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00002020 /*
2021 * There are traced children. We'll make the parent
2022 * block to avoid a false ECHILD error due to our
2023 * ptrace having stolen the children. However,
2024 * we shouldn't block if there are zombies to reap.
2025 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
2026 */
Roland McGrathfccfb942003-10-01 21:59:44 +00002027 struct tcb *child = NULL;
Roland McGrath09623452003-05-23 02:27:13 +00002028 if (tcp->nzombies > 0 &&
2029 (tcp->u_arg[0] == -1 ||
Roland McGrathfccfb942003-10-01 21:59:44 +00002030 (child = pid2tcb(tcp->u_arg[0])) == NULL))
Roland McGrath09623452003-05-23 02:27:13 +00002031 return 0;
Roland McGrathfccfb942003-10-01 21:59:44 +00002032 if (tcp->u_arg[0] > 0) {
2033 /*
2034 * If the parent waits for a specified child
2035 * PID, then it must get ECHILD right away
2036 * if that PID is not one of its children.
2037 * Make sure that the requested PID matches
2038 * one of the parent's children that we are
2039 * tracing, and don't suspend it otherwise.
2040 */
2041 if (child == NULL)
2042 child = pid2tcb(tcp->u_arg[0]);
2043 if (child == NULL || child->parent != (
2044#ifdef TCB_CLONE_THREAD
2045 (tcp->flags & TCB_CLONE_THREAD)
2046 ? tcp->parent :
2047#endif
Roland McGrathd56a6562005-08-03 11:23:43 +00002048 tcp) ||
2049 (child->flags & TCB_EXITING))
Roland McGrathfccfb942003-10-01 21:59:44 +00002050 return 0;
2051 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002052 tcp->flags |= TCB_SUSPENDED;
2053 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002054#ifdef TCB_CLONE_THREAD
2055 if (tcp->flags & TCB_CLONE_THREAD)
2056 tcp->parent->nclone_waiting++;
2057#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002058 }
2059 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002060 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathc74c0b72004-09-01 19:39:46 +00002061 if (tcp->u_arg[flagarg] & WNOHANG) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00002062 /* We must force a fake result of 0 instead of
2063 the ECHILD error. */
2064 extern int force_result();
2065 return force_result(tcp, 0, 0);
2066 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00002067 }
Roland McGrath09623452003-05-23 02:27:13 +00002068 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2069 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2070 /*
2071 * We just reaped a child we don't know about,
2072 * presumably a zombie we already droptcb'd.
2073 */
2074 tcp->nzombies--;
2075 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002076 return 0;
2077}
2078
2079#ifdef SVR4
2080
2081int
2082sys_wait(tcp)
2083struct tcb *tcp;
2084{
2085 if (exiting(tcp)) {
2086 /* The library wrapper stuffs this into the user variable. */
2087 if (!syserror(tcp))
2088 printstatus(getrval2(tcp));
2089 }
2090 return 0;
2091}
2092
2093#endif /* SVR4 */
2094
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002095#ifdef FREEBSD
2096int
2097sys_wait(tcp)
2098struct tcb *tcp;
2099{
2100 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00002101
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002102 if (exiting(tcp)) {
2103 if (!syserror(tcp)) {
2104 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2105 tprintf("%#lx", tcp->u_arg[0]);
2106 else
2107 printstatus(status);
2108 }
2109 }
2110 return 0;
2111}
2112#endif
2113
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002114int
2115sys_waitpid(tcp)
2116struct tcb *tcp;
2117{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002118 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002119}
2120
2121int
2122sys_wait4(tcp)
2123struct tcb *tcp;
2124{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002125 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002126}
2127
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002128#ifdef ALPHA
2129int
2130sys_osf_wait4(tcp)
2131struct tcb *tcp;
2132{
2133 return printwaitn(tcp, 4, 1);
2134}
2135#endif
2136
Roland McGrathc74c0b72004-09-01 19:39:46 +00002137#if defined SVR4 || defined LINUX
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002138
Roland McGrathd9f816f2004-09-04 03:39:20 +00002139static const struct xlat waitid_types[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002140 { P_PID, "P_PID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002141#ifdef P_PPID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002142 { P_PPID, "P_PPID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002143#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002144 { P_PGID, "P_PGID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002145#ifdef P_SID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002146 { P_SID, "P_SID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002147#endif
2148#ifdef P_CID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002149 { P_CID, "P_CID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002150#endif
2151#ifdef P_UID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002152 { P_UID, "P_UID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002153#endif
2154#ifdef P_GID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002155 { P_GID, "P_GID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002156#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002157 { P_ALL, "P_ALL" },
2158#ifdef P_LWPID
2159 { P_LWPID, "P_LWPID" },
2160#endif
2161 { 0, NULL },
2162};
2163
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002164int
2165sys_waitid(tcp)
2166struct tcb *tcp;
2167{
2168 siginfo_t si;
2169 int exited;
2170
2171 if (entering(tcp)) {
2172 printxval(waitid_types, tcp->u_arg[0], "P_???");
2173 tprintf(", %ld, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002174 }
2175 else {
2176 /* siginfo */
2177 exited = 0;
2178 if (!tcp->u_arg[2])
2179 tprintf("NULL");
2180 else if (syserror(tcp))
2181 tprintf("%#lx", tcp->u_arg[2]);
2182 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2183 tprintf("{???}");
2184 else
John Hughes58265892001-10-18 15:13:53 +00002185 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002186 /* options */
2187 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00002188 printflags(wait4_options, tcp->u_arg[3], "W???");
Roland McGrath39426a32004-10-06 22:02:59 +00002189 if (tcp->u_nargs > 4) {
2190 /* usage */
2191 tprintf(", ");
2192 if (!tcp->u_arg[4])
2193 tprintf("NULL");
2194 else if (tcp->u_error)
2195 tprintf("%#lx", tcp->u_arg[4]);
2196 else
2197 printrusage(tcp, tcp->u_arg[4]);
2198 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002199 }
2200 return 0;
2201}
2202
Roland McGrathc74c0b72004-09-01 19:39:46 +00002203#endif /* SVR4 or LINUX */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002204
2205int
2206sys_alarm(tcp)
2207struct tcb *tcp;
2208{
2209 if (entering(tcp))
2210 tprintf("%lu", tcp->u_arg[0]);
2211 return 0;
2212}
2213
2214int
2215sys_uname(tcp)
2216struct tcb *tcp;
2217{
2218 struct utsname uname;
2219
2220 if (exiting(tcp)) {
2221 if (syserror(tcp) || !verbose(tcp))
2222 tprintf("%#lx", tcp->u_arg[0]);
2223 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2224 tprintf("{...}");
2225 else if (!abbrev(tcp)) {
2226
2227 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2228 uname.sysname, uname.nodename);
2229 tprintf("release=\"%s\", version=\"%s\", ",
2230 uname.release, uname.version);
2231 tprintf("machine=\"%s\"", uname.machine);
2232#ifdef LINUX
2233#ifndef __GLIBC__
2234 tprintf(", domainname=\"%s\"", uname.domainname);
2235#endif /* __GLIBC__ */
2236#endif /* LINUX */
2237 tprintf("}");
2238 }
2239 else
2240 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2241 uname.sysname, uname.nodename);
2242 }
2243 return 0;
2244}
2245
2246#ifndef SVR4
2247
Roland McGrathd9f816f2004-09-04 03:39:20 +00002248static const struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002249#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002250 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2251 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2252 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2253 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2254 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2255 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2256 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2257 { PTRACE_CONT, "PTRACE_CONT" },
2258 { PTRACE_KILL, "PTRACE_KILL" },
2259 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2260 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2261 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002262#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002263 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002264#endif
2265#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002266 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002267#endif
2268#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002269 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002270#endif
2271#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002272 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002273#endif
2274#ifdef PTRACE_GETFPXREGS
2275 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2276#endif
2277#ifdef PTRACE_SETFPXREGS
2278 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2279#endif
Roland McGrathf04bb482005-05-09 07:45:33 +00002280#ifdef PTRACE_GETVRREGS
2281 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2282#endif
2283#ifdef PTRACE_SETVRREGS
2284 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2285#endif
Roland McGrathbf621d42003-01-14 09:46:21 +00002286#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002287 { PTRACE_READDATA, "PTRACE_READDATA" },
2288 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2289 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2290 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2291 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2292 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2293#ifdef SPARC
2294 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2295 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2296#else /* !SPARC */
2297 { PTRACE_22, "PTRACE_PTRACE_22" },
2298 { PTRACE_23, "PTRACE_PTRACE_23" },
2299#endif /* !SPARC */
2300#endif /* SUNOS4 */
2301 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2302#ifdef SUNOS4
2303 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2304#ifdef I386
2305 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2306 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2307 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2308#else /* !I386 */
2309 { PTRACE_26, "PTRACE_26" },
2310 { PTRACE_27, "PTRACE_27" },
2311 { PTRACE_28, "PTRACE_28" },
2312#endif /* !I386 */
2313 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2314#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002315#else /* FREEBSD */
2316 { PT_TRACE_ME, "PT_TRACE_ME" },
2317 { PT_READ_I, "PT_READ_I" },
2318 { PT_READ_D, "PT_READ_D" },
2319 { PT_WRITE_I, "PT_WRITE_I" },
2320 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002321#ifdef PT_READ_U
2322 { PT_READ_U, "PT_READ_U" },
2323#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002324 { PT_CONTINUE, "PT_CONTINUE" },
2325 { PT_KILL, "PT_KILL" },
2326 { PT_STEP, "PT_STEP" },
2327 { PT_ATTACH, "PT_ATTACH" },
2328 { PT_DETACH, "PT_DETACH" },
2329 { PT_GETREGS, "PT_GETREGS" },
2330 { PT_SETREGS, "PT_SETREGS" },
2331 { PT_GETFPREGS, "PT_GETFPREGS" },
2332 { PT_SETFPREGS, "PT_SETFPREGS" },
2333 { PT_GETDBREGS, "PT_GETDBREGS" },
2334 { PT_SETDBREGS, "PT_SETDBREGS" },
2335#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002336 { 0, NULL },
2337};
2338
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002339#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002340#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2341static
2342#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
Roland McGrathd9f816f2004-09-04 03:39:20 +00002343const struct xlat struct_user_offsets[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002344#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002345#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002346 { PT_PSWMASK, "psw_mask" },
2347 { PT_PSWADDR, "psw_addr" },
2348 { PT_GPR0, "gpr0" },
2349 { PT_GPR1, "gpr1" },
2350 { PT_GPR2, "gpr2" },
2351 { PT_GPR3, "gpr3" },
2352 { PT_GPR4, "gpr4" },
2353 { PT_GPR5, "gpr5" },
2354 { PT_GPR6, "gpr6" },
2355 { PT_GPR7, "gpr7" },
2356 { PT_GPR8, "gpr8" },
2357 { PT_GPR9, "gpr9" },
2358 { PT_GPR10, "gpr10" },
2359 { PT_GPR11, "gpr11" },
2360 { PT_GPR12, "gpr12" },
2361 { PT_GPR13, "gpr13" },
2362 { PT_GPR14, "gpr14" },
2363 { PT_GPR15, "gpr15" },
2364 { PT_ACR0, "acr0" },
2365 { PT_ACR1, "acr1" },
2366 { PT_ACR2, "acr2" },
2367 { PT_ACR3, "acr3" },
2368 { PT_ACR4, "acr4" },
2369 { PT_ACR5, "acr5" },
2370 { PT_ACR6, "acr6" },
2371 { PT_ACR7, "acr7" },
2372 { PT_ACR8, "acr8" },
2373 { PT_ACR9, "acr9" },
2374 { PT_ACR10, "acr10" },
2375 { PT_ACR11, "acr11" },
2376 { PT_ACR12, "acr12" },
2377 { PT_ACR13, "acr13" },
2378 { PT_ACR14, "acr14" },
2379 { PT_ACR15, "acr15" },
2380 { PT_ORIGGPR2, "orig_gpr2" },
2381 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002382#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002383 { PT_FPR0_HI, "fpr0.hi" },
2384 { PT_FPR0_LO, "fpr0.lo" },
2385 { PT_FPR1_HI, "fpr1.hi" },
2386 { PT_FPR1_LO, "fpr1.lo" },
2387 { PT_FPR2_HI, "fpr2.hi" },
2388 { PT_FPR2_LO, "fpr2.lo" },
2389 { PT_FPR3_HI, "fpr3.hi" },
2390 { PT_FPR3_LO, "fpr3.lo" },
2391 { PT_FPR4_HI, "fpr4.hi" },
2392 { PT_FPR4_LO, "fpr4.lo" },
2393 { PT_FPR5_HI, "fpr5.hi" },
2394 { PT_FPR5_LO, "fpr5.lo" },
2395 { PT_FPR6_HI, "fpr6.hi" },
2396 { PT_FPR6_LO, "fpr6.lo" },
2397 { PT_FPR7_HI, "fpr7.hi" },
2398 { PT_FPR7_LO, "fpr7.lo" },
2399 { PT_FPR8_HI, "fpr8.hi" },
2400 { PT_FPR8_LO, "fpr8.lo" },
2401 { PT_FPR9_HI, "fpr9.hi" },
2402 { PT_FPR9_LO, "fpr9.lo" },
2403 { PT_FPR10_HI, "fpr10.hi" },
2404 { PT_FPR10_LO, "fpr10.lo" },
2405 { PT_FPR11_HI, "fpr11.hi" },
2406 { PT_FPR11_LO, "fpr11.lo" },
2407 { PT_FPR12_HI, "fpr12.hi" },
2408 { PT_FPR12_LO, "fpr12.lo" },
2409 { PT_FPR13_HI, "fpr13.hi" },
2410 { PT_FPR13_LO, "fpr13.lo" },
2411 { PT_FPR14_HI, "fpr14.hi" },
2412 { PT_FPR14_LO, "fpr14.lo" },
2413 { PT_FPR15_HI, "fpr15.hi" },
2414 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002415#endif
2416#if defined(S390X)
2417 { PT_FPR0, "fpr0" },
2418 { PT_FPR1, "fpr1" },
2419 { PT_FPR2, "fpr2" },
2420 { PT_FPR3, "fpr3" },
2421 { PT_FPR4, "fpr4" },
2422 { PT_FPR5, "fpr5" },
2423 { PT_FPR6, "fpr6" },
2424 { PT_FPR7, "fpr7" },
2425 { PT_FPR8, "fpr8" },
2426 { PT_FPR9, "fpr9" },
2427 { PT_FPR10, "fpr10" },
2428 { PT_FPR11, "fpr11" },
2429 { PT_FPR12, "fpr12" },
2430 { PT_FPR13, "fpr13" },
2431 { PT_FPR14, "fpr14" },
2432 { PT_FPR15, "fpr15" },
2433#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002434 { PT_CR_9, "cr9" },
2435 { PT_CR_10, "cr10" },
2436 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002437 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002438#endif
2439#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002440 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002441#elif defined(HPPA)
2442 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002443#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002444#ifndef PT_ORIG_R3
2445#define PT_ORIG_R3 34
2446#endif
Roland McGratheb285352003-01-14 09:59:00 +00002447#define REGSIZE (sizeof(unsigned long))
2448 { REGSIZE*PT_R0, "r0" },
2449 { REGSIZE*PT_R1, "r1" },
2450 { REGSIZE*PT_R2, "r2" },
2451 { REGSIZE*PT_R3, "r3" },
2452 { REGSIZE*PT_R4, "r4" },
2453 { REGSIZE*PT_R5, "r5" },
2454 { REGSIZE*PT_R6, "r6" },
2455 { REGSIZE*PT_R7, "r7" },
2456 { REGSIZE*PT_R8, "r8" },
2457 { REGSIZE*PT_R9, "r9" },
2458 { REGSIZE*PT_R10, "r10" },
2459 { REGSIZE*PT_R11, "r11" },
2460 { REGSIZE*PT_R12, "r12" },
2461 { REGSIZE*PT_R13, "r13" },
2462 { REGSIZE*PT_R14, "r14" },
2463 { REGSIZE*PT_R15, "r15" },
2464 { REGSIZE*PT_R16, "r16" },
2465 { REGSIZE*PT_R17, "r17" },
2466 { REGSIZE*PT_R18, "r18" },
2467 { REGSIZE*PT_R19, "r19" },
2468 { REGSIZE*PT_R20, "r20" },
2469 { REGSIZE*PT_R21, "r21" },
2470 { REGSIZE*PT_R22, "r22" },
2471 { REGSIZE*PT_R23, "r23" },
2472 { REGSIZE*PT_R24, "r24" },
2473 { REGSIZE*PT_R25, "r25" },
2474 { REGSIZE*PT_R26, "r26" },
2475 { REGSIZE*PT_R27, "r27" },
2476 { REGSIZE*PT_R28, "r28" },
2477 { REGSIZE*PT_R29, "r29" },
2478 { REGSIZE*PT_R30, "r30" },
2479 { REGSIZE*PT_R31, "r31" },
2480 { REGSIZE*PT_NIP, "NIP" },
2481 { REGSIZE*PT_MSR, "MSR" },
2482 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2483 { REGSIZE*PT_CTR, "CTR" },
2484 { REGSIZE*PT_LNK, "LNK" },
2485 { REGSIZE*PT_XER, "XER" },
2486 { REGSIZE*PT_CCR, "CCR" },
2487 { REGSIZE*PT_FPR0, "FPR0" },
2488#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002489#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002490#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002491 { 0, "r0" },
2492 { 1, "r1" },
2493 { 2, "r2" },
2494 { 3, "r3" },
2495 { 4, "r4" },
2496 { 5, "r5" },
2497 { 6, "r6" },
2498 { 7, "r7" },
2499 { 8, "r8" },
2500 { 9, "r9" },
2501 { 10, "r10" },
2502 { 11, "r11" },
2503 { 12, "r12" },
2504 { 13, "r13" },
2505 { 14, "r14" },
2506 { 15, "r15" },
2507 { 16, "r16" },
2508 { 17, "r17" },
2509 { 18, "r18" },
2510 { 19, "r19" },
2511 { 20, "r20" },
2512 { 21, "r21" },
2513 { 22, "r22" },
2514 { 23, "r23" },
2515 { 24, "r24" },
2516 { 25, "r25" },
2517 { 26, "r26" },
2518 { 27, "r27" },
2519 { 28, "r28" },
2520 { 29, "gp" },
2521 { 30, "fp" },
2522 { 31, "zero" },
2523 { 32, "fp0" },
2524 { 33, "fp" },
2525 { 34, "fp2" },
2526 { 35, "fp3" },
2527 { 36, "fp4" },
2528 { 37, "fp5" },
2529 { 38, "fp6" },
2530 { 39, "fp7" },
2531 { 40, "fp8" },
2532 { 41, "fp9" },
2533 { 42, "fp10" },
2534 { 43, "fp11" },
2535 { 44, "fp12" },
2536 { 45, "fp13" },
2537 { 46, "fp14" },
2538 { 47, "fp15" },
2539 { 48, "fp16" },
2540 { 49, "fp17" },
2541 { 50, "fp18" },
2542 { 51, "fp19" },
2543 { 52, "fp20" },
2544 { 53, "fp21" },
2545 { 54, "fp22" },
2546 { 55, "fp23" },
2547 { 56, "fp24" },
2548 { 57, "fp25" },
2549 { 58, "fp26" },
2550 { 59, "fp27" },
2551 { 60, "fp28" },
2552 { 61, "fp29" },
2553 { 62, "fp30" },
2554 { 63, "fp31" },
2555 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002556#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002557#ifdef IA64
2558 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2559 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2560 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2561 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2562 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2563 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2564 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2565 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2566 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2567 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2568 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2569 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2570 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2571 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2572 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2573 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2574 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2575 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2576 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2577 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2578 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2579 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2580 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2581 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2582 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2583 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2584 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2585 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2586 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2587 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2588 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2589 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2590 /* switch stack: */
2591 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2592 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2593 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2594 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2595 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2596 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2597 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2598 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2599 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2600 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002601 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2602 { PT_B4, "b4" }, { PT_B5, "b5" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002603 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002604 /* pt_regs */
Roland McGrathca4e10c2004-01-13 10:13:20 +00002605 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2606 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002607 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2608 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2609 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2610 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2611 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2612 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2613 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2614 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2615 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2616 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2617 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2618 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2619 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2620 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2621 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
Roland McGrathfb1bc072004-03-01 21:29:24 +00002622# ifdef PT_AR_CSD
2623 { PT_AR_CSD, "ar.csd" },
2624# endif
2625# ifdef PT_AR_SSD
2626 { PT_AR_SSD, "ar.ssd" },
2627# endif
Roland McGrathca4e10c2004-01-13 10:13:20 +00002628 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002629#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002630#ifdef I386
2631 { 4*EBX, "4*EBX" },
2632 { 4*ECX, "4*ECX" },
2633 { 4*EDX, "4*EDX" },
2634 { 4*ESI, "4*ESI" },
2635 { 4*EDI, "4*EDI" },
2636 { 4*EBP, "4*EBP" },
2637 { 4*EAX, "4*EAX" },
2638 { 4*DS, "4*DS" },
2639 { 4*ES, "4*ES" },
2640 { 4*FS, "4*FS" },
2641 { 4*GS, "4*GS" },
2642 { 4*ORIG_EAX, "4*ORIG_EAX" },
2643 { 4*EIP, "4*EIP" },
2644 { 4*CS, "4*CS" },
2645 { 4*EFL, "4*EFL" },
2646 { 4*UESP, "4*UESP" },
2647 { 4*SS, "4*SS" },
2648#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002649#ifdef X86_64
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002650 { 8*R15, "8*R15" },
2651 { 8*R14, "8*R14" },
2652 { 8*R13, "8*R13" },
2653 { 8*R12, "8*R12" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002654 { 8*RBP, "8*RBP" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002655 { 8*RBX, "8*RBX" },
2656 { 8*R11, "8*R11" },
2657 { 8*R10, "8*R10" },
2658 { 8*R9, "8*R9" },
2659 { 8*R8, "8*R8" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002660 { 8*RAX, "8*RAX" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002661 { 8*RCX, "8*RCX" },
2662 { 8*RDX, "8*RDX" },
2663 { 8*RSI, "8*RSI" },
2664 { 8*RDI, "8*RDI" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002665#if 0
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002666 { DS, "DS" },
2667 { ES, "ES" },
2668 { FS, "FS" },
2669 { GS, "GS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002670#endif
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002671 { 8*ORIG_RAX, "8*ORIG_RAX" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002672 { 8*RIP, "8*RIP" },
2673 { 8*CS, "8*CS" },
2674 { 8*EFLAGS, "8*EFL" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002675 { 8*RSP, "8*RSP" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002676 { 8*SS, "8*SS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002677#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002678#ifdef M68K
2679 { 4*PT_D1, "4*PT_D1" },
2680 { 4*PT_D2, "4*PT_D2" },
2681 { 4*PT_D3, "4*PT_D3" },
2682 { 4*PT_D4, "4*PT_D4" },
2683 { 4*PT_D5, "4*PT_D5" },
2684 { 4*PT_D6, "4*PT_D6" },
2685 { 4*PT_D7, "4*PT_D7" },
2686 { 4*PT_A0, "4*PT_A0" },
2687 { 4*PT_A1, "4*PT_A1" },
2688 { 4*PT_A2, "4*PT_A2" },
2689 { 4*PT_A3, "4*PT_A3" },
2690 { 4*PT_A4, "4*PT_A4" },
2691 { 4*PT_A5, "4*PT_A5" },
2692 { 4*PT_A6, "4*PT_A6" },
2693 { 4*PT_D0, "4*PT_D0" },
2694 { 4*PT_USP, "4*PT_USP" },
2695 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2696 { 4*PT_SR, "4*PT_SR" },
2697 { 4*PT_PC, "4*PT_PC" },
2698#endif /* M68K */
2699#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002700#ifdef SH
2701 { 4*REG_REG0, "4*REG_REG0" },
2702 { 4*(REG_REG0+1), "4*REG_REG1" },
2703 { 4*(REG_REG0+2), "4*REG_REG2" },
2704 { 4*(REG_REG0+3), "4*REG_REG3" },
2705 { 4*(REG_REG0+4), "4*REG_REG4" },
2706 { 4*(REG_REG0+5), "4*REG_REG5" },
2707 { 4*(REG_REG0+6), "4*REG_REG6" },
2708 { 4*(REG_REG0+7), "4*REG_REG7" },
2709 { 4*(REG_REG0+8), "4*REG_REG8" },
2710 { 4*(REG_REG0+9), "4*REG_REG9" },
2711 { 4*(REG_REG0+10), "4*REG_REG10" },
2712 { 4*(REG_REG0+11), "4*REG_REG11" },
2713 { 4*(REG_REG0+12), "4*REG_REG12" },
2714 { 4*(REG_REG0+13), "4*REG_REG13" },
2715 { 4*(REG_REG0+14), "4*REG_REG14" },
2716 { 4*REG_REG15, "4*REG_REG15" },
2717 { 4*REG_PC, "4*REG_PC" },
2718 { 4*REG_PR, "4*REG_PR" },
2719 { 4*REG_SR, "4*REG_SR" },
2720 { 4*REG_GBR, "4*REG_GBR" },
2721 { 4*REG_MACH, "4*REG_MACH" },
2722 { 4*REG_MACL, "4*REG_MACL" },
2723 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2724 { 4*REG_FPUL, "4*REG_FPUL" },
2725 { 4*REG_FPREG0, "4*REG_FPREG0" },
2726 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2727 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2728 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2729 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2730 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2731 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2732 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2733 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2734 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2735 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2736 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2737 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2738 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2739 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2740 { 4*REG_FPREG15, "4*REG_FPREG15" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002741#ifdef REG_XDREG0
Wichert Akkermanccef6372002-05-01 16:39:22 +00002742 { 4*REG_XDREG0, "4*REG_XDREG0" },
2743 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2744 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2745 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2746 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2747 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2748 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2749 { 4*REG_XDREG14, "4*REG_XDREG14" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002750#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002751 { 4*REG_FPSCR, "4*REG_FPSCR" },
2752#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002753#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002754 { 0, "PC(L)" },
2755 { 4, "PC(U)" },
2756 { 8, "SR(L)" },
2757 { 12, "SR(U)" },
2758 { 16, "syscall no.(L)" },
2759 { 20, "syscall_no.(U)" },
2760 { 24, "R0(L)" },
2761 { 28, "R0(U)" },
2762 { 32, "R1(L)" },
2763 { 36, "R1(U)" },
2764 { 40, "R2(L)" },
2765 { 44, "R2(U)" },
2766 { 48, "R3(L)" },
2767 { 52, "R3(U)" },
2768 { 56, "R4(L)" },
2769 { 60, "R4(U)" },
2770 { 64, "R5(L)" },
2771 { 68, "R5(U)" },
2772 { 72, "R6(L)" },
2773 { 76, "R6(U)" },
2774 { 80, "R7(L)" },
2775 { 84, "R7(U)" },
2776 { 88, "R8(L)" },
2777 { 92, "R8(U)" },
2778 { 96, "R9(L)" },
2779 { 100, "R9(U)" },
2780 { 104, "R10(L)" },
2781 { 108, "R10(U)" },
2782 { 112, "R11(L)" },
2783 { 116, "R11(U)" },
2784 { 120, "R12(L)" },
2785 { 124, "R12(U)" },
2786 { 128, "R13(L)" },
2787 { 132, "R13(U)" },
2788 { 136, "R14(L)" },
2789 { 140, "R14(U)" },
2790 { 144, "R15(L)" },
2791 { 148, "R15(U)" },
2792 { 152, "R16(L)" },
2793 { 156, "R16(U)" },
2794 { 160, "R17(L)" },
2795 { 164, "R17(U)" },
2796 { 168, "R18(L)" },
2797 { 172, "R18(U)" },
2798 { 176, "R19(L)" },
2799 { 180, "R19(U)" },
2800 { 184, "R20(L)" },
2801 { 188, "R20(U)" },
2802 { 192, "R21(L)" },
2803 { 196, "R21(U)" },
2804 { 200, "R22(L)" },
2805 { 204, "R22(U)" },
2806 { 208, "R23(L)" },
2807 { 212, "R23(U)" },
2808 { 216, "R24(L)" },
2809 { 220, "R24(U)" },
2810 { 224, "R25(L)" },
2811 { 228, "R25(U)" },
2812 { 232, "R26(L)" },
2813 { 236, "R26(U)" },
2814 { 240, "R27(L)" },
2815 { 244, "R27(U)" },
2816 { 248, "R28(L)" },
2817 { 252, "R28(U)" },
2818 { 256, "R29(L)" },
2819 { 260, "R29(U)" },
2820 { 264, "R30(L)" },
2821 { 268, "R30(U)" },
2822 { 272, "R31(L)" },
2823 { 276, "R31(U)" },
2824 { 280, "R32(L)" },
2825 { 284, "R32(U)" },
2826 { 288, "R33(L)" },
2827 { 292, "R33(U)" },
2828 { 296, "R34(L)" },
2829 { 300, "R34(U)" },
2830 { 304, "R35(L)" },
2831 { 308, "R35(U)" },
2832 { 312, "R36(L)" },
2833 { 316, "R36(U)" },
2834 { 320, "R37(L)" },
2835 { 324, "R37(U)" },
2836 { 328, "R38(L)" },
2837 { 332, "R38(U)" },
2838 { 336, "R39(L)" },
2839 { 340, "R39(U)" },
2840 { 344, "R40(L)" },
2841 { 348, "R40(U)" },
2842 { 352, "R41(L)" },
2843 { 356, "R41(U)" },
2844 { 360, "R42(L)" },
2845 { 364, "R42(U)" },
2846 { 368, "R43(L)" },
2847 { 372, "R43(U)" },
2848 { 376, "R44(L)" },
2849 { 380, "R44(U)" },
2850 { 384, "R45(L)" },
2851 { 388, "R45(U)" },
2852 { 392, "R46(L)" },
2853 { 396, "R46(U)" },
2854 { 400, "R47(L)" },
2855 { 404, "R47(U)" },
2856 { 408, "R48(L)" },
2857 { 412, "R48(U)" },
2858 { 416, "R49(L)" },
2859 { 420, "R49(U)" },
2860 { 424, "R50(L)" },
2861 { 428, "R50(U)" },
2862 { 432, "R51(L)" },
2863 { 436, "R51(U)" },
2864 { 440, "R52(L)" },
2865 { 444, "R52(U)" },
2866 { 448, "R53(L)" },
2867 { 452, "R53(U)" },
2868 { 456, "R54(L)" },
2869 { 460, "R54(U)" },
2870 { 464, "R55(L)" },
2871 { 468, "R55(U)" },
2872 { 472, "R56(L)" },
2873 { 476, "R56(U)" },
2874 { 480, "R57(L)" },
2875 { 484, "R57(U)" },
2876 { 488, "R58(L)" },
2877 { 492, "R58(U)" },
2878 { 496, "R59(L)" },
2879 { 500, "R59(U)" },
2880 { 504, "R60(L)" },
2881 { 508, "R60(U)" },
2882 { 512, "R61(L)" },
2883 { 516, "R61(U)" },
2884 { 520, "R62(L)" },
2885 { 524, "R62(U)" },
2886 { 528, "TR0(L)" },
2887 { 532, "TR0(U)" },
2888 { 536, "TR1(L)" },
2889 { 540, "TR1(U)" },
2890 { 544, "TR2(L)" },
2891 { 548, "TR2(U)" },
2892 { 552, "TR3(L)" },
2893 { 556, "TR3(U)" },
2894 { 560, "TR4(L)" },
2895 { 564, "TR4(U)" },
2896 { 568, "TR5(L)" },
2897 { 572, "TR5(U)" },
2898 { 576, "TR6(L)" },
2899 { 580, "TR6(U)" },
2900 { 584, "TR7(L)" },
2901 { 588, "TR7(U)" },
2902 /* This entry is in case pt_regs contains dregs (depends on
2903 the kernel build options). */
2904 { uoff(regs), "offsetof(struct user, regs)" },
2905 { uoff(fpu), "offsetof(struct user, fpu)" },
2906#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002907#ifdef ARM
2908 { uoff(regs.ARM_r0), "r0" },
2909 { uoff(regs.ARM_r1), "r1" },
2910 { uoff(regs.ARM_r2), "r2" },
2911 { uoff(regs.ARM_r3), "r3" },
2912 { uoff(regs.ARM_r4), "r4" },
2913 { uoff(regs.ARM_r5), "r5" },
2914 { uoff(regs.ARM_r6), "r6" },
2915 { uoff(regs.ARM_r7), "r7" },
2916 { uoff(regs.ARM_r8), "r8" },
2917 { uoff(regs.ARM_r9), "r9" },
2918 { uoff(regs.ARM_r10), "r10" },
2919 { uoff(regs.ARM_fp), "fp" },
2920 { uoff(regs.ARM_ip), "ip" },
2921 { uoff(regs.ARM_sp), "sp" },
2922 { uoff(regs.ARM_lr), "lr" },
2923 { uoff(regs.ARM_pc), "pc" },
2924 { uoff(regs.ARM_cpsr), "cpsr" },
2925#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002926
Roland McGrath542c2c62008-05-20 01:11:56 +00002927#ifdef MIPS
2928 { 0, "r0" },
2929 { 1, "r1" },
2930 { 2, "r2" },
2931 { 3, "r3" },
2932 { 4, "r4" },
2933 { 5, "r5" },
2934 { 6, "r6" },
2935 { 7, "r7" },
2936 { 8, "r8" },
2937 { 9, "r9" },
2938 { 10, "r10" },
2939 { 11, "r11" },
2940 { 12, "r12" },
2941 { 13, "r13" },
2942 { 14, "r14" },
2943 { 15, "r15" },
2944 { 16, "r16" },
2945 { 17, "r17" },
2946 { 18, "r18" },
2947 { 19, "r19" },
2948 { 20, "r20" },
2949 { 21, "r21" },
2950 { 22, "r22" },
2951 { 23, "r23" },
2952 { 24, "r24" },
2953 { 25, "r25" },
2954 { 26, "r26" },
2955 { 27, "r27" },
2956 { 28, "r28" },
2957 { 29, "r29" },
2958 { 30, "r30" },
2959 { 31, "r31" },
2960 { 32, "f0" },
2961 { 33, "f1" },
2962 { 34, "f2" },
2963 { 35, "f3" },
2964 { 36, "f4" },
2965 { 37, "f5" },
2966 { 38, "f6" },
2967 { 39, "f7" },
2968 { 40, "f8" },
2969 { 41, "f9" },
2970 { 42, "f10" },
2971 { 43, "f11" },
2972 { 44, "f12" },
2973 { 45, "f13" },
2974 { 46, "f14" },
2975 { 47, "f15" },
2976 { 48, "f16" },
2977 { 49, "f17" },
2978 { 50, "f18" },
2979 { 51, "f19" },
2980 { 52, "f20" },
2981 { 53, "f21" },
2982 { 54, "f22" },
2983 { 55, "f23" },
2984 { 56, "f24" },
2985 { 57, "f25" },
2986 { 58, "f26" },
2987 { 59, "f27" },
2988 { 60, "f28" },
2989 { 61, "f29" },
2990 { 62, "f30" },
2991 { 63, "f31" },
2992 { 64, "pc" },
2993 { 65, "cause" },
2994 { 66, "badvaddr" },
2995 { 67, "mmhi" },
2996 { 68, "mmlo" },
2997 { 69, "fpcsr" },
2998 { 70, "fpeir" },
2999#endif
3000
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003001#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003002 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00003003#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00003004#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003005 { uoff(i387), "offsetof(struct user, i387)" },
3006#else /* !I386 */
3007#ifdef M68K
3008 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3009#endif /* M68K */
3010#endif /* !I386 */
3011 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3012 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3013 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003014#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003015 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003016#endif
Roland McGrathf5a47772003-06-26 22:40:42 +00003017#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00003018 { uoff(start_data), "offsetof(struct user, start_data)" },
3019#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003020#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003021 { uoff(start_stack), "offsetof(struct user, start_stack)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003022#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003023 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003024#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003025 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00003026#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003027#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003028 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003029#endif
3030#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003031 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3032#endif
3033 { uoff(magic), "offsetof(struct user, magic)" },
3034 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00003035#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003036 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3037#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00003038#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003039#endif /* !ALPHA */
3040#endif /* !POWERPC/!SPARC */
3041#endif /* LINUX */
3042#ifdef SUNOS4
3043 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3044 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3045 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3046 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3047 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3048 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3049 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3050 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3051 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3052 { uoff(u_error), "offsetof(struct user, u_error)" },
3053 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3054 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3055 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3056 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3057 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3058 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3059 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3060 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3061 { uoff(u_code), "offsetof(struct user, u_code)" },
3062 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3063 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3064 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3065 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3066 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3067 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3068 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3069 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3070 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3071 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3072 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3073 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3074 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3075 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3076 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3077 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3078 { uoff(u_start), "offsetof(struct user, u_start)" },
3079 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3080 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3081 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3082 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3083 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3084 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3085 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3086 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3087 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3088#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00003089#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003090 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00003091#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003092 { 0, NULL },
3093};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003094#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003095
3096int
3097sys_ptrace(tcp)
3098struct tcb *tcp;
3099{
Roland McGrathd9f816f2004-09-04 03:39:20 +00003100 const struct xlat *x;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003101 long addr;
3102
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003103 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00003104 printxval(ptrace_cmds, tcp->u_arg[0],
3105#ifndef FREEBSD
3106 "PTRACE_???"
3107#else
3108 "PT_???"
3109#endif
3110 );
3111 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003112 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003113#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003114 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3115 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3116 for (x = struct_user_offsets; x->str; x++) {
3117 if (x->val >= addr)
3118 break;
3119 }
3120 if (!x->str)
3121 tprintf("%#lx, ", addr);
3122 else if (x->val > addr && x != struct_user_offsets) {
3123 x--;
3124 tprintf("%s + %ld, ", x->str, addr - x->val);
3125 }
3126 else
3127 tprintf("%s, ", x->str);
3128 }
3129 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003130#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003131 tprintf("%#lx, ", tcp->u_arg[2]);
3132#ifdef LINUX
3133 switch (tcp->u_arg[0]) {
Roland McGrath1e868062007-11-19 22:11:45 +00003134#ifndef IA64
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003135 case PTRACE_PEEKDATA:
3136 case PTRACE_PEEKTEXT:
3137 case PTRACE_PEEKUSER:
3138 break;
Roland McGrath1e868062007-11-19 22:11:45 +00003139#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003140 case PTRACE_CONT:
3141 case PTRACE_SINGLESTEP:
3142 case PTRACE_SYSCALL:
3143 case PTRACE_DETACH:
3144 printsignal(tcp->u_arg[3]);
3145 break;
3146 default:
3147 tprintf("%#lx", tcp->u_arg[3]);
3148 break;
3149 }
3150 } else {
3151 switch (tcp->u_arg[0]) {
3152 case PTRACE_PEEKDATA:
3153 case PTRACE_PEEKTEXT:
3154 case PTRACE_PEEKUSER:
Roland McGrath1e868062007-11-19 22:11:45 +00003155#ifdef IA64
3156 return RVAL_HEX;
3157#else
Roland McGratheb285352003-01-14 09:59:00 +00003158 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003159 break;
Roland McGrath1e868062007-11-19 22:11:45 +00003160#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003161 }
3162 }
3163#endif /* LINUX */
3164#ifdef SUNOS4
3165 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3166 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3167 tprintf("%lu, ", tcp->u_arg[3]);
3168 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3169 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3170 tcp->u_arg[0] != PTRACE_READTEXT) {
3171 tprintf("%#lx", tcp->u_arg[3]);
3172 }
3173 } else {
3174 if (tcp->u_arg[0] == PTRACE_READDATA ||
3175 tcp->u_arg[0] == PTRACE_READTEXT) {
3176 tprintf("%lu, ", tcp->u_arg[3]);
3177 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3178 }
3179 }
3180#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003181#ifdef FREEBSD
3182 tprintf("%lu", tcp->u_arg[3]);
3183 }
3184#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003185 return 0;
3186}
3187
3188#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00003189
3190#ifdef LINUX
Roland McGrath51942a92007-07-05 18:59:11 +00003191# ifndef FUTEX_CMP_REQUEUE
3192# define FUTEX_CMP_REQUEUE 4
3193# endif
3194# ifndef FUTEX_WAKE_OP
3195# define FUTEX_WAKE_OP 5
3196# endif
3197# ifndef FUTEX_LOCK_PI
3198# define FUTEX_LOCK_PI 6
3199# define FUTEX_UNLOCK_PI 7
3200# define FUTEX_TRYLOCK_PI 8
3201# endif
Roland McGrath1aeaf742008-07-18 01:27:39 +00003202# ifndef FUTEX_WAIT_BITSET
3203# define FUTEX_WAIT_BITSET 9
3204# endif
3205# ifndef FUTEX_WAKE_BITSET
3206# define FUTEX_WAKE_BITSET 10
Roland McGrath51942a92007-07-05 18:59:11 +00003207# endif
3208# ifndef FUTEX_PRIVATE_FLAG
3209# define FUTEX_PRIVATE_FLAG 128
3210# endif
Roland McGrathd9f816f2004-09-04 03:39:20 +00003211static const struct xlat futexops[] = {
Roland McGrath51942a92007-07-05 18:59:11 +00003212 { FUTEX_WAIT, "FUTEX_WAIT" },
3213 { FUTEX_WAKE, "FUTEX_WAKE" },
3214 { FUTEX_FD, "FUTEX_FD" },
3215 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3216 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3217 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3218 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3219 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3220 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
Roland McGrath1aeaf742008-07-18 01:27:39 +00003221 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3222 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
Roland McGrath51942a92007-07-05 18:59:11 +00003223 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3224 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3225 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3226 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3227 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3228 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3229 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3230 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3231 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
Roland McGrath1aeaf742008-07-18 01:27:39 +00003232 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3233 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
Roland McGrath51942a92007-07-05 18:59:11 +00003234 { 0, NULL }
3235};
3236#ifndef FUTEX_OP_SET
3237# define FUTEX_OP_SET 0
3238# define FUTEX_OP_ADD 1
3239# define FUTEX_OP_OR 2
3240# define FUTEX_OP_ANDN 3
3241# define FUTEX_OP_XOR 4
3242# define FUTEX_OP_CMP_EQ 0
3243# define FUTEX_OP_CMP_NE 1
3244# define FUTEX_OP_CMP_LT 2
3245# define FUTEX_OP_CMP_LE 3
3246# define FUTEX_OP_CMP_GT 4
3247# define FUTEX_OP_CMP_GE 5
3248#endif
3249static const struct xlat futexwakeops[] = {
3250 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3251 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3252 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3253 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3254 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3255 { 0, NULL }
3256};
3257static const struct xlat futexwakecmps[] = {
3258 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3259 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3260 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3261 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3262 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3263 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3264 { 0, NULL }
Roland McGrath5a223472002-12-15 23:58:26 +00003265};
3266
3267int
3268sys_futex(tcp)
3269struct tcb *tcp;
3270{
3271 if (entering(tcp)) {
Roland McGrath1aeaf742008-07-18 01:27:39 +00003272 long int cmd = tcp->u_arg[1] & 127;
Roland McGrath5a223472002-12-15 23:58:26 +00003273 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00003274 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003275 tprintf(", %ld", tcp->u_arg[2]);
Roland McGrath1aeaf742008-07-18 01:27:39 +00003276 if (cmd == FUTEX_WAKE_BITSET)
3277 tprintf(", %lx", tcp->u_arg[5]);
3278 else if (cmd == FUTEX_WAIT) {
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003279 tprintf(", ");
3280 printtv(tcp, tcp->u_arg[3]);
Roland McGrath1aeaf742008-07-18 01:27:39 +00003281 } else if (cmd == FUTEX_WAIT_BITSET) {
3282 tprintf(", ");
3283 printtv(tcp, tcp->u_arg[3]);
3284 tprintf(", %lx", tcp->u_arg[5]);
Roland McGrath51942a92007-07-05 18:59:11 +00003285 } else if (cmd == FUTEX_REQUEUE)
Roland McGrath88812d62003-06-26 22:27:23 +00003286 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath51942a92007-07-05 18:59:11 +00003287 else if (cmd == FUTEX_CMP_REQUEUE)
3288 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3289 else if (cmd == FUTEX_WAKE_OP) {
3290 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3291 if ((tcp->u_arg[5] >> 28) & 8)
3292 tprintf("FUTEX_OP_OPARG_SHIFT|");
3293 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3294 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3295 if ((tcp->u_arg[5] >> 24) & 8)
3296 tprintf("FUTEX_OP_OPARG_SHIFT|");
3297 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3298 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3299 }
Roland McGrath5a223472002-12-15 23:58:26 +00003300 }
3301 return 0;
3302}
3303
3304static void
Roland McGrath79fbda52004-04-14 02:45:55 +00003305print_affinitylist(tcp, list, len)
3306struct tcb *tcp;
3307long list;
Roland McGrath5a223472002-12-15 23:58:26 +00003308unsigned int len;
3309{
3310 int first = 1;
3311 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00003312 while (len >= sizeof (unsigned long)) {
Roland McGrath79fbda52004-04-14 02:45:55 +00003313 unsigned long w;
3314 umove(tcp, list, &w);
3315 tprintf("%s %lx", first ? "" : ",", w);
Roland McGrath5a223472002-12-15 23:58:26 +00003316 first = 0;
3317 len -= sizeof (unsigned long);
Roland McGrath79fbda52004-04-14 02:45:55 +00003318 list += sizeof(unsigned long);
Roland McGrath5a223472002-12-15 23:58:26 +00003319 }
3320 tprintf(" }");
3321}
3322
3323int
3324sys_sched_setaffinity(tcp)
3325struct tcb *tcp;
3326{
3327 if (entering(tcp)) {
3328 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath79fbda52004-04-14 02:45:55 +00003329 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
Roland McGrath5a223472002-12-15 23:58:26 +00003330 }
3331 return 0;
3332}
3333
3334int
3335sys_sched_getaffinity(tcp)
3336struct tcb *tcp;
3337{
3338 if (entering(tcp)) {
3339 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3340 } else {
Roland McGrath79fbda52004-04-14 02:45:55 +00003341 if (tcp->u_rval == -1)
3342 tprintf("%#lx", tcp->u_arg[2]);
3343 else
3344 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
Roland McGrath5a223472002-12-15 23:58:26 +00003345 }
3346 return 0;
3347}
Roland McGrath279d3782004-03-01 20:27:37 +00003348
Roland McGrathd9f816f2004-09-04 03:39:20 +00003349static const struct xlat schedulers[] = {
Roland McGrath279d3782004-03-01 20:27:37 +00003350 { SCHED_OTHER, "SCHED_OTHER" },
3351 { SCHED_RR, "SCHED_RR" },
3352 { SCHED_FIFO, "SCHED_FIFO" },
3353 { 0, NULL }
3354};
3355
3356int
3357sys_sched_getscheduler(tcp)
3358struct tcb *tcp;
3359{
3360 if (entering(tcp)) {
3361 tprintf("%d", (int) tcp->u_arg[0]);
3362 } else if (! syserror(tcp)) {
3363 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3364 if (tcp->auxstr != NULL)
3365 return RVAL_STR;
3366 }
3367 return 0;
3368}
3369
3370int
3371sys_sched_setscheduler(tcp)
3372struct tcb *tcp;
3373{
3374 if (entering(tcp)) {
3375 struct sched_param p;
3376 tprintf("%d, ", (int) tcp->u_arg[0]);
3377 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3378 if (umove(tcp, tcp->u_arg[2], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003379 tprintf(", %#lx", tcp->u_arg[2]);
Roland McGrath279d3782004-03-01 20:27:37 +00003380 else
3381 tprintf(", { %d }", p.__sched_priority);
3382 }
3383 return 0;
3384}
3385
3386int
3387sys_sched_getparam(tcp)
3388struct tcb *tcp;
3389{
3390 if (entering(tcp)) {
3391 tprintf("%d, ", (int) tcp->u_arg[0]);
3392 } else {
3393 struct sched_param p;
3394 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003395 tprintf("%#lx", tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003396 else
3397 tprintf("{ %d }", p.__sched_priority);
3398 }
3399 return 0;
3400}
3401
3402int
3403sys_sched_setparam(tcp)
3404struct tcb *tcp;
3405{
3406 if (entering(tcp)) {
3407 struct sched_param p;
3408 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003409 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003410 else
3411 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3412 }
3413 return 0;
3414}
3415
3416int
3417sys_sched_get_priority_min(tcp)
3418struct tcb *tcp;
3419{
3420 if (entering(tcp)) {
3421 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3422 }
3423 return 0;
3424}
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003425
3426#ifdef X86_64
3427#include <asm/prctl.h>
3428
3429static const struct xlat archvals[] = {
3430 { ARCH_SET_GS, "ARCH_SET_GS" },
3431 { ARCH_SET_FS, "ARCH_SET_FS" },
3432 { ARCH_GET_FS, "ARCH_GET_FS" },
3433 { ARCH_GET_GS, "ARCH_GET_GS" },
3434 { 0, NULL },
3435};
3436
3437int
3438sys_arch_prctl(tcp)
3439struct tcb *tcp;
3440{
3441 if (entering(tcp)) {
3442 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3443 if (tcp->u_arg[0] == ARCH_SET_GS
3444 || tcp->u_arg[0] == ARCH_SET_FS)
3445 tprintf(", %#lx", tcp->u_arg[1]);
3446 } else {
3447 if (tcp->u_arg[0] == ARCH_GET_GS
3448 || tcp->u_arg[0] == ARCH_GET_FS) {
3449 long int v;
3450 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3451 tprintf(", [%#lx]", v);
3452 else
3453 tprintf(", %#lx", tcp->u_arg[1]);
3454 }
3455 }
3456 return 0;
3457}
3458#endif
3459
Roland McGrathdb8319f2007-08-02 01:37:55 +00003460
3461int
3462sys_getcpu(tcp)
3463struct tcb *tcp;
3464{
3465 if (exiting(tcp)) {
3466 unsigned u;
3467 if (tcp->u_arg[0] == 0)
3468 tprintf("NULL, ");
3469 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3470 tprintf("%#lx, ", tcp->u_arg[0]);
3471 else
3472 tprintf("[%u], ", u);
3473 if (tcp->u_arg[1] == 0)
3474 tprintf("NULL, ");
3475 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3476 tprintf("%#lx, ", tcp->u_arg[1]);
3477 else
3478 tprintf("[%u], ", u);
3479 tprintf("%#lx", tcp->u_arg[2]);
3480 }
3481 return 0;
3482}
3483
Roland McGrath5a223472002-12-15 23:58:26 +00003484#endif