blob: 23e44f6df7a8d86ae614f52c8aa043f0e9942b1a [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
Wichert Akkerman8829a551999-06-11 13:18:40 +0000189#ifdef PR_COREPID
190 { PR_COREPID, "PR_COREPID" },
191#endif
192#ifdef PR_ATTACHADDRPERM
193 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
194#endif
195#ifdef PR_PTHREADEXIT
196 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
197#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000198#ifdef PR_SET_PDEATHSIG
199 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
200#endif
201#ifdef PR_GET_PDEATHSIG
202 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
203#endif
Dmitry V. Levinf02cf212008-09-03 00:54:40 +0000204#ifdef PR_GET_DUMPABLE
205 { PR_GET_DUMPABLE, "PR_GET_DUMPABLE" },
206#endif
207#ifdef PR_SET_DUMPABLE
208 { PR_SET_DUMPABLE, "PR_SET_DUMPABLE" },
209#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000210#ifdef PR_GET_UNALIGN
211 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
212#endif
213#ifdef PR_SET_UNALIGN
214 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
215#endif
216#ifdef PR_GET_KEEPCAPS
Dmitry V. Levin8dd31dd2008-11-11 00:25:22 +0000217 { PR_GET_KEEPCAPS, "PR_GET_KEEPCAPS" },
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000218#endif
219#ifdef PR_SET_KEEPCAPS
Dmitry V. Levin8dd31dd2008-11-11 00:25:22 +0000220 { PR_SET_KEEPCAPS, "PR_SET_KEEPCAPS" },
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000221#endif
Roland McGrathe5039fb2007-11-03 23:58:07 +0000222#ifdef PR_GET_FPEMU
223 { PR_GET_FPEMU, "PR_GET_FPEMU" },
224#endif
225#ifdef PR_SET_FPEMU
226 { PR_SET_FPEMU, "PR_SET_FPEMU" },
227#endif
228#ifdef PR_GET_FPEXC
229 { PR_GET_FPEXC, "PR_GET_FPEXC" },
230#endif
231#ifdef PR_SET_FPEXC
232 { PR_SET_FPEXC, "PR_SET_FPEXC" },
233#endif
234#ifdef PR_GET_TIMING
235 { PR_GET_TIMING, "PR_GET_TIMING" },
236#endif
237#ifdef PR_SET_TIMING
238 { PR_SET_TIMING, "PR_SET_TIMING" },
239#endif
240#ifdef PR_SET_NAME
241 { PR_SET_NAME, "PR_SET_NAME" },
242#endif
243#ifdef PR_GET_NAME
244 { PR_GET_NAME, "PR_GET_NAME" },
245#endif
246#ifdef PR_GET_ENDIAN
247 { PR_GET_ENDIAN, "PR_GET_ENDIAN" },
248#endif
249#ifdef PR_SET_ENDIAN
250 { PR_SET_ENDIAN, "PR_SET_ENDIAN" },
251#endif
252#ifdef PR_GET_SECCOMP
253 { PR_GET_SECCOMP, "PR_GET_SECCOMP" },
254#endif
255#ifdef PR_SET_SECCOMP
256 { PR_SET_SECCOMP, "PR_SET_SECCOMP" },
257#endif
Dmitry V. Levin8dd31dd2008-11-11 00:25:22 +0000258#ifdef PR_GET_TSC
259 { PR_GET_TSC, "PR_GET_TSC" },
260#endif
261#ifdef PR_SET_TSC
262 { PR_SET_TSC, "PR_SET_TSC" },
263#endif
264#ifdef PR_GET_SECUREBITS
265 { PR_GET_SECUREBITS, "PR_GET_SECUREBITS" },
266#endif
267#ifdef PR_SET_SECUREBITS
268 { PR_SET_SECUREBITS, "PR_SET_SECUREBITS" },
269#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000270 { 0, NULL },
271};
272
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000273
Roland McGratha4d48532005-06-08 20:45:28 +0000274static const char *
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000275unalignctl_string (unsigned int ctl)
276{
277 static char buf[16];
278
279 switch (ctl) {
280#ifdef PR_UNALIGN_NOPRINT
281 case PR_UNALIGN_NOPRINT:
282 return "NOPRINT";
283#endif
284#ifdef PR_UNALIGN_SIGBUS
285 case PR_UNALIGN_SIGBUS:
286 return "SIGBUS";
287#endif
288 default:
289 break;
290 }
291 sprintf(buf, "%x", ctl);
292 return buf;
293}
294
295
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000296int
297sys_prctl(tcp)
298struct tcb *tcp;
299{
300 int i;
301
302 if (entering(tcp)) {
303 printxval(prctl_options, tcp->u_arg[0], "PR_???");
304 switch (tcp->u_arg[0]) {
305#ifdef PR_GETNSHARE
306 case PR_GETNSHARE:
307 break;
308#endif
Dmitry V. Levin50f60132008-09-03 00:56:52 +0000309#ifdef PR_SET_PDEATHSIG
310 case PR_SET_PDEATHSIG:
311 tprintf(", %lu", tcp->u_arg[1]);
312 break;
313#endif
314#ifdef PR_GET_PDEATHSIG
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000315 case PR_GET_PDEATHSIG:
316 break;
317#endif
Dmitry V. Levin50f60132008-09-03 00:56:52 +0000318#ifdef PR_SET_DUMPABLE
319 case PR_SET_DUMPABLE:
320 tprintf(", %lu", tcp->u_arg[1]);
321 break;
322#endif
323#ifdef PR_GET_DUMPABLE
324 case PR_GET_DUMPABLE:
325 break;
326#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000327#ifdef PR_SET_UNALIGN
328 case PR_SET_UNALIGN:
329 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
330 break;
331#endif
332#ifdef PR_GET_UNALIGN
333 case PR_GET_UNALIGN:
334 tprintf(", %#lx", tcp->u_arg[1]);
335 break;
336#endif
Dmitry V. Levin50f60132008-09-03 00:56:52 +0000337#ifdef PR_SET_KEEPCAPS
338 case PR_SET_KEEPCAPS:
339 tprintf(", %lu", tcp->u_arg[1]);
340 break;
341#endif
342#ifdef PR_GET_KEEPCAPS
343 case PR_GET_KEEPCAPS:
344 break;
345#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000346 default:
347 for (i = 1; i < tcp->u_nargs; i++)
348 tprintf(", %#lx", tcp->u_arg[i]);
349 break;
350 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000351 } else {
352 switch (tcp->u_arg[0]) {
353#ifdef PR_GET_PDEATHSIG
354 case PR_GET_PDEATHSIG:
Dmitry V. Levin50f60132008-09-03 00:56:52 +0000355 if (umove(tcp, tcp->u_arg[1], &i) < 0)
356 tprintf(", %#lx", tcp->u_arg[1]);
357 else
358 tprintf(", {%u}", i);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000359 break;
360#endif
Dmitry V. Levin50f60132008-09-03 00:56:52 +0000361#ifdef PR_GET_DUMPABLE
362 case PR_GET_DUMPABLE:
363 return RVAL_UDECIMAL;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000364#endif
365#ifdef PR_GET_UNALIGN
366 case PR_GET_UNALIGN:
Dmitry V. Levin50f60132008-09-03 00:56:52 +0000367 if (syserror(tcp) || umove(tcp, tcp->u_arg[1], &i) < 0)
368 break;
369 tcp->auxstr = unalignctl_string(i);
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000370 return RVAL_STR;
Dmitry V. Levin50f60132008-09-03 00:56:52 +0000371#endif
372#ifdef PR_GET_KEEPCAPS
373 case PR_GET_KEEPCAPS:
374 return RVAL_UDECIMAL;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000375#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000376 default:
377 break;
378 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000379 }
380 return 0;
381}
382
383#endif /* HAVE_PRCTL */
384
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000385#if defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000386int
387sys_gethostid(tcp)
388struct tcb *tcp;
389{
390 if (exiting(tcp))
391 return RVAL_HEX;
392 return 0;
393}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000394#endif /* FREEBSD || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000395
396int
397sys_sethostname(tcp)
398struct tcb *tcp;
399{
400 if (entering(tcp)) {
401 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
402 tprintf(", %lu", tcp->u_arg[1]);
403 }
404 return 0;
405}
406
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000407#if defined(ALPHA) || defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000408int
409sys_gethostname(tcp)
410struct tcb *tcp;
411{
412 if (exiting(tcp)) {
413 if (syserror(tcp))
414 tprintf("%#lx", tcp->u_arg[0]);
415 else
416 printpath(tcp, tcp->u_arg[0]);
417 tprintf(", %lu", tcp->u_arg[1]);
418 }
419 return 0;
420}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000421#endif /* ALPHA || FREEBSD || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000422
423int
424sys_setdomainname(tcp)
425struct tcb *tcp;
426{
427 if (entering(tcp)) {
428 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
429 tprintf(", %lu", tcp->u_arg[1]);
430 }
431 return 0;
432}
433
Wichert Akkerman5daa0281999-03-15 19:49:42 +0000434#if !defined(LINUX)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000435
436int
437sys_getdomainname(tcp)
438struct tcb *tcp;
439{
440 if (exiting(tcp)) {
441 if (syserror(tcp))
442 tprintf("%#lx", tcp->u_arg[0]);
443 else
444 printpath(tcp, tcp->u_arg[0]);
445 tprintf(", %lu", tcp->u_arg[1]);
446 }
447 return 0;
448}
449#endif /* !LINUX */
450
451int
452sys_exit(tcp)
453struct tcb *tcp;
454{
455 if (exiting(tcp)) {
456 fprintf(stderr, "_exit returned!\n");
457 return -1;
458 }
459 /* special case: we stop tracing this process, finish line now */
460 tprintf("%ld) ", tcp->u_arg[0]);
461 tabto(acolumn);
462 tprintf("= ?");
Denys Vlasenkoef2fbf82009-01-06 21:45:06 +0000463 printtrailer();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000464 return 0;
465}
466
467int
468internal_exit(tcp)
469struct tcb *tcp;
470{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000471 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000472 tcp->flags |= TCB_EXITING;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000473#ifdef __NR_exit_group
Roland McGrath08267b82004-02-20 22:56:43 +0000474# ifdef IA64
475 if (ia32) {
476 if (tcp->scno == 252)
477 tcp->flags |= TCB_GROUP_EXITING;
478 } else
479# endif
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000480 if (known_scno(tcp) == __NR_exit_group)
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000481 tcp->flags |= TCB_GROUP_EXITING;
482#endif
483 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000484 return 0;
485}
486
Roland McGrathee9d4352002-12-18 04:16:10 +0000487/* TCP is creating a child we want to follow.
488 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
489 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
Denys Vlasenko418d66a2009-01-17 01:52:54 +0000490static void
Roland McGrathee9d4352002-12-18 04:16:10 +0000491fork_tcb(struct tcb *tcp)
492{
Denys Vlasenko418d66a2009-01-17 01:52:54 +0000493 if (nprocs == tcbtabsize)
494 expand_tcbtab();
Roland McGrathee9d4352002-12-18 04:16:10 +0000495
496 tcp->flags |= TCB_FOLLOWFORK;
Roland McGrathee9d4352002-12-18 04:16:10 +0000497}
498
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000499#ifdef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000500
501int
Denys Vlasenko418d66a2009-01-17 01:52:54 +0000502sys_fork(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000503{
Dmitry V. Levin21a75342008-09-03 01:22:18 +0000504 if (exiting(tcp) && !syserror(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000505 if (getrval2(tcp)) {
506 tcp->auxstr = "child process";
507 return RVAL_UDECIMAL | RVAL_STR;
508 }
509 }
510 return 0;
511}
512
John Hughes4e36a812001-04-18 15:11:51 +0000513#if UNIXWARE > 2
514
515int
516sys_rfork(tcp)
517struct tcb *tcp;
518{
519 if (entering(tcp)) {
520 tprintf ("%ld", tcp->u_arg[0]);
521 }
Dmitry V. Levin21a75342008-09-03 01:22:18 +0000522 else if (!syserror(tcp)) {
John Hughes4e36a812001-04-18 15:11:51 +0000523 if (getrval2(tcp)) {
524 tcp->auxstr = "child process";
525 return RVAL_UDECIMAL | RVAL_STR;
526 }
527 }
528 return 0;
529}
530
531#endif
532
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000533int
534internal_fork(tcp)
535struct tcb *tcp;
536{
537 struct tcb *tcpchild;
538
539 if (exiting(tcp)) {
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000540#ifdef SYS_rfork
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000541 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000542 return 0;
543#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000544 if (getrval2(tcp))
545 return 0;
546 if (!followfork)
547 return 0;
Denys Vlasenko418d66a2009-01-17 01:52:54 +0000548 fork_tcb(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000549 if (syserror(tcp))
550 return 0;
Denys Vlasenko418d66a2009-01-17 01:52:54 +0000551 tcpchild = alloctcb(tcp->u_rval);
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000552 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000553 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000554 }
555 return 0;
556}
557
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000558#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000559
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000560#ifdef LINUX
561
562/* defines copied from linux/sched.h since we can't include that
563 * ourselves (it conflicts with *lots* of libc includes)
564 */
565#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
566#define CLONE_VM 0x00000100 /* set if VM shared between processes */
567#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
568#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
569#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000570#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000571#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
572#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
573#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000574#define CLONE_THREAD 0x00010000 /* Same thread group? */
575#define CLONE_NEWNS 0x00020000 /* New namespace group? */
576#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
577#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
578#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
579#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
580#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
581#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
582#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000583
Roland McGrathd9f816f2004-09-04 03:39:20 +0000584static const struct xlat clone_flags[] = {
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000585 { CLONE_VM, "CLONE_VM" },
586 { CLONE_FS, "CLONE_FS" },
587 { CLONE_FILES, "CLONE_FILES" },
588 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000589 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000590 { CLONE_PTRACE, "CLONE_PTRACE" },
591 { CLONE_VFORK, "CLONE_VFORK" },
592 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000593 { CLONE_THREAD, "CLONE_THREAD" },
594 { CLONE_NEWNS, "CLONE_NEWNS" },
595 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
596 { CLONE_SETTLS, "CLONE_SETTLS" },
597 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
598 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
599 { CLONE_DETACHED, "CLONE_DETACHED" },
600 { CLONE_UNTRACED, "CLONE_UNTRACED" },
601 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000602 { 0, NULL },
603};
604
Roland McGrath909875b2002-12-22 03:34:36 +0000605# ifdef I386
606# include <asm/ldt.h>
Roland McGrath7decfb22004-03-01 22:10:52 +0000607# ifdef HAVE_STRUCT_USER_DESC
608# define modify_ldt_ldt_s user_desc
609# endif
Roland McGrath909875b2002-12-22 03:34:36 +0000610extern void print_ldt_entry();
611# endif
612
Roland McGrath9677b3a2003-03-12 09:54:36 +0000613# if defined IA64
614# define ARG_FLAGS 0
615# define ARG_STACK 1
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000616# define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
617# define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
618# define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
619# define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000620# elif defined S390 || defined S390X
Roland McGrath9677b3a2003-03-12 09:54:36 +0000621# define ARG_STACK 0
622# define ARG_FLAGS 1
623# define ARG_PTID 2
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000624# define ARG_CTID 3
625# define ARG_TLS 4
Roland McGrath9c555e72003-07-09 09:47:59 +0000626# elif defined X86_64 || defined ALPHA
Roland McGrath361aac52003-03-18 07:43:42 +0000627# define ARG_FLAGS 0
628# define ARG_STACK 1
629# define ARG_PTID 2
630# define ARG_CTID 3
631# define ARG_TLS 4
Roland McGrath9677b3a2003-03-12 09:54:36 +0000632# else
633# define ARG_FLAGS 0
634# define ARG_STACK 1
635# define ARG_PTID 2
636# define ARG_TLS 3
637# define ARG_CTID 4
638# endif
639
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000640int
641sys_clone(tcp)
642struct tcb *tcp;
643{
644 if (exiting(tcp)) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000645 unsigned long flags = tcp->u_arg[ARG_FLAGS];
646 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
647# ifdef ARG_STACKSIZE
648 if (ARG_STACKSIZE != -1)
649 tprintf("stack_size=%#lx, ",
650 tcp->u_arg[ARG_STACKSIZE]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000651# endif
Roland McGrath9677b3a2003-03-12 09:54:36 +0000652 tprintf("flags=");
Roland McGrathb2dee132005-06-01 19:02:36 +0000653 printflags(clone_flags, flags &~ CSIGNAL, NULL);
Roland McGrath984154d2003-05-23 01:08:42 +0000654 if ((flags & CSIGNAL) != 0)
655 tprintf("|%s", signame(flags & CSIGNAL));
Roland McGrathb4968be2003-01-20 09:04:33 +0000656 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
Roland McGrath9677b3a2003-03-12 09:54:36 +0000657 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
Roland McGrath909875b2002-12-22 03:34:36 +0000658 return 0;
Roland McGrath6f67a982003-03-21 07:33:15 +0000659 if (flags & CLONE_PARENT_SETTID)
660 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000661 if (flags & CLONE_SETTLS) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000662# ifdef I386
Roland McGrath909875b2002-12-22 03:34:36 +0000663 struct modify_ldt_ldt_s copy;
Roland McGrath9677b3a2003-03-12 09:54:36 +0000664 if (umove(tcp, tcp->u_arg[ARG_TLS], &copy) != -1) {
Roland McGrath909875b2002-12-22 03:34:36 +0000665 tprintf(", {entry_number:%d, ",
666 copy.entry_number);
667 if (!verbose(tcp))
668 tprintf("...}");
669 else
670 print_ldt_entry(&copy);
671 }
672 else
Roland McGrath9677b3a2003-03-12 09:54:36 +0000673# endif
Roland McGrath43f2c842003-03-12 09:58:14 +0000674 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
Roland McGrath909875b2002-12-22 03:34:36 +0000675 }
Roland McGrath9677b3a2003-03-12 09:54:36 +0000676 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
677 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000678 }
679 return 0;
680}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000681
682int
683sys_unshare(struct tcb *tcp)
684{
685 if (entering(tcp))
686 printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
687 return 0;
688}
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000689#endif
690
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000691int
692sys_fork(tcp)
693struct tcb *tcp;
694{
695 if (exiting(tcp))
696 return RVAL_UDECIMAL;
697 return 0;
698}
699
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000700int
Denys Vlasenko418d66a2009-01-17 01:52:54 +0000701change_syscall(struct tcb *tcp, int new)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000702{
703#if defined(LINUX)
704#if defined(I386)
705 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000706 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000707 return -1;
708 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000709#elif defined(X86_64)
710 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000711 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000712 return -1;
713 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000714#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000715 if (ptrace(PTRACE_POKEUSER, tcp->pid,
716 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000717 return -1;
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000718 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000719#elif defined(S390) || defined(S390X)
720 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
721 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
722 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000723 return 0;
724#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000725 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000726 return -1;
727 return 0;
Roland McGrath6d1a65c2004-07-12 07:44:08 +0000728#elif defined(SPARC) || defined(SPARC64)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000729 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000730 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
731 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000732 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000733 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
734 return -1;
735 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000736#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000737 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000738 return -1;
739 return 0;
740#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000741 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000742 return -1;
743 return 0;
Dmitry V. Levin87ea1f42008-11-10 22:21:41 +0000744#elif defined(BFIN)
745 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_P0), new)<0)
746 return -1;
747 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000748#elif defined(IA64)
Roland McGrath08267b82004-02-20 22:56:43 +0000749 if (ia32) {
750 switch (new) {
Denys Vlasenko418d66a2009-01-17 01:52:54 +0000751 case 2:
752 break; /* x86 SYS_fork */
753 case SYS_clone:
754 new = 120;
755 break;
756 default:
Roland McGrath08267b82004-02-20 22:56:43 +0000757 fprintf(stderr, "%s: unexpected syscall %d\n",
758 __FUNCTION__, new);
759 return -1;
760 }
761 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
762 return -1;
763 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000764 return -1;
765 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000766#elif defined(HPPA)
767 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
768 return -1;
769 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000770#elif defined(SH)
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000771 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
772 return -1;
773 return 0;
Roland McGrathf5a47772003-06-26 22:40:42 +0000774#elif defined(SH64)
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000775 /* Top half of reg encodes the no. of args n as 0x1n.
776 Assume 0 args as kernel never actually checks... */
777 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
778 0x100000 | new) < 0)
779 return -1;
780 return 0;
Roland McGrathf691bd22006-04-25 07:34:41 +0000781#elif defined(ARM)
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000782 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
Roland McGrathf691bd22006-04-25 07:34:41 +0000783# ifndef PTRACE_SET_SYSCALL
784# define PTRACE_SET_SYSCALL 23
785# endif
786
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000787 if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new) != 0)
Roland McGrathf691bd22006-04-25 07:34:41 +0000788 return -1;
789
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000790 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000791#else
792#warning Do not know how to handle change_syscall for this architecture
793#endif /* architecture */
794#endif /* LINUX */
795 return -1;
796}
797
Roland McGratha4d48532005-06-08 20:45:28 +0000798#if 0
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000799int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000800setarg(tcp, argnum)
801 struct tcb *tcp;
802 int argnum;
803{
804#if defined (IA64)
805 {
806 unsigned long *bsp, *ap;
807
Denys Vlasenko932fc7d2008-12-16 18:18:40 +0000808 if (upeek(tcp, PT_AR_BSP, (long *) &bsp) , 0)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000809 return -1;
810
811 ap = ia64_rse_skip_regs(bsp, argnum);
812 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000813 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000814 if (errno)
815 return -1;
816
817 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000818#elif defined(I386)
819 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000820 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000821 if (errno)
822 return -1;
823 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000824#elif defined(X86_64)
825 {
826 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
827 if (errno)
828 return -1;
829 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000830#elif defined(POWERPC)
831#ifndef PT_ORIG_R3
832#define PT_ORIG_R3 34
833#endif
834 {
835 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000836 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000837 tcp->u_arg[argnum]);
838 if (errno)
839 return -1;
840 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000841#elif defined(MIPS)
842 {
843 errno = 0;
844 if (argnum < 4)
845 ptrace(PTRACE_POKEUSER, tcp->pid,
846 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
847 else {
848 unsigned long *sp;
849
Denys Vlasenko932fc7d2008-12-16 18:18:40 +0000850 if (upeek(tcp, REG_SP, (long *) &sp) , 0)
Ralf Baechlee3816102000-08-01 00:06:06 +0000851 return -1;
852
853 ptrace(PTRACE_POKEDATA, tcp->pid,
854 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
855 }
856 if (errno)
857 return -1;
858 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000859#elif defined(S390) || defined(S390X)
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000860 {
Michal Ludvig10a88d02002-10-07 14:31:00 +0000861 if(argnum <= 5)
862 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000863 (char *) (argnum==0 ? PT_ORIGGPR2 :
864 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000865 tcp->u_arg[argnum]);
866 else
867 return -E2BIG;
868 if (errno)
869 return -1;
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000870 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000871#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000872# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000873#endif
874 return 0;
875}
Roland McGratha4d48532005-06-08 20:45:28 +0000876#endif
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000877
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000878#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000879int
880internal_clone(tcp)
881struct tcb *tcp;
882{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000883 struct tcb *tcpchild;
884 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000885 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000886 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000887 return 0;
Denys Vlasenko418d66a2009-01-17 01:52:54 +0000888 fork_tcb(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000889 if (setbpt(tcp) < 0)
890 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000891 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000892 int bpt = tcp->flags & TCB_BPTSET;
893
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000894 if (!(tcp->flags & TCB_FOLLOWFORK))
895 return 0;
896
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000897 if (syserror(tcp)) {
898 if (bpt)
899 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000900 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000901 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000902
903 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000904
905#ifdef CLONE_PTRACE /* See new setbpt code. */
906 tcpchild = pid2tcb(pid);
907 if (tcpchild != NULL) {
908 /* The child already reported its startup trap
909 before the parent reported its syscall return. */
910 if ((tcpchild->flags
911 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
912 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
913 fprintf(stderr, "\
914[preattached child %d of %d in weird state!]\n",
915 pid, tcp->pid);
916 }
917 else
918#endif
Denys Vlasenkodb78f762009-01-26 12:55:40 +0000919 {
920 fork_tcb(tcp);
921 tcpchild = alloctcb(pid);
922 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000923
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000924#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000925 /* Attach to the new child */
926 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000927 if (bpt)
928 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000929 perror("PTRACE_ATTACH");
930 fprintf(stderr, "Too late?\n");
931 droptcb(tcpchild);
932 return 0;
933 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000934#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000935
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000936 if (bpt)
937 clearbpt(tcp);
938
Ulrich Drepper90512f01999-12-24 07:22:25 +0000939 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000940 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000941 if (bpt) {
942 tcpchild->flags |= TCB_BPTSET;
943 tcpchild->baddr = tcp->baddr;
944 memcpy(tcpchild->inst, tcp->inst,
945 sizeof tcpchild->inst);
946 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000947 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000948 tcp->nchildren++;
949 if (tcpchild->flags & TCB_SUSPENDED) {
950 /* The child was born suspended, due to our having
951 forced CLONE_PTRACE. */
952 if (bpt)
953 clearbpt(tcpchild);
954
955 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
Denys Vlasenkof9a7e632009-01-17 00:21:31 +0000956 /* TCB_SUSPENDED tasks are not collected by waitpid
957 * loop, and left stopped. Restart it:
958 */
Denys Vlasenko732d1bf2008-12-17 19:21:59 +0000959 if (ptrace_restart(PTRACE_SYSCALL, tcpchild, 0) < 0)
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000960 return -1;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000961
962 if (!qflag)
963 fprintf(stderr, "\
964Process %u resumed (parent %d ready)\n",
965 pid, tcp->pid);
966 }
967 else {
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000968 if (!qflag)
969 fprintf(stderr, "Process %d attached\n", pid);
970 }
971
972#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000973 {
974 /*
975 * Save the flags used in this call,
976 * in case we point TCP to our parent below.
977 */
978 int call_flags = tcp->u_arg[ARG_FLAGS];
979 if ((tcp->flags & TCB_CLONE_THREAD) &&
980 tcp->parent != NULL) {
981 /* The parent in this clone is itself a
982 thread belonging to another process.
983 There is no meaning to the parentage
984 relationship of the new child with the
985 thread, only with the process. We
986 associate the new thread with our
987 parent. Since this is done for every
988 new thread, there will never be a
989 TCB_CLONE_THREAD process that has
990 children. */
991 --tcp->nchildren;
992 tcp = tcp->parent;
993 tcpchild->parent = tcp;
994 ++tcp->nchildren;
995 }
996 if (call_flags & CLONE_THREAD) {
997 tcpchild->flags |= TCB_CLONE_THREAD;
998 ++tcp->nclone_threads;
999 }
1000 if (call_flags & CLONE_DETACHED) {
1001 tcpchild->flags |= TCB_CLONE_DETACHED;
1002 ++tcp->nclone_detached;
1003 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001004 }
1005#endif
1006
1007 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +00001008 return 0;
1009}
1010#endif
1011
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001012int
1013internal_fork(tcp)
1014struct tcb *tcp;
1015{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001016#ifdef LINUX
1017 /* We do special magic with clone for any clone or fork. */
1018 return internal_clone(tcp);
1019#else
1020
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001021 struct tcb *tcpchild;
1022 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +00001023 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001024
1025#ifdef SYS_vfork
Roland McGratha4f9f2d2005-06-07 23:21:20 +00001026 if (known_scno(tcp) == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +00001027 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath41c48222008-07-18 00:25:10 +00001028 if (change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +00001029 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +00001030 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001031#endif
1032 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +00001033 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001034 return 0;
Denys Vlasenko418d66a2009-01-17 01:52:54 +00001035 fork_tcb(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001036 if (setbpt(tcp) < 0)
1037 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +00001038 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001039 else {
1040 int bpt = tcp->flags & TCB_BPTSET;
1041
1042 if (!(tcp->flags & TCB_FOLLOWFORK))
1043 return 0;
1044 if (bpt)
1045 clearbpt(tcp);
1046
1047 if (syserror(tcp))
1048 return 0;
1049
1050 pid = tcp->u_rval;
Denys Vlasenko418d66a2009-01-17 01:52:54 +00001051 fork_tcb(tcp);
1052 tcpchild = alloctcb(pid);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001053#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +00001054#ifdef HPPA
1055 /* The child must have run before it can be attached. */
1056 /* This must be a bug in the parisc kernel, but I havn't
1057 * identified it yet. Seems to be an issue associated
1058 * with attaching to a process (which sends it a signal)
1059 * before that process has ever been scheduled. When
1060 * debugging, I started seeing crashes in
1061 * arch/parisc/kernel/signal.c:do_signal(), apparently
1062 * caused by r8 getting corrupt over the dequeue_signal()
1063 * call. Didn't make much sense though...
1064 */
1065 {
1066 struct timeval tv;
1067 tv.tv_sec = 0;
1068 tv.tv_usec = 10000;
1069 select(0, NULL, NULL, NULL, &tv);
1070 }
1071#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001072 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
1073 perror("PTRACE_ATTACH");
1074 fprintf(stderr, "Too late?\n");
1075 droptcb(tcpchild);
1076 return 0;
1077 }
1078#endif /* LINUX */
1079#ifdef SUNOS4
1080#ifdef oldway
1081 /* The child must have run before it can be attached. */
1082 {
1083 struct timeval tv;
1084 tv.tv_sec = 0;
1085 tv.tv_usec = 10000;
1086 select(0, NULL, NULL, NULL, &tv);
1087 }
1088 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1089 perror("PTRACE_ATTACH");
1090 fprintf(stderr, "Too late?\n");
1091 droptcb(tcpchild);
1092 return 0;
1093 }
1094#else /* !oldway */
1095 /* Try to catch the new process as soon as possible. */
1096 {
1097 int i;
1098 for (i = 0; i < 1024; i++)
1099 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1100 break;
1101 if (i == 1024) {
1102 perror("PTRACE_ATTACH");
1103 fprintf(stderr, "Too late?\n");
1104 droptcb(tcpchild);
1105 return 0;
1106 }
1107 }
1108#endif /* !oldway */
1109#endif /* SUNOS4 */
1110 tcpchild->flags |= TCB_ATTACHED;
1111 /* Child has BPT too, must be removed on first occasion */
1112 if (bpt) {
1113 tcpchild->flags |= TCB_BPTSET;
1114 tcpchild->baddr = tcp->baddr;
1115 memcpy(tcpchild->inst, tcp->inst,
1116 sizeof tcpchild->inst);
1117 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001118 tcpchild->parent = tcp;
1119 tcp->nchildren++;
1120 if (!qflag)
1121 fprintf(stderr, "Process %d attached\n", pid);
1122 }
1123 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001124#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001125}
1126
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001127#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001128
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001129#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001130
1131int
1132sys_vfork(tcp)
1133struct tcb *tcp;
1134{
1135 if (exiting(tcp))
1136 return RVAL_UDECIMAL;
1137 return 0;
1138}
1139
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001140#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001141
1142#ifndef LINUX
1143
1144static char idstr[16];
1145
1146int
1147sys_getpid(tcp)
1148struct tcb *tcp;
1149{
1150 if (exiting(tcp)) {
1151 sprintf(idstr, "ppid %lu", getrval2(tcp));
1152 tcp->auxstr = idstr;
1153 return RVAL_STR;
1154 }
1155 return 0;
1156}
1157
1158int
1159sys_getuid(tcp)
1160struct tcb *tcp;
1161{
1162 if (exiting(tcp)) {
1163 sprintf(idstr, "euid %lu", getrval2(tcp));
1164 tcp->auxstr = idstr;
1165 return RVAL_STR;
1166 }
1167 return 0;
1168}
1169
1170int
1171sys_getgid(tcp)
1172struct tcb *tcp;
1173{
1174 if (exiting(tcp)) {
1175 sprintf(idstr, "egid %lu", getrval2(tcp));
1176 tcp->auxstr = idstr;
1177 return RVAL_STR;
1178 }
1179 return 0;
1180}
1181
1182#endif /* !LINUX */
1183
1184#ifdef LINUX
1185
1186int
1187sys_setuid(tcp)
1188struct tcb *tcp;
1189{
1190 if (entering(tcp)) {
1191 tprintf("%u", (uid_t) tcp->u_arg[0]);
1192 }
1193 return 0;
1194}
1195
1196int
1197sys_setgid(tcp)
1198struct tcb *tcp;
1199{
1200 if (entering(tcp)) {
1201 tprintf("%u", (gid_t) tcp->u_arg[0]);
1202 }
1203 return 0;
1204}
1205
1206int
1207sys_getresuid(tcp)
1208 struct tcb *tcp;
1209{
1210 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001211 __kernel_uid_t uid;
1212 if (syserror(tcp))
1213 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1214 tcp->u_arg[1], tcp->u_arg[2]);
1215 else {
1216 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1217 tprintf("%#lx, ", tcp->u_arg[0]);
1218 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001219 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001220 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1221 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001222 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001223 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001224 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1225 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001226 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001227 tprintf("[%lu]", (unsigned long) uid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001228 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001229 }
1230 return 0;
1231}
1232
1233int
1234sys_getresgid(tcp)
1235struct tcb *tcp;
1236{
1237 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001238 __kernel_gid_t gid;
1239 if (syserror(tcp))
1240 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1241 tcp->u_arg[1], tcp->u_arg[2]);
1242 else {
1243 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1244 tprintf("%#lx, ", tcp->u_arg[0]);
1245 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001246 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001247 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1248 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001249 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001250 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001251 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1252 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001253 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001254 tprintf("[%lu]", (unsigned long) gid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001255 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001256 }
1257 return 0;
1258}
1259
1260#endif /* LINUX */
1261
1262int
1263sys_setreuid(tcp)
1264struct tcb *tcp;
1265{
1266 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001267 printuid("", tcp->u_arg[0]);
1268 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001269 }
1270 return 0;
1271}
1272
1273int
1274sys_setregid(tcp)
1275struct tcb *tcp;
1276{
1277 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001278 printuid("", tcp->u_arg[0]);
1279 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001280 }
1281 return 0;
1282}
1283
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001284#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001285int
1286sys_setresuid(tcp)
1287 struct tcb *tcp;
1288{
1289 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001290 printuid("", tcp->u_arg[0]);
1291 printuid(", ", tcp->u_arg[1]);
1292 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001293 }
1294 return 0;
1295}
1296int
1297sys_setresgid(tcp)
1298 struct tcb *tcp;
1299{
1300 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001301 printuid("", tcp->u_arg[0]);
1302 printuid(", ", tcp->u_arg[1]);
1303 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001304 }
1305 return 0;
1306}
1307
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001308#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001309
1310int
1311sys_setgroups(tcp)
1312struct tcb *tcp;
1313{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001314 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001315 unsigned long len, size, start, cur, end, abbrev_end;
1316 GETGROUPS_T gid;
1317 int failed = 0;
1318
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001319 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001320 tprintf("%lu, ", len);
1321 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001322 tprintf("[]");
1323 return 0;
1324 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001325 start = tcp->u_arg[1];
1326 if (start == 0) {
1327 tprintf("NULL");
1328 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001329 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001330 size = len * sizeof(gid);
1331 end = start + size;
1332 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1333 tprintf("%#lx", start);
1334 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001335 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001336 if (abbrev(tcp)) {
1337 abbrev_end = start + max_strlen * sizeof(gid);
1338 if (abbrev_end < start)
1339 abbrev_end = end;
1340 } else {
1341 abbrev_end = end;
1342 }
1343 tprintf("[");
1344 for (cur = start; cur < end; cur += sizeof(gid)) {
1345 if (cur > start)
1346 tprintf(", ");
1347 if (cur >= abbrev_end) {
1348 tprintf("...");
1349 break;
1350 }
1351 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1352 tprintf("?");
1353 failed = 1;
1354 break;
1355 }
1356 tprintf("%lu", (unsigned long) gid);
1357 }
1358 tprintf("]");
1359 if (failed)
1360 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001361 }
1362 return 0;
1363}
1364
1365int
1366sys_getgroups(tcp)
1367struct tcb *tcp;
1368{
Roland McGrathaa524c82005-06-01 19:22:06 +00001369 unsigned long len;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001370
1371 if (entering(tcp)) {
1372 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001373 tprintf("%lu, ", len);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001374 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001375 unsigned long size, start, cur, end, abbrev_end;
1376 GETGROUPS_T gid;
1377 int failed = 0;
1378
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001379 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001380 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001381 tprintf("[]");
1382 return 0;
1383 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001384 start = tcp->u_arg[1];
1385 if (start == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001386 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001387 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001388 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001389 if (tcp->u_arg[0] == 0) {
1390 tprintf("%#lx", start);
1391 return 0;
1392 }
1393 size = len * sizeof(gid);
1394 end = start + size;
1395 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1396 size / sizeof(gid) != len || end < start) {
1397 tprintf("%#lx", start);
1398 return 0;
1399 }
1400 if (abbrev(tcp)) {
1401 abbrev_end = start + max_strlen * sizeof(gid);
1402 if (abbrev_end < start)
1403 abbrev_end = end;
1404 } else {
1405 abbrev_end = end;
1406 }
1407 tprintf("[");
1408 for (cur = start; cur < end; cur += sizeof(gid)) {
1409 if (cur > start)
1410 tprintf(", ");
1411 if (cur >= abbrev_end) {
1412 tprintf("...");
1413 break;
1414 }
1415 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1416 tprintf("?");
1417 failed = 1;
1418 break;
1419 }
1420 tprintf("%lu", (unsigned long) gid);
1421 }
1422 tprintf("]");
1423 if (failed)
1424 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001425 }
1426 return 0;
1427}
1428
Roland McGrath83bd47a2003-11-13 22:32:26 +00001429#ifdef LINUX
1430int
1431sys_setgroups32(tcp)
1432struct tcb *tcp;
1433{
Roland McGrath83bd47a2003-11-13 22:32:26 +00001434 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001435 unsigned long len, size, start, cur, end, abbrev_end;
1436 GETGROUPS32_T gid;
1437 int failed = 0;
1438
Roland McGrath83bd47a2003-11-13 22:32:26 +00001439 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001440 tprintf("%lu, ", len);
1441 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001442 tprintf("[]");
1443 return 0;
1444 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001445 start = tcp->u_arg[1];
1446 if (start == 0) {
1447 tprintf("NULL");
1448 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001449 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001450 size = len * sizeof(gid);
1451 end = start + size;
1452 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1453 tprintf("%#lx", start);
1454 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001455 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001456 if (abbrev(tcp)) {
1457 abbrev_end = start + max_strlen * sizeof(gid);
1458 if (abbrev_end < start)
1459 abbrev_end = end;
1460 } else {
1461 abbrev_end = end;
1462 }
1463 tprintf("[");
1464 for (cur = start; cur < end; cur += sizeof(gid)) {
1465 if (cur > start)
1466 tprintf(", ");
1467 if (cur >= abbrev_end) {
1468 tprintf("...");
1469 break;
1470 }
1471 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1472 tprintf("?");
1473 failed = 1;
1474 break;
1475 }
1476 tprintf("%lu", (unsigned long) gid);
1477 }
1478 tprintf("]");
1479 if (failed)
1480 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001481 }
1482 return 0;
1483}
1484
1485int
1486sys_getgroups32(tcp)
1487struct tcb *tcp;
1488{
Roland McGrathaa524c82005-06-01 19:22:06 +00001489 unsigned long len;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001490
1491 if (entering(tcp)) {
1492 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001493 tprintf("%lu, ", len);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001494 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001495 unsigned long size, start, cur, end, abbrev_end;
1496 GETGROUPS32_T gid;
1497 int failed = 0;
1498
Roland McGrath83bd47a2003-11-13 22:32:26 +00001499 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001500 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001501 tprintf("[]");
1502 return 0;
1503 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001504 start = tcp->u_arg[1];
1505 if (start == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001506 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001507 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001508 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001509 size = len * sizeof(gid);
1510 end = start + size;
1511 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1512 size / sizeof(gid) != len || end < start) {
1513 tprintf("%#lx", start);
1514 return 0;
1515 }
1516 if (abbrev(tcp)) {
1517 abbrev_end = start + max_strlen * sizeof(gid);
1518 if (abbrev_end < start)
1519 abbrev_end = end;
1520 } else {
1521 abbrev_end = end;
1522 }
1523 tprintf("[");
1524 for (cur = start; cur < end; cur += sizeof(gid)) {
1525 if (cur > start)
1526 tprintf(", ");
1527 if (cur >= abbrev_end) {
1528 tprintf("...");
1529 break;
1530 }
1531 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1532 tprintf("?");
1533 failed = 1;
1534 break;
1535 }
1536 tprintf("%lu", (unsigned long) gid);
1537 }
1538 tprintf("]");
1539 if (failed)
1540 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001541 }
1542 return 0;
1543}
1544#endif /* LINUX */
1545
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001546#if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001547int
1548sys_setpgrp(tcp)
1549struct tcb *tcp;
1550{
1551 if (entering(tcp)) {
1552#ifndef SVR4
1553 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1554#endif /* !SVR4 */
1555 }
1556 return 0;
1557}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001558#endif /* ALPHA || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001559
1560int
1561sys_getpgrp(tcp)
1562struct tcb *tcp;
1563{
1564 if (entering(tcp)) {
1565#ifndef SVR4
1566 tprintf("%lu", tcp->u_arg[0]);
1567#endif /* !SVR4 */
1568 }
1569 return 0;
1570}
1571
1572int
1573sys_getsid(tcp)
1574struct tcb *tcp;
1575{
1576 if (entering(tcp)) {
1577 tprintf("%lu", tcp->u_arg[0]);
1578 }
1579 return 0;
1580}
1581
1582int
1583sys_setsid(tcp)
1584struct tcb *tcp;
1585{
1586 return 0;
1587}
1588
1589int
1590sys_getpgid(tcp)
1591struct tcb *tcp;
1592{
1593 if (entering(tcp)) {
1594 tprintf("%lu", tcp->u_arg[0]);
1595 }
1596 return 0;
1597}
1598
1599int
1600sys_setpgid(tcp)
1601struct tcb *tcp;
1602{
1603 if (entering(tcp)) {
1604 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1605 }
1606 return 0;
1607}
1608
John Hughesc61eb3d2002-05-17 11:37:50 +00001609#if UNIXWARE >= 2
1610
1611#include <sys/privilege.h>
1612
1613
Roland McGrathd9f816f2004-09-04 03:39:20 +00001614static const struct xlat procpriv_cmds [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001615 { SETPRV, "SETPRV" },
1616 { CLRPRV, "CLRPRV" },
1617 { PUTPRV, "PUTPRV" },
1618 { GETPRV, "GETPRV" },
1619 { CNTPRV, "CNTPRV" },
1620 { 0, NULL },
1621};
1622
1623
Roland McGrathd9f816f2004-09-04 03:39:20 +00001624static const struct xlat procpriv_priv [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001625 { P_OWNER, "P_OWNER" },
1626 { P_AUDIT, "P_AUDIT" },
1627 { P_COMPAT, "P_COMPAT" },
1628 { P_DACREAD, "P_DACREAD" },
1629 { P_DACWRITE, "P_DACWRITE" },
1630 { P_DEV, "P_DEV" },
1631 { P_FILESYS, "P_FILESYS" },
1632 { P_MACREAD, "P_MACREAD" },
1633 { P_MACWRITE, "P_MACWRITE" },
1634 { P_MOUNT, "P_MOUNT" },
1635 { P_MULTIDIR, "P_MULTIDIR" },
1636 { P_SETPLEVEL, "P_SETPLEVEL" },
1637 { P_SETSPRIV, "P_SETSPRIV" },
1638 { P_SETUID, "P_SETUID" },
1639 { P_SYSOPS, "P_SYSOPS" },
1640 { P_SETUPRIV, "P_SETUPRIV" },
1641 { P_DRIVER, "P_DRIVER" },
1642 { P_RTIME, "P_RTIME" },
1643 { P_MACUPGRADE, "P_MACUPGRADE" },
1644 { P_FSYSRANGE, "P_FSYSRANGE" },
1645 { P_SETFLEVEL, "P_SETFLEVEL" },
1646 { P_AUDITWR, "P_AUDITWR" },
1647 { P_TSHAR, "P_TSHAR" },
1648 { P_PLOCK, "P_PLOCK" },
1649 { P_CORE, "P_CORE" },
1650 { P_LOADMOD, "P_LOADMOD" },
1651 { P_BIND, "P_BIND" },
1652 { P_ALLPRIVS, "P_ALLPRIVS" },
1653 { 0, NULL },
1654};
1655
1656
Roland McGrathd9f816f2004-09-04 03:39:20 +00001657static const struct xlat procpriv_type [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001658 { PS_FIX, "PS_FIX" },
1659 { PS_INH, "PS_INH" },
1660 { PS_MAX, "PS_MAX" },
1661 { PS_WKG, "PS_WKG" },
1662 { 0, NULL },
1663};
1664
1665
1666static void
Dmitry V. Levinab9008b2007-01-11 22:05:04 +00001667printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
John Hughesc61eb3d2002-05-17 11:37:50 +00001668{
1669 priv_t buf [128];
1670 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1671 int dots = len > max;
1672 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001673
John Hughesc61eb3d2002-05-17 11:37:50 +00001674 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001675
John Hughesc61eb3d2002-05-17 11:37:50 +00001676 if (len <= 0 ||
1677 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1678 {
1679 tprintf ("%#lx", addr);
1680 return;
1681 }
1682
1683 tprintf ("[");
1684
1685 for (i = 0; i < len; ++i) {
Dmitry V. Levinab9008b2007-01-11 22:05:04 +00001686 const char *t, *p;
John Hughesc61eb3d2002-05-17 11:37:50 +00001687
1688 if (i) tprintf (", ");
1689
1690 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1691 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1692 {
1693 tprintf ("%s|%s", t, p);
1694 }
1695 else {
1696 tprintf ("%#lx", buf [i]);
1697 }
1698 }
1699
1700 if (dots) tprintf (" ...");
1701
1702 tprintf ("]");
1703}
1704
1705
1706int
1707sys_procpriv(tcp)
1708struct tcb *tcp;
1709{
1710 if (entering(tcp)) {
1711 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1712 switch (tcp->u_arg[0]) {
1713 case CNTPRV:
1714 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1715 break;
1716
1717 case GETPRV:
1718 break;
1719
1720 default:
1721 tprintf (", ");
1722 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1723 tprintf (", %ld", tcp->u_arg[2]);
1724 }
1725 }
1726 else if (tcp->u_arg[0] == GETPRV) {
1727 if (syserror (tcp)) {
1728 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1729 }
1730 else {
1731 tprintf (", ");
1732 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1733 tprintf (", %ld", tcp->u_arg[2]);
1734 }
1735 }
Roland McGrath5a223472002-12-15 23:58:26 +00001736
John Hughesc61eb3d2002-05-17 11:37:50 +00001737 return 0;
1738}
1739
1740#endif
1741
1742
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001743static void
1744printargv(tcp, addr)
1745struct tcb *tcp;
1746long addr;
1747{
Roland McGrath85a3bc42007-08-02 02:13:05 +00001748 union {
1749 int p32;
1750 long p64;
1751 char data[sizeof(long)];
1752 } cp;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001753 char *sep;
Roland McGrath85a3bc42007-08-02 02:13:05 +00001754 int n = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001755
Roland McGrath85a3bc42007-08-02 02:13:05 +00001756 cp.p64 = 1;
1757 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1758 if (umoven(tcp, addr, personality_wordsize[current_personality],
1759 cp.data) < 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001760 tprintf("%#lx", addr);
1761 return;
1762 }
Roland McGrath85a3bc42007-08-02 02:13:05 +00001763 if (personality_wordsize[current_personality] == 4)
1764 cp.p64 = cp.p32;
1765 if (cp.p64 == 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001766 break;
1767 tprintf(sep);
Roland McGrath85a3bc42007-08-02 02:13:05 +00001768 printstr(tcp, cp.p64, -1);
1769 addr += personality_wordsize[current_personality];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001770 }
Roland McGrath85a3bc42007-08-02 02:13:05 +00001771 if (cp.p64)
1772 tprintf("%s...", sep);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001773}
1774
1775static void
1776printargc(fmt, tcp, addr)
1777char *fmt;
1778struct tcb *tcp;
1779long addr;
1780{
1781 int count;
1782 char *cp;
1783
1784 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1785 addr += sizeof(char *);
1786 }
1787 tprintf(fmt, count, count == 1 ? "" : "s");
1788}
1789
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001790#if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001791int
1792sys_execv(tcp)
1793struct tcb *tcp;
1794{
1795 if (entering(tcp)) {
1796 printpath(tcp, tcp->u_arg[0]);
1797 if (!verbose(tcp))
1798 tprintf(", %#lx", tcp->u_arg[1]);
1799#if 0
1800 else if (abbrev(tcp))
1801 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1802#endif
1803 else {
1804 tprintf(", [");
1805 printargv(tcp, tcp->u_arg[1]);
1806 tprintf("]");
1807 }
1808 }
1809 return 0;
1810}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001811#endif /* SPARC || SPARC64 || SUNOS4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001812
1813int
1814sys_execve(tcp)
1815struct tcb *tcp;
1816{
1817 if (entering(tcp)) {
1818 printpath(tcp, tcp->u_arg[0]);
1819 if (!verbose(tcp))
1820 tprintf(", %#lx", tcp->u_arg[1]);
1821#if 0
1822 else if (abbrev(tcp))
1823 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1824#endif
1825 else {
1826 tprintf(", [");
1827 printargv(tcp, tcp->u_arg[1]);
1828 tprintf("]");
1829 }
1830 if (!verbose(tcp))
1831 tprintf(", %#lx", tcp->u_arg[2]);
1832 else if (abbrev(tcp))
1833 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1834 else {
1835 tprintf(", [");
1836 printargv(tcp, tcp->u_arg[2]);
1837 tprintf("]");
1838 }
1839 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001840 return 0;
1841}
1842
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001843#if UNIXWARE > 2
John Hughes4e36a812001-04-18 15:11:51 +00001844
1845int sys_rexecve(tcp)
1846struct tcb *tcp;
1847{
1848 if (entering (tcp)) {
1849 sys_execve (tcp);
1850 tprintf (", %ld", tcp->u_arg[3]);
1851 }
1852 return 0;
1853}
1854
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001855#endif
John Hughes4e36a812001-04-18 15:11:51 +00001856
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001857int
1858internal_exec(tcp)
1859struct tcb *tcp;
1860{
1861#ifdef SUNOS4
1862 if (exiting(tcp) && !syserror(tcp) && followfork)
1863 fixvfork(tcp);
1864#endif /* SUNOS4 */
Roland McGrathfdb097f2004-07-12 07:38:55 +00001865#if defined LINUX && defined TCB_WAITEXECVE
1866 if (exiting(tcp) && syserror(tcp))
1867 tcp->flags &= ~TCB_WAITEXECVE;
1868 else
1869 tcp->flags |= TCB_WAITEXECVE;
1870#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001871 return 0;
1872}
1873
1874#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001875#ifndef __WNOTHREAD
1876#define __WNOTHREAD 0x20000000
1877#endif
1878#ifndef __WALL
1879#define __WALL 0x40000000
1880#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001881#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001882#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001883#endif
1884#endif /* LINUX */
1885
Roland McGrathd9f816f2004-09-04 03:39:20 +00001886static const struct xlat wait4_options[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001887 { WNOHANG, "WNOHANG" },
1888#ifndef WSTOPPED
1889 { WUNTRACED, "WUNTRACED" },
1890#endif
1891#ifdef WEXITED
1892 { WEXITED, "WEXITED" },
1893#endif
1894#ifdef WTRAPPED
1895 { WTRAPPED, "WTRAPPED" },
1896#endif
1897#ifdef WSTOPPED
1898 { WSTOPPED, "WSTOPPED" },
1899#endif
1900#ifdef WCONTINUED
1901 { WCONTINUED, "WCONTINUED" },
1902#endif
1903#ifdef WNOWAIT
1904 { WNOWAIT, "WNOWAIT" },
1905#endif
1906#ifdef __WCLONE
1907 { __WCLONE, "__WCLONE" },
1908#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001909#ifdef __WALL
1910 { __WALL, "__WALL" },
1911#endif
1912#ifdef __WNOTHREAD
1913 { __WNOTHREAD, "__WNOTHREAD" },
1914#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001915 { 0, NULL },
1916};
1917
Roland McGrath5e02a572004-10-19 23:33:47 +00001918#if !defined WCOREFLAG && defined WCOREFLG
1919# define WCOREFLAG WCOREFLG
1920#endif
1921#ifndef WCOREFLAG
1922#define WCOREFLAG 0x80
1923#endif
1924
1925#ifndef W_STOPCODE
1926#define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1927#endif
1928#ifndef W_EXITCODE
1929#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1930#endif
1931
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001932static int
1933printstatus(status)
1934int status;
1935{
1936 int exited = 0;
1937
1938 /*
1939 * Here is a tricky presentation problem. This solution
1940 * is still not entirely satisfactory but since there
1941 * are no wait status constructors it will have to do.
1942 */
Roland McGrath79fbda52004-04-14 02:45:55 +00001943 if (WIFSTOPPED(status)) {
1944 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001945 signame(WSTOPSIG(status)));
Roland McGrath79fbda52004-04-14 02:45:55 +00001946 status &= ~W_STOPCODE(WSTOPSIG(status));
1947 }
1948 else if (WIFSIGNALED(status)) {
1949 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001950 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001951 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
Roland McGrath79fbda52004-04-14 02:45:55 +00001952 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1953 }
1954 else if (WIFEXITED(status)) {
1955 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001956 WEXITSTATUS(status));
1957 exited = 1;
Roland McGrath79fbda52004-04-14 02:45:55 +00001958 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001959 }
Roland McGrath79fbda52004-04-14 02:45:55 +00001960 else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001961 tprintf("[%#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001962 return 0;
1963 }
1964
1965 if (status == 0)
1966 tprintf("]");
1967 else
Roland McGrathf8cc83c2004-06-04 01:24:07 +00001968 tprintf(" | %#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001969
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001970 return exited;
1971}
1972
1973static int
Denys Vlasenko59432db2009-01-26 19:09:35 +00001974printwaitn(struct tcb *tcp, int n, int bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001975{
1976 int status;
1977 int exited = 0;
1978
1979 if (entering(tcp)) {
Roland McGrath5b63d962008-07-18 02:16:47 +00001980 /*
1981 * Sign-extend a 32-bit value when that's what it is.
Denys Vlasenko59432db2009-01-26 19:09:35 +00001982 *
1983 * NB: On Linux, kernel-side pid_t is typedef'ed to int
1984 * on all arches; also, glibc-2.8 truncates wait3 and wait4
1985 * pid argument to int on 64bit arches, producing,
1986 * for example, wait4(4294967295, ...) instead of -1
1987 * in strace.
1988 * Therefore, maybe it makes sense to *unconditionally*
1989 * widen int to long here...
Roland McGrath5b63d962008-07-18 02:16:47 +00001990 */
1991 long pid = tcp->u_arg[0];
1992 if (personality_wordsize[current_personality] < sizeof pid)
1993 pid = (long) (int) pid;
1994 tprintf("%ld, ", pid);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001995 } else {
1996 /* status */
1997 if (!tcp->u_arg[1])
1998 tprintf("NULL");
1999 else if (syserror(tcp) || tcp->u_rval == 0)
2000 tprintf("%#lx", tcp->u_arg[1]);
2001 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
2002 tprintf("[?]");
2003 else
2004 exited = printstatus(status);
2005 /* options */
2006 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00002007 printflags(wait4_options, tcp->u_arg[2], "W???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002008 if (n == 4) {
2009 tprintf(", ");
2010 /* usage */
2011 if (!tcp->u_arg[3])
2012 tprintf("NULL");
2013#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002014 else if (tcp->u_rval > 0) {
Denys Vlasenko59432db2009-01-26 19:09:35 +00002015#ifdef ALPHA
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002016 if (bitness)
2017 printrusage32(tcp, tcp->u_arg[3]);
2018 else
2019#endif
2020 printrusage(tcp, tcp->u_arg[3]);
2021 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002022#endif /* LINUX */
2023#ifdef SUNOS4
2024 else if (tcp->u_rval > 0 && exited)
2025 printrusage(tcp, tcp->u_arg[3]);
2026#endif /* SUNOS4 */
2027 else
2028 tprintf("%#lx", tcp->u_arg[3]);
2029 }
2030 }
2031 return 0;
2032}
2033
2034int
Roland McGrathc74c0b72004-09-01 19:39:46 +00002035internal_wait(tcp, flagarg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002036struct tcb *tcp;
Roland McGrathc74c0b72004-09-01 19:39:46 +00002037int flagarg;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002038{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002039 int got_kids;
2040
2041#ifdef TCB_CLONE_THREAD
2042 if (tcp->flags & TCB_CLONE_THREAD)
2043 /* The children we wait for are our parent's children. */
2044 got_kids = (tcp->parent->nchildren
2045 > tcp->parent->nclone_detached);
2046 else
2047 got_kids = (tcp->nchildren > tcp->nclone_detached);
2048#else
2049 got_kids = tcp->nchildren > 0;
2050#endif
2051
2052 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00002053 /* There are children that this parent should block for.
2054 But ptrace made us the parent of the traced children
2055 and the real parent will get ECHILD from the wait call.
2056
2057 XXX If we attached with strace -f -p PID, then there
2058 may be untraced dead children the parent could be reaping
2059 now, but we make him block. */
2060
2061 /* ??? WTA: fix bug with hanging children */
2062
Roland McGrathc74c0b72004-09-01 19:39:46 +00002063 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00002064 /*
2065 * There are traced children. We'll make the parent
2066 * block to avoid a false ECHILD error due to our
2067 * ptrace having stolen the children. However,
2068 * we shouldn't block if there are zombies to reap.
2069 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
2070 */
Roland McGrathfccfb942003-10-01 21:59:44 +00002071 struct tcb *child = NULL;
Roland McGrath09623452003-05-23 02:27:13 +00002072 if (tcp->nzombies > 0 &&
2073 (tcp->u_arg[0] == -1 ||
Roland McGrathfccfb942003-10-01 21:59:44 +00002074 (child = pid2tcb(tcp->u_arg[0])) == NULL))
Roland McGrath09623452003-05-23 02:27:13 +00002075 return 0;
Roland McGrathfccfb942003-10-01 21:59:44 +00002076 if (tcp->u_arg[0] > 0) {
2077 /*
2078 * If the parent waits for a specified child
2079 * PID, then it must get ECHILD right away
2080 * if that PID is not one of its children.
2081 * Make sure that the requested PID matches
2082 * one of the parent's children that we are
2083 * tracing, and don't suspend it otherwise.
2084 */
2085 if (child == NULL)
2086 child = pid2tcb(tcp->u_arg[0]);
2087 if (child == NULL || child->parent != (
2088#ifdef TCB_CLONE_THREAD
2089 (tcp->flags & TCB_CLONE_THREAD)
2090 ? tcp->parent :
2091#endif
Roland McGrathd56a6562005-08-03 11:23:43 +00002092 tcp) ||
2093 (child->flags & TCB_EXITING))
Roland McGrathfccfb942003-10-01 21:59:44 +00002094 return 0;
2095 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002096 tcp->flags |= TCB_SUSPENDED;
2097 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002098#ifdef TCB_CLONE_THREAD
2099 if (tcp->flags & TCB_CLONE_THREAD)
2100 tcp->parent->nclone_waiting++;
2101#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002102 }
2103 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002104 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathc74c0b72004-09-01 19:39:46 +00002105 if (tcp->u_arg[flagarg] & WNOHANG) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00002106 /* We must force a fake result of 0 instead of
2107 the ECHILD error. */
2108 extern int force_result();
2109 return force_result(tcp, 0, 0);
2110 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00002111 }
Roland McGrath09623452003-05-23 02:27:13 +00002112 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2113 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2114 /*
2115 * We just reaped a child we don't know about,
2116 * presumably a zombie we already droptcb'd.
2117 */
2118 tcp->nzombies--;
2119 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002120 return 0;
2121}
2122
2123#ifdef SVR4
2124
2125int
2126sys_wait(tcp)
2127struct tcb *tcp;
2128{
2129 if (exiting(tcp)) {
2130 /* The library wrapper stuffs this into the user variable. */
2131 if (!syserror(tcp))
2132 printstatus(getrval2(tcp));
2133 }
2134 return 0;
2135}
2136
2137#endif /* SVR4 */
2138
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002139#ifdef FREEBSD
2140int
2141sys_wait(tcp)
2142struct tcb *tcp;
2143{
2144 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00002145
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002146 if (exiting(tcp)) {
2147 if (!syserror(tcp)) {
2148 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2149 tprintf("%#lx", tcp->u_arg[0]);
2150 else
2151 printstatus(status);
2152 }
2153 }
2154 return 0;
2155}
2156#endif
2157
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002158int
2159sys_waitpid(tcp)
2160struct tcb *tcp;
2161{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002162 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002163}
2164
2165int
2166sys_wait4(tcp)
2167struct tcb *tcp;
2168{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002169 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002170}
2171
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002172#ifdef ALPHA
2173int
2174sys_osf_wait4(tcp)
2175struct tcb *tcp;
2176{
2177 return printwaitn(tcp, 4, 1);
2178}
2179#endif
2180
Roland McGrathc74c0b72004-09-01 19:39:46 +00002181#if defined SVR4 || defined LINUX
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002182
Roland McGrathd9f816f2004-09-04 03:39:20 +00002183static const struct xlat waitid_types[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002184 { P_PID, "P_PID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002185#ifdef P_PPID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002186 { P_PPID, "P_PPID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002187#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002188 { P_PGID, "P_PGID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002189#ifdef P_SID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002190 { P_SID, "P_SID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002191#endif
2192#ifdef P_CID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002193 { P_CID, "P_CID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002194#endif
2195#ifdef P_UID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002196 { P_UID, "P_UID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002197#endif
2198#ifdef P_GID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002199 { P_GID, "P_GID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002200#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002201 { P_ALL, "P_ALL" },
2202#ifdef P_LWPID
2203 { P_LWPID, "P_LWPID" },
2204#endif
2205 { 0, NULL },
2206};
2207
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002208int
2209sys_waitid(tcp)
2210struct tcb *tcp;
2211{
2212 siginfo_t si;
2213 int exited;
2214
2215 if (entering(tcp)) {
2216 printxval(waitid_types, tcp->u_arg[0], "P_???");
2217 tprintf(", %ld, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002218 }
2219 else {
2220 /* siginfo */
2221 exited = 0;
2222 if (!tcp->u_arg[2])
2223 tprintf("NULL");
2224 else if (syserror(tcp))
2225 tprintf("%#lx", tcp->u_arg[2]);
2226 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2227 tprintf("{???}");
2228 else
Denys Vlasenkof535b542009-01-13 18:30:55 +00002229 printsiginfo(&si, verbose(tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002230 /* options */
2231 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00002232 printflags(wait4_options, tcp->u_arg[3], "W???");
Roland McGrath39426a32004-10-06 22:02:59 +00002233 if (tcp->u_nargs > 4) {
2234 /* usage */
2235 tprintf(", ");
2236 if (!tcp->u_arg[4])
2237 tprintf("NULL");
2238 else if (tcp->u_error)
2239 tprintf("%#lx", tcp->u_arg[4]);
2240 else
2241 printrusage(tcp, tcp->u_arg[4]);
2242 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002243 }
2244 return 0;
2245}
2246
Roland McGrathc74c0b72004-09-01 19:39:46 +00002247#endif /* SVR4 or LINUX */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002248
2249int
2250sys_alarm(tcp)
2251struct tcb *tcp;
2252{
2253 if (entering(tcp))
2254 tprintf("%lu", tcp->u_arg[0]);
2255 return 0;
2256}
2257
2258int
2259sys_uname(tcp)
2260struct tcb *tcp;
2261{
2262 struct utsname uname;
2263
2264 if (exiting(tcp)) {
2265 if (syserror(tcp) || !verbose(tcp))
2266 tprintf("%#lx", tcp->u_arg[0]);
2267 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2268 tprintf("{...}");
2269 else if (!abbrev(tcp)) {
2270
2271 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2272 uname.sysname, uname.nodename);
2273 tprintf("release=\"%s\", version=\"%s\", ",
2274 uname.release, uname.version);
2275 tprintf("machine=\"%s\"", uname.machine);
2276#ifdef LINUX
2277#ifndef __GLIBC__
2278 tprintf(", domainname=\"%s\"", uname.domainname);
2279#endif /* __GLIBC__ */
2280#endif /* LINUX */
2281 tprintf("}");
2282 }
2283 else
2284 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2285 uname.sysname, uname.nodename);
2286 }
2287 return 0;
2288}
2289
2290#ifndef SVR4
2291
Roland McGrathd9f816f2004-09-04 03:39:20 +00002292static const struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002293#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002294 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2295 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2296 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2297 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2298 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2299 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2300 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2301 { PTRACE_CONT, "PTRACE_CONT" },
2302 { PTRACE_KILL, "PTRACE_KILL" },
2303 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2304 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2305 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002306#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002307 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002308#endif
2309#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002310 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002311#endif
2312#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002313 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002314#endif
2315#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002316 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002317#endif
2318#ifdef PTRACE_GETFPXREGS
2319 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2320#endif
2321#ifdef PTRACE_SETFPXREGS
2322 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2323#endif
Roland McGrathf04bb482005-05-09 07:45:33 +00002324#ifdef PTRACE_GETVRREGS
2325 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2326#endif
2327#ifdef PTRACE_SETVRREGS
2328 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2329#endif
Denys Vlasenkof535b542009-01-13 18:30:55 +00002330#ifdef PTRACE_SETOPTIONS
2331 { PTRACE_SETOPTIONS, "PTRACE_SETOPTIONS", },
2332#endif
2333#ifdef PTRACE_GETEVENTMSG
2334 { PTRACE_GETEVENTMSG, "PTRACE_GETEVENTMSG", },
2335#endif
2336#ifdef PTRACE_GETSIGINFO
2337 { PTRACE_GETSIGINFO, "PTRACE_GETSIGINFO", },
2338#endif
2339#ifdef PTRACE_SETSIGINFO
2340 { PTRACE_SETSIGINFO, "PTRACE_SETSIGINFO", },
2341#endif
Roland McGrathbf621d42003-01-14 09:46:21 +00002342#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002343 { PTRACE_READDATA, "PTRACE_READDATA" },
2344 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2345 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2346 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2347 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2348 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2349#ifdef SPARC
2350 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2351 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2352#else /* !SPARC */
2353 { PTRACE_22, "PTRACE_PTRACE_22" },
2354 { PTRACE_23, "PTRACE_PTRACE_23" },
2355#endif /* !SPARC */
2356#endif /* SUNOS4 */
2357 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2358#ifdef SUNOS4
2359 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2360#ifdef I386
2361 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2362 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2363 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2364#else /* !I386 */
2365 { PTRACE_26, "PTRACE_26" },
2366 { PTRACE_27, "PTRACE_27" },
2367 { PTRACE_28, "PTRACE_28" },
2368#endif /* !I386 */
2369 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2370#endif /* SUNOS4 */
Denys Vlasenkof535b542009-01-13 18:30:55 +00002371
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002372#else /* FREEBSD */
Denys Vlasenkof535b542009-01-13 18:30:55 +00002373
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002374 { PT_TRACE_ME, "PT_TRACE_ME" },
2375 { PT_READ_I, "PT_READ_I" },
2376 { PT_READ_D, "PT_READ_D" },
2377 { PT_WRITE_I, "PT_WRITE_I" },
2378 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002379#ifdef PT_READ_U
2380 { PT_READ_U, "PT_READ_U" },
2381#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002382 { PT_CONTINUE, "PT_CONTINUE" },
2383 { PT_KILL, "PT_KILL" },
2384 { PT_STEP, "PT_STEP" },
2385 { PT_ATTACH, "PT_ATTACH" },
2386 { PT_DETACH, "PT_DETACH" },
2387 { PT_GETREGS, "PT_GETREGS" },
2388 { PT_SETREGS, "PT_SETREGS" },
2389 { PT_GETFPREGS, "PT_GETFPREGS" },
2390 { PT_SETFPREGS, "PT_SETFPREGS" },
2391 { PT_GETDBREGS, "PT_GETDBREGS" },
2392 { PT_SETDBREGS, "PT_SETDBREGS" },
2393#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002394 { 0, NULL },
2395};
2396
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002397#ifndef FREEBSD
Denys Vlasenkof535b542009-01-13 18:30:55 +00002398#ifdef PTRACE_SETOPTIONS
2399static const struct xlat ptrace_setoptions_flags[] = {
2400#ifdef PTRACE_O_TRACESYSGOOD
2401 { PTRACE_O_TRACESYSGOOD,"PTRACE_O_TRACESYSGOOD" },
2402#endif
2403#ifdef PTRACE_O_TRACEFORK
2404 { PTRACE_O_TRACEFORK, "PTRACE_O_TRACEFORK" },
2405#endif
2406#ifdef PTRACE_O_TRACEVFORK
2407 { PTRACE_O_TRACEVFORK, "PTRACE_O_TRACEVFORK" },
2408#endif
2409#ifdef PTRACE_O_TRACECLONE
2410 { PTRACE_O_TRACECLONE, "PTRACE_O_TRACECLONE" },
2411#endif
2412#ifdef PTRACE_O_TRACEEXEC
2413 { PTRACE_O_TRACEEXEC, "PTRACE_O_TRACEEXEC" },
2414#endif
2415#ifdef PTRACE_O_TRACEVFORKDONE
2416 { PTRACE_O_TRACEVFORKDONE,"PTRACE_O_TRACEVFORKDONE"},
2417#endif
2418#ifdef PTRACE_O_TRACEEXIT
2419 { PTRACE_O_TRACEEXIT, "PTRACE_O_TRACEEXIT" },
2420#endif
2421 { 0, NULL },
2422};
2423#endif
2424#endif
2425
2426#ifndef FREEBSD
Roland McGrathd9f816f2004-09-04 03:39:20 +00002427const struct xlat struct_user_offsets[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002428#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002429#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002430 { PT_PSWMASK, "psw_mask" },
2431 { PT_PSWADDR, "psw_addr" },
2432 { PT_GPR0, "gpr0" },
2433 { PT_GPR1, "gpr1" },
2434 { PT_GPR2, "gpr2" },
2435 { PT_GPR3, "gpr3" },
2436 { PT_GPR4, "gpr4" },
2437 { PT_GPR5, "gpr5" },
2438 { PT_GPR6, "gpr6" },
2439 { PT_GPR7, "gpr7" },
2440 { PT_GPR8, "gpr8" },
2441 { PT_GPR9, "gpr9" },
2442 { PT_GPR10, "gpr10" },
2443 { PT_GPR11, "gpr11" },
2444 { PT_GPR12, "gpr12" },
2445 { PT_GPR13, "gpr13" },
2446 { PT_GPR14, "gpr14" },
2447 { PT_GPR15, "gpr15" },
2448 { PT_ACR0, "acr0" },
2449 { PT_ACR1, "acr1" },
2450 { PT_ACR2, "acr2" },
2451 { PT_ACR3, "acr3" },
2452 { PT_ACR4, "acr4" },
2453 { PT_ACR5, "acr5" },
2454 { PT_ACR6, "acr6" },
2455 { PT_ACR7, "acr7" },
2456 { PT_ACR8, "acr8" },
2457 { PT_ACR9, "acr9" },
2458 { PT_ACR10, "acr10" },
2459 { PT_ACR11, "acr11" },
2460 { PT_ACR12, "acr12" },
2461 { PT_ACR13, "acr13" },
2462 { PT_ACR14, "acr14" },
2463 { PT_ACR15, "acr15" },
2464 { PT_ORIGGPR2, "orig_gpr2" },
2465 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002466#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002467 { PT_FPR0_HI, "fpr0.hi" },
2468 { PT_FPR0_LO, "fpr0.lo" },
2469 { PT_FPR1_HI, "fpr1.hi" },
2470 { PT_FPR1_LO, "fpr1.lo" },
2471 { PT_FPR2_HI, "fpr2.hi" },
2472 { PT_FPR2_LO, "fpr2.lo" },
2473 { PT_FPR3_HI, "fpr3.hi" },
2474 { PT_FPR3_LO, "fpr3.lo" },
2475 { PT_FPR4_HI, "fpr4.hi" },
2476 { PT_FPR4_LO, "fpr4.lo" },
2477 { PT_FPR5_HI, "fpr5.hi" },
2478 { PT_FPR5_LO, "fpr5.lo" },
2479 { PT_FPR6_HI, "fpr6.hi" },
2480 { PT_FPR6_LO, "fpr6.lo" },
2481 { PT_FPR7_HI, "fpr7.hi" },
2482 { PT_FPR7_LO, "fpr7.lo" },
2483 { PT_FPR8_HI, "fpr8.hi" },
2484 { PT_FPR8_LO, "fpr8.lo" },
2485 { PT_FPR9_HI, "fpr9.hi" },
2486 { PT_FPR9_LO, "fpr9.lo" },
2487 { PT_FPR10_HI, "fpr10.hi" },
2488 { PT_FPR10_LO, "fpr10.lo" },
2489 { PT_FPR11_HI, "fpr11.hi" },
2490 { PT_FPR11_LO, "fpr11.lo" },
2491 { PT_FPR12_HI, "fpr12.hi" },
2492 { PT_FPR12_LO, "fpr12.lo" },
2493 { PT_FPR13_HI, "fpr13.hi" },
2494 { PT_FPR13_LO, "fpr13.lo" },
2495 { PT_FPR14_HI, "fpr14.hi" },
2496 { PT_FPR14_LO, "fpr14.lo" },
2497 { PT_FPR15_HI, "fpr15.hi" },
2498 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002499#endif
2500#if defined(S390X)
2501 { PT_FPR0, "fpr0" },
2502 { PT_FPR1, "fpr1" },
2503 { PT_FPR2, "fpr2" },
2504 { PT_FPR3, "fpr3" },
2505 { PT_FPR4, "fpr4" },
2506 { PT_FPR5, "fpr5" },
2507 { PT_FPR6, "fpr6" },
2508 { PT_FPR7, "fpr7" },
2509 { PT_FPR8, "fpr8" },
2510 { PT_FPR9, "fpr9" },
2511 { PT_FPR10, "fpr10" },
2512 { PT_FPR11, "fpr11" },
2513 { PT_FPR12, "fpr12" },
2514 { PT_FPR13, "fpr13" },
2515 { PT_FPR14, "fpr14" },
2516 { PT_FPR15, "fpr15" },
2517#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002518 { PT_CR_9, "cr9" },
2519 { PT_CR_10, "cr10" },
2520 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002521 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002522#endif
2523#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002524 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002525#elif defined(HPPA)
2526 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002527#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002528#ifndef PT_ORIG_R3
2529#define PT_ORIG_R3 34
2530#endif
Roland McGratheb285352003-01-14 09:59:00 +00002531#define REGSIZE (sizeof(unsigned long))
2532 { REGSIZE*PT_R0, "r0" },
2533 { REGSIZE*PT_R1, "r1" },
2534 { REGSIZE*PT_R2, "r2" },
2535 { REGSIZE*PT_R3, "r3" },
2536 { REGSIZE*PT_R4, "r4" },
2537 { REGSIZE*PT_R5, "r5" },
2538 { REGSIZE*PT_R6, "r6" },
2539 { REGSIZE*PT_R7, "r7" },
2540 { REGSIZE*PT_R8, "r8" },
2541 { REGSIZE*PT_R9, "r9" },
2542 { REGSIZE*PT_R10, "r10" },
2543 { REGSIZE*PT_R11, "r11" },
2544 { REGSIZE*PT_R12, "r12" },
2545 { REGSIZE*PT_R13, "r13" },
2546 { REGSIZE*PT_R14, "r14" },
2547 { REGSIZE*PT_R15, "r15" },
2548 { REGSIZE*PT_R16, "r16" },
2549 { REGSIZE*PT_R17, "r17" },
2550 { REGSIZE*PT_R18, "r18" },
2551 { REGSIZE*PT_R19, "r19" },
2552 { REGSIZE*PT_R20, "r20" },
2553 { REGSIZE*PT_R21, "r21" },
2554 { REGSIZE*PT_R22, "r22" },
2555 { REGSIZE*PT_R23, "r23" },
2556 { REGSIZE*PT_R24, "r24" },
2557 { REGSIZE*PT_R25, "r25" },
2558 { REGSIZE*PT_R26, "r26" },
2559 { REGSIZE*PT_R27, "r27" },
2560 { REGSIZE*PT_R28, "r28" },
2561 { REGSIZE*PT_R29, "r29" },
2562 { REGSIZE*PT_R30, "r30" },
2563 { REGSIZE*PT_R31, "r31" },
2564 { REGSIZE*PT_NIP, "NIP" },
2565 { REGSIZE*PT_MSR, "MSR" },
2566 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2567 { REGSIZE*PT_CTR, "CTR" },
2568 { REGSIZE*PT_LNK, "LNK" },
2569 { REGSIZE*PT_XER, "XER" },
2570 { REGSIZE*PT_CCR, "CCR" },
2571 { REGSIZE*PT_FPR0, "FPR0" },
2572#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002573#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002574#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002575 { 0, "r0" },
2576 { 1, "r1" },
2577 { 2, "r2" },
2578 { 3, "r3" },
2579 { 4, "r4" },
2580 { 5, "r5" },
2581 { 6, "r6" },
2582 { 7, "r7" },
2583 { 8, "r8" },
2584 { 9, "r9" },
2585 { 10, "r10" },
2586 { 11, "r11" },
2587 { 12, "r12" },
2588 { 13, "r13" },
2589 { 14, "r14" },
2590 { 15, "r15" },
2591 { 16, "r16" },
2592 { 17, "r17" },
2593 { 18, "r18" },
2594 { 19, "r19" },
2595 { 20, "r20" },
2596 { 21, "r21" },
2597 { 22, "r22" },
2598 { 23, "r23" },
2599 { 24, "r24" },
2600 { 25, "r25" },
2601 { 26, "r26" },
2602 { 27, "r27" },
2603 { 28, "r28" },
2604 { 29, "gp" },
2605 { 30, "fp" },
2606 { 31, "zero" },
2607 { 32, "fp0" },
2608 { 33, "fp" },
2609 { 34, "fp2" },
2610 { 35, "fp3" },
2611 { 36, "fp4" },
2612 { 37, "fp5" },
2613 { 38, "fp6" },
2614 { 39, "fp7" },
2615 { 40, "fp8" },
2616 { 41, "fp9" },
2617 { 42, "fp10" },
2618 { 43, "fp11" },
2619 { 44, "fp12" },
2620 { 45, "fp13" },
2621 { 46, "fp14" },
2622 { 47, "fp15" },
2623 { 48, "fp16" },
2624 { 49, "fp17" },
2625 { 50, "fp18" },
2626 { 51, "fp19" },
2627 { 52, "fp20" },
2628 { 53, "fp21" },
2629 { 54, "fp22" },
2630 { 55, "fp23" },
2631 { 56, "fp24" },
2632 { 57, "fp25" },
2633 { 58, "fp26" },
2634 { 59, "fp27" },
2635 { 60, "fp28" },
2636 { 61, "fp29" },
2637 { 62, "fp30" },
2638 { 63, "fp31" },
2639 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002640#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002641#ifdef IA64
2642 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2643 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2644 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2645 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2646 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2647 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2648 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2649 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2650 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2651 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2652 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2653 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2654 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2655 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2656 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2657 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2658 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2659 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2660 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2661 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2662 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2663 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2664 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2665 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2666 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2667 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2668 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2669 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2670 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2671 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2672 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2673 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2674 /* switch stack: */
2675 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2676 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2677 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2678 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2679 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2680 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2681 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2682 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2683 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2684 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002685 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2686 { PT_B4, "b4" }, { PT_B5, "b5" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002687 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002688 /* pt_regs */
Roland McGrathca4e10c2004-01-13 10:13:20 +00002689 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2690 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002691 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2692 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2693 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2694 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2695 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2696 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2697 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2698 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2699 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2700 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2701 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2702 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2703 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2704 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2705 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
Roland McGrathfb1bc072004-03-01 21:29:24 +00002706# ifdef PT_AR_CSD
2707 { PT_AR_CSD, "ar.csd" },
2708# endif
2709# ifdef PT_AR_SSD
2710 { PT_AR_SSD, "ar.ssd" },
2711# endif
Roland McGrathca4e10c2004-01-13 10:13:20 +00002712 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002713#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002714#ifdef I386
2715 { 4*EBX, "4*EBX" },
2716 { 4*ECX, "4*ECX" },
2717 { 4*EDX, "4*EDX" },
2718 { 4*ESI, "4*ESI" },
2719 { 4*EDI, "4*EDI" },
2720 { 4*EBP, "4*EBP" },
2721 { 4*EAX, "4*EAX" },
2722 { 4*DS, "4*DS" },
2723 { 4*ES, "4*ES" },
2724 { 4*FS, "4*FS" },
2725 { 4*GS, "4*GS" },
2726 { 4*ORIG_EAX, "4*ORIG_EAX" },
2727 { 4*EIP, "4*EIP" },
2728 { 4*CS, "4*CS" },
2729 { 4*EFL, "4*EFL" },
2730 { 4*UESP, "4*UESP" },
2731 { 4*SS, "4*SS" },
2732#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002733#ifdef X86_64
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002734 { 8*R15, "8*R15" },
2735 { 8*R14, "8*R14" },
2736 { 8*R13, "8*R13" },
2737 { 8*R12, "8*R12" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002738 { 8*RBP, "8*RBP" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002739 { 8*RBX, "8*RBX" },
2740 { 8*R11, "8*R11" },
2741 { 8*R10, "8*R10" },
2742 { 8*R9, "8*R9" },
2743 { 8*R8, "8*R8" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002744 { 8*RAX, "8*RAX" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002745 { 8*RCX, "8*RCX" },
2746 { 8*RDX, "8*RDX" },
2747 { 8*RSI, "8*RSI" },
2748 { 8*RDI, "8*RDI" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002749#if 0
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002750 { DS, "DS" },
2751 { ES, "ES" },
2752 { FS, "FS" },
2753 { GS, "GS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002754#endif
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002755 { 8*ORIG_RAX, "8*ORIG_RAX" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002756 { 8*RIP, "8*RIP" },
2757 { 8*CS, "8*CS" },
2758 { 8*EFLAGS, "8*EFL" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002759 { 8*RSP, "8*RSP" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002760 { 8*SS, "8*SS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002761#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002762#ifdef M68K
2763 { 4*PT_D1, "4*PT_D1" },
2764 { 4*PT_D2, "4*PT_D2" },
2765 { 4*PT_D3, "4*PT_D3" },
2766 { 4*PT_D4, "4*PT_D4" },
2767 { 4*PT_D5, "4*PT_D5" },
2768 { 4*PT_D6, "4*PT_D6" },
2769 { 4*PT_D7, "4*PT_D7" },
2770 { 4*PT_A0, "4*PT_A0" },
2771 { 4*PT_A1, "4*PT_A1" },
2772 { 4*PT_A2, "4*PT_A2" },
2773 { 4*PT_A3, "4*PT_A3" },
2774 { 4*PT_A4, "4*PT_A4" },
2775 { 4*PT_A5, "4*PT_A5" },
2776 { 4*PT_A6, "4*PT_A6" },
2777 { 4*PT_D0, "4*PT_D0" },
2778 { 4*PT_USP, "4*PT_USP" },
2779 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2780 { 4*PT_SR, "4*PT_SR" },
2781 { 4*PT_PC, "4*PT_PC" },
2782#endif /* M68K */
2783#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002784#ifdef SH
Denys Vlasenkoadedb512008-12-30 18:47:55 +00002785 { 4*REG_REG0, "4*REG_REG0" },
2786 { 4*(REG_REG0+1), "4*REG_REG1" },
2787 { 4*(REG_REG0+2), "4*REG_REG2" },
2788 { 4*(REG_REG0+3), "4*REG_REG3" },
2789 { 4*(REG_REG0+4), "4*REG_REG4" },
2790 { 4*(REG_REG0+5), "4*REG_REG5" },
2791 { 4*(REG_REG0+6), "4*REG_REG6" },
2792 { 4*(REG_REG0+7), "4*REG_REG7" },
2793 { 4*(REG_REG0+8), "4*REG_REG8" },
2794 { 4*(REG_REG0+9), "4*REG_REG9" },
2795 { 4*(REG_REG0+10), "4*REG_REG10" },
2796 { 4*(REG_REG0+11), "4*REG_REG11" },
2797 { 4*(REG_REG0+12), "4*REG_REG12" },
2798 { 4*(REG_REG0+13), "4*REG_REG13" },
2799 { 4*(REG_REG0+14), "4*REG_REG14" },
2800 { 4*REG_REG15, "4*REG_REG15" },
2801 { 4*REG_PC, "4*REG_PC" },
2802 { 4*REG_PR, "4*REG_PR" },
2803 { 4*REG_SR, "4*REG_SR" },
2804 { 4*REG_GBR, "4*REG_GBR" },
2805 { 4*REG_MACH, "4*REG_MACH" },
2806 { 4*REG_MACL, "4*REG_MACL" },
2807 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2808 { 4*REG_FPUL, "4*REG_FPUL" },
2809 { 4*REG_FPREG0, "4*REG_FPREG0" },
2810 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2811 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2812 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2813 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2814 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2815 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2816 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2817 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2818 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2819 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2820 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2821 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2822 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2823 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2824 { 4*REG_FPREG15, "4*REG_FPREG15" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002825#ifdef REG_XDREG0
Denys Vlasenkoadedb512008-12-30 18:47:55 +00002826 { 4*REG_XDREG0, "4*REG_XDREG0" },
2827 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2828 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2829 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2830 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2831 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2832 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2833 { 4*REG_XDREG14, "4*REG_XDREG14" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002834#endif
Denys Vlasenkoadedb512008-12-30 18:47:55 +00002835 { 4*REG_FPSCR, "4*REG_FPSCR" },
Wichert Akkermanccef6372002-05-01 16:39:22 +00002836#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002837#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002838 { 0, "PC(L)" },
2839 { 4, "PC(U)" },
2840 { 8, "SR(L)" },
2841 { 12, "SR(U)" },
2842 { 16, "syscall no.(L)" },
2843 { 20, "syscall_no.(U)" },
2844 { 24, "R0(L)" },
2845 { 28, "R0(U)" },
2846 { 32, "R1(L)" },
2847 { 36, "R1(U)" },
2848 { 40, "R2(L)" },
2849 { 44, "R2(U)" },
2850 { 48, "R3(L)" },
2851 { 52, "R3(U)" },
2852 { 56, "R4(L)" },
2853 { 60, "R4(U)" },
2854 { 64, "R5(L)" },
2855 { 68, "R5(U)" },
2856 { 72, "R6(L)" },
2857 { 76, "R6(U)" },
2858 { 80, "R7(L)" },
2859 { 84, "R7(U)" },
2860 { 88, "R8(L)" },
2861 { 92, "R8(U)" },
2862 { 96, "R9(L)" },
2863 { 100, "R9(U)" },
2864 { 104, "R10(L)" },
2865 { 108, "R10(U)" },
2866 { 112, "R11(L)" },
2867 { 116, "R11(U)" },
2868 { 120, "R12(L)" },
2869 { 124, "R12(U)" },
2870 { 128, "R13(L)" },
2871 { 132, "R13(U)" },
2872 { 136, "R14(L)" },
2873 { 140, "R14(U)" },
2874 { 144, "R15(L)" },
2875 { 148, "R15(U)" },
2876 { 152, "R16(L)" },
2877 { 156, "R16(U)" },
2878 { 160, "R17(L)" },
2879 { 164, "R17(U)" },
2880 { 168, "R18(L)" },
2881 { 172, "R18(U)" },
2882 { 176, "R19(L)" },
2883 { 180, "R19(U)" },
2884 { 184, "R20(L)" },
2885 { 188, "R20(U)" },
2886 { 192, "R21(L)" },
2887 { 196, "R21(U)" },
2888 { 200, "R22(L)" },
2889 { 204, "R22(U)" },
2890 { 208, "R23(L)" },
2891 { 212, "R23(U)" },
2892 { 216, "R24(L)" },
2893 { 220, "R24(U)" },
2894 { 224, "R25(L)" },
2895 { 228, "R25(U)" },
2896 { 232, "R26(L)" },
2897 { 236, "R26(U)" },
2898 { 240, "R27(L)" },
2899 { 244, "R27(U)" },
2900 { 248, "R28(L)" },
2901 { 252, "R28(U)" },
2902 { 256, "R29(L)" },
2903 { 260, "R29(U)" },
2904 { 264, "R30(L)" },
2905 { 268, "R30(U)" },
2906 { 272, "R31(L)" },
2907 { 276, "R31(U)" },
2908 { 280, "R32(L)" },
2909 { 284, "R32(U)" },
2910 { 288, "R33(L)" },
2911 { 292, "R33(U)" },
2912 { 296, "R34(L)" },
2913 { 300, "R34(U)" },
2914 { 304, "R35(L)" },
2915 { 308, "R35(U)" },
2916 { 312, "R36(L)" },
2917 { 316, "R36(U)" },
2918 { 320, "R37(L)" },
2919 { 324, "R37(U)" },
2920 { 328, "R38(L)" },
2921 { 332, "R38(U)" },
2922 { 336, "R39(L)" },
2923 { 340, "R39(U)" },
2924 { 344, "R40(L)" },
2925 { 348, "R40(U)" },
2926 { 352, "R41(L)" },
2927 { 356, "R41(U)" },
2928 { 360, "R42(L)" },
2929 { 364, "R42(U)" },
2930 { 368, "R43(L)" },
2931 { 372, "R43(U)" },
2932 { 376, "R44(L)" },
2933 { 380, "R44(U)" },
2934 { 384, "R45(L)" },
2935 { 388, "R45(U)" },
2936 { 392, "R46(L)" },
2937 { 396, "R46(U)" },
2938 { 400, "R47(L)" },
2939 { 404, "R47(U)" },
2940 { 408, "R48(L)" },
2941 { 412, "R48(U)" },
2942 { 416, "R49(L)" },
2943 { 420, "R49(U)" },
2944 { 424, "R50(L)" },
2945 { 428, "R50(U)" },
2946 { 432, "R51(L)" },
2947 { 436, "R51(U)" },
2948 { 440, "R52(L)" },
2949 { 444, "R52(U)" },
2950 { 448, "R53(L)" },
2951 { 452, "R53(U)" },
2952 { 456, "R54(L)" },
2953 { 460, "R54(U)" },
2954 { 464, "R55(L)" },
2955 { 468, "R55(U)" },
2956 { 472, "R56(L)" },
2957 { 476, "R56(U)" },
2958 { 480, "R57(L)" },
2959 { 484, "R57(U)" },
2960 { 488, "R58(L)" },
2961 { 492, "R58(U)" },
2962 { 496, "R59(L)" },
2963 { 500, "R59(U)" },
2964 { 504, "R60(L)" },
2965 { 508, "R60(U)" },
2966 { 512, "R61(L)" },
2967 { 516, "R61(U)" },
2968 { 520, "R62(L)" },
2969 { 524, "R62(U)" },
2970 { 528, "TR0(L)" },
2971 { 532, "TR0(U)" },
2972 { 536, "TR1(L)" },
2973 { 540, "TR1(U)" },
2974 { 544, "TR2(L)" },
2975 { 548, "TR2(U)" },
2976 { 552, "TR3(L)" },
2977 { 556, "TR3(U)" },
2978 { 560, "TR4(L)" },
2979 { 564, "TR4(U)" },
2980 { 568, "TR5(L)" },
2981 { 572, "TR5(U)" },
2982 { 576, "TR6(L)" },
2983 { 580, "TR6(U)" },
2984 { 584, "TR7(L)" },
2985 { 588, "TR7(U)" },
Denys Vlasenkoadedb512008-12-30 18:47:55 +00002986 /* This entry is in case pt_regs contains dregs (depends on
2987 the kernel build options). */
Roland McGrathe1e584b2003-06-02 19:18:58 +00002988 { uoff(regs), "offsetof(struct user, regs)" },
2989 { uoff(fpu), "offsetof(struct user, fpu)" },
2990#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002991#ifdef ARM
2992 { uoff(regs.ARM_r0), "r0" },
2993 { uoff(regs.ARM_r1), "r1" },
2994 { uoff(regs.ARM_r2), "r2" },
2995 { uoff(regs.ARM_r3), "r3" },
2996 { uoff(regs.ARM_r4), "r4" },
2997 { uoff(regs.ARM_r5), "r5" },
2998 { uoff(regs.ARM_r6), "r6" },
2999 { uoff(regs.ARM_r7), "r7" },
3000 { uoff(regs.ARM_r8), "r8" },
3001 { uoff(regs.ARM_r9), "r9" },
3002 { uoff(regs.ARM_r10), "r10" },
3003 { uoff(regs.ARM_fp), "fp" },
3004 { uoff(regs.ARM_ip), "ip" },
3005 { uoff(regs.ARM_sp), "sp" },
3006 { uoff(regs.ARM_lr), "lr" },
3007 { uoff(regs.ARM_pc), "pc" },
3008 { uoff(regs.ARM_cpsr), "cpsr" },
3009#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00003010
Roland McGrath542c2c62008-05-20 01:11:56 +00003011#ifdef MIPS
3012 { 0, "r0" },
3013 { 1, "r1" },
3014 { 2, "r2" },
3015 { 3, "r3" },
3016 { 4, "r4" },
3017 { 5, "r5" },
3018 { 6, "r6" },
3019 { 7, "r7" },
3020 { 8, "r8" },
3021 { 9, "r9" },
3022 { 10, "r10" },
3023 { 11, "r11" },
3024 { 12, "r12" },
3025 { 13, "r13" },
3026 { 14, "r14" },
3027 { 15, "r15" },
3028 { 16, "r16" },
3029 { 17, "r17" },
3030 { 18, "r18" },
3031 { 19, "r19" },
3032 { 20, "r20" },
3033 { 21, "r21" },
3034 { 22, "r22" },
3035 { 23, "r23" },
3036 { 24, "r24" },
3037 { 25, "r25" },
3038 { 26, "r26" },
3039 { 27, "r27" },
3040 { 28, "r28" },
3041 { 29, "r29" },
3042 { 30, "r30" },
3043 { 31, "r31" },
3044 { 32, "f0" },
3045 { 33, "f1" },
3046 { 34, "f2" },
3047 { 35, "f3" },
3048 { 36, "f4" },
3049 { 37, "f5" },
3050 { 38, "f6" },
3051 { 39, "f7" },
3052 { 40, "f8" },
3053 { 41, "f9" },
3054 { 42, "f10" },
3055 { 43, "f11" },
3056 { 44, "f12" },
3057 { 45, "f13" },
3058 { 46, "f14" },
3059 { 47, "f15" },
3060 { 48, "f16" },
3061 { 49, "f17" },
3062 { 50, "f18" },
3063 { 51, "f19" },
3064 { 52, "f20" },
3065 { 53, "f21" },
3066 { 54, "f22" },
3067 { 55, "f23" },
3068 { 56, "f24" },
3069 { 57, "f25" },
3070 { 58, "f26" },
3071 { 59, "f27" },
3072 { 60, "f28" },
3073 { 61, "f29" },
3074 { 62, "f30" },
3075 { 63, "f31" },
3076 { 64, "pc" },
3077 { 65, "cause" },
3078 { 66, "badvaddr" },
3079 { 67, "mmhi" },
3080 { 68, "mmlo" },
3081 { 69, "fpcsr" },
3082 { 70, "fpeir" },
3083#endif
3084
Dmitry V. Levin87ea1f42008-11-10 22:21:41 +00003085#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(BFIN)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003086 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00003087#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00003088#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003089 { uoff(i387), "offsetof(struct user, i387)" },
3090#else /* !I386 */
3091#ifdef M68K
3092 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3093#endif /* M68K */
3094#endif /* !I386 */
3095 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3096 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3097 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003098#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003099 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003100#endif
Roland McGrathf5a47772003-06-26 22:40:42 +00003101#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00003102 { uoff(start_data), "offsetof(struct user, start_data)" },
3103#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003104#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003105 { uoff(start_stack), "offsetof(struct user, start_stack)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003106#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003107 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003108#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003109 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00003110#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003111#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003112 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003113#endif
Dmitry V. Levin87ea1f42008-11-10 22:21:41 +00003114#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003115 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3116#endif
3117 { uoff(magic), "offsetof(struct user, magic)" },
3118 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00003119#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003120 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3121#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00003122#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003123#endif /* !ALPHA */
3124#endif /* !POWERPC/!SPARC */
3125#endif /* LINUX */
3126#ifdef SUNOS4
3127 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3128 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3129 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3130 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3131 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3132 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3133 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3134 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3135 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3136 { uoff(u_error), "offsetof(struct user, u_error)" },
3137 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3138 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3139 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3140 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3141 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3142 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3143 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3144 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3145 { uoff(u_code), "offsetof(struct user, u_code)" },
3146 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3147 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3148 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3149 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3150 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3151 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3152 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3153 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3154 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3155 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3156 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3157 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3158 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3159 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3160 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3161 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3162 { uoff(u_start), "offsetof(struct user, u_start)" },
3163 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3164 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3165 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3166 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3167 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3168 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3169 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3170 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3171 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3172#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00003173#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003174 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00003175#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003176 { 0, NULL },
3177};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003178#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003179
3180int
3181sys_ptrace(tcp)
3182struct tcb *tcp;
3183{
Roland McGrathd9f816f2004-09-04 03:39:20 +00003184 const struct xlat *x;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003185 long addr;
3186
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003187 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00003188 printxval(ptrace_cmds, tcp->u_arg[0],
3189#ifndef FREEBSD
3190 "PTRACE_???"
3191#else
3192 "PT_???"
3193#endif
3194 );
3195 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003196 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003197#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003198 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3199 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3200 for (x = struct_user_offsets; x->str; x++) {
3201 if (x->val >= addr)
3202 break;
3203 }
3204 if (!x->str)
3205 tprintf("%#lx, ", addr);
3206 else if (x->val > addr && x != struct_user_offsets) {
3207 x--;
3208 tprintf("%s + %ld, ", x->str, addr - x->val);
3209 }
3210 else
3211 tprintf("%s, ", x->str);
3212 }
3213 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003214#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003215 tprintf("%#lx, ", tcp->u_arg[2]);
3216#ifdef LINUX
3217 switch (tcp->u_arg[0]) {
Roland McGrath1e868062007-11-19 22:11:45 +00003218#ifndef IA64
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003219 case PTRACE_PEEKDATA:
3220 case PTRACE_PEEKTEXT:
3221 case PTRACE_PEEKUSER:
3222 break;
Roland McGrath1e868062007-11-19 22:11:45 +00003223#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003224 case PTRACE_CONT:
3225 case PTRACE_SINGLESTEP:
3226 case PTRACE_SYSCALL:
3227 case PTRACE_DETACH:
3228 printsignal(tcp->u_arg[3]);
3229 break;
Denys Vlasenkof535b542009-01-13 18:30:55 +00003230#ifdef PTRACE_SETOPTIONS
3231 case PTRACE_SETOPTIONS:
3232 printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
3233 break;
3234#endif
3235#ifdef PTRACE_SETSIGINFO
3236 case PTRACE_SETSIGINFO: {
3237 siginfo_t si;
3238 if (!tcp->u_arg[3])
3239 tprintf("NULL");
3240 else if (syserror(tcp))
3241 tprintf("%#lx", tcp->u_arg[3]);
3242 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3243 tprintf("{???}");
3244 else
3245 printsiginfo(&si, verbose(tcp));
3246 break;
3247 }
3248#endif
3249#ifdef PTRACE_GETSIGINFO
3250 case PTRACE_GETSIGINFO:
3251 /* Don't print anything, do it at syscall return. */
3252 break;
3253#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003254 default:
3255 tprintf("%#lx", tcp->u_arg[3]);
3256 break;
3257 }
3258 } else {
3259 switch (tcp->u_arg[0]) {
3260 case PTRACE_PEEKDATA:
3261 case PTRACE_PEEKTEXT:
3262 case PTRACE_PEEKUSER:
Roland McGrath1e868062007-11-19 22:11:45 +00003263#ifdef IA64
3264 return RVAL_HEX;
3265#else
Roland McGratheb285352003-01-14 09:59:00 +00003266 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003267 break;
Roland McGrath1e868062007-11-19 22:11:45 +00003268#endif
Denys Vlasenkof535b542009-01-13 18:30:55 +00003269#ifdef PTRACE_GETSIGINFO
3270 case PTRACE_GETSIGINFO: {
3271 siginfo_t si;
3272 if (!tcp->u_arg[3])
3273 tprintf("NULL");
3274 else if (syserror(tcp))
3275 tprintf("%#lx", tcp->u_arg[3]);
3276 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3277 tprintf("{???}");
3278 else
3279 printsiginfo(&si, verbose(tcp));
3280 break;
3281 }
3282#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003283 }
3284 }
3285#endif /* LINUX */
3286#ifdef SUNOS4
3287 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3288 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3289 tprintf("%lu, ", tcp->u_arg[3]);
3290 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3291 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3292 tcp->u_arg[0] != PTRACE_READTEXT) {
3293 tprintf("%#lx", tcp->u_arg[3]);
3294 }
3295 } else {
3296 if (tcp->u_arg[0] == PTRACE_READDATA ||
3297 tcp->u_arg[0] == PTRACE_READTEXT) {
3298 tprintf("%lu, ", tcp->u_arg[3]);
3299 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3300 }
3301 }
3302#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003303#ifdef FREEBSD
3304 tprintf("%lu", tcp->u_arg[3]);
3305 }
3306#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003307 return 0;
3308}
3309
3310#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00003311
3312#ifdef LINUX
Roland McGrath51942a92007-07-05 18:59:11 +00003313# ifndef FUTEX_CMP_REQUEUE
3314# define FUTEX_CMP_REQUEUE 4
3315# endif
3316# ifndef FUTEX_WAKE_OP
3317# define FUTEX_WAKE_OP 5
3318# endif
3319# ifndef FUTEX_LOCK_PI
3320# define FUTEX_LOCK_PI 6
3321# define FUTEX_UNLOCK_PI 7
3322# define FUTEX_TRYLOCK_PI 8
3323# endif
Roland McGrath1aeaf742008-07-18 01:27:39 +00003324# ifndef FUTEX_WAIT_BITSET
3325# define FUTEX_WAIT_BITSET 9
3326# endif
3327# ifndef FUTEX_WAKE_BITSET
3328# define FUTEX_WAKE_BITSET 10
Roland McGrath51942a92007-07-05 18:59:11 +00003329# endif
3330# ifndef FUTEX_PRIVATE_FLAG
3331# define FUTEX_PRIVATE_FLAG 128
3332# endif
Roland McGrathd9f816f2004-09-04 03:39:20 +00003333static const struct xlat futexops[] = {
Roland McGrath51942a92007-07-05 18:59:11 +00003334 { FUTEX_WAIT, "FUTEX_WAIT" },
3335 { FUTEX_WAKE, "FUTEX_WAKE" },
3336 { FUTEX_FD, "FUTEX_FD" },
3337 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3338 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3339 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3340 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3341 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3342 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
Roland McGrath1aeaf742008-07-18 01:27:39 +00003343 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3344 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
Roland McGrath51942a92007-07-05 18:59:11 +00003345 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3346 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3347 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3348 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3349 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3350 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3351 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3352 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3353 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
Roland McGrath1aeaf742008-07-18 01:27:39 +00003354 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3355 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
Roland McGrath51942a92007-07-05 18:59:11 +00003356 { 0, NULL }
3357};
3358#ifndef FUTEX_OP_SET
3359# define FUTEX_OP_SET 0
3360# define FUTEX_OP_ADD 1
3361# define FUTEX_OP_OR 2
3362# define FUTEX_OP_ANDN 3
3363# define FUTEX_OP_XOR 4
3364# define FUTEX_OP_CMP_EQ 0
3365# define FUTEX_OP_CMP_NE 1
3366# define FUTEX_OP_CMP_LT 2
3367# define FUTEX_OP_CMP_LE 3
3368# define FUTEX_OP_CMP_GT 4
3369# define FUTEX_OP_CMP_GE 5
3370#endif
3371static const struct xlat futexwakeops[] = {
3372 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3373 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3374 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3375 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3376 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3377 { 0, NULL }
3378};
3379static const struct xlat futexwakecmps[] = {
3380 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3381 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3382 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3383 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3384 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3385 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3386 { 0, NULL }
Roland McGrath5a223472002-12-15 23:58:26 +00003387};
3388
3389int
3390sys_futex(tcp)
3391struct tcb *tcp;
3392{
3393 if (entering(tcp)) {
Roland McGrath1aeaf742008-07-18 01:27:39 +00003394 long int cmd = tcp->u_arg[1] & 127;
Roland McGrath5a223472002-12-15 23:58:26 +00003395 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00003396 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003397 tprintf(", %ld", tcp->u_arg[2]);
Roland McGrath1aeaf742008-07-18 01:27:39 +00003398 if (cmd == FUTEX_WAKE_BITSET)
3399 tprintf(", %lx", tcp->u_arg[5]);
3400 else if (cmd == FUTEX_WAIT) {
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003401 tprintf(", ");
3402 printtv(tcp, tcp->u_arg[3]);
Roland McGrath1aeaf742008-07-18 01:27:39 +00003403 } else if (cmd == FUTEX_WAIT_BITSET) {
3404 tprintf(", ");
3405 printtv(tcp, tcp->u_arg[3]);
3406 tprintf(", %lx", tcp->u_arg[5]);
Roland McGrath51942a92007-07-05 18:59:11 +00003407 } else if (cmd == FUTEX_REQUEUE)
Roland McGrath88812d62003-06-26 22:27:23 +00003408 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath51942a92007-07-05 18:59:11 +00003409 else if (cmd == FUTEX_CMP_REQUEUE)
3410 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3411 else if (cmd == FUTEX_WAKE_OP) {
3412 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3413 if ((tcp->u_arg[5] >> 28) & 8)
3414 tprintf("FUTEX_OP_OPARG_SHIFT|");
3415 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3416 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3417 if ((tcp->u_arg[5] >> 24) & 8)
3418 tprintf("FUTEX_OP_OPARG_SHIFT|");
3419 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3420 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3421 }
Roland McGrath5a223472002-12-15 23:58:26 +00003422 }
3423 return 0;
3424}
3425
3426static void
Roland McGrath79fbda52004-04-14 02:45:55 +00003427print_affinitylist(tcp, list, len)
3428struct tcb *tcp;
3429long list;
Roland McGrath5a223472002-12-15 23:58:26 +00003430unsigned int len;
3431{
3432 int first = 1;
3433 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00003434 while (len >= sizeof (unsigned long)) {
Roland McGrath79fbda52004-04-14 02:45:55 +00003435 unsigned long w;
3436 umove(tcp, list, &w);
3437 tprintf("%s %lx", first ? "" : ",", w);
Roland McGrath5a223472002-12-15 23:58:26 +00003438 first = 0;
3439 len -= sizeof (unsigned long);
Roland McGrath79fbda52004-04-14 02:45:55 +00003440 list += sizeof(unsigned long);
Roland McGrath5a223472002-12-15 23:58:26 +00003441 }
3442 tprintf(" }");
3443}
3444
3445int
3446sys_sched_setaffinity(tcp)
3447struct tcb *tcp;
3448{
3449 if (entering(tcp)) {
3450 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath79fbda52004-04-14 02:45:55 +00003451 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
Roland McGrath5a223472002-12-15 23:58:26 +00003452 }
3453 return 0;
3454}
3455
3456int
3457sys_sched_getaffinity(tcp)
3458struct tcb *tcp;
3459{
3460 if (entering(tcp)) {
3461 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3462 } else {
Roland McGrath79fbda52004-04-14 02:45:55 +00003463 if (tcp->u_rval == -1)
3464 tprintf("%#lx", tcp->u_arg[2]);
3465 else
3466 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
Roland McGrath5a223472002-12-15 23:58:26 +00003467 }
3468 return 0;
3469}
Roland McGrath279d3782004-03-01 20:27:37 +00003470
Roland McGrathd9f816f2004-09-04 03:39:20 +00003471static const struct xlat schedulers[] = {
Roland McGrath279d3782004-03-01 20:27:37 +00003472 { SCHED_OTHER, "SCHED_OTHER" },
3473 { SCHED_RR, "SCHED_RR" },
3474 { SCHED_FIFO, "SCHED_FIFO" },
3475 { 0, NULL }
3476};
3477
3478int
3479sys_sched_getscheduler(tcp)
3480struct tcb *tcp;
3481{
3482 if (entering(tcp)) {
3483 tprintf("%d", (int) tcp->u_arg[0]);
3484 } else if (! syserror(tcp)) {
3485 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3486 if (tcp->auxstr != NULL)
3487 return RVAL_STR;
3488 }
3489 return 0;
3490}
3491
3492int
3493sys_sched_setscheduler(tcp)
3494struct tcb *tcp;
3495{
3496 if (entering(tcp)) {
3497 struct sched_param p;
3498 tprintf("%d, ", (int) tcp->u_arg[0]);
3499 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3500 if (umove(tcp, tcp->u_arg[2], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003501 tprintf(", %#lx", tcp->u_arg[2]);
Roland McGrath279d3782004-03-01 20:27:37 +00003502 else
3503 tprintf(", { %d }", p.__sched_priority);
3504 }
3505 return 0;
3506}
3507
3508int
3509sys_sched_getparam(tcp)
3510struct tcb *tcp;
3511{
3512 if (entering(tcp)) {
3513 tprintf("%d, ", (int) tcp->u_arg[0]);
3514 } else {
3515 struct sched_param p;
3516 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003517 tprintf("%#lx", tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003518 else
3519 tprintf("{ %d }", p.__sched_priority);
3520 }
3521 return 0;
3522}
3523
3524int
3525sys_sched_setparam(tcp)
3526struct tcb *tcp;
3527{
3528 if (entering(tcp)) {
3529 struct sched_param p;
3530 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003531 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003532 else
3533 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3534 }
3535 return 0;
3536}
3537
3538int
3539sys_sched_get_priority_min(tcp)
3540struct tcb *tcp;
3541{
3542 if (entering(tcp)) {
3543 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3544 }
3545 return 0;
3546}
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003547
3548#ifdef X86_64
3549#include <asm/prctl.h>
3550
3551static const struct xlat archvals[] = {
3552 { ARCH_SET_GS, "ARCH_SET_GS" },
3553 { ARCH_SET_FS, "ARCH_SET_FS" },
3554 { ARCH_GET_FS, "ARCH_GET_FS" },
3555 { ARCH_GET_GS, "ARCH_GET_GS" },
3556 { 0, NULL },
3557};
3558
3559int
3560sys_arch_prctl(tcp)
3561struct tcb *tcp;
3562{
3563 if (entering(tcp)) {
3564 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3565 if (tcp->u_arg[0] == ARCH_SET_GS
3566 || tcp->u_arg[0] == ARCH_SET_FS)
3567 tprintf(", %#lx", tcp->u_arg[1]);
3568 } else {
3569 if (tcp->u_arg[0] == ARCH_GET_GS
3570 || tcp->u_arg[0] == ARCH_GET_FS) {
3571 long int v;
3572 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3573 tprintf(", [%#lx]", v);
3574 else
3575 tprintf(", %#lx", tcp->u_arg[1]);
3576 }
3577 }
3578 return 0;
3579}
3580#endif
3581
Roland McGrathdb8319f2007-08-02 01:37:55 +00003582
3583int
3584sys_getcpu(tcp)
3585struct tcb *tcp;
3586{
3587 if (exiting(tcp)) {
3588 unsigned u;
3589 if (tcp->u_arg[0] == 0)
3590 tprintf("NULL, ");
3591 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3592 tprintf("%#lx, ", tcp->u_arg[0]);
3593 else
3594 tprintf("[%u], ", u);
3595 if (tcp->u_arg[1] == 0)
3596 tprintf("NULL, ");
3597 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3598 tprintf("%#lx, ", tcp->u_arg[1]);
3599 else
3600 tprintf("[%u], ", u);
3601 tprintf("%#lx", tcp->u_arg[2]);
3602 }
3603 return 0;
3604}
3605
Roland McGrath5a223472002-12-15 23:58:26 +00003606#endif