blob: f95add37b01d16b90b63a93ff86a54a6363caa1d [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("= ?");
463 printtrailer(tcp);
464 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;
Roland McGrath43b286f2003-01-10 11:14:41 +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)
Roland McGrathac971c22003-03-31 01:03:33 +0000778 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
Wichert Akkermanccef6372002-05-01 16:39:22 +0000779 return -1;
780 return 0;
Roland McGrathf5a47772003-06-26 22:40:42 +0000781#elif defined(SH64)
Roland McGrathe1e584b2003-06-02 19:18:58 +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)
789 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
790# ifndef PTRACE_SET_SYSCALL
791# define PTRACE_SET_SYSCALL 23
792# endif
793
794 if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new) != 0)
795 return -1;
796
797 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
815 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
816 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
857 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
858 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)
867 {
868 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;
877 }
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);
966 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
967 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
968 return -1;
969 }
970
971 if (!qflag)
972 fprintf(stderr, "\
973Process %u resumed (parent %d ready)\n",
974 pid, tcp->pid);
975 }
976 else {
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000977 if (!qflag)
978 fprintf(stderr, "Process %d attached\n", pid);
979 }
980
981#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000982 {
983 /*
984 * Save the flags used in this call,
985 * in case we point TCP to our parent below.
986 */
987 int call_flags = tcp->u_arg[ARG_FLAGS];
988 if ((tcp->flags & TCB_CLONE_THREAD) &&
989 tcp->parent != NULL) {
990 /* The parent in this clone is itself a
991 thread belonging to another process.
992 There is no meaning to the parentage
993 relationship of the new child with the
994 thread, only with the process. We
995 associate the new thread with our
996 parent. Since this is done for every
997 new thread, there will never be a
998 TCB_CLONE_THREAD process that has
999 children. */
1000 --tcp->nchildren;
1001 tcp = tcp->parent;
1002 tcpchild->parent = tcp;
1003 ++tcp->nchildren;
1004 }
1005 if (call_flags & CLONE_THREAD) {
1006 tcpchild->flags |= TCB_CLONE_THREAD;
1007 ++tcp->nclone_threads;
1008 }
1009 if (call_flags & CLONE_DETACHED) {
1010 tcpchild->flags |= TCB_CLONE_DETACHED;
1011 ++tcp->nclone_detached;
1012 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001013 }
1014#endif
1015
1016 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +00001017 return 0;
1018}
1019#endif
1020
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001021int
1022internal_fork(tcp)
1023struct tcb *tcp;
1024{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001025#ifdef LINUX
1026 /* We do special magic with clone for any clone or fork. */
1027 return internal_clone(tcp);
1028#else
1029
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001030 struct tcb *tcpchild;
1031 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +00001032 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001033
1034#ifdef SYS_vfork
Roland McGratha4f9f2d2005-06-07 23:21:20 +00001035 if (known_scno(tcp) == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +00001036 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath41c48222008-07-18 00:25:10 +00001037 if (change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +00001038 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +00001039 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001040#endif
1041 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +00001042 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001043 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +00001044 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001045 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001046 if (setbpt(tcp) < 0)
1047 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +00001048 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001049 else {
1050 int bpt = tcp->flags & TCB_BPTSET;
1051
1052 if (!(tcp->flags & TCB_FOLLOWFORK))
1053 return 0;
1054 if (bpt)
1055 clearbpt(tcp);
1056
1057 if (syserror(tcp))
1058 return 0;
1059
1060 pid = tcp->u_rval;
Dmitry V. Levin76860f62006-10-11 22:55:25 +00001061 if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001062 kill(pid, SIGKILL); /* XXX */
1063 return 0;
1064 }
1065#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +00001066#ifdef HPPA
1067 /* The child must have run before it can be attached. */
1068 /* This must be a bug in the parisc kernel, but I havn't
1069 * identified it yet. Seems to be an issue associated
1070 * with attaching to a process (which sends it a signal)
1071 * before that process has ever been scheduled. When
1072 * debugging, I started seeing crashes in
1073 * arch/parisc/kernel/signal.c:do_signal(), apparently
1074 * caused by r8 getting corrupt over the dequeue_signal()
1075 * call. Didn't make much sense though...
1076 */
1077 {
1078 struct timeval tv;
1079 tv.tv_sec = 0;
1080 tv.tv_usec = 10000;
1081 select(0, NULL, NULL, NULL, &tv);
1082 }
1083#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001084 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
1085 perror("PTRACE_ATTACH");
1086 fprintf(stderr, "Too late?\n");
1087 droptcb(tcpchild);
1088 return 0;
1089 }
1090#endif /* LINUX */
1091#ifdef SUNOS4
1092#ifdef oldway
1093 /* The child must have run before it can be attached. */
1094 {
1095 struct timeval tv;
1096 tv.tv_sec = 0;
1097 tv.tv_usec = 10000;
1098 select(0, NULL, NULL, NULL, &tv);
1099 }
1100 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1101 perror("PTRACE_ATTACH");
1102 fprintf(stderr, "Too late?\n");
1103 droptcb(tcpchild);
1104 return 0;
1105 }
1106#else /* !oldway */
1107 /* Try to catch the new process as soon as possible. */
1108 {
1109 int i;
1110 for (i = 0; i < 1024; i++)
1111 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1112 break;
1113 if (i == 1024) {
1114 perror("PTRACE_ATTACH");
1115 fprintf(stderr, "Too late?\n");
1116 droptcb(tcpchild);
1117 return 0;
1118 }
1119 }
1120#endif /* !oldway */
1121#endif /* SUNOS4 */
1122 tcpchild->flags |= TCB_ATTACHED;
1123 /* Child has BPT too, must be removed on first occasion */
1124 if (bpt) {
1125 tcpchild->flags |= TCB_BPTSET;
1126 tcpchild->baddr = tcp->baddr;
1127 memcpy(tcpchild->inst, tcp->inst,
1128 sizeof tcpchild->inst);
1129 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001130 tcpchild->parent = tcp;
1131 tcp->nchildren++;
1132 if (!qflag)
1133 fprintf(stderr, "Process %d attached\n", pid);
1134 }
1135 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001136#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001137}
1138
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001139#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001140
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001141#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001142
1143int
1144sys_vfork(tcp)
1145struct tcb *tcp;
1146{
1147 if (exiting(tcp))
1148 return RVAL_UDECIMAL;
1149 return 0;
1150}
1151
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001152#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001153
1154#ifndef LINUX
1155
1156static char idstr[16];
1157
1158int
1159sys_getpid(tcp)
1160struct tcb *tcp;
1161{
1162 if (exiting(tcp)) {
1163 sprintf(idstr, "ppid %lu", getrval2(tcp));
1164 tcp->auxstr = idstr;
1165 return RVAL_STR;
1166 }
1167 return 0;
1168}
1169
1170int
1171sys_getuid(tcp)
1172struct tcb *tcp;
1173{
1174 if (exiting(tcp)) {
1175 sprintf(idstr, "euid %lu", getrval2(tcp));
1176 tcp->auxstr = idstr;
1177 return RVAL_STR;
1178 }
1179 return 0;
1180}
1181
1182int
1183sys_getgid(tcp)
1184struct tcb *tcp;
1185{
1186 if (exiting(tcp)) {
1187 sprintf(idstr, "egid %lu", getrval2(tcp));
1188 tcp->auxstr = idstr;
1189 return RVAL_STR;
1190 }
1191 return 0;
1192}
1193
1194#endif /* !LINUX */
1195
1196#ifdef LINUX
1197
1198int
1199sys_setuid(tcp)
1200struct tcb *tcp;
1201{
1202 if (entering(tcp)) {
1203 tprintf("%u", (uid_t) tcp->u_arg[0]);
1204 }
1205 return 0;
1206}
1207
1208int
1209sys_setgid(tcp)
1210struct tcb *tcp;
1211{
1212 if (entering(tcp)) {
1213 tprintf("%u", (gid_t) tcp->u_arg[0]);
1214 }
1215 return 0;
1216}
1217
1218int
1219sys_getresuid(tcp)
1220 struct tcb *tcp;
1221{
1222 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001223 __kernel_uid_t uid;
1224 if (syserror(tcp))
1225 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1226 tcp->u_arg[1], tcp->u_arg[2]);
1227 else {
1228 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1229 tprintf("%#lx, ", tcp->u_arg[0]);
1230 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001231 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001232 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1233 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001234 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001235 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001236 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1237 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001238 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001239 tprintf("[%lu]", (unsigned long) uid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001240 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001241 }
1242 return 0;
1243}
1244
1245int
1246sys_getresgid(tcp)
1247struct tcb *tcp;
1248{
1249 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001250 __kernel_gid_t gid;
1251 if (syserror(tcp))
1252 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1253 tcp->u_arg[1], tcp->u_arg[2]);
1254 else {
1255 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1256 tprintf("%#lx, ", tcp->u_arg[0]);
1257 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001258 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001259 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1260 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001261 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001262 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001263 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1264 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001265 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001266 tprintf("[%lu]", (unsigned long) gid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001267 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001268 }
1269 return 0;
1270}
1271
1272#endif /* LINUX */
1273
1274int
1275sys_setreuid(tcp)
1276struct tcb *tcp;
1277{
1278 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001279 printuid("", tcp->u_arg[0]);
1280 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001281 }
1282 return 0;
1283}
1284
1285int
1286sys_setregid(tcp)
1287struct tcb *tcp;
1288{
1289 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001290 printuid("", tcp->u_arg[0]);
1291 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001292 }
1293 return 0;
1294}
1295
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001296#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001297int
1298sys_setresuid(tcp)
1299 struct tcb *tcp;
1300{
1301 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001302 printuid("", tcp->u_arg[0]);
1303 printuid(", ", tcp->u_arg[1]);
1304 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001305 }
1306 return 0;
1307}
1308int
1309sys_setresgid(tcp)
1310 struct tcb *tcp;
1311{
1312 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001313 printuid("", tcp->u_arg[0]);
1314 printuid(", ", tcp->u_arg[1]);
1315 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001316 }
1317 return 0;
1318}
1319
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001320#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001321
1322int
1323sys_setgroups(tcp)
1324struct tcb *tcp;
1325{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001326 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001327 unsigned long len, size, start, cur, end, abbrev_end;
1328 GETGROUPS_T gid;
1329 int failed = 0;
1330
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001331 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001332 tprintf("%lu, ", len);
1333 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001334 tprintf("[]");
1335 return 0;
1336 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001337 start = tcp->u_arg[1];
1338 if (start == 0) {
1339 tprintf("NULL");
1340 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001341 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001342 size = len * sizeof(gid);
1343 end = start + size;
1344 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1345 tprintf("%#lx", start);
1346 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001347 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001348 if (abbrev(tcp)) {
1349 abbrev_end = start + max_strlen * sizeof(gid);
1350 if (abbrev_end < start)
1351 abbrev_end = end;
1352 } else {
1353 abbrev_end = end;
1354 }
1355 tprintf("[");
1356 for (cur = start; cur < end; cur += sizeof(gid)) {
1357 if (cur > start)
1358 tprintf(", ");
1359 if (cur >= abbrev_end) {
1360 tprintf("...");
1361 break;
1362 }
1363 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1364 tprintf("?");
1365 failed = 1;
1366 break;
1367 }
1368 tprintf("%lu", (unsigned long) gid);
1369 }
1370 tprintf("]");
1371 if (failed)
1372 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001373 }
1374 return 0;
1375}
1376
1377int
1378sys_getgroups(tcp)
1379struct tcb *tcp;
1380{
Roland McGrathaa524c82005-06-01 19:22:06 +00001381 unsigned long len;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001382
1383 if (entering(tcp)) {
1384 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001385 tprintf("%lu, ", len);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001386 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001387 unsigned long size, start, cur, end, abbrev_end;
1388 GETGROUPS_T gid;
1389 int failed = 0;
1390
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001391 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001392 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001393 tprintf("[]");
1394 return 0;
1395 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001396 start = tcp->u_arg[1];
1397 if (start == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001398 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001399 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001400 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001401 if (tcp->u_arg[0] == 0) {
1402 tprintf("%#lx", start);
1403 return 0;
1404 }
1405 size = len * sizeof(gid);
1406 end = start + size;
1407 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1408 size / sizeof(gid) != len || end < start) {
1409 tprintf("%#lx", start);
1410 return 0;
1411 }
1412 if (abbrev(tcp)) {
1413 abbrev_end = start + max_strlen * sizeof(gid);
1414 if (abbrev_end < start)
1415 abbrev_end = end;
1416 } else {
1417 abbrev_end = end;
1418 }
1419 tprintf("[");
1420 for (cur = start; cur < end; cur += sizeof(gid)) {
1421 if (cur > start)
1422 tprintf(", ");
1423 if (cur >= abbrev_end) {
1424 tprintf("...");
1425 break;
1426 }
1427 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1428 tprintf("?");
1429 failed = 1;
1430 break;
1431 }
1432 tprintf("%lu", (unsigned long) gid);
1433 }
1434 tprintf("]");
1435 if (failed)
1436 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001437 }
1438 return 0;
1439}
1440
Roland McGrath83bd47a2003-11-13 22:32:26 +00001441#ifdef LINUX
1442int
1443sys_setgroups32(tcp)
1444struct tcb *tcp;
1445{
Roland McGrath83bd47a2003-11-13 22:32:26 +00001446 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001447 unsigned long len, size, start, cur, end, abbrev_end;
1448 GETGROUPS32_T gid;
1449 int failed = 0;
1450
Roland McGrath83bd47a2003-11-13 22:32:26 +00001451 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001452 tprintf("%lu, ", len);
1453 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001454 tprintf("[]");
1455 return 0;
1456 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001457 start = tcp->u_arg[1];
1458 if (start == 0) {
1459 tprintf("NULL");
1460 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001461 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001462 size = len * sizeof(gid);
1463 end = start + size;
1464 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1465 tprintf("%#lx", start);
1466 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001467 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001468 if (abbrev(tcp)) {
1469 abbrev_end = start + max_strlen * sizeof(gid);
1470 if (abbrev_end < start)
1471 abbrev_end = end;
1472 } else {
1473 abbrev_end = end;
1474 }
1475 tprintf("[");
1476 for (cur = start; cur < end; cur += sizeof(gid)) {
1477 if (cur > start)
1478 tprintf(", ");
1479 if (cur >= abbrev_end) {
1480 tprintf("...");
1481 break;
1482 }
1483 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1484 tprintf("?");
1485 failed = 1;
1486 break;
1487 }
1488 tprintf("%lu", (unsigned long) gid);
1489 }
1490 tprintf("]");
1491 if (failed)
1492 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001493 }
1494 return 0;
1495}
1496
1497int
1498sys_getgroups32(tcp)
1499struct tcb *tcp;
1500{
Roland McGrathaa524c82005-06-01 19:22:06 +00001501 unsigned long len;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001502
1503 if (entering(tcp)) {
1504 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001505 tprintf("%lu, ", len);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001506 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001507 unsigned long size, start, cur, end, abbrev_end;
1508 GETGROUPS32_T gid;
1509 int failed = 0;
1510
Roland McGrath83bd47a2003-11-13 22:32:26 +00001511 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001512 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001513 tprintf("[]");
1514 return 0;
1515 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001516 start = tcp->u_arg[1];
1517 if (start == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001518 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001519 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001520 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001521 size = len * sizeof(gid);
1522 end = start + size;
1523 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1524 size / sizeof(gid) != len || end < start) {
1525 tprintf("%#lx", start);
1526 return 0;
1527 }
1528 if (abbrev(tcp)) {
1529 abbrev_end = start + max_strlen * sizeof(gid);
1530 if (abbrev_end < start)
1531 abbrev_end = end;
1532 } else {
1533 abbrev_end = end;
1534 }
1535 tprintf("[");
1536 for (cur = start; cur < end; cur += sizeof(gid)) {
1537 if (cur > start)
1538 tprintf(", ");
1539 if (cur >= abbrev_end) {
1540 tprintf("...");
1541 break;
1542 }
1543 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1544 tprintf("?");
1545 failed = 1;
1546 break;
1547 }
1548 tprintf("%lu", (unsigned long) gid);
1549 }
1550 tprintf("]");
1551 if (failed)
1552 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001553 }
1554 return 0;
1555}
1556#endif /* LINUX */
1557
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001558#if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001559int
1560sys_setpgrp(tcp)
1561struct tcb *tcp;
1562{
1563 if (entering(tcp)) {
1564#ifndef SVR4
1565 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1566#endif /* !SVR4 */
1567 }
1568 return 0;
1569}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001570#endif /* ALPHA || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001571
1572int
1573sys_getpgrp(tcp)
1574struct tcb *tcp;
1575{
1576 if (entering(tcp)) {
1577#ifndef SVR4
1578 tprintf("%lu", tcp->u_arg[0]);
1579#endif /* !SVR4 */
1580 }
1581 return 0;
1582}
1583
1584int
1585sys_getsid(tcp)
1586struct tcb *tcp;
1587{
1588 if (entering(tcp)) {
1589 tprintf("%lu", tcp->u_arg[0]);
1590 }
1591 return 0;
1592}
1593
1594int
1595sys_setsid(tcp)
1596struct tcb *tcp;
1597{
1598 return 0;
1599}
1600
1601int
1602sys_getpgid(tcp)
1603struct tcb *tcp;
1604{
1605 if (entering(tcp)) {
1606 tprintf("%lu", tcp->u_arg[0]);
1607 }
1608 return 0;
1609}
1610
1611int
1612sys_setpgid(tcp)
1613struct tcb *tcp;
1614{
1615 if (entering(tcp)) {
1616 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1617 }
1618 return 0;
1619}
1620
John Hughesc61eb3d2002-05-17 11:37:50 +00001621#if UNIXWARE >= 2
1622
1623#include <sys/privilege.h>
1624
1625
Roland McGrathd9f816f2004-09-04 03:39:20 +00001626static const struct xlat procpriv_cmds [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001627 { SETPRV, "SETPRV" },
1628 { CLRPRV, "CLRPRV" },
1629 { PUTPRV, "PUTPRV" },
1630 { GETPRV, "GETPRV" },
1631 { CNTPRV, "CNTPRV" },
1632 { 0, NULL },
1633};
1634
1635
Roland McGrathd9f816f2004-09-04 03:39:20 +00001636static const struct xlat procpriv_priv [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001637 { P_OWNER, "P_OWNER" },
1638 { P_AUDIT, "P_AUDIT" },
1639 { P_COMPAT, "P_COMPAT" },
1640 { P_DACREAD, "P_DACREAD" },
1641 { P_DACWRITE, "P_DACWRITE" },
1642 { P_DEV, "P_DEV" },
1643 { P_FILESYS, "P_FILESYS" },
1644 { P_MACREAD, "P_MACREAD" },
1645 { P_MACWRITE, "P_MACWRITE" },
1646 { P_MOUNT, "P_MOUNT" },
1647 { P_MULTIDIR, "P_MULTIDIR" },
1648 { P_SETPLEVEL, "P_SETPLEVEL" },
1649 { P_SETSPRIV, "P_SETSPRIV" },
1650 { P_SETUID, "P_SETUID" },
1651 { P_SYSOPS, "P_SYSOPS" },
1652 { P_SETUPRIV, "P_SETUPRIV" },
1653 { P_DRIVER, "P_DRIVER" },
1654 { P_RTIME, "P_RTIME" },
1655 { P_MACUPGRADE, "P_MACUPGRADE" },
1656 { P_FSYSRANGE, "P_FSYSRANGE" },
1657 { P_SETFLEVEL, "P_SETFLEVEL" },
1658 { P_AUDITWR, "P_AUDITWR" },
1659 { P_TSHAR, "P_TSHAR" },
1660 { P_PLOCK, "P_PLOCK" },
1661 { P_CORE, "P_CORE" },
1662 { P_LOADMOD, "P_LOADMOD" },
1663 { P_BIND, "P_BIND" },
1664 { P_ALLPRIVS, "P_ALLPRIVS" },
1665 { 0, NULL },
1666};
1667
1668
Roland McGrathd9f816f2004-09-04 03:39:20 +00001669static const struct xlat procpriv_type [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001670 { PS_FIX, "PS_FIX" },
1671 { PS_INH, "PS_INH" },
1672 { PS_MAX, "PS_MAX" },
1673 { PS_WKG, "PS_WKG" },
1674 { 0, NULL },
1675};
1676
1677
1678static void
Dmitry V. Levinab9008b2007-01-11 22:05:04 +00001679printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
John Hughesc61eb3d2002-05-17 11:37:50 +00001680{
1681 priv_t buf [128];
1682 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1683 int dots = len > max;
1684 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001685
John Hughesc61eb3d2002-05-17 11:37:50 +00001686 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001687
John Hughesc61eb3d2002-05-17 11:37:50 +00001688 if (len <= 0 ||
1689 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1690 {
1691 tprintf ("%#lx", addr);
1692 return;
1693 }
1694
1695 tprintf ("[");
1696
1697 for (i = 0; i < len; ++i) {
Dmitry V. Levinab9008b2007-01-11 22:05:04 +00001698 const char *t, *p;
John Hughesc61eb3d2002-05-17 11:37:50 +00001699
1700 if (i) tprintf (", ");
1701
1702 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1703 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1704 {
1705 tprintf ("%s|%s", t, p);
1706 }
1707 else {
1708 tprintf ("%#lx", buf [i]);
1709 }
1710 }
1711
1712 if (dots) tprintf (" ...");
1713
1714 tprintf ("]");
1715}
1716
1717
1718int
1719sys_procpriv(tcp)
1720struct tcb *tcp;
1721{
1722 if (entering(tcp)) {
1723 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1724 switch (tcp->u_arg[0]) {
1725 case CNTPRV:
1726 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1727 break;
1728
1729 case GETPRV:
1730 break;
1731
1732 default:
1733 tprintf (", ");
1734 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1735 tprintf (", %ld", tcp->u_arg[2]);
1736 }
1737 }
1738 else if (tcp->u_arg[0] == GETPRV) {
1739 if (syserror (tcp)) {
1740 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1741 }
1742 else {
1743 tprintf (", ");
1744 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1745 tprintf (", %ld", tcp->u_arg[2]);
1746 }
1747 }
Roland McGrath5a223472002-12-15 23:58:26 +00001748
John Hughesc61eb3d2002-05-17 11:37:50 +00001749 return 0;
1750}
1751
1752#endif
1753
1754
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001755static void
1756printargv(tcp, addr)
1757struct tcb *tcp;
1758long addr;
1759{
Roland McGrath85a3bc42007-08-02 02:13:05 +00001760 union {
1761 int p32;
1762 long p64;
1763 char data[sizeof(long)];
1764 } cp;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001765 char *sep;
Roland McGrath85a3bc42007-08-02 02:13:05 +00001766 int n = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001767
Roland McGrath85a3bc42007-08-02 02:13:05 +00001768 cp.p64 = 1;
1769 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1770 if (umoven(tcp, addr, personality_wordsize[current_personality],
1771 cp.data) < 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001772 tprintf("%#lx", addr);
1773 return;
1774 }
Roland McGrath85a3bc42007-08-02 02:13:05 +00001775 if (personality_wordsize[current_personality] == 4)
1776 cp.p64 = cp.p32;
1777 if (cp.p64 == 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001778 break;
1779 tprintf(sep);
Roland McGrath85a3bc42007-08-02 02:13:05 +00001780 printstr(tcp, cp.p64, -1);
1781 addr += personality_wordsize[current_personality];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001782 }
Roland McGrath85a3bc42007-08-02 02:13:05 +00001783 if (cp.p64)
1784 tprintf("%s...", sep);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001785}
1786
1787static void
1788printargc(fmt, tcp, addr)
1789char *fmt;
1790struct tcb *tcp;
1791long addr;
1792{
1793 int count;
1794 char *cp;
1795
1796 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1797 addr += sizeof(char *);
1798 }
1799 tprintf(fmt, count, count == 1 ? "" : "s");
1800}
1801
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001802#if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001803int
1804sys_execv(tcp)
1805struct tcb *tcp;
1806{
1807 if (entering(tcp)) {
1808 printpath(tcp, tcp->u_arg[0]);
1809 if (!verbose(tcp))
1810 tprintf(", %#lx", tcp->u_arg[1]);
1811#if 0
1812 else if (abbrev(tcp))
1813 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1814#endif
1815 else {
1816 tprintf(", [");
1817 printargv(tcp, tcp->u_arg[1]);
1818 tprintf("]");
1819 }
1820 }
1821 return 0;
1822}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001823#endif /* SPARC || SPARC64 || SUNOS4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001824
1825int
1826sys_execve(tcp)
1827struct tcb *tcp;
1828{
1829 if (entering(tcp)) {
1830 printpath(tcp, tcp->u_arg[0]);
1831 if (!verbose(tcp))
1832 tprintf(", %#lx", tcp->u_arg[1]);
1833#if 0
1834 else if (abbrev(tcp))
1835 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1836#endif
1837 else {
1838 tprintf(", [");
1839 printargv(tcp, tcp->u_arg[1]);
1840 tprintf("]");
1841 }
1842 if (!verbose(tcp))
1843 tprintf(", %#lx", tcp->u_arg[2]);
1844 else if (abbrev(tcp))
1845 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1846 else {
1847 tprintf(", [");
1848 printargv(tcp, tcp->u_arg[2]);
1849 tprintf("]");
1850 }
1851 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001852 return 0;
1853}
1854
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001855#if UNIXWARE > 2
John Hughes4e36a812001-04-18 15:11:51 +00001856
1857int sys_rexecve(tcp)
1858struct tcb *tcp;
1859{
1860 if (entering (tcp)) {
1861 sys_execve (tcp);
1862 tprintf (", %ld", tcp->u_arg[3]);
1863 }
1864 return 0;
1865}
1866
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001867#endif
John Hughes4e36a812001-04-18 15:11:51 +00001868
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001869int
1870internal_exec(tcp)
1871struct tcb *tcp;
1872{
1873#ifdef SUNOS4
1874 if (exiting(tcp) && !syserror(tcp) && followfork)
1875 fixvfork(tcp);
1876#endif /* SUNOS4 */
Roland McGrathfdb097f2004-07-12 07:38:55 +00001877#if defined LINUX && defined TCB_WAITEXECVE
1878 if (exiting(tcp) && syserror(tcp))
1879 tcp->flags &= ~TCB_WAITEXECVE;
1880 else
1881 tcp->flags |= TCB_WAITEXECVE;
1882#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001883 return 0;
1884}
1885
1886#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001887#ifndef __WNOTHREAD
1888#define __WNOTHREAD 0x20000000
1889#endif
1890#ifndef __WALL
1891#define __WALL 0x40000000
1892#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001893#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001894#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001895#endif
1896#endif /* LINUX */
1897
Roland McGrathd9f816f2004-09-04 03:39:20 +00001898static const struct xlat wait4_options[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001899 { WNOHANG, "WNOHANG" },
1900#ifndef WSTOPPED
1901 { WUNTRACED, "WUNTRACED" },
1902#endif
1903#ifdef WEXITED
1904 { WEXITED, "WEXITED" },
1905#endif
1906#ifdef WTRAPPED
1907 { WTRAPPED, "WTRAPPED" },
1908#endif
1909#ifdef WSTOPPED
1910 { WSTOPPED, "WSTOPPED" },
1911#endif
1912#ifdef WCONTINUED
1913 { WCONTINUED, "WCONTINUED" },
1914#endif
1915#ifdef WNOWAIT
1916 { WNOWAIT, "WNOWAIT" },
1917#endif
1918#ifdef __WCLONE
1919 { __WCLONE, "__WCLONE" },
1920#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001921#ifdef __WALL
1922 { __WALL, "__WALL" },
1923#endif
1924#ifdef __WNOTHREAD
1925 { __WNOTHREAD, "__WNOTHREAD" },
1926#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001927 { 0, NULL },
1928};
1929
Roland McGrath5e02a572004-10-19 23:33:47 +00001930#if !defined WCOREFLAG && defined WCOREFLG
1931# define WCOREFLAG WCOREFLG
1932#endif
1933#ifndef WCOREFLAG
1934#define WCOREFLAG 0x80
1935#endif
1936
1937#ifndef W_STOPCODE
1938#define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1939#endif
1940#ifndef W_EXITCODE
1941#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1942#endif
1943
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001944static int
1945printstatus(status)
1946int status;
1947{
1948 int exited = 0;
1949
1950 /*
1951 * Here is a tricky presentation problem. This solution
1952 * is still not entirely satisfactory but since there
1953 * are no wait status constructors it will have to do.
1954 */
Roland McGrath79fbda52004-04-14 02:45:55 +00001955 if (WIFSTOPPED(status)) {
1956 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001957 signame(WSTOPSIG(status)));
Roland McGrath79fbda52004-04-14 02:45:55 +00001958 status &= ~W_STOPCODE(WSTOPSIG(status));
1959 }
1960 else if (WIFSIGNALED(status)) {
1961 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001962 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001963 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
Roland McGrath79fbda52004-04-14 02:45:55 +00001964 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1965 }
1966 else if (WIFEXITED(status)) {
1967 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001968 WEXITSTATUS(status));
1969 exited = 1;
Roland McGrath79fbda52004-04-14 02:45:55 +00001970 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001971 }
Roland McGrath79fbda52004-04-14 02:45:55 +00001972 else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001973 tprintf("[%#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001974 return 0;
1975 }
1976
1977 if (status == 0)
1978 tprintf("]");
1979 else
Roland McGrathf8cc83c2004-06-04 01:24:07 +00001980 tprintf(" | %#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001981
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001982 return exited;
1983}
1984
1985static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001986printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001987struct tcb *tcp;
1988int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001989int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001990{
1991 int status;
1992 int exited = 0;
1993
1994 if (entering(tcp)) {
Roland McGrath5b63d962008-07-18 02:16:47 +00001995 /*
1996 * Sign-extend a 32-bit value when that's what it is.
1997 */
1998 long pid = tcp->u_arg[0];
1999 if (personality_wordsize[current_personality] < sizeof pid)
2000 pid = (long) (int) pid;
2001 tprintf("%ld, ", pid);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002002 } else {
2003 /* status */
2004 if (!tcp->u_arg[1])
2005 tprintf("NULL");
2006 else if (syserror(tcp) || tcp->u_rval == 0)
2007 tprintf("%#lx", tcp->u_arg[1]);
2008 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
2009 tprintf("[?]");
2010 else
2011 exited = printstatus(status);
2012 /* options */
2013 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00002014 printflags(wait4_options, tcp->u_arg[2], "W???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002015 if (n == 4) {
2016 tprintf(", ");
2017 /* usage */
2018 if (!tcp->u_arg[3])
2019 tprintf("NULL");
2020#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002021 else if (tcp->u_rval > 0) {
2022#ifdef LINUX_64BIT
2023 if (bitness)
2024 printrusage32(tcp, tcp->u_arg[3]);
2025 else
2026#endif
2027 printrusage(tcp, tcp->u_arg[3]);
2028 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002029#endif /* LINUX */
2030#ifdef SUNOS4
2031 else if (tcp->u_rval > 0 && exited)
2032 printrusage(tcp, tcp->u_arg[3]);
2033#endif /* SUNOS4 */
2034 else
2035 tprintf("%#lx", tcp->u_arg[3]);
2036 }
2037 }
2038 return 0;
2039}
2040
2041int
Roland McGrathc74c0b72004-09-01 19:39:46 +00002042internal_wait(tcp, flagarg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002043struct tcb *tcp;
Roland McGrathc74c0b72004-09-01 19:39:46 +00002044int flagarg;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002045{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002046 int got_kids;
2047
2048#ifdef TCB_CLONE_THREAD
2049 if (tcp->flags & TCB_CLONE_THREAD)
2050 /* The children we wait for are our parent's children. */
2051 got_kids = (tcp->parent->nchildren
2052 > tcp->parent->nclone_detached);
2053 else
2054 got_kids = (tcp->nchildren > tcp->nclone_detached);
2055#else
2056 got_kids = tcp->nchildren > 0;
2057#endif
2058
2059 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00002060 /* There are children that this parent should block for.
2061 But ptrace made us the parent of the traced children
2062 and the real parent will get ECHILD from the wait call.
2063
2064 XXX If we attached with strace -f -p PID, then there
2065 may be untraced dead children the parent could be reaping
2066 now, but we make him block. */
2067
2068 /* ??? WTA: fix bug with hanging children */
2069
Roland McGrathc74c0b72004-09-01 19:39:46 +00002070 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00002071 /*
2072 * There are traced children. We'll make the parent
2073 * block to avoid a false ECHILD error due to our
2074 * ptrace having stolen the children. However,
2075 * we shouldn't block if there are zombies to reap.
2076 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
2077 */
Roland McGrathfccfb942003-10-01 21:59:44 +00002078 struct tcb *child = NULL;
Roland McGrath09623452003-05-23 02:27:13 +00002079 if (tcp->nzombies > 0 &&
2080 (tcp->u_arg[0] == -1 ||
Roland McGrathfccfb942003-10-01 21:59:44 +00002081 (child = pid2tcb(tcp->u_arg[0])) == NULL))
Roland McGrath09623452003-05-23 02:27:13 +00002082 return 0;
Roland McGrathfccfb942003-10-01 21:59:44 +00002083 if (tcp->u_arg[0] > 0) {
2084 /*
2085 * If the parent waits for a specified child
2086 * PID, then it must get ECHILD right away
2087 * if that PID is not one of its children.
2088 * Make sure that the requested PID matches
2089 * one of the parent's children that we are
2090 * tracing, and don't suspend it otherwise.
2091 */
2092 if (child == NULL)
2093 child = pid2tcb(tcp->u_arg[0]);
2094 if (child == NULL || child->parent != (
2095#ifdef TCB_CLONE_THREAD
2096 (tcp->flags & TCB_CLONE_THREAD)
2097 ? tcp->parent :
2098#endif
Roland McGrathd56a6562005-08-03 11:23:43 +00002099 tcp) ||
2100 (child->flags & TCB_EXITING))
Roland McGrathfccfb942003-10-01 21:59:44 +00002101 return 0;
2102 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002103 tcp->flags |= TCB_SUSPENDED;
2104 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002105#ifdef TCB_CLONE_THREAD
2106 if (tcp->flags & TCB_CLONE_THREAD)
2107 tcp->parent->nclone_waiting++;
2108#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002109 }
2110 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002111 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathc74c0b72004-09-01 19:39:46 +00002112 if (tcp->u_arg[flagarg] & WNOHANG) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00002113 /* We must force a fake result of 0 instead of
2114 the ECHILD error. */
2115 extern int force_result();
2116 return force_result(tcp, 0, 0);
2117 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00002118 }
Roland McGrath09623452003-05-23 02:27:13 +00002119 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2120 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2121 /*
2122 * We just reaped a child we don't know about,
2123 * presumably a zombie we already droptcb'd.
2124 */
2125 tcp->nzombies--;
2126 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002127 return 0;
2128}
2129
2130#ifdef SVR4
2131
2132int
2133sys_wait(tcp)
2134struct tcb *tcp;
2135{
2136 if (exiting(tcp)) {
2137 /* The library wrapper stuffs this into the user variable. */
2138 if (!syserror(tcp))
2139 printstatus(getrval2(tcp));
2140 }
2141 return 0;
2142}
2143
2144#endif /* SVR4 */
2145
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002146#ifdef FREEBSD
2147int
2148sys_wait(tcp)
2149struct tcb *tcp;
2150{
2151 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00002152
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002153 if (exiting(tcp)) {
2154 if (!syserror(tcp)) {
2155 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2156 tprintf("%#lx", tcp->u_arg[0]);
2157 else
2158 printstatus(status);
2159 }
2160 }
2161 return 0;
2162}
2163#endif
2164
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002165int
2166sys_waitpid(tcp)
2167struct tcb *tcp;
2168{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002169 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002170}
2171
2172int
2173sys_wait4(tcp)
2174struct tcb *tcp;
2175{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002176 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002177}
2178
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002179#ifdef ALPHA
2180int
2181sys_osf_wait4(tcp)
2182struct tcb *tcp;
2183{
2184 return printwaitn(tcp, 4, 1);
2185}
2186#endif
2187
Roland McGrathc74c0b72004-09-01 19:39:46 +00002188#if defined SVR4 || defined LINUX
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002189
Roland McGrathd9f816f2004-09-04 03:39:20 +00002190static const struct xlat waitid_types[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002191 { P_PID, "P_PID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002192#ifdef P_PPID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002193 { P_PPID, "P_PPID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002194#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002195 { P_PGID, "P_PGID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002196#ifdef P_SID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002197 { P_SID, "P_SID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002198#endif
2199#ifdef P_CID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002200 { P_CID, "P_CID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002201#endif
2202#ifdef P_UID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002203 { P_UID, "P_UID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002204#endif
2205#ifdef P_GID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002206 { P_GID, "P_GID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002207#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002208 { P_ALL, "P_ALL" },
2209#ifdef P_LWPID
2210 { P_LWPID, "P_LWPID" },
2211#endif
2212 { 0, NULL },
2213};
2214
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002215int
2216sys_waitid(tcp)
2217struct tcb *tcp;
2218{
2219 siginfo_t si;
2220 int exited;
2221
2222 if (entering(tcp)) {
2223 printxval(waitid_types, tcp->u_arg[0], "P_???");
2224 tprintf(", %ld, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002225 }
2226 else {
2227 /* siginfo */
2228 exited = 0;
2229 if (!tcp->u_arg[2])
2230 tprintf("NULL");
2231 else if (syserror(tcp))
2232 tprintf("%#lx", tcp->u_arg[2]);
2233 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2234 tprintf("{???}");
2235 else
John Hughes58265892001-10-18 15:13:53 +00002236 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002237 /* options */
2238 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00002239 printflags(wait4_options, tcp->u_arg[3], "W???");
Roland McGrath39426a32004-10-06 22:02:59 +00002240 if (tcp->u_nargs > 4) {
2241 /* usage */
2242 tprintf(", ");
2243 if (!tcp->u_arg[4])
2244 tprintf("NULL");
2245 else if (tcp->u_error)
2246 tprintf("%#lx", tcp->u_arg[4]);
2247 else
2248 printrusage(tcp, tcp->u_arg[4]);
2249 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002250 }
2251 return 0;
2252}
2253
Roland McGrathc74c0b72004-09-01 19:39:46 +00002254#endif /* SVR4 or LINUX */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002255
2256int
2257sys_alarm(tcp)
2258struct tcb *tcp;
2259{
2260 if (entering(tcp))
2261 tprintf("%lu", tcp->u_arg[0]);
2262 return 0;
2263}
2264
2265int
2266sys_uname(tcp)
2267struct tcb *tcp;
2268{
2269 struct utsname uname;
2270
2271 if (exiting(tcp)) {
2272 if (syserror(tcp) || !verbose(tcp))
2273 tprintf("%#lx", tcp->u_arg[0]);
2274 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2275 tprintf("{...}");
2276 else if (!abbrev(tcp)) {
2277
2278 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2279 uname.sysname, uname.nodename);
2280 tprintf("release=\"%s\", version=\"%s\", ",
2281 uname.release, uname.version);
2282 tprintf("machine=\"%s\"", uname.machine);
2283#ifdef LINUX
2284#ifndef __GLIBC__
2285 tprintf(", domainname=\"%s\"", uname.domainname);
2286#endif /* __GLIBC__ */
2287#endif /* LINUX */
2288 tprintf("}");
2289 }
2290 else
2291 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2292 uname.sysname, uname.nodename);
2293 }
2294 return 0;
2295}
2296
2297#ifndef SVR4
2298
Roland McGrathd9f816f2004-09-04 03:39:20 +00002299static const struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002300#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002301 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2302 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2303 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2304 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2305 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2306 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2307 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2308 { PTRACE_CONT, "PTRACE_CONT" },
2309 { PTRACE_KILL, "PTRACE_KILL" },
2310 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2311 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2312 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002313#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002314 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002315#endif
2316#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002317 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002318#endif
2319#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002320 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002321#endif
2322#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002323 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002324#endif
2325#ifdef PTRACE_GETFPXREGS
2326 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2327#endif
2328#ifdef PTRACE_SETFPXREGS
2329 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2330#endif
Roland McGrathf04bb482005-05-09 07:45:33 +00002331#ifdef PTRACE_GETVRREGS
2332 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2333#endif
2334#ifdef PTRACE_SETVRREGS
2335 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2336#endif
Roland McGrathbf621d42003-01-14 09:46:21 +00002337#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002338 { PTRACE_READDATA, "PTRACE_READDATA" },
2339 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2340 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2341 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2342 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2343 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2344#ifdef SPARC
2345 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2346 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2347#else /* !SPARC */
2348 { PTRACE_22, "PTRACE_PTRACE_22" },
2349 { PTRACE_23, "PTRACE_PTRACE_23" },
2350#endif /* !SPARC */
2351#endif /* SUNOS4 */
2352 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2353#ifdef SUNOS4
2354 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2355#ifdef I386
2356 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2357 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2358 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2359#else /* !I386 */
2360 { PTRACE_26, "PTRACE_26" },
2361 { PTRACE_27, "PTRACE_27" },
2362 { PTRACE_28, "PTRACE_28" },
2363#endif /* !I386 */
2364 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2365#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002366#else /* FREEBSD */
2367 { PT_TRACE_ME, "PT_TRACE_ME" },
2368 { PT_READ_I, "PT_READ_I" },
2369 { PT_READ_D, "PT_READ_D" },
2370 { PT_WRITE_I, "PT_WRITE_I" },
2371 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002372#ifdef PT_READ_U
2373 { PT_READ_U, "PT_READ_U" },
2374#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002375 { PT_CONTINUE, "PT_CONTINUE" },
2376 { PT_KILL, "PT_KILL" },
2377 { PT_STEP, "PT_STEP" },
2378 { PT_ATTACH, "PT_ATTACH" },
2379 { PT_DETACH, "PT_DETACH" },
2380 { PT_GETREGS, "PT_GETREGS" },
2381 { PT_SETREGS, "PT_SETREGS" },
2382 { PT_GETFPREGS, "PT_GETFPREGS" },
2383 { PT_SETFPREGS, "PT_SETFPREGS" },
2384 { PT_GETDBREGS, "PT_GETDBREGS" },
2385 { PT_SETDBREGS, "PT_SETDBREGS" },
2386#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002387 { 0, NULL },
2388};
2389
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002390#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002391#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2392static
2393#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
Roland McGrathd9f816f2004-09-04 03:39:20 +00002394const struct xlat struct_user_offsets[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002395#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002396#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002397 { PT_PSWMASK, "psw_mask" },
2398 { PT_PSWADDR, "psw_addr" },
2399 { PT_GPR0, "gpr0" },
2400 { PT_GPR1, "gpr1" },
2401 { PT_GPR2, "gpr2" },
2402 { PT_GPR3, "gpr3" },
2403 { PT_GPR4, "gpr4" },
2404 { PT_GPR5, "gpr5" },
2405 { PT_GPR6, "gpr6" },
2406 { PT_GPR7, "gpr7" },
2407 { PT_GPR8, "gpr8" },
2408 { PT_GPR9, "gpr9" },
2409 { PT_GPR10, "gpr10" },
2410 { PT_GPR11, "gpr11" },
2411 { PT_GPR12, "gpr12" },
2412 { PT_GPR13, "gpr13" },
2413 { PT_GPR14, "gpr14" },
2414 { PT_GPR15, "gpr15" },
2415 { PT_ACR0, "acr0" },
2416 { PT_ACR1, "acr1" },
2417 { PT_ACR2, "acr2" },
2418 { PT_ACR3, "acr3" },
2419 { PT_ACR4, "acr4" },
2420 { PT_ACR5, "acr5" },
2421 { PT_ACR6, "acr6" },
2422 { PT_ACR7, "acr7" },
2423 { PT_ACR8, "acr8" },
2424 { PT_ACR9, "acr9" },
2425 { PT_ACR10, "acr10" },
2426 { PT_ACR11, "acr11" },
2427 { PT_ACR12, "acr12" },
2428 { PT_ACR13, "acr13" },
2429 { PT_ACR14, "acr14" },
2430 { PT_ACR15, "acr15" },
2431 { PT_ORIGGPR2, "orig_gpr2" },
2432 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002433#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002434 { PT_FPR0_HI, "fpr0.hi" },
2435 { PT_FPR0_LO, "fpr0.lo" },
2436 { PT_FPR1_HI, "fpr1.hi" },
2437 { PT_FPR1_LO, "fpr1.lo" },
2438 { PT_FPR2_HI, "fpr2.hi" },
2439 { PT_FPR2_LO, "fpr2.lo" },
2440 { PT_FPR3_HI, "fpr3.hi" },
2441 { PT_FPR3_LO, "fpr3.lo" },
2442 { PT_FPR4_HI, "fpr4.hi" },
2443 { PT_FPR4_LO, "fpr4.lo" },
2444 { PT_FPR5_HI, "fpr5.hi" },
2445 { PT_FPR5_LO, "fpr5.lo" },
2446 { PT_FPR6_HI, "fpr6.hi" },
2447 { PT_FPR6_LO, "fpr6.lo" },
2448 { PT_FPR7_HI, "fpr7.hi" },
2449 { PT_FPR7_LO, "fpr7.lo" },
2450 { PT_FPR8_HI, "fpr8.hi" },
2451 { PT_FPR8_LO, "fpr8.lo" },
2452 { PT_FPR9_HI, "fpr9.hi" },
2453 { PT_FPR9_LO, "fpr9.lo" },
2454 { PT_FPR10_HI, "fpr10.hi" },
2455 { PT_FPR10_LO, "fpr10.lo" },
2456 { PT_FPR11_HI, "fpr11.hi" },
2457 { PT_FPR11_LO, "fpr11.lo" },
2458 { PT_FPR12_HI, "fpr12.hi" },
2459 { PT_FPR12_LO, "fpr12.lo" },
2460 { PT_FPR13_HI, "fpr13.hi" },
2461 { PT_FPR13_LO, "fpr13.lo" },
2462 { PT_FPR14_HI, "fpr14.hi" },
2463 { PT_FPR14_LO, "fpr14.lo" },
2464 { PT_FPR15_HI, "fpr15.hi" },
2465 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002466#endif
2467#if defined(S390X)
2468 { PT_FPR0, "fpr0" },
2469 { PT_FPR1, "fpr1" },
2470 { PT_FPR2, "fpr2" },
2471 { PT_FPR3, "fpr3" },
2472 { PT_FPR4, "fpr4" },
2473 { PT_FPR5, "fpr5" },
2474 { PT_FPR6, "fpr6" },
2475 { PT_FPR7, "fpr7" },
2476 { PT_FPR8, "fpr8" },
2477 { PT_FPR9, "fpr9" },
2478 { PT_FPR10, "fpr10" },
2479 { PT_FPR11, "fpr11" },
2480 { PT_FPR12, "fpr12" },
2481 { PT_FPR13, "fpr13" },
2482 { PT_FPR14, "fpr14" },
2483 { PT_FPR15, "fpr15" },
2484#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002485 { PT_CR_9, "cr9" },
2486 { PT_CR_10, "cr10" },
2487 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002488 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002489#endif
2490#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002491 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002492#elif defined(HPPA)
2493 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002494#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002495#ifndef PT_ORIG_R3
2496#define PT_ORIG_R3 34
2497#endif
Roland McGratheb285352003-01-14 09:59:00 +00002498#define REGSIZE (sizeof(unsigned long))
2499 { REGSIZE*PT_R0, "r0" },
2500 { REGSIZE*PT_R1, "r1" },
2501 { REGSIZE*PT_R2, "r2" },
2502 { REGSIZE*PT_R3, "r3" },
2503 { REGSIZE*PT_R4, "r4" },
2504 { REGSIZE*PT_R5, "r5" },
2505 { REGSIZE*PT_R6, "r6" },
2506 { REGSIZE*PT_R7, "r7" },
2507 { REGSIZE*PT_R8, "r8" },
2508 { REGSIZE*PT_R9, "r9" },
2509 { REGSIZE*PT_R10, "r10" },
2510 { REGSIZE*PT_R11, "r11" },
2511 { REGSIZE*PT_R12, "r12" },
2512 { REGSIZE*PT_R13, "r13" },
2513 { REGSIZE*PT_R14, "r14" },
2514 { REGSIZE*PT_R15, "r15" },
2515 { REGSIZE*PT_R16, "r16" },
2516 { REGSIZE*PT_R17, "r17" },
2517 { REGSIZE*PT_R18, "r18" },
2518 { REGSIZE*PT_R19, "r19" },
2519 { REGSIZE*PT_R20, "r20" },
2520 { REGSIZE*PT_R21, "r21" },
2521 { REGSIZE*PT_R22, "r22" },
2522 { REGSIZE*PT_R23, "r23" },
2523 { REGSIZE*PT_R24, "r24" },
2524 { REGSIZE*PT_R25, "r25" },
2525 { REGSIZE*PT_R26, "r26" },
2526 { REGSIZE*PT_R27, "r27" },
2527 { REGSIZE*PT_R28, "r28" },
2528 { REGSIZE*PT_R29, "r29" },
2529 { REGSIZE*PT_R30, "r30" },
2530 { REGSIZE*PT_R31, "r31" },
2531 { REGSIZE*PT_NIP, "NIP" },
2532 { REGSIZE*PT_MSR, "MSR" },
2533 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2534 { REGSIZE*PT_CTR, "CTR" },
2535 { REGSIZE*PT_LNK, "LNK" },
2536 { REGSIZE*PT_XER, "XER" },
2537 { REGSIZE*PT_CCR, "CCR" },
2538 { REGSIZE*PT_FPR0, "FPR0" },
2539#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002540#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002541#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002542 { 0, "r0" },
2543 { 1, "r1" },
2544 { 2, "r2" },
2545 { 3, "r3" },
2546 { 4, "r4" },
2547 { 5, "r5" },
2548 { 6, "r6" },
2549 { 7, "r7" },
2550 { 8, "r8" },
2551 { 9, "r9" },
2552 { 10, "r10" },
2553 { 11, "r11" },
2554 { 12, "r12" },
2555 { 13, "r13" },
2556 { 14, "r14" },
2557 { 15, "r15" },
2558 { 16, "r16" },
2559 { 17, "r17" },
2560 { 18, "r18" },
2561 { 19, "r19" },
2562 { 20, "r20" },
2563 { 21, "r21" },
2564 { 22, "r22" },
2565 { 23, "r23" },
2566 { 24, "r24" },
2567 { 25, "r25" },
2568 { 26, "r26" },
2569 { 27, "r27" },
2570 { 28, "r28" },
2571 { 29, "gp" },
2572 { 30, "fp" },
2573 { 31, "zero" },
2574 { 32, "fp0" },
2575 { 33, "fp" },
2576 { 34, "fp2" },
2577 { 35, "fp3" },
2578 { 36, "fp4" },
2579 { 37, "fp5" },
2580 { 38, "fp6" },
2581 { 39, "fp7" },
2582 { 40, "fp8" },
2583 { 41, "fp9" },
2584 { 42, "fp10" },
2585 { 43, "fp11" },
2586 { 44, "fp12" },
2587 { 45, "fp13" },
2588 { 46, "fp14" },
2589 { 47, "fp15" },
2590 { 48, "fp16" },
2591 { 49, "fp17" },
2592 { 50, "fp18" },
2593 { 51, "fp19" },
2594 { 52, "fp20" },
2595 { 53, "fp21" },
2596 { 54, "fp22" },
2597 { 55, "fp23" },
2598 { 56, "fp24" },
2599 { 57, "fp25" },
2600 { 58, "fp26" },
2601 { 59, "fp27" },
2602 { 60, "fp28" },
2603 { 61, "fp29" },
2604 { 62, "fp30" },
2605 { 63, "fp31" },
2606 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002607#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002608#ifdef IA64
2609 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2610 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2611 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2612 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2613 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2614 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2615 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2616 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2617 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2618 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2619 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2620 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2621 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2622 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2623 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2624 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2625 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2626 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2627 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2628 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2629 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2630 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2631 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2632 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2633 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2634 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2635 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2636 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2637 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2638 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2639 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2640 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2641 /* switch stack: */
2642 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2643 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2644 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2645 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2646 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2647 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2648 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2649 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2650 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2651 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002652 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2653 { PT_B4, "b4" }, { PT_B5, "b5" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002654 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002655 /* pt_regs */
Roland McGrathca4e10c2004-01-13 10:13:20 +00002656 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2657 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002658 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2659 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2660 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2661 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2662 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2663 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2664 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2665 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2666 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2667 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2668 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2669 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2670 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2671 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2672 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
Roland McGrathfb1bc072004-03-01 21:29:24 +00002673# ifdef PT_AR_CSD
2674 { PT_AR_CSD, "ar.csd" },
2675# endif
2676# ifdef PT_AR_SSD
2677 { PT_AR_SSD, "ar.ssd" },
2678# endif
Roland McGrathca4e10c2004-01-13 10:13:20 +00002679 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002680#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002681#ifdef I386
2682 { 4*EBX, "4*EBX" },
2683 { 4*ECX, "4*ECX" },
2684 { 4*EDX, "4*EDX" },
2685 { 4*ESI, "4*ESI" },
2686 { 4*EDI, "4*EDI" },
2687 { 4*EBP, "4*EBP" },
2688 { 4*EAX, "4*EAX" },
2689 { 4*DS, "4*DS" },
2690 { 4*ES, "4*ES" },
2691 { 4*FS, "4*FS" },
2692 { 4*GS, "4*GS" },
2693 { 4*ORIG_EAX, "4*ORIG_EAX" },
2694 { 4*EIP, "4*EIP" },
2695 { 4*CS, "4*CS" },
2696 { 4*EFL, "4*EFL" },
2697 { 4*UESP, "4*UESP" },
2698 { 4*SS, "4*SS" },
2699#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002700#ifdef X86_64
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002701 { 8*R15, "8*R15" },
2702 { 8*R14, "8*R14" },
2703 { 8*R13, "8*R13" },
2704 { 8*R12, "8*R12" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002705 { 8*RBP, "8*RBP" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002706 { 8*RBX, "8*RBX" },
2707 { 8*R11, "8*R11" },
2708 { 8*R10, "8*R10" },
2709 { 8*R9, "8*R9" },
2710 { 8*R8, "8*R8" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002711 { 8*RAX, "8*RAX" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002712 { 8*RCX, "8*RCX" },
2713 { 8*RDX, "8*RDX" },
2714 { 8*RSI, "8*RSI" },
2715 { 8*RDI, "8*RDI" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002716#if 0
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002717 { DS, "DS" },
2718 { ES, "ES" },
2719 { FS, "FS" },
2720 { GS, "GS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002721#endif
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002722 { 8*ORIG_RAX, "8*ORIG_RAX" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002723 { 8*RIP, "8*RIP" },
2724 { 8*CS, "8*CS" },
2725 { 8*EFLAGS, "8*EFL" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002726 { 8*RSP, "8*RSP" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002727 { 8*SS, "8*SS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002728#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002729#ifdef M68K
2730 { 4*PT_D1, "4*PT_D1" },
2731 { 4*PT_D2, "4*PT_D2" },
2732 { 4*PT_D3, "4*PT_D3" },
2733 { 4*PT_D4, "4*PT_D4" },
2734 { 4*PT_D5, "4*PT_D5" },
2735 { 4*PT_D6, "4*PT_D6" },
2736 { 4*PT_D7, "4*PT_D7" },
2737 { 4*PT_A0, "4*PT_A0" },
2738 { 4*PT_A1, "4*PT_A1" },
2739 { 4*PT_A2, "4*PT_A2" },
2740 { 4*PT_A3, "4*PT_A3" },
2741 { 4*PT_A4, "4*PT_A4" },
2742 { 4*PT_A5, "4*PT_A5" },
2743 { 4*PT_A6, "4*PT_A6" },
2744 { 4*PT_D0, "4*PT_D0" },
2745 { 4*PT_USP, "4*PT_USP" },
2746 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2747 { 4*PT_SR, "4*PT_SR" },
2748 { 4*PT_PC, "4*PT_PC" },
2749#endif /* M68K */
2750#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002751#ifdef SH
2752 { 4*REG_REG0, "4*REG_REG0" },
2753 { 4*(REG_REG0+1), "4*REG_REG1" },
2754 { 4*(REG_REG0+2), "4*REG_REG2" },
2755 { 4*(REG_REG0+3), "4*REG_REG3" },
2756 { 4*(REG_REG0+4), "4*REG_REG4" },
2757 { 4*(REG_REG0+5), "4*REG_REG5" },
2758 { 4*(REG_REG0+6), "4*REG_REG6" },
2759 { 4*(REG_REG0+7), "4*REG_REG7" },
2760 { 4*(REG_REG0+8), "4*REG_REG8" },
2761 { 4*(REG_REG0+9), "4*REG_REG9" },
2762 { 4*(REG_REG0+10), "4*REG_REG10" },
2763 { 4*(REG_REG0+11), "4*REG_REG11" },
2764 { 4*(REG_REG0+12), "4*REG_REG12" },
2765 { 4*(REG_REG0+13), "4*REG_REG13" },
2766 { 4*(REG_REG0+14), "4*REG_REG14" },
2767 { 4*REG_REG15, "4*REG_REG15" },
2768 { 4*REG_PC, "4*REG_PC" },
2769 { 4*REG_PR, "4*REG_PR" },
2770 { 4*REG_SR, "4*REG_SR" },
2771 { 4*REG_GBR, "4*REG_GBR" },
2772 { 4*REG_MACH, "4*REG_MACH" },
2773 { 4*REG_MACL, "4*REG_MACL" },
2774 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2775 { 4*REG_FPUL, "4*REG_FPUL" },
2776 { 4*REG_FPREG0, "4*REG_FPREG0" },
2777 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2778 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2779 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2780 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2781 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2782 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2783 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2784 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2785 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2786 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2787 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2788 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2789 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2790 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2791 { 4*REG_FPREG15, "4*REG_FPREG15" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002792#ifdef REG_XDREG0
Wichert Akkermanccef6372002-05-01 16:39:22 +00002793 { 4*REG_XDREG0, "4*REG_XDREG0" },
2794 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2795 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2796 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2797 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2798 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2799 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2800 { 4*REG_XDREG14, "4*REG_XDREG14" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002801#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002802 { 4*REG_FPSCR, "4*REG_FPSCR" },
2803#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002804#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002805 { 0, "PC(L)" },
2806 { 4, "PC(U)" },
2807 { 8, "SR(L)" },
2808 { 12, "SR(U)" },
2809 { 16, "syscall no.(L)" },
2810 { 20, "syscall_no.(U)" },
2811 { 24, "R0(L)" },
2812 { 28, "R0(U)" },
2813 { 32, "R1(L)" },
2814 { 36, "R1(U)" },
2815 { 40, "R2(L)" },
2816 { 44, "R2(U)" },
2817 { 48, "R3(L)" },
2818 { 52, "R3(U)" },
2819 { 56, "R4(L)" },
2820 { 60, "R4(U)" },
2821 { 64, "R5(L)" },
2822 { 68, "R5(U)" },
2823 { 72, "R6(L)" },
2824 { 76, "R6(U)" },
2825 { 80, "R7(L)" },
2826 { 84, "R7(U)" },
2827 { 88, "R8(L)" },
2828 { 92, "R8(U)" },
2829 { 96, "R9(L)" },
2830 { 100, "R9(U)" },
2831 { 104, "R10(L)" },
2832 { 108, "R10(U)" },
2833 { 112, "R11(L)" },
2834 { 116, "R11(U)" },
2835 { 120, "R12(L)" },
2836 { 124, "R12(U)" },
2837 { 128, "R13(L)" },
2838 { 132, "R13(U)" },
2839 { 136, "R14(L)" },
2840 { 140, "R14(U)" },
2841 { 144, "R15(L)" },
2842 { 148, "R15(U)" },
2843 { 152, "R16(L)" },
2844 { 156, "R16(U)" },
2845 { 160, "R17(L)" },
2846 { 164, "R17(U)" },
2847 { 168, "R18(L)" },
2848 { 172, "R18(U)" },
2849 { 176, "R19(L)" },
2850 { 180, "R19(U)" },
2851 { 184, "R20(L)" },
2852 { 188, "R20(U)" },
2853 { 192, "R21(L)" },
2854 { 196, "R21(U)" },
2855 { 200, "R22(L)" },
2856 { 204, "R22(U)" },
2857 { 208, "R23(L)" },
2858 { 212, "R23(U)" },
2859 { 216, "R24(L)" },
2860 { 220, "R24(U)" },
2861 { 224, "R25(L)" },
2862 { 228, "R25(U)" },
2863 { 232, "R26(L)" },
2864 { 236, "R26(U)" },
2865 { 240, "R27(L)" },
2866 { 244, "R27(U)" },
2867 { 248, "R28(L)" },
2868 { 252, "R28(U)" },
2869 { 256, "R29(L)" },
2870 { 260, "R29(U)" },
2871 { 264, "R30(L)" },
2872 { 268, "R30(U)" },
2873 { 272, "R31(L)" },
2874 { 276, "R31(U)" },
2875 { 280, "R32(L)" },
2876 { 284, "R32(U)" },
2877 { 288, "R33(L)" },
2878 { 292, "R33(U)" },
2879 { 296, "R34(L)" },
2880 { 300, "R34(U)" },
2881 { 304, "R35(L)" },
2882 { 308, "R35(U)" },
2883 { 312, "R36(L)" },
2884 { 316, "R36(U)" },
2885 { 320, "R37(L)" },
2886 { 324, "R37(U)" },
2887 { 328, "R38(L)" },
2888 { 332, "R38(U)" },
2889 { 336, "R39(L)" },
2890 { 340, "R39(U)" },
2891 { 344, "R40(L)" },
2892 { 348, "R40(U)" },
2893 { 352, "R41(L)" },
2894 { 356, "R41(U)" },
2895 { 360, "R42(L)" },
2896 { 364, "R42(U)" },
2897 { 368, "R43(L)" },
2898 { 372, "R43(U)" },
2899 { 376, "R44(L)" },
2900 { 380, "R44(U)" },
2901 { 384, "R45(L)" },
2902 { 388, "R45(U)" },
2903 { 392, "R46(L)" },
2904 { 396, "R46(U)" },
2905 { 400, "R47(L)" },
2906 { 404, "R47(U)" },
2907 { 408, "R48(L)" },
2908 { 412, "R48(U)" },
2909 { 416, "R49(L)" },
2910 { 420, "R49(U)" },
2911 { 424, "R50(L)" },
2912 { 428, "R50(U)" },
2913 { 432, "R51(L)" },
2914 { 436, "R51(U)" },
2915 { 440, "R52(L)" },
2916 { 444, "R52(U)" },
2917 { 448, "R53(L)" },
2918 { 452, "R53(U)" },
2919 { 456, "R54(L)" },
2920 { 460, "R54(U)" },
2921 { 464, "R55(L)" },
2922 { 468, "R55(U)" },
2923 { 472, "R56(L)" },
2924 { 476, "R56(U)" },
2925 { 480, "R57(L)" },
2926 { 484, "R57(U)" },
2927 { 488, "R58(L)" },
2928 { 492, "R58(U)" },
2929 { 496, "R59(L)" },
2930 { 500, "R59(U)" },
2931 { 504, "R60(L)" },
2932 { 508, "R60(U)" },
2933 { 512, "R61(L)" },
2934 { 516, "R61(U)" },
2935 { 520, "R62(L)" },
2936 { 524, "R62(U)" },
2937 { 528, "TR0(L)" },
2938 { 532, "TR0(U)" },
2939 { 536, "TR1(L)" },
2940 { 540, "TR1(U)" },
2941 { 544, "TR2(L)" },
2942 { 548, "TR2(U)" },
2943 { 552, "TR3(L)" },
2944 { 556, "TR3(U)" },
2945 { 560, "TR4(L)" },
2946 { 564, "TR4(U)" },
2947 { 568, "TR5(L)" },
2948 { 572, "TR5(U)" },
2949 { 576, "TR6(L)" },
2950 { 580, "TR6(U)" },
2951 { 584, "TR7(L)" },
2952 { 588, "TR7(U)" },
2953 /* This entry is in case pt_regs contains dregs (depends on
2954 the kernel build options). */
2955 { uoff(regs), "offsetof(struct user, regs)" },
2956 { uoff(fpu), "offsetof(struct user, fpu)" },
2957#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002958#ifdef ARM
2959 { uoff(regs.ARM_r0), "r0" },
2960 { uoff(regs.ARM_r1), "r1" },
2961 { uoff(regs.ARM_r2), "r2" },
2962 { uoff(regs.ARM_r3), "r3" },
2963 { uoff(regs.ARM_r4), "r4" },
2964 { uoff(regs.ARM_r5), "r5" },
2965 { uoff(regs.ARM_r6), "r6" },
2966 { uoff(regs.ARM_r7), "r7" },
2967 { uoff(regs.ARM_r8), "r8" },
2968 { uoff(regs.ARM_r9), "r9" },
2969 { uoff(regs.ARM_r10), "r10" },
2970 { uoff(regs.ARM_fp), "fp" },
2971 { uoff(regs.ARM_ip), "ip" },
2972 { uoff(regs.ARM_sp), "sp" },
2973 { uoff(regs.ARM_lr), "lr" },
2974 { uoff(regs.ARM_pc), "pc" },
2975 { uoff(regs.ARM_cpsr), "cpsr" },
2976#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002977
Roland McGrath542c2c62008-05-20 01:11:56 +00002978#ifdef MIPS
2979 { 0, "r0" },
2980 { 1, "r1" },
2981 { 2, "r2" },
2982 { 3, "r3" },
2983 { 4, "r4" },
2984 { 5, "r5" },
2985 { 6, "r6" },
2986 { 7, "r7" },
2987 { 8, "r8" },
2988 { 9, "r9" },
2989 { 10, "r10" },
2990 { 11, "r11" },
2991 { 12, "r12" },
2992 { 13, "r13" },
2993 { 14, "r14" },
2994 { 15, "r15" },
2995 { 16, "r16" },
2996 { 17, "r17" },
2997 { 18, "r18" },
2998 { 19, "r19" },
2999 { 20, "r20" },
3000 { 21, "r21" },
3001 { 22, "r22" },
3002 { 23, "r23" },
3003 { 24, "r24" },
3004 { 25, "r25" },
3005 { 26, "r26" },
3006 { 27, "r27" },
3007 { 28, "r28" },
3008 { 29, "r29" },
3009 { 30, "r30" },
3010 { 31, "r31" },
3011 { 32, "f0" },
3012 { 33, "f1" },
3013 { 34, "f2" },
3014 { 35, "f3" },
3015 { 36, "f4" },
3016 { 37, "f5" },
3017 { 38, "f6" },
3018 { 39, "f7" },
3019 { 40, "f8" },
3020 { 41, "f9" },
3021 { 42, "f10" },
3022 { 43, "f11" },
3023 { 44, "f12" },
3024 { 45, "f13" },
3025 { 46, "f14" },
3026 { 47, "f15" },
3027 { 48, "f16" },
3028 { 49, "f17" },
3029 { 50, "f18" },
3030 { 51, "f19" },
3031 { 52, "f20" },
3032 { 53, "f21" },
3033 { 54, "f22" },
3034 { 55, "f23" },
3035 { 56, "f24" },
3036 { 57, "f25" },
3037 { 58, "f26" },
3038 { 59, "f27" },
3039 { 60, "f28" },
3040 { 61, "f29" },
3041 { 62, "f30" },
3042 { 63, "f31" },
3043 { 64, "pc" },
3044 { 65, "cause" },
3045 { 66, "badvaddr" },
3046 { 67, "mmhi" },
3047 { 68, "mmlo" },
3048 { 69, "fpcsr" },
3049 { 70, "fpeir" },
3050#endif
3051
Dmitry V. Levin87ea1f42008-11-10 22:21:41 +00003052#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(BFIN)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003053 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00003054#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00003055#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003056 { uoff(i387), "offsetof(struct user, i387)" },
3057#else /* !I386 */
3058#ifdef M68K
3059 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3060#endif /* M68K */
3061#endif /* !I386 */
3062 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3063 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3064 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003065#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003066 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003067#endif
Roland McGrathf5a47772003-06-26 22:40:42 +00003068#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00003069 { uoff(start_data), "offsetof(struct user, start_data)" },
3070#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003071#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003072 { uoff(start_stack), "offsetof(struct user, start_stack)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003073#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003074 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003075#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003076 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00003077#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003078#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003079 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003080#endif
Dmitry V. Levin87ea1f42008-11-10 22:21:41 +00003081#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003082 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3083#endif
3084 { uoff(magic), "offsetof(struct user, magic)" },
3085 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00003086#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003087 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3088#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00003089#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003090#endif /* !ALPHA */
3091#endif /* !POWERPC/!SPARC */
3092#endif /* LINUX */
3093#ifdef SUNOS4
3094 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3095 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3096 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3097 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3098 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3099 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3100 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3101 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3102 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3103 { uoff(u_error), "offsetof(struct user, u_error)" },
3104 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3105 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3106 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3107 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3108 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3109 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3110 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3111 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3112 { uoff(u_code), "offsetof(struct user, u_code)" },
3113 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3114 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3115 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3116 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3117 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3118 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3119 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3120 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3121 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3122 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3123 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3124 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3125 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3126 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3127 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3128 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3129 { uoff(u_start), "offsetof(struct user, u_start)" },
3130 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3131 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3132 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3133 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3134 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3135 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3136 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3137 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3138 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3139#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00003140#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003141 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00003142#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003143 { 0, NULL },
3144};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003145#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003146
3147int
3148sys_ptrace(tcp)
3149struct tcb *tcp;
3150{
Roland McGrathd9f816f2004-09-04 03:39:20 +00003151 const struct xlat *x;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003152 long addr;
3153
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003154 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00003155 printxval(ptrace_cmds, tcp->u_arg[0],
3156#ifndef FREEBSD
3157 "PTRACE_???"
3158#else
3159 "PT_???"
3160#endif
3161 );
3162 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003163 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003164#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003165 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3166 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3167 for (x = struct_user_offsets; x->str; x++) {
3168 if (x->val >= addr)
3169 break;
3170 }
3171 if (!x->str)
3172 tprintf("%#lx, ", addr);
3173 else if (x->val > addr && x != struct_user_offsets) {
3174 x--;
3175 tprintf("%s + %ld, ", x->str, addr - x->val);
3176 }
3177 else
3178 tprintf("%s, ", x->str);
3179 }
3180 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003181#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003182 tprintf("%#lx, ", tcp->u_arg[2]);
3183#ifdef LINUX
3184 switch (tcp->u_arg[0]) {
Roland McGrath1e868062007-11-19 22:11:45 +00003185#ifndef IA64
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003186 case PTRACE_PEEKDATA:
3187 case PTRACE_PEEKTEXT:
3188 case PTRACE_PEEKUSER:
3189 break;
Roland McGrath1e868062007-11-19 22:11:45 +00003190#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003191 case PTRACE_CONT:
3192 case PTRACE_SINGLESTEP:
3193 case PTRACE_SYSCALL:
3194 case PTRACE_DETACH:
3195 printsignal(tcp->u_arg[3]);
3196 break;
3197 default:
3198 tprintf("%#lx", tcp->u_arg[3]);
3199 break;
3200 }
3201 } else {
3202 switch (tcp->u_arg[0]) {
3203 case PTRACE_PEEKDATA:
3204 case PTRACE_PEEKTEXT:
3205 case PTRACE_PEEKUSER:
Roland McGrath1e868062007-11-19 22:11:45 +00003206#ifdef IA64
3207 return RVAL_HEX;
3208#else
Roland McGratheb285352003-01-14 09:59:00 +00003209 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003210 break;
Roland McGrath1e868062007-11-19 22:11:45 +00003211#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003212 }
3213 }
3214#endif /* LINUX */
3215#ifdef SUNOS4
3216 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3217 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3218 tprintf("%lu, ", tcp->u_arg[3]);
3219 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3220 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3221 tcp->u_arg[0] != PTRACE_READTEXT) {
3222 tprintf("%#lx", tcp->u_arg[3]);
3223 }
3224 } else {
3225 if (tcp->u_arg[0] == PTRACE_READDATA ||
3226 tcp->u_arg[0] == PTRACE_READTEXT) {
3227 tprintf("%lu, ", tcp->u_arg[3]);
3228 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3229 }
3230 }
3231#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003232#ifdef FREEBSD
3233 tprintf("%lu", tcp->u_arg[3]);
3234 }
3235#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003236 return 0;
3237}
3238
3239#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00003240
3241#ifdef LINUX
Roland McGrath51942a92007-07-05 18:59:11 +00003242# ifndef FUTEX_CMP_REQUEUE
3243# define FUTEX_CMP_REQUEUE 4
3244# endif
3245# ifndef FUTEX_WAKE_OP
3246# define FUTEX_WAKE_OP 5
3247# endif
3248# ifndef FUTEX_LOCK_PI
3249# define FUTEX_LOCK_PI 6
3250# define FUTEX_UNLOCK_PI 7
3251# define FUTEX_TRYLOCK_PI 8
3252# endif
Roland McGrath1aeaf742008-07-18 01:27:39 +00003253# ifndef FUTEX_WAIT_BITSET
3254# define FUTEX_WAIT_BITSET 9
3255# endif
3256# ifndef FUTEX_WAKE_BITSET
3257# define FUTEX_WAKE_BITSET 10
Roland McGrath51942a92007-07-05 18:59:11 +00003258# endif
3259# ifndef FUTEX_PRIVATE_FLAG
3260# define FUTEX_PRIVATE_FLAG 128
3261# endif
Roland McGrathd9f816f2004-09-04 03:39:20 +00003262static const struct xlat futexops[] = {
Roland McGrath51942a92007-07-05 18:59:11 +00003263 { FUTEX_WAIT, "FUTEX_WAIT" },
3264 { FUTEX_WAKE, "FUTEX_WAKE" },
3265 { FUTEX_FD, "FUTEX_FD" },
3266 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3267 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3268 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3269 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3270 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3271 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
Roland McGrath1aeaf742008-07-18 01:27:39 +00003272 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3273 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
Roland McGrath51942a92007-07-05 18:59:11 +00003274 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3275 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3276 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3277 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3278 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3279 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3280 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3281 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3282 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
Roland McGrath1aeaf742008-07-18 01:27:39 +00003283 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3284 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
Roland McGrath51942a92007-07-05 18:59:11 +00003285 { 0, NULL }
3286};
3287#ifndef FUTEX_OP_SET
3288# define FUTEX_OP_SET 0
3289# define FUTEX_OP_ADD 1
3290# define FUTEX_OP_OR 2
3291# define FUTEX_OP_ANDN 3
3292# define FUTEX_OP_XOR 4
3293# define FUTEX_OP_CMP_EQ 0
3294# define FUTEX_OP_CMP_NE 1
3295# define FUTEX_OP_CMP_LT 2
3296# define FUTEX_OP_CMP_LE 3
3297# define FUTEX_OP_CMP_GT 4
3298# define FUTEX_OP_CMP_GE 5
3299#endif
3300static const struct xlat futexwakeops[] = {
3301 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3302 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3303 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3304 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3305 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3306 { 0, NULL }
3307};
3308static const struct xlat futexwakecmps[] = {
3309 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3310 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3311 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3312 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3313 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3314 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3315 { 0, NULL }
Roland McGrath5a223472002-12-15 23:58:26 +00003316};
3317
3318int
3319sys_futex(tcp)
3320struct tcb *tcp;
3321{
3322 if (entering(tcp)) {
Roland McGrath1aeaf742008-07-18 01:27:39 +00003323 long int cmd = tcp->u_arg[1] & 127;
Roland McGrath5a223472002-12-15 23:58:26 +00003324 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00003325 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003326 tprintf(", %ld", tcp->u_arg[2]);
Roland McGrath1aeaf742008-07-18 01:27:39 +00003327 if (cmd == FUTEX_WAKE_BITSET)
3328 tprintf(", %lx", tcp->u_arg[5]);
3329 else if (cmd == FUTEX_WAIT) {
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003330 tprintf(", ");
3331 printtv(tcp, tcp->u_arg[3]);
Roland McGrath1aeaf742008-07-18 01:27:39 +00003332 } else if (cmd == FUTEX_WAIT_BITSET) {
3333 tprintf(", ");
3334 printtv(tcp, tcp->u_arg[3]);
3335 tprintf(", %lx", tcp->u_arg[5]);
Roland McGrath51942a92007-07-05 18:59:11 +00003336 } else if (cmd == FUTEX_REQUEUE)
Roland McGrath88812d62003-06-26 22:27:23 +00003337 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath51942a92007-07-05 18:59:11 +00003338 else if (cmd == FUTEX_CMP_REQUEUE)
3339 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3340 else if (cmd == FUTEX_WAKE_OP) {
3341 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3342 if ((tcp->u_arg[5] >> 28) & 8)
3343 tprintf("FUTEX_OP_OPARG_SHIFT|");
3344 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3345 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3346 if ((tcp->u_arg[5] >> 24) & 8)
3347 tprintf("FUTEX_OP_OPARG_SHIFT|");
3348 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3349 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3350 }
Roland McGrath5a223472002-12-15 23:58:26 +00003351 }
3352 return 0;
3353}
3354
3355static void
Roland McGrath79fbda52004-04-14 02:45:55 +00003356print_affinitylist(tcp, list, len)
3357struct tcb *tcp;
3358long list;
Roland McGrath5a223472002-12-15 23:58:26 +00003359unsigned int len;
3360{
3361 int first = 1;
3362 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00003363 while (len >= sizeof (unsigned long)) {
Roland McGrath79fbda52004-04-14 02:45:55 +00003364 unsigned long w;
3365 umove(tcp, list, &w);
3366 tprintf("%s %lx", first ? "" : ",", w);
Roland McGrath5a223472002-12-15 23:58:26 +00003367 first = 0;
3368 len -= sizeof (unsigned long);
Roland McGrath79fbda52004-04-14 02:45:55 +00003369 list += sizeof(unsigned long);
Roland McGrath5a223472002-12-15 23:58:26 +00003370 }
3371 tprintf(" }");
3372}
3373
3374int
3375sys_sched_setaffinity(tcp)
3376struct tcb *tcp;
3377{
3378 if (entering(tcp)) {
3379 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath79fbda52004-04-14 02:45:55 +00003380 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
Roland McGrath5a223472002-12-15 23:58:26 +00003381 }
3382 return 0;
3383}
3384
3385int
3386sys_sched_getaffinity(tcp)
3387struct tcb *tcp;
3388{
3389 if (entering(tcp)) {
3390 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3391 } else {
Roland McGrath79fbda52004-04-14 02:45:55 +00003392 if (tcp->u_rval == -1)
3393 tprintf("%#lx", tcp->u_arg[2]);
3394 else
3395 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
Roland McGrath5a223472002-12-15 23:58:26 +00003396 }
3397 return 0;
3398}
Roland McGrath279d3782004-03-01 20:27:37 +00003399
Roland McGrathd9f816f2004-09-04 03:39:20 +00003400static const struct xlat schedulers[] = {
Roland McGrath279d3782004-03-01 20:27:37 +00003401 { SCHED_OTHER, "SCHED_OTHER" },
3402 { SCHED_RR, "SCHED_RR" },
3403 { SCHED_FIFO, "SCHED_FIFO" },
3404 { 0, NULL }
3405};
3406
3407int
3408sys_sched_getscheduler(tcp)
3409struct tcb *tcp;
3410{
3411 if (entering(tcp)) {
3412 tprintf("%d", (int) tcp->u_arg[0]);
3413 } else if (! syserror(tcp)) {
3414 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3415 if (tcp->auxstr != NULL)
3416 return RVAL_STR;
3417 }
3418 return 0;
3419}
3420
3421int
3422sys_sched_setscheduler(tcp)
3423struct tcb *tcp;
3424{
3425 if (entering(tcp)) {
3426 struct sched_param p;
3427 tprintf("%d, ", (int) tcp->u_arg[0]);
3428 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3429 if (umove(tcp, tcp->u_arg[2], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003430 tprintf(", %#lx", tcp->u_arg[2]);
Roland McGrath279d3782004-03-01 20:27:37 +00003431 else
3432 tprintf(", { %d }", p.__sched_priority);
3433 }
3434 return 0;
3435}
3436
3437int
3438sys_sched_getparam(tcp)
3439struct tcb *tcp;
3440{
3441 if (entering(tcp)) {
3442 tprintf("%d, ", (int) tcp->u_arg[0]);
3443 } else {
3444 struct sched_param p;
3445 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003446 tprintf("%#lx", tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003447 else
3448 tprintf("{ %d }", p.__sched_priority);
3449 }
3450 return 0;
3451}
3452
3453int
3454sys_sched_setparam(tcp)
3455struct tcb *tcp;
3456{
3457 if (entering(tcp)) {
3458 struct sched_param p;
3459 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003460 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003461 else
3462 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3463 }
3464 return 0;
3465}
3466
3467int
3468sys_sched_get_priority_min(tcp)
3469struct tcb *tcp;
3470{
3471 if (entering(tcp)) {
3472 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3473 }
3474 return 0;
3475}
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003476
3477#ifdef X86_64
3478#include <asm/prctl.h>
3479
3480static const struct xlat archvals[] = {
3481 { ARCH_SET_GS, "ARCH_SET_GS" },
3482 { ARCH_SET_FS, "ARCH_SET_FS" },
3483 { ARCH_GET_FS, "ARCH_GET_FS" },
3484 { ARCH_GET_GS, "ARCH_GET_GS" },
3485 { 0, NULL },
3486};
3487
3488int
3489sys_arch_prctl(tcp)
3490struct tcb *tcp;
3491{
3492 if (entering(tcp)) {
3493 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3494 if (tcp->u_arg[0] == ARCH_SET_GS
3495 || tcp->u_arg[0] == ARCH_SET_FS)
3496 tprintf(", %#lx", tcp->u_arg[1]);
3497 } else {
3498 if (tcp->u_arg[0] == ARCH_GET_GS
3499 || tcp->u_arg[0] == ARCH_GET_FS) {
3500 long int v;
3501 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3502 tprintf(", [%#lx]", v);
3503 else
3504 tprintf(", %#lx", tcp->u_arg[1]);
3505 }
3506 }
3507 return 0;
3508}
3509#endif
3510
Roland McGrathdb8319f2007-08-02 01:37:55 +00003511
3512int
3513sys_getcpu(tcp)
3514struct tcb *tcp;
3515{
3516 if (exiting(tcp)) {
3517 unsigned u;
3518 if (tcp->u_arg[0] == 0)
3519 tprintf("NULL, ");
3520 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3521 tprintf("%#lx, ", tcp->u_arg[0]);
3522 else
3523 tprintf("[%u], ", u);
3524 if (tcp->u_arg[1] == 0)
3525 tprintf("NULL, ");
3526 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3527 tprintf("%#lx, ", tcp->u_arg[1]);
3528 else
3529 tprintf("[%u], ", u);
3530 tprintf("%#lx", tcp->u_arg[2]);
3531 }
3532 return 0;
3533}
3534
Roland McGrath5a223472002-12-15 23:58:26 +00003535#endif