blob: 7107361a7798b43e615519dc35f5148d46028425 [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. */
490static int
491fork_tcb(struct tcb *tcp)
492{
493 if (nprocs == tcbtabsize) {
Roland McGrath7b54a7a2004-06-04 01:50:45 +0000494 if (expand_tcbtab()) {
Roland McGrathee9d4352002-12-18 04:16:10 +0000495 tcp->flags &= ~TCB_FOLLOWFORK;
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000496 return 1;
Roland McGrathee9d4352002-12-18 04:16:10 +0000497 }
Roland McGrathee9d4352002-12-18 04:16:10 +0000498 }
499
500 tcp->flags |= TCB_FOLLOWFORK;
501 return 0;
502}
503
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000504#ifdef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000505
506int
507sys_fork(tcp)
508struct tcb *tcp;
509{
Dmitry V. Levin21a75342008-09-03 01:22:18 +0000510 if (exiting(tcp) && !syserror(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000511 if (getrval2(tcp)) {
512 tcp->auxstr = "child process";
513 return RVAL_UDECIMAL | RVAL_STR;
514 }
515 }
516 return 0;
517}
518
John Hughes4e36a812001-04-18 15:11:51 +0000519#if UNIXWARE > 2
520
521int
522sys_rfork(tcp)
523struct tcb *tcp;
524{
525 if (entering(tcp)) {
526 tprintf ("%ld", tcp->u_arg[0]);
527 }
Dmitry V. Levin21a75342008-09-03 01:22:18 +0000528 else if (!syserror(tcp)) {
John Hughes4e36a812001-04-18 15:11:51 +0000529 if (getrval2(tcp)) {
530 tcp->auxstr = "child process";
531 return RVAL_UDECIMAL | RVAL_STR;
532 }
533 }
534 return 0;
535}
536
537#endif
538
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000539int
540internal_fork(tcp)
541struct tcb *tcp;
542{
543 struct tcb *tcpchild;
544
545 if (exiting(tcp)) {
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000546#ifdef SYS_rfork
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000547 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000548 return 0;
549#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000550 if (getrval2(tcp))
551 return 0;
552 if (!followfork)
553 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000554 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000555 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000556 if (syserror(tcp))
557 return 0;
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000558 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000559 return 0;
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000560 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000561 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000562 }
563 return 0;
564}
565
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000566#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000567
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000568#ifdef LINUX
569
570/* defines copied from linux/sched.h since we can't include that
571 * ourselves (it conflicts with *lots* of libc includes)
572 */
573#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
574#define CLONE_VM 0x00000100 /* set if VM shared between processes */
575#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
576#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
577#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000578#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000579#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
580#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
581#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000582#define CLONE_THREAD 0x00010000 /* Same thread group? */
583#define CLONE_NEWNS 0x00020000 /* New namespace group? */
584#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
585#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
586#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
587#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
588#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
589#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
590#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000591
Roland McGrathd9f816f2004-09-04 03:39:20 +0000592static const struct xlat clone_flags[] = {
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000593 { CLONE_VM, "CLONE_VM" },
594 { CLONE_FS, "CLONE_FS" },
595 { CLONE_FILES, "CLONE_FILES" },
596 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000597 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000598 { CLONE_PTRACE, "CLONE_PTRACE" },
599 { CLONE_VFORK, "CLONE_VFORK" },
600 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000601 { CLONE_THREAD, "CLONE_THREAD" },
602 { CLONE_NEWNS, "CLONE_NEWNS" },
603 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
604 { CLONE_SETTLS, "CLONE_SETTLS" },
605 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
606 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
607 { CLONE_DETACHED, "CLONE_DETACHED" },
608 { CLONE_UNTRACED, "CLONE_UNTRACED" },
609 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000610 { 0, NULL },
611};
612
Roland McGrath909875b2002-12-22 03:34:36 +0000613# ifdef I386
614# include <asm/ldt.h>
Roland McGrath7decfb22004-03-01 22:10:52 +0000615# ifdef HAVE_STRUCT_USER_DESC
616# define modify_ldt_ldt_s user_desc
617# endif
Roland McGrath909875b2002-12-22 03:34:36 +0000618extern void print_ldt_entry();
619# endif
620
Roland McGrath9677b3a2003-03-12 09:54:36 +0000621# if defined IA64
622# define ARG_FLAGS 0
623# define ARG_STACK 1
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000624# define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
625# define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
626# define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
627# define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000628# elif defined S390 || defined S390X
Roland McGrath9677b3a2003-03-12 09:54:36 +0000629# define ARG_STACK 0
630# define ARG_FLAGS 1
631# define ARG_PTID 2
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000632# define ARG_CTID 3
633# define ARG_TLS 4
Roland McGrath9c555e72003-07-09 09:47:59 +0000634# elif defined X86_64 || defined ALPHA
Roland McGrath361aac52003-03-18 07:43:42 +0000635# define ARG_FLAGS 0
636# define ARG_STACK 1
637# define ARG_PTID 2
638# define ARG_CTID 3
639# define ARG_TLS 4
Roland McGrath9677b3a2003-03-12 09:54:36 +0000640# else
641# define ARG_FLAGS 0
642# define ARG_STACK 1
643# define ARG_PTID 2
644# define ARG_TLS 3
645# define ARG_CTID 4
646# endif
647
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000648int
649sys_clone(tcp)
650struct tcb *tcp;
651{
652 if (exiting(tcp)) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000653 unsigned long flags = tcp->u_arg[ARG_FLAGS];
654 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
655# ifdef ARG_STACKSIZE
656 if (ARG_STACKSIZE != -1)
657 tprintf("stack_size=%#lx, ",
658 tcp->u_arg[ARG_STACKSIZE]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000659# endif
Roland McGrath9677b3a2003-03-12 09:54:36 +0000660 tprintf("flags=");
Roland McGrathb2dee132005-06-01 19:02:36 +0000661 printflags(clone_flags, flags &~ CSIGNAL, NULL);
Roland McGrath984154d2003-05-23 01:08:42 +0000662 if ((flags & CSIGNAL) != 0)
663 tprintf("|%s", signame(flags & CSIGNAL));
Roland McGrathb4968be2003-01-20 09:04:33 +0000664 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
Roland McGrath9677b3a2003-03-12 09:54:36 +0000665 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
Roland McGrath909875b2002-12-22 03:34:36 +0000666 return 0;
Roland McGrath6f67a982003-03-21 07:33:15 +0000667 if (flags & CLONE_PARENT_SETTID)
668 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000669 if (flags & CLONE_SETTLS) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000670# ifdef I386
Roland McGrath909875b2002-12-22 03:34:36 +0000671 struct modify_ldt_ldt_s copy;
Roland McGrath9677b3a2003-03-12 09:54:36 +0000672 if (umove(tcp, tcp->u_arg[ARG_TLS], &copy) != -1) {
Roland McGrath909875b2002-12-22 03:34:36 +0000673 tprintf(", {entry_number:%d, ",
674 copy.entry_number);
675 if (!verbose(tcp))
676 tprintf("...}");
677 else
678 print_ldt_entry(&copy);
679 }
680 else
Roland McGrath9677b3a2003-03-12 09:54:36 +0000681# endif
Roland McGrath43f2c842003-03-12 09:58:14 +0000682 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
Roland McGrath909875b2002-12-22 03:34:36 +0000683 }
Roland McGrath9677b3a2003-03-12 09:54:36 +0000684 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
685 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000686 }
687 return 0;
688}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000689
690int
691sys_unshare(struct tcb *tcp)
692{
693 if (entering(tcp))
694 printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
695 return 0;
696}
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000697#endif
698
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000699int
700sys_fork(tcp)
701struct tcb *tcp;
702{
703 if (exiting(tcp))
704 return RVAL_UDECIMAL;
705 return 0;
706}
707
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000708int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000709change_syscall(tcp, new)
710struct tcb *tcp;
711int new;
712{
713#if defined(LINUX)
714#if defined(I386)
715 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000716 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000717 return -1;
718 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000719#elif defined(X86_64)
720 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000721 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000722 return -1;
723 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000724#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000725 if (ptrace(PTRACE_POKEUSER, tcp->pid,
726 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000727 return -1;
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000728 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000729#elif defined(S390) || defined(S390X)
730 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
731 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
732 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000733 return 0;
734#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000735 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000736 return -1;
737 return 0;
Roland McGrath6d1a65c2004-07-12 07:44:08 +0000738#elif defined(SPARC) || defined(SPARC64)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000739 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000740 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
741 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000742 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000743 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
744 return -1;
745 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000746#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000747 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000748 return -1;
749 return 0;
750#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000751 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000752 return -1;
753 return 0;
Dmitry V. Levin87ea1f42008-11-10 22:21:41 +0000754#elif defined(BFIN)
755 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_P0), new)<0)
756 return -1;
757 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000758#elif defined(IA64)
Roland McGrath08267b82004-02-20 22:56:43 +0000759 if (ia32) {
760 switch (new) {
761 case 2: break; /* x86 SYS_fork */
762 case SYS_clone: new = 120; break;
763 default:
764 fprintf(stderr, "%s: unexpected syscall %d\n",
765 __FUNCTION__, new);
766 return -1;
767 }
768 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
769 return -1;
770 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000771 return -1;
772 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000773#elif defined(HPPA)
774 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
775 return -1;
776 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000777#elif defined(SH)
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000778 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
779 return -1;
780 return 0;
Roland McGrathf5a47772003-06-26 22:40:42 +0000781#elif defined(SH64)
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000782 /* Top half of reg encodes the no. of args n as 0x1n.
783 Assume 0 args as kernel never actually checks... */
784 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
785 0x100000 | new) < 0)
786 return -1;
787 return 0;
Roland McGrathf691bd22006-04-25 07:34:41 +0000788#elif defined(ARM)
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000789 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
Roland McGrathf691bd22006-04-25 07:34:41 +0000790# ifndef PTRACE_SET_SYSCALL
791# define PTRACE_SET_SYSCALL 23
792# endif
793
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000794 if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new) != 0)
Roland McGrathf691bd22006-04-25 07:34:41 +0000795 return -1;
796
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000797 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000798#else
799#warning Do not know how to handle change_syscall for this architecture
800#endif /* architecture */
801#endif /* LINUX */
802 return -1;
803}
804
Roland McGratha4d48532005-06-08 20:45:28 +0000805#if 0
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000806int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000807setarg(tcp, argnum)
808 struct tcb *tcp;
809 int argnum;
810{
811#if defined (IA64)
812 {
813 unsigned long *bsp, *ap;
814
Denys Vlasenko932fc7d2008-12-16 18:18:40 +0000815 if (upeek(tcp, PT_AR_BSP, (long *) &bsp) , 0)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000816 return -1;
817
818 ap = ia64_rse_skip_regs(bsp, argnum);
819 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000820 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000821 if (errno)
822 return -1;
823
824 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000825#elif defined(I386)
826 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000827 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000828 if (errno)
829 return -1;
830 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000831#elif defined(X86_64)
832 {
833 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
834 if (errno)
835 return -1;
836 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000837#elif defined(POWERPC)
838#ifndef PT_ORIG_R3
839#define PT_ORIG_R3 34
840#endif
841 {
842 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000843 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000844 tcp->u_arg[argnum]);
845 if (errno)
846 return -1;
847 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000848#elif defined(MIPS)
849 {
850 errno = 0;
851 if (argnum < 4)
852 ptrace(PTRACE_POKEUSER, tcp->pid,
853 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
854 else {
855 unsigned long *sp;
856
Denys Vlasenko932fc7d2008-12-16 18:18:40 +0000857 if (upeek(tcp, REG_SP, (long *) &sp) , 0)
Ralf Baechlee3816102000-08-01 00:06:06 +0000858 return -1;
859
860 ptrace(PTRACE_POKEDATA, tcp->pid,
861 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
862 }
863 if (errno)
864 return -1;
865 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000866#elif defined(S390) || defined(S390X)
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000867 {
Michal Ludvig10a88d02002-10-07 14:31:00 +0000868 if(argnum <= 5)
869 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000870 (char *) (argnum==0 ? PT_ORIGGPR2 :
871 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000872 tcp->u_arg[argnum]);
873 else
874 return -E2BIG;
875 if (errno)
876 return -1;
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000877 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000878#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000879# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000880#endif
881 return 0;
882}
Roland McGratha4d48532005-06-08 20:45:28 +0000883#endif
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000884
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000885#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000886int
887internal_clone(tcp)
888struct tcb *tcp;
889{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000890 struct tcb *tcpchild;
891 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000892 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000893 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000894 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000895 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000896 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000897 if (setbpt(tcp) < 0)
898 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000899 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000900 int bpt = tcp->flags & TCB_BPTSET;
901
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000902 if (!(tcp->flags & TCB_FOLLOWFORK))
903 return 0;
904
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000905 if (syserror(tcp)) {
906 if (bpt)
907 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000908 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000909 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000910
911 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000912
913#ifdef CLONE_PTRACE /* See new setbpt code. */
914 tcpchild = pid2tcb(pid);
915 if (tcpchild != NULL) {
916 /* The child already reported its startup trap
917 before the parent reported its syscall return. */
918 if ((tcpchild->flags
919 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
920 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
921 fprintf(stderr, "\
922[preattached child %d of %d in weird state!]\n",
923 pid, tcp->pid);
924 }
925 else
926#endif
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000927 if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000928 if (bpt)
929 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000930 kill(pid, SIGKILL); /* XXX */
931 return 0;
932 }
933
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000934#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000935 /* Attach to the new child */
936 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000937 if (bpt)
938 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000939 perror("PTRACE_ATTACH");
940 fprintf(stderr, "Too late?\n");
941 droptcb(tcpchild);
942 return 0;
943 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000944#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000945
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000946 if (bpt)
947 clearbpt(tcp);
948
Ulrich Drepper90512f01999-12-24 07:22:25 +0000949 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000950 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000951 if (bpt) {
952 tcpchild->flags |= TCB_BPTSET;
953 tcpchild->baddr = tcp->baddr;
954 memcpy(tcpchild->inst, tcp->inst,
955 sizeof tcpchild->inst);
956 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000957 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000958 tcp->nchildren++;
959 if (tcpchild->flags & TCB_SUSPENDED) {
960 /* The child was born suspended, due to our having
961 forced CLONE_PTRACE. */
962 if (bpt)
963 clearbpt(tcpchild);
964
965 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
Denys Vlasenkof9a7e632009-01-17 00:21:31 +0000966 /* TCB_SUSPENDED tasks are not collected by waitpid
967 * loop, and left stopped. Restart it:
968 */
Denys Vlasenko732d1bf2008-12-17 19:21:59 +0000969 if (ptrace_restart(PTRACE_SYSCALL, tcpchild, 0) < 0)
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000970 return -1;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000971
972 if (!qflag)
973 fprintf(stderr, "\
974Process %u resumed (parent %d ready)\n",
975 pid, tcp->pid);
976 }
977 else {
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000978 if (!qflag)
979 fprintf(stderr, "Process %d attached\n", pid);
980 }
981
982#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000983 {
984 /*
985 * Save the flags used in this call,
986 * in case we point TCP to our parent below.
987 */
988 int call_flags = tcp->u_arg[ARG_FLAGS];
989 if ((tcp->flags & TCB_CLONE_THREAD) &&
990 tcp->parent != NULL) {
991 /* The parent in this clone is itself a
992 thread belonging to another process.
993 There is no meaning to the parentage
994 relationship of the new child with the
995 thread, only with the process. We
996 associate the new thread with our
997 parent. Since this is done for every
998 new thread, there will never be a
999 TCB_CLONE_THREAD process that has
1000 children. */
1001 --tcp->nchildren;
1002 tcp = tcp->parent;
1003 tcpchild->parent = tcp;
1004 ++tcp->nchildren;
1005 }
1006 if (call_flags & CLONE_THREAD) {
1007 tcpchild->flags |= TCB_CLONE_THREAD;
1008 ++tcp->nclone_threads;
1009 }
1010 if (call_flags & CLONE_DETACHED) {
1011 tcpchild->flags |= TCB_CLONE_DETACHED;
1012 ++tcp->nclone_detached;
1013 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001014 }
1015#endif
1016
1017 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +00001018 return 0;
1019}
1020#endif
1021
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001022int
1023internal_fork(tcp)
1024struct tcb *tcp;
1025{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001026#ifdef LINUX
1027 /* We do special magic with clone for any clone or fork. */
1028 return internal_clone(tcp);
1029#else
1030
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001031 struct tcb *tcpchild;
1032 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +00001033 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001034
1035#ifdef SYS_vfork
Roland McGratha4f9f2d2005-06-07 23:21:20 +00001036 if (known_scno(tcp) == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +00001037 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath41c48222008-07-18 00:25:10 +00001038 if (change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +00001039 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +00001040 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001041#endif
1042 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +00001043 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001044 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +00001045 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001046 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001047 if (setbpt(tcp) < 0)
1048 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +00001049 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001050 else {
1051 int bpt = tcp->flags & TCB_BPTSET;
1052
1053 if (!(tcp->flags & TCB_FOLLOWFORK))
1054 return 0;
1055 if (bpt)
1056 clearbpt(tcp);
1057
1058 if (syserror(tcp))
1059 return 0;
1060
1061 pid = tcp->u_rval;
Dmitry V. Levin76860f62006-10-11 22:55:25 +00001062 if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001063 kill(pid, SIGKILL); /* XXX */
1064 return 0;
1065 }
1066#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +00001067#ifdef HPPA
1068 /* The child must have run before it can be attached. */
1069 /* This must be a bug in the parisc kernel, but I havn't
1070 * identified it yet. Seems to be an issue associated
1071 * with attaching to a process (which sends it a signal)
1072 * before that process has ever been scheduled. When
1073 * debugging, I started seeing crashes in
1074 * arch/parisc/kernel/signal.c:do_signal(), apparently
1075 * caused by r8 getting corrupt over the dequeue_signal()
1076 * call. Didn't make much sense though...
1077 */
1078 {
1079 struct timeval tv;
1080 tv.tv_sec = 0;
1081 tv.tv_usec = 10000;
1082 select(0, NULL, NULL, NULL, &tv);
1083 }
1084#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001085 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
1086 perror("PTRACE_ATTACH");
1087 fprintf(stderr, "Too late?\n");
1088 droptcb(tcpchild);
1089 return 0;
1090 }
1091#endif /* LINUX */
1092#ifdef SUNOS4
1093#ifdef oldway
1094 /* The child must have run before it can be attached. */
1095 {
1096 struct timeval tv;
1097 tv.tv_sec = 0;
1098 tv.tv_usec = 10000;
1099 select(0, NULL, NULL, NULL, &tv);
1100 }
1101 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1102 perror("PTRACE_ATTACH");
1103 fprintf(stderr, "Too late?\n");
1104 droptcb(tcpchild);
1105 return 0;
1106 }
1107#else /* !oldway */
1108 /* Try to catch the new process as soon as possible. */
1109 {
1110 int i;
1111 for (i = 0; i < 1024; i++)
1112 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1113 break;
1114 if (i == 1024) {
1115 perror("PTRACE_ATTACH");
1116 fprintf(stderr, "Too late?\n");
1117 droptcb(tcpchild);
1118 return 0;
1119 }
1120 }
1121#endif /* !oldway */
1122#endif /* SUNOS4 */
1123 tcpchild->flags |= TCB_ATTACHED;
1124 /* Child has BPT too, must be removed on first occasion */
1125 if (bpt) {
1126 tcpchild->flags |= TCB_BPTSET;
1127 tcpchild->baddr = tcp->baddr;
1128 memcpy(tcpchild->inst, tcp->inst,
1129 sizeof tcpchild->inst);
1130 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001131 tcpchild->parent = tcp;
1132 tcp->nchildren++;
1133 if (!qflag)
1134 fprintf(stderr, "Process %d attached\n", pid);
1135 }
1136 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001137#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001138}
1139
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001140#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001141
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001142#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001143
1144int
1145sys_vfork(tcp)
1146struct tcb *tcp;
1147{
1148 if (exiting(tcp))
1149 return RVAL_UDECIMAL;
1150 return 0;
1151}
1152
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001153#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001154
1155#ifndef LINUX
1156
1157static char idstr[16];
1158
1159int
1160sys_getpid(tcp)
1161struct tcb *tcp;
1162{
1163 if (exiting(tcp)) {
1164 sprintf(idstr, "ppid %lu", getrval2(tcp));
1165 tcp->auxstr = idstr;
1166 return RVAL_STR;
1167 }
1168 return 0;
1169}
1170
1171int
1172sys_getuid(tcp)
1173struct tcb *tcp;
1174{
1175 if (exiting(tcp)) {
1176 sprintf(idstr, "euid %lu", getrval2(tcp));
1177 tcp->auxstr = idstr;
1178 return RVAL_STR;
1179 }
1180 return 0;
1181}
1182
1183int
1184sys_getgid(tcp)
1185struct tcb *tcp;
1186{
1187 if (exiting(tcp)) {
1188 sprintf(idstr, "egid %lu", getrval2(tcp));
1189 tcp->auxstr = idstr;
1190 return RVAL_STR;
1191 }
1192 return 0;
1193}
1194
1195#endif /* !LINUX */
1196
1197#ifdef LINUX
1198
1199int
1200sys_setuid(tcp)
1201struct tcb *tcp;
1202{
1203 if (entering(tcp)) {
1204 tprintf("%u", (uid_t) tcp->u_arg[0]);
1205 }
1206 return 0;
1207}
1208
1209int
1210sys_setgid(tcp)
1211struct tcb *tcp;
1212{
1213 if (entering(tcp)) {
1214 tprintf("%u", (gid_t) tcp->u_arg[0]);
1215 }
1216 return 0;
1217}
1218
1219int
1220sys_getresuid(tcp)
1221 struct tcb *tcp;
1222{
1223 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001224 __kernel_uid_t uid;
1225 if (syserror(tcp))
1226 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1227 tcp->u_arg[1], tcp->u_arg[2]);
1228 else {
1229 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1230 tprintf("%#lx, ", tcp->u_arg[0]);
1231 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001232 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001233 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1234 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001235 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001236 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001237 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1238 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001239 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001240 tprintf("[%lu]", (unsigned long) uid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001241 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001242 }
1243 return 0;
1244}
1245
1246int
1247sys_getresgid(tcp)
1248struct tcb *tcp;
1249{
1250 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001251 __kernel_gid_t gid;
1252 if (syserror(tcp))
1253 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1254 tcp->u_arg[1], tcp->u_arg[2]);
1255 else {
1256 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1257 tprintf("%#lx, ", tcp->u_arg[0]);
1258 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001259 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001260 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1261 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001262 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001263 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001264 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1265 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001266 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001267 tprintf("[%lu]", (unsigned long) gid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001268 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001269 }
1270 return 0;
1271}
1272
1273#endif /* LINUX */
1274
1275int
1276sys_setreuid(tcp)
1277struct tcb *tcp;
1278{
1279 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001280 printuid("", tcp->u_arg[0]);
1281 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001282 }
1283 return 0;
1284}
1285
1286int
1287sys_setregid(tcp)
1288struct tcb *tcp;
1289{
1290 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001291 printuid("", tcp->u_arg[0]);
1292 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001293 }
1294 return 0;
1295}
1296
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001297#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001298int
1299sys_setresuid(tcp)
1300 struct tcb *tcp;
1301{
1302 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001303 printuid("", tcp->u_arg[0]);
1304 printuid(", ", tcp->u_arg[1]);
1305 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001306 }
1307 return 0;
1308}
1309int
1310sys_setresgid(tcp)
1311 struct tcb *tcp;
1312{
1313 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001314 printuid("", tcp->u_arg[0]);
1315 printuid(", ", tcp->u_arg[1]);
1316 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001317 }
1318 return 0;
1319}
1320
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001321#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001322
1323int
1324sys_setgroups(tcp)
1325struct tcb *tcp;
1326{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001327 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001328 unsigned long len, size, start, cur, end, abbrev_end;
1329 GETGROUPS_T gid;
1330 int failed = 0;
1331
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001332 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001333 tprintf("%lu, ", len);
1334 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001335 tprintf("[]");
1336 return 0;
1337 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001338 start = tcp->u_arg[1];
1339 if (start == 0) {
1340 tprintf("NULL");
1341 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001342 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001343 size = len * sizeof(gid);
1344 end = start + size;
1345 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1346 tprintf("%#lx", start);
1347 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001348 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001349 if (abbrev(tcp)) {
1350 abbrev_end = start + max_strlen * sizeof(gid);
1351 if (abbrev_end < start)
1352 abbrev_end = end;
1353 } else {
1354 abbrev_end = end;
1355 }
1356 tprintf("[");
1357 for (cur = start; cur < end; cur += sizeof(gid)) {
1358 if (cur > start)
1359 tprintf(", ");
1360 if (cur >= abbrev_end) {
1361 tprintf("...");
1362 break;
1363 }
1364 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1365 tprintf("?");
1366 failed = 1;
1367 break;
1368 }
1369 tprintf("%lu", (unsigned long) gid);
1370 }
1371 tprintf("]");
1372 if (failed)
1373 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001374 }
1375 return 0;
1376}
1377
1378int
1379sys_getgroups(tcp)
1380struct tcb *tcp;
1381{
Roland McGrathaa524c82005-06-01 19:22:06 +00001382 unsigned long len;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001383
1384 if (entering(tcp)) {
1385 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001386 tprintf("%lu, ", len);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001387 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001388 unsigned long size, start, cur, end, abbrev_end;
1389 GETGROUPS_T gid;
1390 int failed = 0;
1391
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001392 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001393 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001394 tprintf("[]");
1395 return 0;
1396 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001397 start = tcp->u_arg[1];
1398 if (start == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001399 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001400 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001401 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001402 if (tcp->u_arg[0] == 0) {
1403 tprintf("%#lx", start);
1404 return 0;
1405 }
1406 size = len * sizeof(gid);
1407 end = start + size;
1408 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1409 size / sizeof(gid) != len || end < start) {
1410 tprintf("%#lx", start);
1411 return 0;
1412 }
1413 if (abbrev(tcp)) {
1414 abbrev_end = start + max_strlen * sizeof(gid);
1415 if (abbrev_end < start)
1416 abbrev_end = end;
1417 } else {
1418 abbrev_end = end;
1419 }
1420 tprintf("[");
1421 for (cur = start; cur < end; cur += sizeof(gid)) {
1422 if (cur > start)
1423 tprintf(", ");
1424 if (cur >= abbrev_end) {
1425 tprintf("...");
1426 break;
1427 }
1428 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1429 tprintf("?");
1430 failed = 1;
1431 break;
1432 }
1433 tprintf("%lu", (unsigned long) gid);
1434 }
1435 tprintf("]");
1436 if (failed)
1437 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001438 }
1439 return 0;
1440}
1441
Roland McGrath83bd47a2003-11-13 22:32:26 +00001442#ifdef LINUX
1443int
1444sys_setgroups32(tcp)
1445struct tcb *tcp;
1446{
Roland McGrath83bd47a2003-11-13 22:32:26 +00001447 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001448 unsigned long len, size, start, cur, end, abbrev_end;
1449 GETGROUPS32_T gid;
1450 int failed = 0;
1451
Roland McGrath83bd47a2003-11-13 22:32:26 +00001452 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001453 tprintf("%lu, ", len);
1454 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001455 tprintf("[]");
1456 return 0;
1457 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001458 start = tcp->u_arg[1];
1459 if (start == 0) {
1460 tprintf("NULL");
1461 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001462 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001463 size = len * sizeof(gid);
1464 end = start + size;
1465 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1466 tprintf("%#lx", start);
1467 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001468 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001469 if (abbrev(tcp)) {
1470 abbrev_end = start + max_strlen * sizeof(gid);
1471 if (abbrev_end < start)
1472 abbrev_end = end;
1473 } else {
1474 abbrev_end = end;
1475 }
1476 tprintf("[");
1477 for (cur = start; cur < end; cur += sizeof(gid)) {
1478 if (cur > start)
1479 tprintf(", ");
1480 if (cur >= abbrev_end) {
1481 tprintf("...");
1482 break;
1483 }
1484 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1485 tprintf("?");
1486 failed = 1;
1487 break;
1488 }
1489 tprintf("%lu", (unsigned long) gid);
1490 }
1491 tprintf("]");
1492 if (failed)
1493 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001494 }
1495 return 0;
1496}
1497
1498int
1499sys_getgroups32(tcp)
1500struct tcb *tcp;
1501{
Roland McGrathaa524c82005-06-01 19:22:06 +00001502 unsigned long len;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001503
1504 if (entering(tcp)) {
1505 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001506 tprintf("%lu, ", len);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001507 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001508 unsigned long size, start, cur, end, abbrev_end;
1509 GETGROUPS32_T gid;
1510 int failed = 0;
1511
Roland McGrath83bd47a2003-11-13 22:32:26 +00001512 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001513 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001514 tprintf("[]");
1515 return 0;
1516 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001517 start = tcp->u_arg[1];
1518 if (start == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001519 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001520 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001521 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001522 size = len * sizeof(gid);
1523 end = start + size;
1524 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1525 size / sizeof(gid) != len || end < start) {
1526 tprintf("%#lx", start);
1527 return 0;
1528 }
1529 if (abbrev(tcp)) {
1530 abbrev_end = start + max_strlen * sizeof(gid);
1531 if (abbrev_end < start)
1532 abbrev_end = end;
1533 } else {
1534 abbrev_end = end;
1535 }
1536 tprintf("[");
1537 for (cur = start; cur < end; cur += sizeof(gid)) {
1538 if (cur > start)
1539 tprintf(", ");
1540 if (cur >= abbrev_end) {
1541 tprintf("...");
1542 break;
1543 }
1544 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1545 tprintf("?");
1546 failed = 1;
1547 break;
1548 }
1549 tprintf("%lu", (unsigned long) gid);
1550 }
1551 tprintf("]");
1552 if (failed)
1553 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001554 }
1555 return 0;
1556}
1557#endif /* LINUX */
1558
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001559#if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001560int
1561sys_setpgrp(tcp)
1562struct tcb *tcp;
1563{
1564 if (entering(tcp)) {
1565#ifndef SVR4
1566 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1567#endif /* !SVR4 */
1568 }
1569 return 0;
1570}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001571#endif /* ALPHA || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001572
1573int
1574sys_getpgrp(tcp)
1575struct tcb *tcp;
1576{
1577 if (entering(tcp)) {
1578#ifndef SVR4
1579 tprintf("%lu", tcp->u_arg[0]);
1580#endif /* !SVR4 */
1581 }
1582 return 0;
1583}
1584
1585int
1586sys_getsid(tcp)
1587struct tcb *tcp;
1588{
1589 if (entering(tcp)) {
1590 tprintf("%lu", tcp->u_arg[0]);
1591 }
1592 return 0;
1593}
1594
1595int
1596sys_setsid(tcp)
1597struct tcb *tcp;
1598{
1599 return 0;
1600}
1601
1602int
1603sys_getpgid(tcp)
1604struct tcb *tcp;
1605{
1606 if (entering(tcp)) {
1607 tprintf("%lu", tcp->u_arg[0]);
1608 }
1609 return 0;
1610}
1611
1612int
1613sys_setpgid(tcp)
1614struct tcb *tcp;
1615{
1616 if (entering(tcp)) {
1617 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1618 }
1619 return 0;
1620}
1621
John Hughesc61eb3d2002-05-17 11:37:50 +00001622#if UNIXWARE >= 2
1623
1624#include <sys/privilege.h>
1625
1626
Roland McGrathd9f816f2004-09-04 03:39:20 +00001627static const struct xlat procpriv_cmds [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001628 { SETPRV, "SETPRV" },
1629 { CLRPRV, "CLRPRV" },
1630 { PUTPRV, "PUTPRV" },
1631 { GETPRV, "GETPRV" },
1632 { CNTPRV, "CNTPRV" },
1633 { 0, NULL },
1634};
1635
1636
Roland McGrathd9f816f2004-09-04 03:39:20 +00001637static const struct xlat procpriv_priv [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001638 { P_OWNER, "P_OWNER" },
1639 { P_AUDIT, "P_AUDIT" },
1640 { P_COMPAT, "P_COMPAT" },
1641 { P_DACREAD, "P_DACREAD" },
1642 { P_DACWRITE, "P_DACWRITE" },
1643 { P_DEV, "P_DEV" },
1644 { P_FILESYS, "P_FILESYS" },
1645 { P_MACREAD, "P_MACREAD" },
1646 { P_MACWRITE, "P_MACWRITE" },
1647 { P_MOUNT, "P_MOUNT" },
1648 { P_MULTIDIR, "P_MULTIDIR" },
1649 { P_SETPLEVEL, "P_SETPLEVEL" },
1650 { P_SETSPRIV, "P_SETSPRIV" },
1651 { P_SETUID, "P_SETUID" },
1652 { P_SYSOPS, "P_SYSOPS" },
1653 { P_SETUPRIV, "P_SETUPRIV" },
1654 { P_DRIVER, "P_DRIVER" },
1655 { P_RTIME, "P_RTIME" },
1656 { P_MACUPGRADE, "P_MACUPGRADE" },
1657 { P_FSYSRANGE, "P_FSYSRANGE" },
1658 { P_SETFLEVEL, "P_SETFLEVEL" },
1659 { P_AUDITWR, "P_AUDITWR" },
1660 { P_TSHAR, "P_TSHAR" },
1661 { P_PLOCK, "P_PLOCK" },
1662 { P_CORE, "P_CORE" },
1663 { P_LOADMOD, "P_LOADMOD" },
1664 { P_BIND, "P_BIND" },
1665 { P_ALLPRIVS, "P_ALLPRIVS" },
1666 { 0, NULL },
1667};
1668
1669
Roland McGrathd9f816f2004-09-04 03:39:20 +00001670static const struct xlat procpriv_type [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001671 { PS_FIX, "PS_FIX" },
1672 { PS_INH, "PS_INH" },
1673 { PS_MAX, "PS_MAX" },
1674 { PS_WKG, "PS_WKG" },
1675 { 0, NULL },
1676};
1677
1678
1679static void
Dmitry V. Levinab9008b2007-01-11 22:05:04 +00001680printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
John Hughesc61eb3d2002-05-17 11:37:50 +00001681{
1682 priv_t buf [128];
1683 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1684 int dots = len > max;
1685 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001686
John Hughesc61eb3d2002-05-17 11:37:50 +00001687 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001688
John Hughesc61eb3d2002-05-17 11:37:50 +00001689 if (len <= 0 ||
1690 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1691 {
1692 tprintf ("%#lx", addr);
1693 return;
1694 }
1695
1696 tprintf ("[");
1697
1698 for (i = 0; i < len; ++i) {
Dmitry V. Levinab9008b2007-01-11 22:05:04 +00001699 const char *t, *p;
John Hughesc61eb3d2002-05-17 11:37:50 +00001700
1701 if (i) tprintf (", ");
1702
1703 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1704 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1705 {
1706 tprintf ("%s|%s", t, p);
1707 }
1708 else {
1709 tprintf ("%#lx", buf [i]);
1710 }
1711 }
1712
1713 if (dots) tprintf (" ...");
1714
1715 tprintf ("]");
1716}
1717
1718
1719int
1720sys_procpriv(tcp)
1721struct tcb *tcp;
1722{
1723 if (entering(tcp)) {
1724 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1725 switch (tcp->u_arg[0]) {
1726 case CNTPRV:
1727 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1728 break;
1729
1730 case GETPRV:
1731 break;
1732
1733 default:
1734 tprintf (", ");
1735 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1736 tprintf (", %ld", tcp->u_arg[2]);
1737 }
1738 }
1739 else if (tcp->u_arg[0] == GETPRV) {
1740 if (syserror (tcp)) {
1741 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1742 }
1743 else {
1744 tprintf (", ");
1745 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1746 tprintf (", %ld", tcp->u_arg[2]);
1747 }
1748 }
Roland McGrath5a223472002-12-15 23:58:26 +00001749
John Hughesc61eb3d2002-05-17 11:37:50 +00001750 return 0;
1751}
1752
1753#endif
1754
1755
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001756static void
1757printargv(tcp, addr)
1758struct tcb *tcp;
1759long addr;
1760{
Roland McGrath85a3bc42007-08-02 02:13:05 +00001761 union {
1762 int p32;
1763 long p64;
1764 char data[sizeof(long)];
1765 } cp;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001766 char *sep;
Roland McGrath85a3bc42007-08-02 02:13:05 +00001767 int n = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001768
Roland McGrath85a3bc42007-08-02 02:13:05 +00001769 cp.p64 = 1;
1770 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1771 if (umoven(tcp, addr, personality_wordsize[current_personality],
1772 cp.data) < 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001773 tprintf("%#lx", addr);
1774 return;
1775 }
Roland McGrath85a3bc42007-08-02 02:13:05 +00001776 if (personality_wordsize[current_personality] == 4)
1777 cp.p64 = cp.p32;
1778 if (cp.p64 == 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001779 break;
1780 tprintf(sep);
Roland McGrath85a3bc42007-08-02 02:13:05 +00001781 printstr(tcp, cp.p64, -1);
1782 addr += personality_wordsize[current_personality];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001783 }
Roland McGrath85a3bc42007-08-02 02:13:05 +00001784 if (cp.p64)
1785 tprintf("%s...", sep);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001786}
1787
1788static void
1789printargc(fmt, tcp, addr)
1790char *fmt;
1791struct tcb *tcp;
1792long addr;
1793{
1794 int count;
1795 char *cp;
1796
1797 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1798 addr += sizeof(char *);
1799 }
1800 tprintf(fmt, count, count == 1 ? "" : "s");
1801}
1802
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001803#if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001804int
1805sys_execv(tcp)
1806struct tcb *tcp;
1807{
1808 if (entering(tcp)) {
1809 printpath(tcp, tcp->u_arg[0]);
1810 if (!verbose(tcp))
1811 tprintf(", %#lx", tcp->u_arg[1]);
1812#if 0
1813 else if (abbrev(tcp))
1814 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1815#endif
1816 else {
1817 tprintf(", [");
1818 printargv(tcp, tcp->u_arg[1]);
1819 tprintf("]");
1820 }
1821 }
1822 return 0;
1823}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001824#endif /* SPARC || SPARC64 || SUNOS4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001825
1826int
1827sys_execve(tcp)
1828struct tcb *tcp;
1829{
1830 if (entering(tcp)) {
1831 printpath(tcp, tcp->u_arg[0]);
1832 if (!verbose(tcp))
1833 tprintf(", %#lx", tcp->u_arg[1]);
1834#if 0
1835 else if (abbrev(tcp))
1836 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1837#endif
1838 else {
1839 tprintf(", [");
1840 printargv(tcp, tcp->u_arg[1]);
1841 tprintf("]");
1842 }
1843 if (!verbose(tcp))
1844 tprintf(", %#lx", tcp->u_arg[2]);
1845 else if (abbrev(tcp))
1846 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1847 else {
1848 tprintf(", [");
1849 printargv(tcp, tcp->u_arg[2]);
1850 tprintf("]");
1851 }
1852 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001853 return 0;
1854}
1855
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001856#if UNIXWARE > 2
John Hughes4e36a812001-04-18 15:11:51 +00001857
1858int sys_rexecve(tcp)
1859struct tcb *tcp;
1860{
1861 if (entering (tcp)) {
1862 sys_execve (tcp);
1863 tprintf (", %ld", tcp->u_arg[3]);
1864 }
1865 return 0;
1866}
1867
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001868#endif
John Hughes4e36a812001-04-18 15:11:51 +00001869
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001870int
1871internal_exec(tcp)
1872struct tcb *tcp;
1873{
1874#ifdef SUNOS4
1875 if (exiting(tcp) && !syserror(tcp) && followfork)
1876 fixvfork(tcp);
1877#endif /* SUNOS4 */
Roland McGrathfdb097f2004-07-12 07:38:55 +00001878#if defined LINUX && defined TCB_WAITEXECVE
1879 if (exiting(tcp) && syserror(tcp))
1880 tcp->flags &= ~TCB_WAITEXECVE;
1881 else
1882 tcp->flags |= TCB_WAITEXECVE;
1883#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001884 return 0;
1885}
1886
1887#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001888#ifndef __WNOTHREAD
1889#define __WNOTHREAD 0x20000000
1890#endif
1891#ifndef __WALL
1892#define __WALL 0x40000000
1893#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001894#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001895#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001896#endif
1897#endif /* LINUX */
1898
Roland McGrathd9f816f2004-09-04 03:39:20 +00001899static const struct xlat wait4_options[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001900 { WNOHANG, "WNOHANG" },
1901#ifndef WSTOPPED
1902 { WUNTRACED, "WUNTRACED" },
1903#endif
1904#ifdef WEXITED
1905 { WEXITED, "WEXITED" },
1906#endif
1907#ifdef WTRAPPED
1908 { WTRAPPED, "WTRAPPED" },
1909#endif
1910#ifdef WSTOPPED
1911 { WSTOPPED, "WSTOPPED" },
1912#endif
1913#ifdef WCONTINUED
1914 { WCONTINUED, "WCONTINUED" },
1915#endif
1916#ifdef WNOWAIT
1917 { WNOWAIT, "WNOWAIT" },
1918#endif
1919#ifdef __WCLONE
1920 { __WCLONE, "__WCLONE" },
1921#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001922#ifdef __WALL
1923 { __WALL, "__WALL" },
1924#endif
1925#ifdef __WNOTHREAD
1926 { __WNOTHREAD, "__WNOTHREAD" },
1927#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001928 { 0, NULL },
1929};
1930
Roland McGrath5e02a572004-10-19 23:33:47 +00001931#if !defined WCOREFLAG && defined WCOREFLG
1932# define WCOREFLAG WCOREFLG
1933#endif
1934#ifndef WCOREFLAG
1935#define WCOREFLAG 0x80
1936#endif
1937
1938#ifndef W_STOPCODE
1939#define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1940#endif
1941#ifndef W_EXITCODE
1942#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1943#endif
1944
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001945static int
1946printstatus(status)
1947int status;
1948{
1949 int exited = 0;
1950
1951 /*
1952 * Here is a tricky presentation problem. This solution
1953 * is still not entirely satisfactory but since there
1954 * are no wait status constructors it will have to do.
1955 */
Roland McGrath79fbda52004-04-14 02:45:55 +00001956 if (WIFSTOPPED(status)) {
1957 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001958 signame(WSTOPSIG(status)));
Roland McGrath79fbda52004-04-14 02:45:55 +00001959 status &= ~W_STOPCODE(WSTOPSIG(status));
1960 }
1961 else if (WIFSIGNALED(status)) {
1962 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001963 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001964 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
Roland McGrath79fbda52004-04-14 02:45:55 +00001965 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1966 }
1967 else if (WIFEXITED(status)) {
1968 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001969 WEXITSTATUS(status));
1970 exited = 1;
Roland McGrath79fbda52004-04-14 02:45:55 +00001971 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001972 }
Roland McGrath79fbda52004-04-14 02:45:55 +00001973 else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001974 tprintf("[%#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001975 return 0;
1976 }
1977
1978 if (status == 0)
1979 tprintf("]");
1980 else
Roland McGrathf8cc83c2004-06-04 01:24:07 +00001981 tprintf(" | %#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001982
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001983 return exited;
1984}
1985
1986static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001987printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001988struct tcb *tcp;
1989int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001990int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001991{
1992 int status;
1993 int exited = 0;
1994
1995 if (entering(tcp)) {
Roland McGrath5b63d962008-07-18 02:16:47 +00001996 /*
1997 * Sign-extend a 32-bit value when that's what it is.
1998 */
1999 long pid = tcp->u_arg[0];
2000 if (personality_wordsize[current_personality] < sizeof pid)
2001 pid = (long) (int) pid;
2002 tprintf("%ld, ", pid);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002003 } else {
2004 /* status */
2005 if (!tcp->u_arg[1])
2006 tprintf("NULL");
2007 else if (syserror(tcp) || tcp->u_rval == 0)
2008 tprintf("%#lx", tcp->u_arg[1]);
2009 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
2010 tprintf("[?]");
2011 else
2012 exited = printstatus(status);
2013 /* options */
2014 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00002015 printflags(wait4_options, tcp->u_arg[2], "W???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002016 if (n == 4) {
2017 tprintf(", ");
2018 /* usage */
2019 if (!tcp->u_arg[3])
2020 tprintf("NULL");
2021#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002022 else if (tcp->u_rval > 0) {
2023#ifdef LINUX_64BIT
2024 if (bitness)
2025 printrusage32(tcp, tcp->u_arg[3]);
2026 else
2027#endif
2028 printrusage(tcp, tcp->u_arg[3]);
2029 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002030#endif /* LINUX */
2031#ifdef SUNOS4
2032 else if (tcp->u_rval > 0 && exited)
2033 printrusage(tcp, tcp->u_arg[3]);
2034#endif /* SUNOS4 */
2035 else
2036 tprintf("%#lx", tcp->u_arg[3]);
2037 }
2038 }
2039 return 0;
2040}
2041
2042int
Roland McGrathc74c0b72004-09-01 19:39:46 +00002043internal_wait(tcp, flagarg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002044struct tcb *tcp;
Roland McGrathc74c0b72004-09-01 19:39:46 +00002045int flagarg;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002046{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002047 int got_kids;
2048
2049#ifdef TCB_CLONE_THREAD
2050 if (tcp->flags & TCB_CLONE_THREAD)
2051 /* The children we wait for are our parent's children. */
2052 got_kids = (tcp->parent->nchildren
2053 > tcp->parent->nclone_detached);
2054 else
2055 got_kids = (tcp->nchildren > tcp->nclone_detached);
2056#else
2057 got_kids = tcp->nchildren > 0;
2058#endif
2059
2060 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00002061 /* There are children that this parent should block for.
2062 But ptrace made us the parent of the traced children
2063 and the real parent will get ECHILD from the wait call.
2064
2065 XXX If we attached with strace -f -p PID, then there
2066 may be untraced dead children the parent could be reaping
2067 now, but we make him block. */
2068
2069 /* ??? WTA: fix bug with hanging children */
2070
Roland McGrathc74c0b72004-09-01 19:39:46 +00002071 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00002072 /*
2073 * There are traced children. We'll make the parent
2074 * block to avoid a false ECHILD error due to our
2075 * ptrace having stolen the children. However,
2076 * we shouldn't block if there are zombies to reap.
2077 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
2078 */
Roland McGrathfccfb942003-10-01 21:59:44 +00002079 struct tcb *child = NULL;
Roland McGrath09623452003-05-23 02:27:13 +00002080 if (tcp->nzombies > 0 &&
2081 (tcp->u_arg[0] == -1 ||
Roland McGrathfccfb942003-10-01 21:59:44 +00002082 (child = pid2tcb(tcp->u_arg[0])) == NULL))
Roland McGrath09623452003-05-23 02:27:13 +00002083 return 0;
Roland McGrathfccfb942003-10-01 21:59:44 +00002084 if (tcp->u_arg[0] > 0) {
2085 /*
2086 * If the parent waits for a specified child
2087 * PID, then it must get ECHILD right away
2088 * if that PID is not one of its children.
2089 * Make sure that the requested PID matches
2090 * one of the parent's children that we are
2091 * tracing, and don't suspend it otherwise.
2092 */
2093 if (child == NULL)
2094 child = pid2tcb(tcp->u_arg[0]);
2095 if (child == NULL || child->parent != (
2096#ifdef TCB_CLONE_THREAD
2097 (tcp->flags & TCB_CLONE_THREAD)
2098 ? tcp->parent :
2099#endif
Roland McGrathd56a6562005-08-03 11:23:43 +00002100 tcp) ||
2101 (child->flags & TCB_EXITING))
Roland McGrathfccfb942003-10-01 21:59:44 +00002102 return 0;
2103 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002104 tcp->flags |= TCB_SUSPENDED;
2105 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002106#ifdef TCB_CLONE_THREAD
2107 if (tcp->flags & TCB_CLONE_THREAD)
2108 tcp->parent->nclone_waiting++;
2109#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002110 }
2111 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002112 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathc74c0b72004-09-01 19:39:46 +00002113 if (tcp->u_arg[flagarg] & WNOHANG) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00002114 /* We must force a fake result of 0 instead of
2115 the ECHILD error. */
2116 extern int force_result();
2117 return force_result(tcp, 0, 0);
2118 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00002119 }
Roland McGrath09623452003-05-23 02:27:13 +00002120 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2121 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2122 /*
2123 * We just reaped a child we don't know about,
2124 * presumably a zombie we already droptcb'd.
2125 */
2126 tcp->nzombies--;
2127 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002128 return 0;
2129}
2130
2131#ifdef SVR4
2132
2133int
2134sys_wait(tcp)
2135struct tcb *tcp;
2136{
2137 if (exiting(tcp)) {
2138 /* The library wrapper stuffs this into the user variable. */
2139 if (!syserror(tcp))
2140 printstatus(getrval2(tcp));
2141 }
2142 return 0;
2143}
2144
2145#endif /* SVR4 */
2146
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002147#ifdef FREEBSD
2148int
2149sys_wait(tcp)
2150struct tcb *tcp;
2151{
2152 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00002153
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002154 if (exiting(tcp)) {
2155 if (!syserror(tcp)) {
2156 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2157 tprintf("%#lx", tcp->u_arg[0]);
2158 else
2159 printstatus(status);
2160 }
2161 }
2162 return 0;
2163}
2164#endif
2165
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002166int
2167sys_waitpid(tcp)
2168struct tcb *tcp;
2169{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002170 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002171}
2172
2173int
2174sys_wait4(tcp)
2175struct tcb *tcp;
2176{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002177 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002178}
2179
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002180#ifdef ALPHA
2181int
2182sys_osf_wait4(tcp)
2183struct tcb *tcp;
2184{
2185 return printwaitn(tcp, 4, 1);
2186}
2187#endif
2188
Roland McGrathc74c0b72004-09-01 19:39:46 +00002189#if defined SVR4 || defined LINUX
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002190
Roland McGrathd9f816f2004-09-04 03:39:20 +00002191static const struct xlat waitid_types[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002192 { P_PID, "P_PID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002193#ifdef P_PPID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002194 { P_PPID, "P_PPID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002195#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002196 { P_PGID, "P_PGID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002197#ifdef P_SID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002198 { P_SID, "P_SID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002199#endif
2200#ifdef P_CID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002201 { P_CID, "P_CID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002202#endif
2203#ifdef P_UID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002204 { P_UID, "P_UID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002205#endif
2206#ifdef P_GID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002207 { P_GID, "P_GID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002208#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002209 { P_ALL, "P_ALL" },
2210#ifdef P_LWPID
2211 { P_LWPID, "P_LWPID" },
2212#endif
2213 { 0, NULL },
2214};
2215
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002216int
2217sys_waitid(tcp)
2218struct tcb *tcp;
2219{
2220 siginfo_t si;
2221 int exited;
2222
2223 if (entering(tcp)) {
2224 printxval(waitid_types, tcp->u_arg[0], "P_???");
2225 tprintf(", %ld, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002226 }
2227 else {
2228 /* siginfo */
2229 exited = 0;
2230 if (!tcp->u_arg[2])
2231 tprintf("NULL");
2232 else if (syserror(tcp))
2233 tprintf("%#lx", tcp->u_arg[2]);
2234 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2235 tprintf("{???}");
2236 else
Denys Vlasenkof535b542009-01-13 18:30:55 +00002237 printsiginfo(&si, verbose(tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002238 /* options */
2239 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00002240 printflags(wait4_options, tcp->u_arg[3], "W???");
Roland McGrath39426a32004-10-06 22:02:59 +00002241 if (tcp->u_nargs > 4) {
2242 /* usage */
2243 tprintf(", ");
2244 if (!tcp->u_arg[4])
2245 tprintf("NULL");
2246 else if (tcp->u_error)
2247 tprintf("%#lx", tcp->u_arg[4]);
2248 else
2249 printrusage(tcp, tcp->u_arg[4]);
2250 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002251 }
2252 return 0;
2253}
2254
Roland McGrathc74c0b72004-09-01 19:39:46 +00002255#endif /* SVR4 or LINUX */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002256
2257int
2258sys_alarm(tcp)
2259struct tcb *tcp;
2260{
2261 if (entering(tcp))
2262 tprintf("%lu", tcp->u_arg[0]);
2263 return 0;
2264}
2265
2266int
2267sys_uname(tcp)
2268struct tcb *tcp;
2269{
2270 struct utsname uname;
2271
2272 if (exiting(tcp)) {
2273 if (syserror(tcp) || !verbose(tcp))
2274 tprintf("%#lx", tcp->u_arg[0]);
2275 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2276 tprintf("{...}");
2277 else if (!abbrev(tcp)) {
2278
2279 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2280 uname.sysname, uname.nodename);
2281 tprintf("release=\"%s\", version=\"%s\", ",
2282 uname.release, uname.version);
2283 tprintf("machine=\"%s\"", uname.machine);
2284#ifdef LINUX
2285#ifndef __GLIBC__
2286 tprintf(", domainname=\"%s\"", uname.domainname);
2287#endif /* __GLIBC__ */
2288#endif /* LINUX */
2289 tprintf("}");
2290 }
2291 else
2292 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2293 uname.sysname, uname.nodename);
2294 }
2295 return 0;
2296}
2297
2298#ifndef SVR4
2299
Roland McGrathd9f816f2004-09-04 03:39:20 +00002300static const struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002301#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002302 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2303 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2304 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2305 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2306 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2307 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2308 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2309 { PTRACE_CONT, "PTRACE_CONT" },
2310 { PTRACE_KILL, "PTRACE_KILL" },
2311 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2312 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2313 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002314#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002315 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002316#endif
2317#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002318 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002319#endif
2320#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002321 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002322#endif
2323#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002324 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002325#endif
2326#ifdef PTRACE_GETFPXREGS
2327 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2328#endif
2329#ifdef PTRACE_SETFPXREGS
2330 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2331#endif
Roland McGrathf04bb482005-05-09 07:45:33 +00002332#ifdef PTRACE_GETVRREGS
2333 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2334#endif
2335#ifdef PTRACE_SETVRREGS
2336 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2337#endif
Denys Vlasenkof535b542009-01-13 18:30:55 +00002338#ifdef PTRACE_SETOPTIONS
2339 { PTRACE_SETOPTIONS, "PTRACE_SETOPTIONS", },
2340#endif
2341#ifdef PTRACE_GETEVENTMSG
2342 { PTRACE_GETEVENTMSG, "PTRACE_GETEVENTMSG", },
2343#endif
2344#ifdef PTRACE_GETSIGINFO
2345 { PTRACE_GETSIGINFO, "PTRACE_GETSIGINFO", },
2346#endif
2347#ifdef PTRACE_SETSIGINFO
2348 { PTRACE_SETSIGINFO, "PTRACE_SETSIGINFO", },
2349#endif
Roland McGrathbf621d42003-01-14 09:46:21 +00002350#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002351 { PTRACE_READDATA, "PTRACE_READDATA" },
2352 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2353 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2354 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2355 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2356 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2357#ifdef SPARC
2358 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2359 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2360#else /* !SPARC */
2361 { PTRACE_22, "PTRACE_PTRACE_22" },
2362 { PTRACE_23, "PTRACE_PTRACE_23" },
2363#endif /* !SPARC */
2364#endif /* SUNOS4 */
2365 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2366#ifdef SUNOS4
2367 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2368#ifdef I386
2369 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2370 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2371 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2372#else /* !I386 */
2373 { PTRACE_26, "PTRACE_26" },
2374 { PTRACE_27, "PTRACE_27" },
2375 { PTRACE_28, "PTRACE_28" },
2376#endif /* !I386 */
2377 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2378#endif /* SUNOS4 */
Denys Vlasenkof535b542009-01-13 18:30:55 +00002379
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002380#else /* FREEBSD */
Denys Vlasenkof535b542009-01-13 18:30:55 +00002381
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002382 { PT_TRACE_ME, "PT_TRACE_ME" },
2383 { PT_READ_I, "PT_READ_I" },
2384 { PT_READ_D, "PT_READ_D" },
2385 { PT_WRITE_I, "PT_WRITE_I" },
2386 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002387#ifdef PT_READ_U
2388 { PT_READ_U, "PT_READ_U" },
2389#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002390 { PT_CONTINUE, "PT_CONTINUE" },
2391 { PT_KILL, "PT_KILL" },
2392 { PT_STEP, "PT_STEP" },
2393 { PT_ATTACH, "PT_ATTACH" },
2394 { PT_DETACH, "PT_DETACH" },
2395 { PT_GETREGS, "PT_GETREGS" },
2396 { PT_SETREGS, "PT_SETREGS" },
2397 { PT_GETFPREGS, "PT_GETFPREGS" },
2398 { PT_SETFPREGS, "PT_SETFPREGS" },
2399 { PT_GETDBREGS, "PT_GETDBREGS" },
2400 { PT_SETDBREGS, "PT_SETDBREGS" },
2401#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002402 { 0, NULL },
2403};
2404
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002405#ifndef FREEBSD
Denys Vlasenkof535b542009-01-13 18:30:55 +00002406#ifdef PTRACE_SETOPTIONS
2407static const struct xlat ptrace_setoptions_flags[] = {
2408#ifdef PTRACE_O_TRACESYSGOOD
2409 { PTRACE_O_TRACESYSGOOD,"PTRACE_O_TRACESYSGOOD" },
2410#endif
2411#ifdef PTRACE_O_TRACEFORK
2412 { PTRACE_O_TRACEFORK, "PTRACE_O_TRACEFORK" },
2413#endif
2414#ifdef PTRACE_O_TRACEVFORK
2415 { PTRACE_O_TRACEVFORK, "PTRACE_O_TRACEVFORK" },
2416#endif
2417#ifdef PTRACE_O_TRACECLONE
2418 { PTRACE_O_TRACECLONE, "PTRACE_O_TRACECLONE" },
2419#endif
2420#ifdef PTRACE_O_TRACEEXEC
2421 { PTRACE_O_TRACEEXEC, "PTRACE_O_TRACEEXEC" },
2422#endif
2423#ifdef PTRACE_O_TRACEVFORKDONE
2424 { PTRACE_O_TRACEVFORKDONE,"PTRACE_O_TRACEVFORKDONE"},
2425#endif
2426#ifdef PTRACE_O_TRACEEXIT
2427 { PTRACE_O_TRACEEXIT, "PTRACE_O_TRACEEXIT" },
2428#endif
2429 { 0, NULL },
2430};
2431#endif
2432#endif
2433
2434#ifndef FREEBSD
Roland McGrathd9f816f2004-09-04 03:39:20 +00002435const struct xlat struct_user_offsets[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002436#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002437#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002438 { PT_PSWMASK, "psw_mask" },
2439 { PT_PSWADDR, "psw_addr" },
2440 { PT_GPR0, "gpr0" },
2441 { PT_GPR1, "gpr1" },
2442 { PT_GPR2, "gpr2" },
2443 { PT_GPR3, "gpr3" },
2444 { PT_GPR4, "gpr4" },
2445 { PT_GPR5, "gpr5" },
2446 { PT_GPR6, "gpr6" },
2447 { PT_GPR7, "gpr7" },
2448 { PT_GPR8, "gpr8" },
2449 { PT_GPR9, "gpr9" },
2450 { PT_GPR10, "gpr10" },
2451 { PT_GPR11, "gpr11" },
2452 { PT_GPR12, "gpr12" },
2453 { PT_GPR13, "gpr13" },
2454 { PT_GPR14, "gpr14" },
2455 { PT_GPR15, "gpr15" },
2456 { PT_ACR0, "acr0" },
2457 { PT_ACR1, "acr1" },
2458 { PT_ACR2, "acr2" },
2459 { PT_ACR3, "acr3" },
2460 { PT_ACR4, "acr4" },
2461 { PT_ACR5, "acr5" },
2462 { PT_ACR6, "acr6" },
2463 { PT_ACR7, "acr7" },
2464 { PT_ACR8, "acr8" },
2465 { PT_ACR9, "acr9" },
2466 { PT_ACR10, "acr10" },
2467 { PT_ACR11, "acr11" },
2468 { PT_ACR12, "acr12" },
2469 { PT_ACR13, "acr13" },
2470 { PT_ACR14, "acr14" },
2471 { PT_ACR15, "acr15" },
2472 { PT_ORIGGPR2, "orig_gpr2" },
2473 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002474#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002475 { PT_FPR0_HI, "fpr0.hi" },
2476 { PT_FPR0_LO, "fpr0.lo" },
2477 { PT_FPR1_HI, "fpr1.hi" },
2478 { PT_FPR1_LO, "fpr1.lo" },
2479 { PT_FPR2_HI, "fpr2.hi" },
2480 { PT_FPR2_LO, "fpr2.lo" },
2481 { PT_FPR3_HI, "fpr3.hi" },
2482 { PT_FPR3_LO, "fpr3.lo" },
2483 { PT_FPR4_HI, "fpr4.hi" },
2484 { PT_FPR4_LO, "fpr4.lo" },
2485 { PT_FPR5_HI, "fpr5.hi" },
2486 { PT_FPR5_LO, "fpr5.lo" },
2487 { PT_FPR6_HI, "fpr6.hi" },
2488 { PT_FPR6_LO, "fpr6.lo" },
2489 { PT_FPR7_HI, "fpr7.hi" },
2490 { PT_FPR7_LO, "fpr7.lo" },
2491 { PT_FPR8_HI, "fpr8.hi" },
2492 { PT_FPR8_LO, "fpr8.lo" },
2493 { PT_FPR9_HI, "fpr9.hi" },
2494 { PT_FPR9_LO, "fpr9.lo" },
2495 { PT_FPR10_HI, "fpr10.hi" },
2496 { PT_FPR10_LO, "fpr10.lo" },
2497 { PT_FPR11_HI, "fpr11.hi" },
2498 { PT_FPR11_LO, "fpr11.lo" },
2499 { PT_FPR12_HI, "fpr12.hi" },
2500 { PT_FPR12_LO, "fpr12.lo" },
2501 { PT_FPR13_HI, "fpr13.hi" },
2502 { PT_FPR13_LO, "fpr13.lo" },
2503 { PT_FPR14_HI, "fpr14.hi" },
2504 { PT_FPR14_LO, "fpr14.lo" },
2505 { PT_FPR15_HI, "fpr15.hi" },
2506 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002507#endif
2508#if defined(S390X)
2509 { PT_FPR0, "fpr0" },
2510 { PT_FPR1, "fpr1" },
2511 { PT_FPR2, "fpr2" },
2512 { PT_FPR3, "fpr3" },
2513 { PT_FPR4, "fpr4" },
2514 { PT_FPR5, "fpr5" },
2515 { PT_FPR6, "fpr6" },
2516 { PT_FPR7, "fpr7" },
2517 { PT_FPR8, "fpr8" },
2518 { PT_FPR9, "fpr9" },
2519 { PT_FPR10, "fpr10" },
2520 { PT_FPR11, "fpr11" },
2521 { PT_FPR12, "fpr12" },
2522 { PT_FPR13, "fpr13" },
2523 { PT_FPR14, "fpr14" },
2524 { PT_FPR15, "fpr15" },
2525#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002526 { PT_CR_9, "cr9" },
2527 { PT_CR_10, "cr10" },
2528 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002529 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002530#endif
2531#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002532 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002533#elif defined(HPPA)
2534 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002535#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002536#ifndef PT_ORIG_R3
2537#define PT_ORIG_R3 34
2538#endif
Roland McGratheb285352003-01-14 09:59:00 +00002539#define REGSIZE (sizeof(unsigned long))
2540 { REGSIZE*PT_R0, "r0" },
2541 { REGSIZE*PT_R1, "r1" },
2542 { REGSIZE*PT_R2, "r2" },
2543 { REGSIZE*PT_R3, "r3" },
2544 { REGSIZE*PT_R4, "r4" },
2545 { REGSIZE*PT_R5, "r5" },
2546 { REGSIZE*PT_R6, "r6" },
2547 { REGSIZE*PT_R7, "r7" },
2548 { REGSIZE*PT_R8, "r8" },
2549 { REGSIZE*PT_R9, "r9" },
2550 { REGSIZE*PT_R10, "r10" },
2551 { REGSIZE*PT_R11, "r11" },
2552 { REGSIZE*PT_R12, "r12" },
2553 { REGSIZE*PT_R13, "r13" },
2554 { REGSIZE*PT_R14, "r14" },
2555 { REGSIZE*PT_R15, "r15" },
2556 { REGSIZE*PT_R16, "r16" },
2557 { REGSIZE*PT_R17, "r17" },
2558 { REGSIZE*PT_R18, "r18" },
2559 { REGSIZE*PT_R19, "r19" },
2560 { REGSIZE*PT_R20, "r20" },
2561 { REGSIZE*PT_R21, "r21" },
2562 { REGSIZE*PT_R22, "r22" },
2563 { REGSIZE*PT_R23, "r23" },
2564 { REGSIZE*PT_R24, "r24" },
2565 { REGSIZE*PT_R25, "r25" },
2566 { REGSIZE*PT_R26, "r26" },
2567 { REGSIZE*PT_R27, "r27" },
2568 { REGSIZE*PT_R28, "r28" },
2569 { REGSIZE*PT_R29, "r29" },
2570 { REGSIZE*PT_R30, "r30" },
2571 { REGSIZE*PT_R31, "r31" },
2572 { REGSIZE*PT_NIP, "NIP" },
2573 { REGSIZE*PT_MSR, "MSR" },
2574 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2575 { REGSIZE*PT_CTR, "CTR" },
2576 { REGSIZE*PT_LNK, "LNK" },
2577 { REGSIZE*PT_XER, "XER" },
2578 { REGSIZE*PT_CCR, "CCR" },
2579 { REGSIZE*PT_FPR0, "FPR0" },
2580#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002581#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002582#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002583 { 0, "r0" },
2584 { 1, "r1" },
2585 { 2, "r2" },
2586 { 3, "r3" },
2587 { 4, "r4" },
2588 { 5, "r5" },
2589 { 6, "r6" },
2590 { 7, "r7" },
2591 { 8, "r8" },
2592 { 9, "r9" },
2593 { 10, "r10" },
2594 { 11, "r11" },
2595 { 12, "r12" },
2596 { 13, "r13" },
2597 { 14, "r14" },
2598 { 15, "r15" },
2599 { 16, "r16" },
2600 { 17, "r17" },
2601 { 18, "r18" },
2602 { 19, "r19" },
2603 { 20, "r20" },
2604 { 21, "r21" },
2605 { 22, "r22" },
2606 { 23, "r23" },
2607 { 24, "r24" },
2608 { 25, "r25" },
2609 { 26, "r26" },
2610 { 27, "r27" },
2611 { 28, "r28" },
2612 { 29, "gp" },
2613 { 30, "fp" },
2614 { 31, "zero" },
2615 { 32, "fp0" },
2616 { 33, "fp" },
2617 { 34, "fp2" },
2618 { 35, "fp3" },
2619 { 36, "fp4" },
2620 { 37, "fp5" },
2621 { 38, "fp6" },
2622 { 39, "fp7" },
2623 { 40, "fp8" },
2624 { 41, "fp9" },
2625 { 42, "fp10" },
2626 { 43, "fp11" },
2627 { 44, "fp12" },
2628 { 45, "fp13" },
2629 { 46, "fp14" },
2630 { 47, "fp15" },
2631 { 48, "fp16" },
2632 { 49, "fp17" },
2633 { 50, "fp18" },
2634 { 51, "fp19" },
2635 { 52, "fp20" },
2636 { 53, "fp21" },
2637 { 54, "fp22" },
2638 { 55, "fp23" },
2639 { 56, "fp24" },
2640 { 57, "fp25" },
2641 { 58, "fp26" },
2642 { 59, "fp27" },
2643 { 60, "fp28" },
2644 { 61, "fp29" },
2645 { 62, "fp30" },
2646 { 63, "fp31" },
2647 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002648#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002649#ifdef IA64
2650 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2651 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2652 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2653 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2654 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2655 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2656 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2657 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2658 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2659 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2660 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2661 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2662 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2663 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2664 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2665 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2666 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2667 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2668 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2669 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2670 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2671 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2672 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2673 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2674 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2675 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2676 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2677 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2678 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2679 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2680 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2681 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2682 /* switch stack: */
2683 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2684 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2685 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2686 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2687 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2688 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2689 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2690 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2691 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2692 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002693 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2694 { PT_B4, "b4" }, { PT_B5, "b5" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002695 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002696 /* pt_regs */
Roland McGrathca4e10c2004-01-13 10:13:20 +00002697 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2698 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002699 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2700 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2701 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2702 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2703 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2704 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2705 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2706 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2707 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2708 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2709 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2710 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2711 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2712 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2713 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
Roland McGrathfb1bc072004-03-01 21:29:24 +00002714# ifdef PT_AR_CSD
2715 { PT_AR_CSD, "ar.csd" },
2716# endif
2717# ifdef PT_AR_SSD
2718 { PT_AR_SSD, "ar.ssd" },
2719# endif
Roland McGrathca4e10c2004-01-13 10:13:20 +00002720 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002721#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002722#ifdef I386
2723 { 4*EBX, "4*EBX" },
2724 { 4*ECX, "4*ECX" },
2725 { 4*EDX, "4*EDX" },
2726 { 4*ESI, "4*ESI" },
2727 { 4*EDI, "4*EDI" },
2728 { 4*EBP, "4*EBP" },
2729 { 4*EAX, "4*EAX" },
2730 { 4*DS, "4*DS" },
2731 { 4*ES, "4*ES" },
2732 { 4*FS, "4*FS" },
2733 { 4*GS, "4*GS" },
2734 { 4*ORIG_EAX, "4*ORIG_EAX" },
2735 { 4*EIP, "4*EIP" },
2736 { 4*CS, "4*CS" },
2737 { 4*EFL, "4*EFL" },
2738 { 4*UESP, "4*UESP" },
2739 { 4*SS, "4*SS" },
2740#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002741#ifdef X86_64
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002742 { 8*R15, "8*R15" },
2743 { 8*R14, "8*R14" },
2744 { 8*R13, "8*R13" },
2745 { 8*R12, "8*R12" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002746 { 8*RBP, "8*RBP" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002747 { 8*RBX, "8*RBX" },
2748 { 8*R11, "8*R11" },
2749 { 8*R10, "8*R10" },
2750 { 8*R9, "8*R9" },
2751 { 8*R8, "8*R8" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002752 { 8*RAX, "8*RAX" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002753 { 8*RCX, "8*RCX" },
2754 { 8*RDX, "8*RDX" },
2755 { 8*RSI, "8*RSI" },
2756 { 8*RDI, "8*RDI" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002757#if 0
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002758 { DS, "DS" },
2759 { ES, "ES" },
2760 { FS, "FS" },
2761 { GS, "GS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002762#endif
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002763 { 8*ORIG_RAX, "8*ORIG_RAX" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002764 { 8*RIP, "8*RIP" },
2765 { 8*CS, "8*CS" },
2766 { 8*EFLAGS, "8*EFL" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002767 { 8*RSP, "8*RSP" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002768 { 8*SS, "8*SS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002769#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002770#ifdef M68K
2771 { 4*PT_D1, "4*PT_D1" },
2772 { 4*PT_D2, "4*PT_D2" },
2773 { 4*PT_D3, "4*PT_D3" },
2774 { 4*PT_D4, "4*PT_D4" },
2775 { 4*PT_D5, "4*PT_D5" },
2776 { 4*PT_D6, "4*PT_D6" },
2777 { 4*PT_D7, "4*PT_D7" },
2778 { 4*PT_A0, "4*PT_A0" },
2779 { 4*PT_A1, "4*PT_A1" },
2780 { 4*PT_A2, "4*PT_A2" },
2781 { 4*PT_A3, "4*PT_A3" },
2782 { 4*PT_A4, "4*PT_A4" },
2783 { 4*PT_A5, "4*PT_A5" },
2784 { 4*PT_A6, "4*PT_A6" },
2785 { 4*PT_D0, "4*PT_D0" },
2786 { 4*PT_USP, "4*PT_USP" },
2787 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2788 { 4*PT_SR, "4*PT_SR" },
2789 { 4*PT_PC, "4*PT_PC" },
2790#endif /* M68K */
2791#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002792#ifdef SH
Denys Vlasenkoadedb512008-12-30 18:47:55 +00002793 { 4*REG_REG0, "4*REG_REG0" },
2794 { 4*(REG_REG0+1), "4*REG_REG1" },
2795 { 4*(REG_REG0+2), "4*REG_REG2" },
2796 { 4*(REG_REG0+3), "4*REG_REG3" },
2797 { 4*(REG_REG0+4), "4*REG_REG4" },
2798 { 4*(REG_REG0+5), "4*REG_REG5" },
2799 { 4*(REG_REG0+6), "4*REG_REG6" },
2800 { 4*(REG_REG0+7), "4*REG_REG7" },
2801 { 4*(REG_REG0+8), "4*REG_REG8" },
2802 { 4*(REG_REG0+9), "4*REG_REG9" },
2803 { 4*(REG_REG0+10), "4*REG_REG10" },
2804 { 4*(REG_REG0+11), "4*REG_REG11" },
2805 { 4*(REG_REG0+12), "4*REG_REG12" },
2806 { 4*(REG_REG0+13), "4*REG_REG13" },
2807 { 4*(REG_REG0+14), "4*REG_REG14" },
2808 { 4*REG_REG15, "4*REG_REG15" },
2809 { 4*REG_PC, "4*REG_PC" },
2810 { 4*REG_PR, "4*REG_PR" },
2811 { 4*REG_SR, "4*REG_SR" },
2812 { 4*REG_GBR, "4*REG_GBR" },
2813 { 4*REG_MACH, "4*REG_MACH" },
2814 { 4*REG_MACL, "4*REG_MACL" },
2815 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2816 { 4*REG_FPUL, "4*REG_FPUL" },
2817 { 4*REG_FPREG0, "4*REG_FPREG0" },
2818 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2819 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2820 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2821 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2822 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2823 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2824 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2825 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2826 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2827 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2828 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2829 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2830 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2831 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2832 { 4*REG_FPREG15, "4*REG_FPREG15" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002833#ifdef REG_XDREG0
Denys Vlasenkoadedb512008-12-30 18:47:55 +00002834 { 4*REG_XDREG0, "4*REG_XDREG0" },
2835 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2836 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2837 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2838 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2839 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2840 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2841 { 4*REG_XDREG14, "4*REG_XDREG14" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002842#endif
Denys Vlasenkoadedb512008-12-30 18:47:55 +00002843 { 4*REG_FPSCR, "4*REG_FPSCR" },
Wichert Akkermanccef6372002-05-01 16:39:22 +00002844#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002845#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002846 { 0, "PC(L)" },
2847 { 4, "PC(U)" },
2848 { 8, "SR(L)" },
2849 { 12, "SR(U)" },
2850 { 16, "syscall no.(L)" },
2851 { 20, "syscall_no.(U)" },
2852 { 24, "R0(L)" },
2853 { 28, "R0(U)" },
2854 { 32, "R1(L)" },
2855 { 36, "R1(U)" },
2856 { 40, "R2(L)" },
2857 { 44, "R2(U)" },
2858 { 48, "R3(L)" },
2859 { 52, "R3(U)" },
2860 { 56, "R4(L)" },
2861 { 60, "R4(U)" },
2862 { 64, "R5(L)" },
2863 { 68, "R5(U)" },
2864 { 72, "R6(L)" },
2865 { 76, "R6(U)" },
2866 { 80, "R7(L)" },
2867 { 84, "R7(U)" },
2868 { 88, "R8(L)" },
2869 { 92, "R8(U)" },
2870 { 96, "R9(L)" },
2871 { 100, "R9(U)" },
2872 { 104, "R10(L)" },
2873 { 108, "R10(U)" },
2874 { 112, "R11(L)" },
2875 { 116, "R11(U)" },
2876 { 120, "R12(L)" },
2877 { 124, "R12(U)" },
2878 { 128, "R13(L)" },
2879 { 132, "R13(U)" },
2880 { 136, "R14(L)" },
2881 { 140, "R14(U)" },
2882 { 144, "R15(L)" },
2883 { 148, "R15(U)" },
2884 { 152, "R16(L)" },
2885 { 156, "R16(U)" },
2886 { 160, "R17(L)" },
2887 { 164, "R17(U)" },
2888 { 168, "R18(L)" },
2889 { 172, "R18(U)" },
2890 { 176, "R19(L)" },
2891 { 180, "R19(U)" },
2892 { 184, "R20(L)" },
2893 { 188, "R20(U)" },
2894 { 192, "R21(L)" },
2895 { 196, "R21(U)" },
2896 { 200, "R22(L)" },
2897 { 204, "R22(U)" },
2898 { 208, "R23(L)" },
2899 { 212, "R23(U)" },
2900 { 216, "R24(L)" },
2901 { 220, "R24(U)" },
2902 { 224, "R25(L)" },
2903 { 228, "R25(U)" },
2904 { 232, "R26(L)" },
2905 { 236, "R26(U)" },
2906 { 240, "R27(L)" },
2907 { 244, "R27(U)" },
2908 { 248, "R28(L)" },
2909 { 252, "R28(U)" },
2910 { 256, "R29(L)" },
2911 { 260, "R29(U)" },
2912 { 264, "R30(L)" },
2913 { 268, "R30(U)" },
2914 { 272, "R31(L)" },
2915 { 276, "R31(U)" },
2916 { 280, "R32(L)" },
2917 { 284, "R32(U)" },
2918 { 288, "R33(L)" },
2919 { 292, "R33(U)" },
2920 { 296, "R34(L)" },
2921 { 300, "R34(U)" },
2922 { 304, "R35(L)" },
2923 { 308, "R35(U)" },
2924 { 312, "R36(L)" },
2925 { 316, "R36(U)" },
2926 { 320, "R37(L)" },
2927 { 324, "R37(U)" },
2928 { 328, "R38(L)" },
2929 { 332, "R38(U)" },
2930 { 336, "R39(L)" },
2931 { 340, "R39(U)" },
2932 { 344, "R40(L)" },
2933 { 348, "R40(U)" },
2934 { 352, "R41(L)" },
2935 { 356, "R41(U)" },
2936 { 360, "R42(L)" },
2937 { 364, "R42(U)" },
2938 { 368, "R43(L)" },
2939 { 372, "R43(U)" },
2940 { 376, "R44(L)" },
2941 { 380, "R44(U)" },
2942 { 384, "R45(L)" },
2943 { 388, "R45(U)" },
2944 { 392, "R46(L)" },
2945 { 396, "R46(U)" },
2946 { 400, "R47(L)" },
2947 { 404, "R47(U)" },
2948 { 408, "R48(L)" },
2949 { 412, "R48(U)" },
2950 { 416, "R49(L)" },
2951 { 420, "R49(U)" },
2952 { 424, "R50(L)" },
2953 { 428, "R50(U)" },
2954 { 432, "R51(L)" },
2955 { 436, "R51(U)" },
2956 { 440, "R52(L)" },
2957 { 444, "R52(U)" },
2958 { 448, "R53(L)" },
2959 { 452, "R53(U)" },
2960 { 456, "R54(L)" },
2961 { 460, "R54(U)" },
2962 { 464, "R55(L)" },
2963 { 468, "R55(U)" },
2964 { 472, "R56(L)" },
2965 { 476, "R56(U)" },
2966 { 480, "R57(L)" },
2967 { 484, "R57(U)" },
2968 { 488, "R58(L)" },
2969 { 492, "R58(U)" },
2970 { 496, "R59(L)" },
2971 { 500, "R59(U)" },
2972 { 504, "R60(L)" },
2973 { 508, "R60(U)" },
2974 { 512, "R61(L)" },
2975 { 516, "R61(U)" },
2976 { 520, "R62(L)" },
2977 { 524, "R62(U)" },
2978 { 528, "TR0(L)" },
2979 { 532, "TR0(U)" },
2980 { 536, "TR1(L)" },
2981 { 540, "TR1(U)" },
2982 { 544, "TR2(L)" },
2983 { 548, "TR2(U)" },
2984 { 552, "TR3(L)" },
2985 { 556, "TR3(U)" },
2986 { 560, "TR4(L)" },
2987 { 564, "TR4(U)" },
2988 { 568, "TR5(L)" },
2989 { 572, "TR5(U)" },
2990 { 576, "TR6(L)" },
2991 { 580, "TR6(U)" },
2992 { 584, "TR7(L)" },
2993 { 588, "TR7(U)" },
Denys Vlasenkoadedb512008-12-30 18:47:55 +00002994 /* This entry is in case pt_regs contains dregs (depends on
2995 the kernel build options). */
Roland McGrathe1e584b2003-06-02 19:18:58 +00002996 { uoff(regs), "offsetof(struct user, regs)" },
2997 { uoff(fpu), "offsetof(struct user, fpu)" },
2998#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002999#ifdef ARM
3000 { uoff(regs.ARM_r0), "r0" },
3001 { uoff(regs.ARM_r1), "r1" },
3002 { uoff(regs.ARM_r2), "r2" },
3003 { uoff(regs.ARM_r3), "r3" },
3004 { uoff(regs.ARM_r4), "r4" },
3005 { uoff(regs.ARM_r5), "r5" },
3006 { uoff(regs.ARM_r6), "r6" },
3007 { uoff(regs.ARM_r7), "r7" },
3008 { uoff(regs.ARM_r8), "r8" },
3009 { uoff(regs.ARM_r9), "r9" },
3010 { uoff(regs.ARM_r10), "r10" },
3011 { uoff(regs.ARM_fp), "fp" },
3012 { uoff(regs.ARM_ip), "ip" },
3013 { uoff(regs.ARM_sp), "sp" },
3014 { uoff(regs.ARM_lr), "lr" },
3015 { uoff(regs.ARM_pc), "pc" },
3016 { uoff(regs.ARM_cpsr), "cpsr" },
3017#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00003018
Roland McGrath542c2c62008-05-20 01:11:56 +00003019#ifdef MIPS
3020 { 0, "r0" },
3021 { 1, "r1" },
3022 { 2, "r2" },
3023 { 3, "r3" },
3024 { 4, "r4" },
3025 { 5, "r5" },
3026 { 6, "r6" },
3027 { 7, "r7" },
3028 { 8, "r8" },
3029 { 9, "r9" },
3030 { 10, "r10" },
3031 { 11, "r11" },
3032 { 12, "r12" },
3033 { 13, "r13" },
3034 { 14, "r14" },
3035 { 15, "r15" },
3036 { 16, "r16" },
3037 { 17, "r17" },
3038 { 18, "r18" },
3039 { 19, "r19" },
3040 { 20, "r20" },
3041 { 21, "r21" },
3042 { 22, "r22" },
3043 { 23, "r23" },
3044 { 24, "r24" },
3045 { 25, "r25" },
3046 { 26, "r26" },
3047 { 27, "r27" },
3048 { 28, "r28" },
3049 { 29, "r29" },
3050 { 30, "r30" },
3051 { 31, "r31" },
3052 { 32, "f0" },
3053 { 33, "f1" },
3054 { 34, "f2" },
3055 { 35, "f3" },
3056 { 36, "f4" },
3057 { 37, "f5" },
3058 { 38, "f6" },
3059 { 39, "f7" },
3060 { 40, "f8" },
3061 { 41, "f9" },
3062 { 42, "f10" },
3063 { 43, "f11" },
3064 { 44, "f12" },
3065 { 45, "f13" },
3066 { 46, "f14" },
3067 { 47, "f15" },
3068 { 48, "f16" },
3069 { 49, "f17" },
3070 { 50, "f18" },
3071 { 51, "f19" },
3072 { 52, "f20" },
3073 { 53, "f21" },
3074 { 54, "f22" },
3075 { 55, "f23" },
3076 { 56, "f24" },
3077 { 57, "f25" },
3078 { 58, "f26" },
3079 { 59, "f27" },
3080 { 60, "f28" },
3081 { 61, "f29" },
3082 { 62, "f30" },
3083 { 63, "f31" },
3084 { 64, "pc" },
3085 { 65, "cause" },
3086 { 66, "badvaddr" },
3087 { 67, "mmhi" },
3088 { 68, "mmlo" },
3089 { 69, "fpcsr" },
3090 { 70, "fpeir" },
3091#endif
3092
Dmitry V. Levin87ea1f42008-11-10 22:21:41 +00003093#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(BFIN)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003094 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00003095#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00003096#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003097 { uoff(i387), "offsetof(struct user, i387)" },
3098#else /* !I386 */
3099#ifdef M68K
3100 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3101#endif /* M68K */
3102#endif /* !I386 */
3103 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3104 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3105 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003106#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003107 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003108#endif
Roland McGrathf5a47772003-06-26 22:40:42 +00003109#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00003110 { uoff(start_data), "offsetof(struct user, start_data)" },
3111#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003112#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003113 { uoff(start_stack), "offsetof(struct user, start_stack)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003114#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003115 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003116#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003117 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00003118#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003119#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003120 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003121#endif
Dmitry V. Levin87ea1f42008-11-10 22:21:41 +00003122#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003123 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3124#endif
3125 { uoff(magic), "offsetof(struct user, magic)" },
3126 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00003127#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003128 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3129#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00003130#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003131#endif /* !ALPHA */
3132#endif /* !POWERPC/!SPARC */
3133#endif /* LINUX */
3134#ifdef SUNOS4
3135 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3136 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3137 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3138 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3139 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3140 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3141 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3142 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3143 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3144 { uoff(u_error), "offsetof(struct user, u_error)" },
3145 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3146 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3147 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3148 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3149 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3150 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3151 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3152 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3153 { uoff(u_code), "offsetof(struct user, u_code)" },
3154 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3155 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3156 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3157 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3158 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3159 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3160 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3161 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3162 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3163 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3164 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3165 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3166 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3167 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3168 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3169 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3170 { uoff(u_start), "offsetof(struct user, u_start)" },
3171 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3172 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3173 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3174 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3175 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3176 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3177 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3178 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3179 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3180#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00003181#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003182 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00003183#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003184 { 0, NULL },
3185};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003186#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003187
3188int
3189sys_ptrace(tcp)
3190struct tcb *tcp;
3191{
Roland McGrathd9f816f2004-09-04 03:39:20 +00003192 const struct xlat *x;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003193 long addr;
3194
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003195 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00003196 printxval(ptrace_cmds, tcp->u_arg[0],
3197#ifndef FREEBSD
3198 "PTRACE_???"
3199#else
3200 "PT_???"
3201#endif
3202 );
3203 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003204 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003205#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003206 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3207 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3208 for (x = struct_user_offsets; x->str; x++) {
3209 if (x->val >= addr)
3210 break;
3211 }
3212 if (!x->str)
3213 tprintf("%#lx, ", addr);
3214 else if (x->val > addr && x != struct_user_offsets) {
3215 x--;
3216 tprintf("%s + %ld, ", x->str, addr - x->val);
3217 }
3218 else
3219 tprintf("%s, ", x->str);
3220 }
3221 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003222#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003223 tprintf("%#lx, ", tcp->u_arg[2]);
3224#ifdef LINUX
3225 switch (tcp->u_arg[0]) {
Roland McGrath1e868062007-11-19 22:11:45 +00003226#ifndef IA64
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003227 case PTRACE_PEEKDATA:
3228 case PTRACE_PEEKTEXT:
3229 case PTRACE_PEEKUSER:
3230 break;
Roland McGrath1e868062007-11-19 22:11:45 +00003231#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003232 case PTRACE_CONT:
3233 case PTRACE_SINGLESTEP:
3234 case PTRACE_SYSCALL:
3235 case PTRACE_DETACH:
3236 printsignal(tcp->u_arg[3]);
3237 break;
Denys Vlasenkof535b542009-01-13 18:30:55 +00003238#ifdef PTRACE_SETOPTIONS
3239 case PTRACE_SETOPTIONS:
3240 printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
3241 break;
3242#endif
3243#ifdef PTRACE_SETSIGINFO
3244 case PTRACE_SETSIGINFO: {
3245 siginfo_t si;
3246 if (!tcp->u_arg[3])
3247 tprintf("NULL");
3248 else if (syserror(tcp))
3249 tprintf("%#lx", tcp->u_arg[3]);
3250 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3251 tprintf("{???}");
3252 else
3253 printsiginfo(&si, verbose(tcp));
3254 break;
3255 }
3256#endif
3257#ifdef PTRACE_GETSIGINFO
3258 case PTRACE_GETSIGINFO:
3259 /* Don't print anything, do it at syscall return. */
3260 break;
3261#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003262 default:
3263 tprintf("%#lx", tcp->u_arg[3]);
3264 break;
3265 }
3266 } else {
3267 switch (tcp->u_arg[0]) {
3268 case PTRACE_PEEKDATA:
3269 case PTRACE_PEEKTEXT:
3270 case PTRACE_PEEKUSER:
Roland McGrath1e868062007-11-19 22:11:45 +00003271#ifdef IA64
3272 return RVAL_HEX;
3273#else
Roland McGratheb285352003-01-14 09:59:00 +00003274 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003275 break;
Roland McGrath1e868062007-11-19 22:11:45 +00003276#endif
Denys Vlasenkof535b542009-01-13 18:30:55 +00003277#ifdef PTRACE_GETSIGINFO
3278 case PTRACE_GETSIGINFO: {
3279 siginfo_t si;
3280 if (!tcp->u_arg[3])
3281 tprintf("NULL");
3282 else if (syserror(tcp))
3283 tprintf("%#lx", tcp->u_arg[3]);
3284 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3285 tprintf("{???}");
3286 else
3287 printsiginfo(&si, verbose(tcp));
3288 break;
3289 }
3290#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003291 }
3292 }
3293#endif /* LINUX */
3294#ifdef SUNOS4
3295 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3296 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3297 tprintf("%lu, ", tcp->u_arg[3]);
3298 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3299 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3300 tcp->u_arg[0] != PTRACE_READTEXT) {
3301 tprintf("%#lx", tcp->u_arg[3]);
3302 }
3303 } else {
3304 if (tcp->u_arg[0] == PTRACE_READDATA ||
3305 tcp->u_arg[0] == PTRACE_READTEXT) {
3306 tprintf("%lu, ", tcp->u_arg[3]);
3307 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3308 }
3309 }
3310#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003311#ifdef FREEBSD
3312 tprintf("%lu", tcp->u_arg[3]);
3313 }
3314#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003315 return 0;
3316}
3317
3318#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00003319
3320#ifdef LINUX
Roland McGrath51942a92007-07-05 18:59:11 +00003321# ifndef FUTEX_CMP_REQUEUE
3322# define FUTEX_CMP_REQUEUE 4
3323# endif
3324# ifndef FUTEX_WAKE_OP
3325# define FUTEX_WAKE_OP 5
3326# endif
3327# ifndef FUTEX_LOCK_PI
3328# define FUTEX_LOCK_PI 6
3329# define FUTEX_UNLOCK_PI 7
3330# define FUTEX_TRYLOCK_PI 8
3331# endif
Roland McGrath1aeaf742008-07-18 01:27:39 +00003332# ifndef FUTEX_WAIT_BITSET
3333# define FUTEX_WAIT_BITSET 9
3334# endif
3335# ifndef FUTEX_WAKE_BITSET
3336# define FUTEX_WAKE_BITSET 10
Roland McGrath51942a92007-07-05 18:59:11 +00003337# endif
3338# ifndef FUTEX_PRIVATE_FLAG
3339# define FUTEX_PRIVATE_FLAG 128
3340# endif
Roland McGrathd9f816f2004-09-04 03:39:20 +00003341static const struct xlat futexops[] = {
Roland McGrath51942a92007-07-05 18:59:11 +00003342 { FUTEX_WAIT, "FUTEX_WAIT" },
3343 { FUTEX_WAKE, "FUTEX_WAKE" },
3344 { FUTEX_FD, "FUTEX_FD" },
3345 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3346 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3347 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3348 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3349 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3350 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
Roland McGrath1aeaf742008-07-18 01:27:39 +00003351 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3352 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
Roland McGrath51942a92007-07-05 18:59:11 +00003353 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3354 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3355 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3356 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3357 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3358 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3359 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3360 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3361 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
Roland McGrath1aeaf742008-07-18 01:27:39 +00003362 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3363 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
Roland McGrath51942a92007-07-05 18:59:11 +00003364 { 0, NULL }
3365};
3366#ifndef FUTEX_OP_SET
3367# define FUTEX_OP_SET 0
3368# define FUTEX_OP_ADD 1
3369# define FUTEX_OP_OR 2
3370# define FUTEX_OP_ANDN 3
3371# define FUTEX_OP_XOR 4
3372# define FUTEX_OP_CMP_EQ 0
3373# define FUTEX_OP_CMP_NE 1
3374# define FUTEX_OP_CMP_LT 2
3375# define FUTEX_OP_CMP_LE 3
3376# define FUTEX_OP_CMP_GT 4
3377# define FUTEX_OP_CMP_GE 5
3378#endif
3379static const struct xlat futexwakeops[] = {
3380 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3381 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3382 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3383 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3384 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3385 { 0, NULL }
3386};
3387static const struct xlat futexwakecmps[] = {
3388 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3389 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3390 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3391 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3392 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3393 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3394 { 0, NULL }
Roland McGrath5a223472002-12-15 23:58:26 +00003395};
3396
3397int
3398sys_futex(tcp)
3399struct tcb *tcp;
3400{
3401 if (entering(tcp)) {
Roland McGrath1aeaf742008-07-18 01:27:39 +00003402 long int cmd = tcp->u_arg[1] & 127;
Roland McGrath5a223472002-12-15 23:58:26 +00003403 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00003404 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003405 tprintf(", %ld", tcp->u_arg[2]);
Roland McGrath1aeaf742008-07-18 01:27:39 +00003406 if (cmd == FUTEX_WAKE_BITSET)
3407 tprintf(", %lx", tcp->u_arg[5]);
3408 else if (cmd == FUTEX_WAIT) {
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003409 tprintf(", ");
3410 printtv(tcp, tcp->u_arg[3]);
Roland McGrath1aeaf742008-07-18 01:27:39 +00003411 } else if (cmd == FUTEX_WAIT_BITSET) {
3412 tprintf(", ");
3413 printtv(tcp, tcp->u_arg[3]);
3414 tprintf(", %lx", tcp->u_arg[5]);
Roland McGrath51942a92007-07-05 18:59:11 +00003415 } else if (cmd == FUTEX_REQUEUE)
Roland McGrath88812d62003-06-26 22:27:23 +00003416 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath51942a92007-07-05 18:59:11 +00003417 else if (cmd == FUTEX_CMP_REQUEUE)
3418 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3419 else if (cmd == FUTEX_WAKE_OP) {
3420 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3421 if ((tcp->u_arg[5] >> 28) & 8)
3422 tprintf("FUTEX_OP_OPARG_SHIFT|");
3423 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3424 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3425 if ((tcp->u_arg[5] >> 24) & 8)
3426 tprintf("FUTEX_OP_OPARG_SHIFT|");
3427 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3428 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3429 }
Roland McGrath5a223472002-12-15 23:58:26 +00003430 }
3431 return 0;
3432}
3433
3434static void
Roland McGrath79fbda52004-04-14 02:45:55 +00003435print_affinitylist(tcp, list, len)
3436struct tcb *tcp;
3437long list;
Roland McGrath5a223472002-12-15 23:58:26 +00003438unsigned int len;
3439{
3440 int first = 1;
3441 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00003442 while (len >= sizeof (unsigned long)) {
Roland McGrath79fbda52004-04-14 02:45:55 +00003443 unsigned long w;
3444 umove(tcp, list, &w);
3445 tprintf("%s %lx", first ? "" : ",", w);
Roland McGrath5a223472002-12-15 23:58:26 +00003446 first = 0;
3447 len -= sizeof (unsigned long);
Roland McGrath79fbda52004-04-14 02:45:55 +00003448 list += sizeof(unsigned long);
Roland McGrath5a223472002-12-15 23:58:26 +00003449 }
3450 tprintf(" }");
3451}
3452
3453int
3454sys_sched_setaffinity(tcp)
3455struct tcb *tcp;
3456{
3457 if (entering(tcp)) {
3458 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath79fbda52004-04-14 02:45:55 +00003459 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
Roland McGrath5a223472002-12-15 23:58:26 +00003460 }
3461 return 0;
3462}
3463
3464int
3465sys_sched_getaffinity(tcp)
3466struct tcb *tcp;
3467{
3468 if (entering(tcp)) {
3469 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3470 } else {
Roland McGrath79fbda52004-04-14 02:45:55 +00003471 if (tcp->u_rval == -1)
3472 tprintf("%#lx", tcp->u_arg[2]);
3473 else
3474 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
Roland McGrath5a223472002-12-15 23:58:26 +00003475 }
3476 return 0;
3477}
Roland McGrath279d3782004-03-01 20:27:37 +00003478
Roland McGrathd9f816f2004-09-04 03:39:20 +00003479static const struct xlat schedulers[] = {
Roland McGrath279d3782004-03-01 20:27:37 +00003480 { SCHED_OTHER, "SCHED_OTHER" },
3481 { SCHED_RR, "SCHED_RR" },
3482 { SCHED_FIFO, "SCHED_FIFO" },
3483 { 0, NULL }
3484};
3485
3486int
3487sys_sched_getscheduler(tcp)
3488struct tcb *tcp;
3489{
3490 if (entering(tcp)) {
3491 tprintf("%d", (int) tcp->u_arg[0]);
3492 } else if (! syserror(tcp)) {
3493 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3494 if (tcp->auxstr != NULL)
3495 return RVAL_STR;
3496 }
3497 return 0;
3498}
3499
3500int
3501sys_sched_setscheduler(tcp)
3502struct tcb *tcp;
3503{
3504 if (entering(tcp)) {
3505 struct sched_param p;
3506 tprintf("%d, ", (int) tcp->u_arg[0]);
3507 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3508 if (umove(tcp, tcp->u_arg[2], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003509 tprintf(", %#lx", tcp->u_arg[2]);
Roland McGrath279d3782004-03-01 20:27:37 +00003510 else
3511 tprintf(", { %d }", p.__sched_priority);
3512 }
3513 return 0;
3514}
3515
3516int
3517sys_sched_getparam(tcp)
3518struct tcb *tcp;
3519{
3520 if (entering(tcp)) {
3521 tprintf("%d, ", (int) tcp->u_arg[0]);
3522 } else {
3523 struct sched_param p;
3524 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003525 tprintf("%#lx", tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003526 else
3527 tprintf("{ %d }", p.__sched_priority);
3528 }
3529 return 0;
3530}
3531
3532int
3533sys_sched_setparam(tcp)
3534struct tcb *tcp;
3535{
3536 if (entering(tcp)) {
3537 struct sched_param p;
3538 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003539 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003540 else
3541 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3542 }
3543 return 0;
3544}
3545
3546int
3547sys_sched_get_priority_min(tcp)
3548struct tcb *tcp;
3549{
3550 if (entering(tcp)) {
3551 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3552 }
3553 return 0;
3554}
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003555
3556#ifdef X86_64
3557#include <asm/prctl.h>
3558
3559static const struct xlat archvals[] = {
3560 { ARCH_SET_GS, "ARCH_SET_GS" },
3561 { ARCH_SET_FS, "ARCH_SET_FS" },
3562 { ARCH_GET_FS, "ARCH_GET_FS" },
3563 { ARCH_GET_GS, "ARCH_GET_GS" },
3564 { 0, NULL },
3565};
3566
3567int
3568sys_arch_prctl(tcp)
3569struct tcb *tcp;
3570{
3571 if (entering(tcp)) {
3572 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3573 if (tcp->u_arg[0] == ARCH_SET_GS
3574 || tcp->u_arg[0] == ARCH_SET_FS)
3575 tprintf(", %#lx", tcp->u_arg[1]);
3576 } else {
3577 if (tcp->u_arg[0] == ARCH_GET_GS
3578 || tcp->u_arg[0] == ARCH_GET_FS) {
3579 long int v;
3580 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3581 tprintf(", [%#lx]", v);
3582 else
3583 tprintf(", %#lx", tcp->u_arg[1]);
3584 }
3585 }
3586 return 0;
3587}
3588#endif
3589
Roland McGrathdb8319f2007-08-02 01:37:55 +00003590
3591int
3592sys_getcpu(tcp)
3593struct tcb *tcp;
3594{
3595 if (exiting(tcp)) {
3596 unsigned u;
3597 if (tcp->u_arg[0] == 0)
3598 tprintf("NULL, ");
3599 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3600 tprintf("%#lx, ", tcp->u_arg[0]);
3601 else
3602 tprintf("[%u], ", u);
3603 if (tcp->u_arg[1] == 0)
3604 tprintf("NULL, ");
3605 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3606 tprintf("%#lx, ", tcp->u_arg[1]);
3607 else
3608 tprintf("[%u], ", u);
3609 tprintf("%#lx", tcp->u_arg[2]);
3610 }
3611 return 0;
3612}
3613
Roland McGrath5a223472002-12-15 23:58:26 +00003614#endif