blob: 8ca94207925a7f47768310663c5ad02954d4a643 [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00005 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Linux for s390 port by D.J. Barrow
8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
Wichert Akkermanccef6372002-05-01 16:39:22 +00009 * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH
10 * port by Greg Banks <gbanks@pocketpenguins.com>
11
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +000012 *
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000013 * All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * $Id$
38 */
39
40#include "defs.h"
41
42#include <fcntl.h>
43#include <sys/stat.h>
44#include <sys/time.h>
45#include <sys/wait.h>
46#include <sys/resource.h>
47#include <sys/utsname.h>
48#include <sys/user.h>
49#include <sys/syscall.h>
50#include <signal.h>
51#ifdef SUNOS4
52#include <machine/reg.h>
53#endif /* SUNOS4 */
54
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +000055#ifdef FREEBSD
56#include <sys/ptrace.h>
57#endif
58
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000059#if HAVE_ASM_REG_H
Roland McGrath6d1a65c2004-07-12 07:44:08 +000060#if defined (SPARC) || defined (SPARC64)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000061# define fpq kernel_fpq
62# define fq kernel_fq
63# define fpu kernel_fpu
Roland McGrath6d1a65c2004-07-12 07:44:08 +000064#endif /* SPARC || SPARC64 */
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000065#include <asm/reg.h>
Roland McGrath6d1a65c2004-07-12 07:44:08 +000066#if defined (SPARC) || defined (SPARC64)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000067# undef fpq
68# undef fq
Roland McGrath5a223472002-12-15 23:58:26 +000069# undef fpu
Roland McGrath6d1a65c2004-07-12 07:44:08 +000070#endif /* SPARC || SPARC64 */
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000071#endif /* HAVE_ASM_REG_H */
72
Wichert Akkerman36915a11999-07-13 15:45:02 +000073#ifdef HAVE_SYS_REG_H
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000074# include <sys/reg.h>
Wichert Akkerman15dea971999-10-06 13:06:34 +000075#ifndef PTRACE_PEEKUSR
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000076# define PTRACE_PEEKUSR PTRACE_PEEKUSER
Wichert Akkerman15dea971999-10-06 13:06:34 +000077#endif
78#ifndef PTRACE_POKEUSR
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000079# define PTRACE_POKEUSR PTRACE_POKEUSER
80#endif
Wichert Akkerman15dea971999-10-06 13:06:34 +000081#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000082
Roland McGrath5bd7cf82003-01-24 04:31:18 +000083#ifdef HAVE_LINUX_PTRACE_H
84#undef PTRACE_SYSCALL
Roland McGrathfb1bc072004-03-01 21:29:24 +000085# ifdef HAVE_STRUCT_IA64_FPREG
86# define ia64_fpreg XXX_ia64_fpreg
87# endif
88# ifdef HAVE_STRUCT_PT_ALL_USER_REGS
89# define pt_all_user_regs XXX_pt_all_user_regs
90# endif
Roland McGrath5bd7cf82003-01-24 04:31:18 +000091#include <linux/ptrace.h>
Roland McGrathfb1bc072004-03-01 21:29:24 +000092# undef ia64_fpreg
93# undef pt_all_user_regs
Roland McGrath5bd7cf82003-01-24 04:31:18 +000094#endif
95
Roland McGrath6d1a65c2004-07-12 07:44:08 +000096#if defined (LINUX) && defined (SPARC64)
97# define r_pc r_tpc
98# undef PTRACE_GETREGS
99# define PTRACE_GETREGS PTRACE_GETREGS64
100# undef PTRACE_SETREGS
101# define PTRACE_SETREGS PTRACE_SETREGS64
102#endif /* LINUX && SPARC64 */
103
Roland McGrath5a223472002-12-15 23:58:26 +0000104#ifdef HAVE_LINUX_FUTEX_H
105#include <linux/futex.h>
106#endif
107#if defined LINUX
108# ifndef FUTEX_WAIT
109# define FUTEX_WAIT 0
110# endif
111# ifndef FUTEX_WAKE
112# define FUTEX_WAKE 1
113# endif
114# ifndef FUTEX_FD
115# define FUTEX_FD 2
116# endif
Roland McGrath88812d62003-06-26 22:27:23 +0000117# ifndef FUTEX_REQUEUE
118# define FUTEX_REQUEUE 3
119# endif
Roland McGrath5a223472002-12-15 23:58:26 +0000120#endif
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000121
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000122#ifdef LINUX
Roland McGrath279d3782004-03-01 20:27:37 +0000123#include <sched.h>
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000124#include <asm/posix_types.h>
125#undef GETGROUPS_T
126#define GETGROUPS_T __kernel_gid_t
Roland McGrath83bd47a2003-11-13 22:32:26 +0000127#undef GETGROUPS32_T
128#define GETGROUPS32_T __kernel_gid32_t
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000129#endif /* LINUX */
130
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000131#if defined(LINUX) && defined(IA64)
132# include <asm/ptrace_offsets.h>
133# include <asm/rse.h>
134#endif
135
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000136#ifdef HAVE_PRCTL
137#include <sys/prctl.h>
138#endif
139
140#ifndef WCOREDUMP
141#define WCOREDUMP(status) ((status) & 0200)
142#endif
143
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000144/* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000145#if defined(HAVE_PRCTL)
Roland McGrathd9f816f2004-09-04 03:39:20 +0000146static const struct xlat prctl_options[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000147#ifdef PR_MAXPROCS
148 { PR_MAXPROCS, "PR_MAXPROCS" },
149#endif
150#ifdef PR_ISBLOCKED
151 { PR_ISBLOCKED, "PR_ISBLOCKED" },
152#endif
153#ifdef PR_SETSTACKSIZE
154 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
155#endif
156#ifdef PR_GETSTACKSIZE
157 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
158#endif
159#ifdef PR_MAXPPROCS
160 { PR_MAXPPROCS, "PR_MAXPPROCS" },
161#endif
162#ifdef PR_UNBLKONEXEC
163 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
164#endif
165#ifdef PR_ATOMICSIM
166 { PR_ATOMICSIM, "PR_ATOMICSIM" },
167#endif
168#ifdef PR_SETEXITSIG
169 { PR_SETEXITSIG, "PR_SETEXITSIG" },
170#endif
171#ifdef PR_RESIDENT
172 { PR_RESIDENT, "PR_RESIDENT" },
173#endif
174#ifdef PR_ATTACHADDR
175 { PR_ATTACHADDR, "PR_ATTACHADDR" },
176#endif
177#ifdef PR_DETACHADDR
178 { PR_DETACHADDR, "PR_DETACHADDR" },
179#endif
180#ifdef PR_TERMCHILD
181 { PR_TERMCHILD, "PR_TERMCHILD" },
182#endif
183#ifdef PR_GETSHMASK
184 { PR_GETSHMASK, "PR_GETSHMASK" },
185#endif
186#ifdef PR_GETNSHARE
187 { PR_GETNSHARE, "PR_GETNSHARE" },
188#endif
189#if defined(PR_SET_PDEATHSIG)
190 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
191#endif
Wichert Akkerman8829a551999-06-11 13:18:40 +0000192#ifdef PR_COREPID
193 { PR_COREPID, "PR_COREPID" },
194#endif
195#ifdef PR_ATTACHADDRPERM
196 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
197#endif
198#ifdef PR_PTHREADEXIT
199 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
200#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000201#ifdef PR_SET_PDEATHSIG
202 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
203#endif
204#ifdef PR_GET_PDEATHSIG
205 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
206#endif
Dmitry V. Levinf02cf212008-09-03 00:54:40 +0000207#ifdef PR_GET_DUMPABLE
208 { PR_GET_DUMPABLE, "PR_GET_DUMPABLE" },
209#endif
210#ifdef PR_SET_DUMPABLE
211 { PR_SET_DUMPABLE, "PR_SET_DUMPABLE" },
212#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000213#ifdef PR_GET_UNALIGN
214 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
215#endif
216#ifdef PR_SET_UNALIGN
217 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
218#endif
219#ifdef PR_GET_KEEPCAPS
220 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" },
221#endif
222#ifdef PR_SET_KEEPCAPS
223 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" },
224#endif
Roland McGrathe5039fb2007-11-03 23:58:07 +0000225#ifdef PR_GET_FPEMU
226 { PR_GET_FPEMU, "PR_GET_FPEMU" },
227#endif
228#ifdef PR_SET_FPEMU
229 { PR_SET_FPEMU, "PR_SET_FPEMU" },
230#endif
231#ifdef PR_GET_FPEXC
232 { PR_GET_FPEXC, "PR_GET_FPEXC" },
233#endif
234#ifdef PR_SET_FPEXC
235 { PR_SET_FPEXC, "PR_SET_FPEXC" },
236#endif
237#ifdef PR_GET_TIMING
238 { PR_GET_TIMING, "PR_GET_TIMING" },
239#endif
240#ifdef PR_SET_TIMING
241 { PR_SET_TIMING, "PR_SET_TIMING" },
242#endif
243#ifdef PR_SET_NAME
244 { PR_SET_NAME, "PR_SET_NAME" },
245#endif
246#ifdef PR_GET_NAME
247 { PR_GET_NAME, "PR_GET_NAME" },
248#endif
249#ifdef PR_GET_ENDIAN
250 { PR_GET_ENDIAN, "PR_GET_ENDIAN" },
251#endif
252#ifdef PR_SET_ENDIAN
253 { PR_SET_ENDIAN, "PR_SET_ENDIAN" },
254#endif
255#ifdef PR_GET_SECCOMP
256 { PR_GET_SECCOMP, "PR_GET_SECCOMP" },
257#endif
258#ifdef PR_SET_SECCOMP
259 { PR_SET_SECCOMP, "PR_SET_SECCOMP" },
260#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000261 { 0, NULL },
262};
263
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000264
Roland McGratha4d48532005-06-08 20:45:28 +0000265static const char *
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000266unalignctl_string (unsigned int ctl)
267{
268 static char buf[16];
269
270 switch (ctl) {
271#ifdef PR_UNALIGN_NOPRINT
272 case PR_UNALIGN_NOPRINT:
273 return "NOPRINT";
274#endif
275#ifdef PR_UNALIGN_SIGBUS
276 case PR_UNALIGN_SIGBUS:
277 return "SIGBUS";
278#endif
279 default:
280 break;
281 }
282 sprintf(buf, "%x", ctl);
283 return buf;
284}
285
286
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000287int
288sys_prctl(tcp)
289struct tcb *tcp;
290{
291 int i;
292
293 if (entering(tcp)) {
294 printxval(prctl_options, tcp->u_arg[0], "PR_???");
295 switch (tcp->u_arg[0]) {
296#ifdef PR_GETNSHARE
297 case PR_GETNSHARE:
298 break;
299#endif
Dmitry V. Levin50f60132008-09-03 00:56:52 +0000300#ifdef PR_SET_PDEATHSIG
301 case PR_SET_PDEATHSIG:
302 tprintf(", %lu", tcp->u_arg[1]);
303 break;
304#endif
305#ifdef PR_GET_PDEATHSIG
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000306 case PR_GET_PDEATHSIG:
307 break;
308#endif
Dmitry V. Levin50f60132008-09-03 00:56:52 +0000309#ifdef PR_SET_DUMPABLE
310 case PR_SET_DUMPABLE:
311 tprintf(", %lu", tcp->u_arg[1]);
312 break;
313#endif
314#ifdef PR_GET_DUMPABLE
315 case PR_GET_DUMPABLE:
316 break;
317#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000318#ifdef PR_SET_UNALIGN
319 case PR_SET_UNALIGN:
320 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
321 break;
322#endif
323#ifdef PR_GET_UNALIGN
324 case PR_GET_UNALIGN:
325 tprintf(", %#lx", tcp->u_arg[1]);
326 break;
327#endif
Dmitry V. Levin50f60132008-09-03 00:56:52 +0000328#ifdef PR_SET_KEEPCAPS
329 case PR_SET_KEEPCAPS:
330 tprintf(", %lu", tcp->u_arg[1]);
331 break;
332#endif
333#ifdef PR_GET_KEEPCAPS
334 case PR_GET_KEEPCAPS:
335 break;
336#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000337 default:
338 for (i = 1; i < tcp->u_nargs; i++)
339 tprintf(", %#lx", tcp->u_arg[i]);
340 break;
341 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000342 } else {
343 switch (tcp->u_arg[0]) {
344#ifdef PR_GET_PDEATHSIG
345 case PR_GET_PDEATHSIG:
Dmitry V. Levin50f60132008-09-03 00:56:52 +0000346 if (umove(tcp, tcp->u_arg[1], &i) < 0)
347 tprintf(", %#lx", tcp->u_arg[1]);
348 else
349 tprintf(", {%u}", i);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000350 break;
351#endif
Dmitry V. Levin50f60132008-09-03 00:56:52 +0000352#ifdef PR_GET_DUMPABLE
353 case PR_GET_DUMPABLE:
354 return RVAL_UDECIMAL;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000355#endif
356#ifdef PR_GET_UNALIGN
357 case PR_GET_UNALIGN:
Dmitry V. Levin50f60132008-09-03 00:56:52 +0000358 if (syserror(tcp) || umove(tcp, tcp->u_arg[1], &i) < 0)
359 break;
360 tcp->auxstr = unalignctl_string(i);
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000361 return RVAL_STR;
Dmitry V. Levin50f60132008-09-03 00:56:52 +0000362#endif
363#ifdef PR_GET_KEEPCAPS
364 case PR_GET_KEEPCAPS:
365 return RVAL_UDECIMAL;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000366#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000367 default:
368 break;
369 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000370 }
371 return 0;
372}
373
374#endif /* HAVE_PRCTL */
375
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000376#if defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000377int
378sys_gethostid(tcp)
379struct tcb *tcp;
380{
381 if (exiting(tcp))
382 return RVAL_HEX;
383 return 0;
384}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000385#endif /* FREEBSD || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000386
387int
388sys_sethostname(tcp)
389struct tcb *tcp;
390{
391 if (entering(tcp)) {
392 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
393 tprintf(", %lu", tcp->u_arg[1]);
394 }
395 return 0;
396}
397
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000398#if defined(ALPHA) || defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000399int
400sys_gethostname(tcp)
401struct tcb *tcp;
402{
403 if (exiting(tcp)) {
404 if (syserror(tcp))
405 tprintf("%#lx", tcp->u_arg[0]);
406 else
407 printpath(tcp, tcp->u_arg[0]);
408 tprintf(", %lu", tcp->u_arg[1]);
409 }
410 return 0;
411}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000412#endif /* ALPHA || FREEBSD || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000413
414int
415sys_setdomainname(tcp)
416struct tcb *tcp;
417{
418 if (entering(tcp)) {
419 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
420 tprintf(", %lu", tcp->u_arg[1]);
421 }
422 return 0;
423}
424
Wichert Akkerman5daa0281999-03-15 19:49:42 +0000425#if !defined(LINUX)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000426
427int
428sys_getdomainname(tcp)
429struct tcb *tcp;
430{
431 if (exiting(tcp)) {
432 if (syserror(tcp))
433 tprintf("%#lx", tcp->u_arg[0]);
434 else
435 printpath(tcp, tcp->u_arg[0]);
436 tprintf(", %lu", tcp->u_arg[1]);
437 }
438 return 0;
439}
440#endif /* !LINUX */
441
442int
443sys_exit(tcp)
444struct tcb *tcp;
445{
446 if (exiting(tcp)) {
447 fprintf(stderr, "_exit returned!\n");
448 return -1;
449 }
450 /* special case: we stop tracing this process, finish line now */
451 tprintf("%ld) ", tcp->u_arg[0]);
452 tabto(acolumn);
453 tprintf("= ?");
454 printtrailer(tcp);
455 return 0;
456}
457
458int
459internal_exit(tcp)
460struct tcb *tcp;
461{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000462 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000463 tcp->flags |= TCB_EXITING;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000464#ifdef __NR_exit_group
Roland McGrath08267b82004-02-20 22:56:43 +0000465# ifdef IA64
466 if (ia32) {
467 if (tcp->scno == 252)
468 tcp->flags |= TCB_GROUP_EXITING;
469 } else
470# endif
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000471 if (known_scno(tcp) == __NR_exit_group)
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000472 tcp->flags |= TCB_GROUP_EXITING;
473#endif
474 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000475 return 0;
476}
477
Roland McGrathee9d4352002-12-18 04:16:10 +0000478/* TCP is creating a child we want to follow.
479 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
480 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
481static int
482fork_tcb(struct tcb *tcp)
483{
484 if (nprocs == tcbtabsize) {
Roland McGrath7b54a7a2004-06-04 01:50:45 +0000485 if (expand_tcbtab()) {
Roland McGrathee9d4352002-12-18 04:16:10 +0000486 tcp->flags &= ~TCB_FOLLOWFORK;
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000487 return 1;
Roland McGrathee9d4352002-12-18 04:16:10 +0000488 }
Roland McGrathee9d4352002-12-18 04:16:10 +0000489 }
490
491 tcp->flags |= TCB_FOLLOWFORK;
492 return 0;
493}
494
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000495#ifdef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000496
497int
498sys_fork(tcp)
499struct tcb *tcp;
500{
Dmitry V. Levin21a75342008-09-03 01:22:18 +0000501 if (exiting(tcp) && !syserror(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000502 if (getrval2(tcp)) {
503 tcp->auxstr = "child process";
504 return RVAL_UDECIMAL | RVAL_STR;
505 }
506 }
507 return 0;
508}
509
John Hughes4e36a812001-04-18 15:11:51 +0000510#if UNIXWARE > 2
511
512int
513sys_rfork(tcp)
514struct tcb *tcp;
515{
516 if (entering(tcp)) {
517 tprintf ("%ld", tcp->u_arg[0]);
518 }
Dmitry V. Levin21a75342008-09-03 01:22:18 +0000519 else if (!syserror(tcp)) {
John Hughes4e36a812001-04-18 15:11:51 +0000520 if (getrval2(tcp)) {
521 tcp->auxstr = "child process";
522 return RVAL_UDECIMAL | RVAL_STR;
523 }
524 }
525 return 0;
526}
527
528#endif
529
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000530int
531internal_fork(tcp)
532struct tcb *tcp;
533{
534 struct tcb *tcpchild;
535
536 if (exiting(tcp)) {
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000537#ifdef SYS_rfork
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000538 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000539 return 0;
540#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000541 if (getrval2(tcp))
542 return 0;
543 if (!followfork)
544 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000545 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000546 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000547 if (syserror(tcp))
548 return 0;
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000549 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000550 return 0;
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000551 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000552 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000553 }
554 return 0;
555}
556
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000557#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000558
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000559#ifdef LINUX
560
561/* defines copied from linux/sched.h since we can't include that
562 * ourselves (it conflicts with *lots* of libc includes)
563 */
564#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
565#define CLONE_VM 0x00000100 /* set if VM shared between processes */
566#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
567#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
568#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000569#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000570#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
571#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
572#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000573#define CLONE_THREAD 0x00010000 /* Same thread group? */
574#define CLONE_NEWNS 0x00020000 /* New namespace group? */
575#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
576#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
577#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
578#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
579#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
580#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
581#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000582
Roland McGrathd9f816f2004-09-04 03:39:20 +0000583static const struct xlat clone_flags[] = {
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000584 { CLONE_VM, "CLONE_VM" },
585 { CLONE_FS, "CLONE_FS" },
586 { CLONE_FILES, "CLONE_FILES" },
587 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000588 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000589 { CLONE_PTRACE, "CLONE_PTRACE" },
590 { CLONE_VFORK, "CLONE_VFORK" },
591 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000592 { CLONE_THREAD, "CLONE_THREAD" },
593 { CLONE_NEWNS, "CLONE_NEWNS" },
594 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
595 { CLONE_SETTLS, "CLONE_SETTLS" },
596 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
597 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
598 { CLONE_DETACHED, "CLONE_DETACHED" },
599 { CLONE_UNTRACED, "CLONE_UNTRACED" },
600 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000601 { 0, NULL },
602};
603
Roland McGrath909875b2002-12-22 03:34:36 +0000604# ifdef I386
605# include <asm/ldt.h>
Roland McGrath7decfb22004-03-01 22:10:52 +0000606# ifdef HAVE_STRUCT_USER_DESC
607# define modify_ldt_ldt_s user_desc
608# endif
Roland McGrath909875b2002-12-22 03:34:36 +0000609extern void print_ldt_entry();
610# endif
611
Roland McGrath9677b3a2003-03-12 09:54:36 +0000612# if defined IA64
613# define ARG_FLAGS 0
614# define ARG_STACK 1
Roland McGratha4f9f2d2005-06-07 23:21:20 +0000615# define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
616# define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
617# define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
618# define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000619# elif defined S390 || defined S390X
Roland McGrath9677b3a2003-03-12 09:54:36 +0000620# define ARG_STACK 0
621# define ARG_FLAGS 1
622# define ARG_PTID 2
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000623# define ARG_CTID 3
624# define ARG_TLS 4
Roland McGrath9c555e72003-07-09 09:47:59 +0000625# elif defined X86_64 || defined ALPHA
Roland McGrath361aac52003-03-18 07:43:42 +0000626# define ARG_FLAGS 0
627# define ARG_STACK 1
628# define ARG_PTID 2
629# define ARG_CTID 3
630# define ARG_TLS 4
Roland McGrath9677b3a2003-03-12 09:54:36 +0000631# else
632# define ARG_FLAGS 0
633# define ARG_STACK 1
634# define ARG_PTID 2
635# define ARG_TLS 3
636# define ARG_CTID 4
637# endif
638
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000639int
640sys_clone(tcp)
641struct tcb *tcp;
642{
643 if (exiting(tcp)) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000644 unsigned long flags = tcp->u_arg[ARG_FLAGS];
645 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
646# ifdef ARG_STACKSIZE
647 if (ARG_STACKSIZE != -1)
648 tprintf("stack_size=%#lx, ",
649 tcp->u_arg[ARG_STACKSIZE]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000650# endif
Roland McGrath9677b3a2003-03-12 09:54:36 +0000651 tprintf("flags=");
Roland McGrathb2dee132005-06-01 19:02:36 +0000652 printflags(clone_flags, flags &~ CSIGNAL, NULL);
Roland McGrath984154d2003-05-23 01:08:42 +0000653 if ((flags & CSIGNAL) != 0)
654 tprintf("|%s", signame(flags & CSIGNAL));
Roland McGrathb4968be2003-01-20 09:04:33 +0000655 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
Roland McGrath9677b3a2003-03-12 09:54:36 +0000656 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
Roland McGrath909875b2002-12-22 03:34:36 +0000657 return 0;
Roland McGrath6f67a982003-03-21 07:33:15 +0000658 if (flags & CLONE_PARENT_SETTID)
659 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000660 if (flags & CLONE_SETTLS) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000661# ifdef I386
Roland McGrath909875b2002-12-22 03:34:36 +0000662 struct modify_ldt_ldt_s copy;
Roland McGrath9677b3a2003-03-12 09:54:36 +0000663 if (umove(tcp, tcp->u_arg[ARG_TLS], &copy) != -1) {
Roland McGrath909875b2002-12-22 03:34:36 +0000664 tprintf(", {entry_number:%d, ",
665 copy.entry_number);
666 if (!verbose(tcp))
667 tprintf("...}");
668 else
669 print_ldt_entry(&copy);
670 }
671 else
Roland McGrath9677b3a2003-03-12 09:54:36 +0000672# endif
Roland McGrath43f2c842003-03-12 09:58:14 +0000673 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
Roland McGrath909875b2002-12-22 03:34:36 +0000674 }
Roland McGrath9677b3a2003-03-12 09:54:36 +0000675 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
676 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000677 }
678 return 0;
679}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000680
681int
682sys_unshare(struct tcb *tcp)
683{
684 if (entering(tcp))
685 printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
686 return 0;
687}
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000688#endif
689
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000690int
691sys_fork(tcp)
692struct tcb *tcp;
693{
694 if (exiting(tcp))
695 return RVAL_UDECIMAL;
696 return 0;
697}
698
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000699int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000700change_syscall(tcp, new)
701struct tcb *tcp;
702int new;
703{
704#if defined(LINUX)
705#if defined(I386)
706 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000707 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000708 return -1;
709 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000710#elif defined(X86_64)
711 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000712 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000713 return -1;
714 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000715#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000716 if (ptrace(PTRACE_POKEUSER, tcp->pid,
717 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000718 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000719 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000720#elif defined(S390) || defined(S390X)
721 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
722 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
723 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000724 return 0;
725#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000726 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000727 return -1;
728 return 0;
Roland McGrath6d1a65c2004-07-12 07:44:08 +0000729#elif defined(SPARC) || defined(SPARC64)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000730 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000731 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
732 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000733 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000734 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
735 return -1;
736 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000737#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000738 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000739 return -1;
740 return 0;
741#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000742 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000743 return -1;
744 return 0;
Dmitry V. Levin87ea1f42008-11-10 22:21:41 +0000745#elif defined(BFIN)
746 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_P0), new)<0)
747 return -1;
748 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000749#elif defined(IA64)
Roland McGrath08267b82004-02-20 22:56:43 +0000750 if (ia32) {
751 switch (new) {
752 case 2: break; /* x86 SYS_fork */
753 case SYS_clone: new = 120; break;
754 default:
755 fprintf(stderr, "%s: unexpected syscall %d\n",
756 __FUNCTION__, new);
757 return -1;
758 }
759 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
760 return -1;
761 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000762 return -1;
763 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000764#elif defined(HPPA)
765 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
766 return -1;
767 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000768#elif defined(SH)
Roland McGrathac971c22003-03-31 01:03:33 +0000769 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
Wichert Akkermanccef6372002-05-01 16:39:22 +0000770 return -1;
771 return 0;
Roland McGrathf5a47772003-06-26 22:40:42 +0000772#elif defined(SH64)
Roland McGrathe1e584b2003-06-02 19:18:58 +0000773 /* Top half of reg encodes the no. of args n as 0x1n.
774 Assume 0 args as kernel never actually checks... */
775 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
776 0x100000 | new) < 0)
777 return -1;
778 return 0;
Roland McGrathf691bd22006-04-25 07:34:41 +0000779#elif defined(ARM)
780 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
781# ifndef PTRACE_SET_SYSCALL
782# define PTRACE_SET_SYSCALL 23
783# endif
784
785 if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new) != 0)
786 return -1;
787
788 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000789#else
790#warning Do not know how to handle change_syscall for this architecture
791#endif /* architecture */
792#endif /* LINUX */
793 return -1;
794}
795
Roland McGratha4d48532005-06-08 20:45:28 +0000796#if 0
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000797int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000798setarg(tcp, argnum)
799 struct tcb *tcp;
800 int argnum;
801{
802#if defined (IA64)
803 {
804 unsigned long *bsp, *ap;
805
806 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
807 return -1;
808
809 ap = ia64_rse_skip_regs(bsp, argnum);
810 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000811 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000812 if (errno)
813 return -1;
814
815 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000816#elif defined(I386)
817 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000818 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000819 if (errno)
820 return -1;
821 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000822#elif defined(X86_64)
823 {
824 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
825 if (errno)
826 return -1;
827 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000828#elif defined(POWERPC)
829#ifndef PT_ORIG_R3
830#define PT_ORIG_R3 34
831#endif
832 {
833 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000834 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000835 tcp->u_arg[argnum]);
836 if (errno)
837 return -1;
838 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000839#elif defined(MIPS)
840 {
841 errno = 0;
842 if (argnum < 4)
843 ptrace(PTRACE_POKEUSER, tcp->pid,
844 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
845 else {
846 unsigned long *sp;
847
848 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
849 return -1;
850
851 ptrace(PTRACE_POKEDATA, tcp->pid,
852 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
853 }
854 if (errno)
855 return -1;
856 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000857#elif defined(S390) || defined(S390X)
858 {
859 if(argnum <= 5)
860 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000861 (char *) (argnum==0 ? PT_ORIGGPR2 :
862 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000863 tcp->u_arg[argnum]);
864 else
865 return -E2BIG;
866 if (errno)
867 return -1;
868 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000869#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000870# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000871#endif
872 return 0;
873}
Roland McGratha4d48532005-06-08 20:45:28 +0000874#endif
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000875
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000876#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000877int
878internal_clone(tcp)
879struct tcb *tcp;
880{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000881 struct tcb *tcpchild;
882 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000883 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000884 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000885 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000886 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000887 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000888 if (setbpt(tcp) < 0)
889 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000890 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000891 int bpt = tcp->flags & TCB_BPTSET;
892
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000893 if (!(tcp->flags & TCB_FOLLOWFORK))
894 return 0;
895
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000896 if (syserror(tcp)) {
897 if (bpt)
898 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000899 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000900 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000901
902 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000903
904#ifdef CLONE_PTRACE /* See new setbpt code. */
905 tcpchild = pid2tcb(pid);
906 if (tcpchild != NULL) {
907 /* The child already reported its startup trap
908 before the parent reported its syscall return. */
909 if ((tcpchild->flags
910 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
911 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
912 fprintf(stderr, "\
913[preattached child %d of %d in weird state!]\n",
914 pid, tcp->pid);
915 }
916 else
917#endif
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000918 if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000919 if (bpt)
920 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000921 kill(pid, SIGKILL); /* XXX */
922 return 0;
923 }
924
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000925#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000926 /* Attach to the new child */
927 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000928 if (bpt)
929 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000930 perror("PTRACE_ATTACH");
931 fprintf(stderr, "Too late?\n");
932 droptcb(tcpchild);
933 return 0;
934 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000935#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000936
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000937 if (bpt)
938 clearbpt(tcp);
939
Ulrich Drepper90512f01999-12-24 07:22:25 +0000940 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000941 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000942 if (bpt) {
943 tcpchild->flags |= TCB_BPTSET;
944 tcpchild->baddr = tcp->baddr;
945 memcpy(tcpchild->inst, tcp->inst,
946 sizeof tcpchild->inst);
947 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000948 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000949 tcp->nchildren++;
950 if (tcpchild->flags & TCB_SUSPENDED) {
951 /* The child was born suspended, due to our having
952 forced CLONE_PTRACE. */
953 if (bpt)
954 clearbpt(tcpchild);
955
956 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
957 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
958 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
959 return -1;
960 }
961
962 if (!qflag)
963 fprintf(stderr, "\
964Process %u resumed (parent %d ready)\n",
965 pid, tcp->pid);
966 }
967 else {
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000968 if (!qflag)
969 fprintf(stderr, "Process %d attached\n", pid);
970 }
971
972#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000973 {
974 /*
975 * Save the flags used in this call,
976 * in case we point TCP to our parent below.
977 */
978 int call_flags = tcp->u_arg[ARG_FLAGS];
979 if ((tcp->flags & TCB_CLONE_THREAD) &&
980 tcp->parent != NULL) {
981 /* The parent in this clone is itself a
982 thread belonging to another process.
983 There is no meaning to the parentage
984 relationship of the new child with the
985 thread, only with the process. We
986 associate the new thread with our
987 parent. Since this is done for every
988 new thread, there will never be a
989 TCB_CLONE_THREAD process that has
990 children. */
991 --tcp->nchildren;
992 tcp = tcp->parent;
993 tcpchild->parent = tcp;
994 ++tcp->nchildren;
995 }
996 if (call_flags & CLONE_THREAD) {
997 tcpchild->flags |= TCB_CLONE_THREAD;
998 ++tcp->nclone_threads;
999 }
1000 if (call_flags & CLONE_DETACHED) {
1001 tcpchild->flags |= TCB_CLONE_DETACHED;
1002 ++tcp->nclone_detached;
1003 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001004 }
1005#endif
1006
1007 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +00001008 return 0;
1009}
1010#endif
1011
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001012int
1013internal_fork(tcp)
1014struct tcb *tcp;
1015{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001016#ifdef LINUX
1017 /* We do special magic with clone for any clone or fork. */
1018 return internal_clone(tcp);
1019#else
1020
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001021 struct tcb *tcpchild;
1022 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +00001023 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001024
1025#ifdef SYS_vfork
Roland McGratha4f9f2d2005-06-07 23:21:20 +00001026 if (known_scno(tcp) == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +00001027 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath41c48222008-07-18 00:25:10 +00001028 if (change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +00001029 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +00001030 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001031#endif
1032 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +00001033 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001034 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +00001035 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001036 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001037 if (setbpt(tcp) < 0)
1038 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +00001039 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001040 else {
1041 int bpt = tcp->flags & TCB_BPTSET;
1042
1043 if (!(tcp->flags & TCB_FOLLOWFORK))
1044 return 0;
1045 if (bpt)
1046 clearbpt(tcp);
1047
1048 if (syserror(tcp))
1049 return 0;
1050
1051 pid = tcp->u_rval;
Dmitry V. Levin76860f62006-10-11 22:55:25 +00001052 if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001053 kill(pid, SIGKILL); /* XXX */
1054 return 0;
1055 }
1056#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +00001057#ifdef HPPA
1058 /* The child must have run before it can be attached. */
1059 /* This must be a bug in the parisc kernel, but I havn't
1060 * identified it yet. Seems to be an issue associated
1061 * with attaching to a process (which sends it a signal)
1062 * before that process has ever been scheduled. When
1063 * debugging, I started seeing crashes in
1064 * arch/parisc/kernel/signal.c:do_signal(), apparently
1065 * caused by r8 getting corrupt over the dequeue_signal()
1066 * call. Didn't make much sense though...
1067 */
1068 {
1069 struct timeval tv;
1070 tv.tv_sec = 0;
1071 tv.tv_usec = 10000;
1072 select(0, NULL, NULL, NULL, &tv);
1073 }
1074#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001075 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
1076 perror("PTRACE_ATTACH");
1077 fprintf(stderr, "Too late?\n");
1078 droptcb(tcpchild);
1079 return 0;
1080 }
1081#endif /* LINUX */
1082#ifdef SUNOS4
1083#ifdef oldway
1084 /* The child must have run before it can be attached. */
1085 {
1086 struct timeval tv;
1087 tv.tv_sec = 0;
1088 tv.tv_usec = 10000;
1089 select(0, NULL, NULL, NULL, &tv);
1090 }
1091 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1092 perror("PTRACE_ATTACH");
1093 fprintf(stderr, "Too late?\n");
1094 droptcb(tcpchild);
1095 return 0;
1096 }
1097#else /* !oldway */
1098 /* Try to catch the new process as soon as possible. */
1099 {
1100 int i;
1101 for (i = 0; i < 1024; i++)
1102 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1103 break;
1104 if (i == 1024) {
1105 perror("PTRACE_ATTACH");
1106 fprintf(stderr, "Too late?\n");
1107 droptcb(tcpchild);
1108 return 0;
1109 }
1110 }
1111#endif /* !oldway */
1112#endif /* SUNOS4 */
1113 tcpchild->flags |= TCB_ATTACHED;
1114 /* Child has BPT too, must be removed on first occasion */
1115 if (bpt) {
1116 tcpchild->flags |= TCB_BPTSET;
1117 tcpchild->baddr = tcp->baddr;
1118 memcpy(tcpchild->inst, tcp->inst,
1119 sizeof tcpchild->inst);
1120 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001121 tcpchild->parent = tcp;
1122 tcp->nchildren++;
1123 if (!qflag)
1124 fprintf(stderr, "Process %d attached\n", pid);
1125 }
1126 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001127#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001128}
1129
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001130#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001131
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001132#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001133
1134int
1135sys_vfork(tcp)
1136struct tcb *tcp;
1137{
1138 if (exiting(tcp))
1139 return RVAL_UDECIMAL;
1140 return 0;
1141}
1142
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001143#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001144
1145#ifndef LINUX
1146
1147static char idstr[16];
1148
1149int
1150sys_getpid(tcp)
1151struct tcb *tcp;
1152{
1153 if (exiting(tcp)) {
1154 sprintf(idstr, "ppid %lu", getrval2(tcp));
1155 tcp->auxstr = idstr;
1156 return RVAL_STR;
1157 }
1158 return 0;
1159}
1160
1161int
1162sys_getuid(tcp)
1163struct tcb *tcp;
1164{
1165 if (exiting(tcp)) {
1166 sprintf(idstr, "euid %lu", getrval2(tcp));
1167 tcp->auxstr = idstr;
1168 return RVAL_STR;
1169 }
1170 return 0;
1171}
1172
1173int
1174sys_getgid(tcp)
1175struct tcb *tcp;
1176{
1177 if (exiting(tcp)) {
1178 sprintf(idstr, "egid %lu", getrval2(tcp));
1179 tcp->auxstr = idstr;
1180 return RVAL_STR;
1181 }
1182 return 0;
1183}
1184
1185#endif /* !LINUX */
1186
1187#ifdef LINUX
1188
1189int
1190sys_setuid(tcp)
1191struct tcb *tcp;
1192{
1193 if (entering(tcp)) {
1194 tprintf("%u", (uid_t) tcp->u_arg[0]);
1195 }
1196 return 0;
1197}
1198
1199int
1200sys_setgid(tcp)
1201struct tcb *tcp;
1202{
1203 if (entering(tcp)) {
1204 tprintf("%u", (gid_t) tcp->u_arg[0]);
1205 }
1206 return 0;
1207}
1208
1209int
1210sys_getresuid(tcp)
1211 struct tcb *tcp;
1212{
1213 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001214 __kernel_uid_t uid;
1215 if (syserror(tcp))
1216 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1217 tcp->u_arg[1], tcp->u_arg[2]);
1218 else {
1219 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1220 tprintf("%#lx, ", tcp->u_arg[0]);
1221 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001222 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001223 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1224 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001225 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001226 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001227 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1228 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001229 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001230 tprintf("[%lu]", (unsigned long) uid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001231 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001232 }
1233 return 0;
1234}
1235
1236int
1237sys_getresgid(tcp)
1238struct tcb *tcp;
1239{
1240 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001241 __kernel_gid_t gid;
1242 if (syserror(tcp))
1243 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1244 tcp->u_arg[1], tcp->u_arg[2]);
1245 else {
1246 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1247 tprintf("%#lx, ", tcp->u_arg[0]);
1248 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001249 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001250 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1251 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001252 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001253 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001254 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1255 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001256 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001257 tprintf("[%lu]", (unsigned long) gid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001258 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001259 }
1260 return 0;
1261}
1262
1263#endif /* LINUX */
1264
1265int
1266sys_setreuid(tcp)
1267struct tcb *tcp;
1268{
1269 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001270 printuid("", tcp->u_arg[0]);
1271 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001272 }
1273 return 0;
1274}
1275
1276int
1277sys_setregid(tcp)
1278struct tcb *tcp;
1279{
1280 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001281 printuid("", tcp->u_arg[0]);
1282 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001283 }
1284 return 0;
1285}
1286
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001287#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001288int
1289sys_setresuid(tcp)
1290 struct tcb *tcp;
1291{
1292 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001293 printuid("", tcp->u_arg[0]);
1294 printuid(", ", tcp->u_arg[1]);
1295 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001296 }
1297 return 0;
1298}
1299int
1300sys_setresgid(tcp)
1301 struct tcb *tcp;
1302{
1303 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001304 printuid("", tcp->u_arg[0]);
1305 printuid(", ", tcp->u_arg[1]);
1306 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001307 }
1308 return 0;
1309}
1310
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001311#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001312
1313int
1314sys_setgroups(tcp)
1315struct tcb *tcp;
1316{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001317 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001318 unsigned long len, size, start, cur, end, abbrev_end;
1319 GETGROUPS_T gid;
1320 int failed = 0;
1321
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001322 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001323 tprintf("%lu, ", len);
1324 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001325 tprintf("[]");
1326 return 0;
1327 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001328 start = tcp->u_arg[1];
1329 if (start == 0) {
1330 tprintf("NULL");
1331 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001332 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001333 size = len * sizeof(gid);
1334 end = start + size;
1335 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1336 tprintf("%#lx", start);
1337 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001338 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001339 if (abbrev(tcp)) {
1340 abbrev_end = start + max_strlen * sizeof(gid);
1341 if (abbrev_end < start)
1342 abbrev_end = end;
1343 } else {
1344 abbrev_end = end;
1345 }
1346 tprintf("[");
1347 for (cur = start; cur < end; cur += sizeof(gid)) {
1348 if (cur > start)
1349 tprintf(", ");
1350 if (cur >= abbrev_end) {
1351 tprintf("...");
1352 break;
1353 }
1354 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1355 tprintf("?");
1356 failed = 1;
1357 break;
1358 }
1359 tprintf("%lu", (unsigned long) gid);
1360 }
1361 tprintf("]");
1362 if (failed)
1363 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001364 }
1365 return 0;
1366}
1367
1368int
1369sys_getgroups(tcp)
1370struct tcb *tcp;
1371{
Roland McGrathaa524c82005-06-01 19:22:06 +00001372 unsigned long len;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001373
1374 if (entering(tcp)) {
1375 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001376 tprintf("%lu, ", len);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001377 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001378 unsigned long size, start, cur, end, abbrev_end;
1379 GETGROUPS_T gid;
1380 int failed = 0;
1381
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001382 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001383 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001384 tprintf("[]");
1385 return 0;
1386 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001387 start = tcp->u_arg[1];
1388 if (start == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001389 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001390 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001391 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001392 if (tcp->u_arg[0] == 0) {
1393 tprintf("%#lx", start);
1394 return 0;
1395 }
1396 size = len * sizeof(gid);
1397 end = start + size;
1398 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1399 size / sizeof(gid) != len || end < start) {
1400 tprintf("%#lx", start);
1401 return 0;
1402 }
1403 if (abbrev(tcp)) {
1404 abbrev_end = start + max_strlen * sizeof(gid);
1405 if (abbrev_end < start)
1406 abbrev_end = end;
1407 } else {
1408 abbrev_end = end;
1409 }
1410 tprintf("[");
1411 for (cur = start; cur < end; cur += sizeof(gid)) {
1412 if (cur > start)
1413 tprintf(", ");
1414 if (cur >= abbrev_end) {
1415 tprintf("...");
1416 break;
1417 }
1418 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1419 tprintf("?");
1420 failed = 1;
1421 break;
1422 }
1423 tprintf("%lu", (unsigned long) gid);
1424 }
1425 tprintf("]");
1426 if (failed)
1427 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001428 }
1429 return 0;
1430}
1431
Roland McGrath83bd47a2003-11-13 22:32:26 +00001432#ifdef LINUX
1433int
1434sys_setgroups32(tcp)
1435struct tcb *tcp;
1436{
Roland McGrath83bd47a2003-11-13 22:32:26 +00001437 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001438 unsigned long len, size, start, cur, end, abbrev_end;
1439 GETGROUPS32_T gid;
1440 int failed = 0;
1441
Roland McGrath83bd47a2003-11-13 22:32:26 +00001442 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001443 tprintf("%lu, ", len);
1444 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001445 tprintf("[]");
1446 return 0;
1447 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001448 start = tcp->u_arg[1];
1449 if (start == 0) {
1450 tprintf("NULL");
1451 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001452 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001453 size = len * sizeof(gid);
1454 end = start + size;
1455 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1456 tprintf("%#lx", start);
1457 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001458 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001459 if (abbrev(tcp)) {
1460 abbrev_end = start + max_strlen * sizeof(gid);
1461 if (abbrev_end < start)
1462 abbrev_end = end;
1463 } else {
1464 abbrev_end = end;
1465 }
1466 tprintf("[");
1467 for (cur = start; cur < end; cur += sizeof(gid)) {
1468 if (cur > start)
1469 tprintf(", ");
1470 if (cur >= abbrev_end) {
1471 tprintf("...");
1472 break;
1473 }
1474 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1475 tprintf("?");
1476 failed = 1;
1477 break;
1478 }
1479 tprintf("%lu", (unsigned long) gid);
1480 }
1481 tprintf("]");
1482 if (failed)
1483 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001484 }
1485 return 0;
1486}
1487
1488int
1489sys_getgroups32(tcp)
1490struct tcb *tcp;
1491{
Roland McGrathaa524c82005-06-01 19:22:06 +00001492 unsigned long len;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001493
1494 if (entering(tcp)) {
1495 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001496 tprintf("%lu, ", len);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001497 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001498 unsigned long size, start, cur, end, abbrev_end;
1499 GETGROUPS32_T gid;
1500 int failed = 0;
1501
Roland McGrath83bd47a2003-11-13 22:32:26 +00001502 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001503 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001504 tprintf("[]");
1505 return 0;
1506 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001507 start = tcp->u_arg[1];
1508 if (start == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001509 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001510 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001511 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001512 size = len * sizeof(gid);
1513 end = start + size;
1514 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1515 size / sizeof(gid) != len || end < start) {
1516 tprintf("%#lx", start);
1517 return 0;
1518 }
1519 if (abbrev(tcp)) {
1520 abbrev_end = start + max_strlen * sizeof(gid);
1521 if (abbrev_end < start)
1522 abbrev_end = end;
1523 } else {
1524 abbrev_end = end;
1525 }
1526 tprintf("[");
1527 for (cur = start; cur < end; cur += sizeof(gid)) {
1528 if (cur > start)
1529 tprintf(", ");
1530 if (cur >= abbrev_end) {
1531 tprintf("...");
1532 break;
1533 }
1534 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1535 tprintf("?");
1536 failed = 1;
1537 break;
1538 }
1539 tprintf("%lu", (unsigned long) gid);
1540 }
1541 tprintf("]");
1542 if (failed)
1543 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001544 }
1545 return 0;
1546}
1547#endif /* LINUX */
1548
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001549#if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001550int
1551sys_setpgrp(tcp)
1552struct tcb *tcp;
1553{
1554 if (entering(tcp)) {
1555#ifndef SVR4
1556 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1557#endif /* !SVR4 */
1558 }
1559 return 0;
1560}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001561#endif /* ALPHA || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001562
1563int
1564sys_getpgrp(tcp)
1565struct tcb *tcp;
1566{
1567 if (entering(tcp)) {
1568#ifndef SVR4
1569 tprintf("%lu", tcp->u_arg[0]);
1570#endif /* !SVR4 */
1571 }
1572 return 0;
1573}
1574
1575int
1576sys_getsid(tcp)
1577struct tcb *tcp;
1578{
1579 if (entering(tcp)) {
1580 tprintf("%lu", tcp->u_arg[0]);
1581 }
1582 return 0;
1583}
1584
1585int
1586sys_setsid(tcp)
1587struct tcb *tcp;
1588{
1589 return 0;
1590}
1591
1592int
1593sys_getpgid(tcp)
1594struct tcb *tcp;
1595{
1596 if (entering(tcp)) {
1597 tprintf("%lu", tcp->u_arg[0]);
1598 }
1599 return 0;
1600}
1601
1602int
1603sys_setpgid(tcp)
1604struct tcb *tcp;
1605{
1606 if (entering(tcp)) {
1607 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1608 }
1609 return 0;
1610}
1611
John Hughesc61eb3d2002-05-17 11:37:50 +00001612#if UNIXWARE >= 2
1613
1614#include <sys/privilege.h>
1615
1616
Roland McGrathd9f816f2004-09-04 03:39:20 +00001617static const struct xlat procpriv_cmds [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001618 { SETPRV, "SETPRV" },
1619 { CLRPRV, "CLRPRV" },
1620 { PUTPRV, "PUTPRV" },
1621 { GETPRV, "GETPRV" },
1622 { CNTPRV, "CNTPRV" },
1623 { 0, NULL },
1624};
1625
1626
Roland McGrathd9f816f2004-09-04 03:39:20 +00001627static const struct xlat procpriv_priv [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001628 { P_OWNER, "P_OWNER" },
1629 { P_AUDIT, "P_AUDIT" },
1630 { P_COMPAT, "P_COMPAT" },
1631 { P_DACREAD, "P_DACREAD" },
1632 { P_DACWRITE, "P_DACWRITE" },
1633 { P_DEV, "P_DEV" },
1634 { P_FILESYS, "P_FILESYS" },
1635 { P_MACREAD, "P_MACREAD" },
1636 { P_MACWRITE, "P_MACWRITE" },
1637 { P_MOUNT, "P_MOUNT" },
1638 { P_MULTIDIR, "P_MULTIDIR" },
1639 { P_SETPLEVEL, "P_SETPLEVEL" },
1640 { P_SETSPRIV, "P_SETSPRIV" },
1641 { P_SETUID, "P_SETUID" },
1642 { P_SYSOPS, "P_SYSOPS" },
1643 { P_SETUPRIV, "P_SETUPRIV" },
1644 { P_DRIVER, "P_DRIVER" },
1645 { P_RTIME, "P_RTIME" },
1646 { P_MACUPGRADE, "P_MACUPGRADE" },
1647 { P_FSYSRANGE, "P_FSYSRANGE" },
1648 { P_SETFLEVEL, "P_SETFLEVEL" },
1649 { P_AUDITWR, "P_AUDITWR" },
1650 { P_TSHAR, "P_TSHAR" },
1651 { P_PLOCK, "P_PLOCK" },
1652 { P_CORE, "P_CORE" },
1653 { P_LOADMOD, "P_LOADMOD" },
1654 { P_BIND, "P_BIND" },
1655 { P_ALLPRIVS, "P_ALLPRIVS" },
1656 { 0, NULL },
1657};
1658
1659
Roland McGrathd9f816f2004-09-04 03:39:20 +00001660static const struct xlat procpriv_type [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001661 { PS_FIX, "PS_FIX" },
1662 { PS_INH, "PS_INH" },
1663 { PS_MAX, "PS_MAX" },
1664 { PS_WKG, "PS_WKG" },
1665 { 0, NULL },
1666};
1667
1668
1669static void
Dmitry V. Levinab9008b2007-01-11 22:05:04 +00001670printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
John Hughesc61eb3d2002-05-17 11:37:50 +00001671{
1672 priv_t buf [128];
1673 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1674 int dots = len > max;
1675 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001676
John Hughesc61eb3d2002-05-17 11:37:50 +00001677 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001678
John Hughesc61eb3d2002-05-17 11:37:50 +00001679 if (len <= 0 ||
1680 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1681 {
1682 tprintf ("%#lx", addr);
1683 return;
1684 }
1685
1686 tprintf ("[");
1687
1688 for (i = 0; i < len; ++i) {
Dmitry V. Levinab9008b2007-01-11 22:05:04 +00001689 const char *t, *p;
John Hughesc61eb3d2002-05-17 11:37:50 +00001690
1691 if (i) tprintf (", ");
1692
1693 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1694 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1695 {
1696 tprintf ("%s|%s", t, p);
1697 }
1698 else {
1699 tprintf ("%#lx", buf [i]);
1700 }
1701 }
1702
1703 if (dots) tprintf (" ...");
1704
1705 tprintf ("]");
1706}
1707
1708
1709int
1710sys_procpriv(tcp)
1711struct tcb *tcp;
1712{
1713 if (entering(tcp)) {
1714 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1715 switch (tcp->u_arg[0]) {
1716 case CNTPRV:
1717 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1718 break;
1719
1720 case GETPRV:
1721 break;
1722
1723 default:
1724 tprintf (", ");
1725 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1726 tprintf (", %ld", tcp->u_arg[2]);
1727 }
1728 }
1729 else if (tcp->u_arg[0] == GETPRV) {
1730 if (syserror (tcp)) {
1731 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1732 }
1733 else {
1734 tprintf (", ");
1735 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1736 tprintf (", %ld", tcp->u_arg[2]);
1737 }
1738 }
Roland McGrath5a223472002-12-15 23:58:26 +00001739
John Hughesc61eb3d2002-05-17 11:37:50 +00001740 return 0;
1741}
1742
1743#endif
1744
1745
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001746static void
1747printargv(tcp, addr)
1748struct tcb *tcp;
1749long addr;
1750{
Roland McGrath85a3bc42007-08-02 02:13:05 +00001751 union {
1752 int p32;
1753 long p64;
1754 char data[sizeof(long)];
1755 } cp;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001756 char *sep;
Roland McGrath85a3bc42007-08-02 02:13:05 +00001757 int n = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001758
Roland McGrath85a3bc42007-08-02 02:13:05 +00001759 cp.p64 = 1;
1760 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1761 if (umoven(tcp, addr, personality_wordsize[current_personality],
1762 cp.data) < 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001763 tprintf("%#lx", addr);
1764 return;
1765 }
Roland McGrath85a3bc42007-08-02 02:13:05 +00001766 if (personality_wordsize[current_personality] == 4)
1767 cp.p64 = cp.p32;
1768 if (cp.p64 == 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001769 break;
1770 tprintf(sep);
Roland McGrath85a3bc42007-08-02 02:13:05 +00001771 printstr(tcp, cp.p64, -1);
1772 addr += personality_wordsize[current_personality];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001773 }
Roland McGrath85a3bc42007-08-02 02:13:05 +00001774 if (cp.p64)
1775 tprintf("%s...", sep);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001776}
1777
1778static void
1779printargc(fmt, tcp, addr)
1780char *fmt;
1781struct tcb *tcp;
1782long addr;
1783{
1784 int count;
1785 char *cp;
1786
1787 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1788 addr += sizeof(char *);
1789 }
1790 tprintf(fmt, count, count == 1 ? "" : "s");
1791}
1792
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001793#if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001794int
1795sys_execv(tcp)
1796struct tcb *tcp;
1797{
1798 if (entering(tcp)) {
1799 printpath(tcp, tcp->u_arg[0]);
1800 if (!verbose(tcp))
1801 tprintf(", %#lx", tcp->u_arg[1]);
1802#if 0
1803 else if (abbrev(tcp))
1804 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1805#endif
1806 else {
1807 tprintf(", [");
1808 printargv(tcp, tcp->u_arg[1]);
1809 tprintf("]");
1810 }
1811 }
1812 return 0;
1813}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001814#endif /* SPARC || SPARC64 || SUNOS4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001815
1816int
1817sys_execve(tcp)
1818struct tcb *tcp;
1819{
1820 if (entering(tcp)) {
1821 printpath(tcp, tcp->u_arg[0]);
1822 if (!verbose(tcp))
1823 tprintf(", %#lx", tcp->u_arg[1]);
1824#if 0
1825 else if (abbrev(tcp))
1826 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1827#endif
1828 else {
1829 tprintf(", [");
1830 printargv(tcp, tcp->u_arg[1]);
1831 tprintf("]");
1832 }
1833 if (!verbose(tcp))
1834 tprintf(", %#lx", tcp->u_arg[2]);
1835 else if (abbrev(tcp))
1836 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1837 else {
1838 tprintf(", [");
1839 printargv(tcp, tcp->u_arg[2]);
1840 tprintf("]");
1841 }
1842 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001843 return 0;
1844}
1845
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001846#if UNIXWARE > 2
John Hughes4e36a812001-04-18 15:11:51 +00001847
1848int sys_rexecve(tcp)
1849struct tcb *tcp;
1850{
1851 if (entering (tcp)) {
1852 sys_execve (tcp);
1853 tprintf (", %ld", tcp->u_arg[3]);
1854 }
1855 return 0;
1856}
1857
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001858#endif
John Hughes4e36a812001-04-18 15:11:51 +00001859
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001860int
1861internal_exec(tcp)
1862struct tcb *tcp;
1863{
1864#ifdef SUNOS4
1865 if (exiting(tcp) && !syserror(tcp) && followfork)
1866 fixvfork(tcp);
1867#endif /* SUNOS4 */
Roland McGrathfdb097f2004-07-12 07:38:55 +00001868#if defined LINUX && defined TCB_WAITEXECVE
1869 if (exiting(tcp) && syserror(tcp))
1870 tcp->flags &= ~TCB_WAITEXECVE;
1871 else
1872 tcp->flags |= TCB_WAITEXECVE;
1873#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001874 return 0;
1875}
1876
1877#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001878#ifndef __WNOTHREAD
1879#define __WNOTHREAD 0x20000000
1880#endif
1881#ifndef __WALL
1882#define __WALL 0x40000000
1883#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001884#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001885#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001886#endif
1887#endif /* LINUX */
1888
Roland McGrathd9f816f2004-09-04 03:39:20 +00001889static const struct xlat wait4_options[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001890 { WNOHANG, "WNOHANG" },
1891#ifndef WSTOPPED
1892 { WUNTRACED, "WUNTRACED" },
1893#endif
1894#ifdef WEXITED
1895 { WEXITED, "WEXITED" },
1896#endif
1897#ifdef WTRAPPED
1898 { WTRAPPED, "WTRAPPED" },
1899#endif
1900#ifdef WSTOPPED
1901 { WSTOPPED, "WSTOPPED" },
1902#endif
1903#ifdef WCONTINUED
1904 { WCONTINUED, "WCONTINUED" },
1905#endif
1906#ifdef WNOWAIT
1907 { WNOWAIT, "WNOWAIT" },
1908#endif
1909#ifdef __WCLONE
1910 { __WCLONE, "__WCLONE" },
1911#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001912#ifdef __WALL
1913 { __WALL, "__WALL" },
1914#endif
1915#ifdef __WNOTHREAD
1916 { __WNOTHREAD, "__WNOTHREAD" },
1917#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001918 { 0, NULL },
1919};
1920
Roland McGrath5e02a572004-10-19 23:33:47 +00001921#if !defined WCOREFLAG && defined WCOREFLG
1922# define WCOREFLAG WCOREFLG
1923#endif
1924#ifndef WCOREFLAG
1925#define WCOREFLAG 0x80
1926#endif
1927
1928#ifndef W_STOPCODE
1929#define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1930#endif
1931#ifndef W_EXITCODE
1932#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1933#endif
1934
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001935static int
1936printstatus(status)
1937int status;
1938{
1939 int exited = 0;
1940
1941 /*
1942 * Here is a tricky presentation problem. This solution
1943 * is still not entirely satisfactory but since there
1944 * are no wait status constructors it will have to do.
1945 */
Roland McGrath79fbda52004-04-14 02:45:55 +00001946 if (WIFSTOPPED(status)) {
1947 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001948 signame(WSTOPSIG(status)));
Roland McGrath79fbda52004-04-14 02:45:55 +00001949 status &= ~W_STOPCODE(WSTOPSIG(status));
1950 }
1951 else if (WIFSIGNALED(status)) {
1952 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001953 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001954 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
Roland McGrath79fbda52004-04-14 02:45:55 +00001955 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1956 }
1957 else if (WIFEXITED(status)) {
1958 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001959 WEXITSTATUS(status));
1960 exited = 1;
Roland McGrath79fbda52004-04-14 02:45:55 +00001961 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001962 }
Roland McGrath79fbda52004-04-14 02:45:55 +00001963 else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001964 tprintf("[%#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001965 return 0;
1966 }
1967
1968 if (status == 0)
1969 tprintf("]");
1970 else
Roland McGrathf8cc83c2004-06-04 01:24:07 +00001971 tprintf(" | %#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001972
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001973 return exited;
1974}
1975
1976static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001977printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001978struct tcb *tcp;
1979int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001980int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001981{
1982 int status;
1983 int exited = 0;
1984
1985 if (entering(tcp)) {
Roland McGrath5b63d962008-07-18 02:16:47 +00001986 /*
1987 * Sign-extend a 32-bit value when that's what it is.
1988 */
1989 long pid = tcp->u_arg[0];
1990 if (personality_wordsize[current_personality] < sizeof pid)
1991 pid = (long) (int) pid;
1992 tprintf("%ld, ", pid);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001993 } else {
1994 /* status */
1995 if (!tcp->u_arg[1])
1996 tprintf("NULL");
1997 else if (syserror(tcp) || tcp->u_rval == 0)
1998 tprintf("%#lx", tcp->u_arg[1]);
1999 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
2000 tprintf("[?]");
2001 else
2002 exited = printstatus(status);
2003 /* options */
2004 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00002005 printflags(wait4_options, tcp->u_arg[2], "W???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002006 if (n == 4) {
2007 tprintf(", ");
2008 /* usage */
2009 if (!tcp->u_arg[3])
2010 tprintf("NULL");
2011#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002012 else if (tcp->u_rval > 0) {
2013#ifdef LINUX_64BIT
2014 if (bitness)
2015 printrusage32(tcp, tcp->u_arg[3]);
2016 else
2017#endif
2018 printrusage(tcp, tcp->u_arg[3]);
2019 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002020#endif /* LINUX */
2021#ifdef SUNOS4
2022 else if (tcp->u_rval > 0 && exited)
2023 printrusage(tcp, tcp->u_arg[3]);
2024#endif /* SUNOS4 */
2025 else
2026 tprintf("%#lx", tcp->u_arg[3]);
2027 }
2028 }
2029 return 0;
2030}
2031
2032int
Roland McGrathc74c0b72004-09-01 19:39:46 +00002033internal_wait(tcp, flagarg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002034struct tcb *tcp;
Roland McGrathc74c0b72004-09-01 19:39:46 +00002035int flagarg;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002036{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002037 int got_kids;
2038
2039#ifdef TCB_CLONE_THREAD
2040 if (tcp->flags & TCB_CLONE_THREAD)
2041 /* The children we wait for are our parent's children. */
2042 got_kids = (tcp->parent->nchildren
2043 > tcp->parent->nclone_detached);
2044 else
2045 got_kids = (tcp->nchildren > tcp->nclone_detached);
2046#else
2047 got_kids = tcp->nchildren > 0;
2048#endif
2049
2050 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00002051 /* There are children that this parent should block for.
2052 But ptrace made us the parent of the traced children
2053 and the real parent will get ECHILD from the wait call.
2054
2055 XXX If we attached with strace -f -p PID, then there
2056 may be untraced dead children the parent could be reaping
2057 now, but we make him block. */
2058
2059 /* ??? WTA: fix bug with hanging children */
2060
Roland McGrathc74c0b72004-09-01 19:39:46 +00002061 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00002062 /*
2063 * There are traced children. We'll make the parent
2064 * block to avoid a false ECHILD error due to our
2065 * ptrace having stolen the children. However,
2066 * we shouldn't block if there are zombies to reap.
2067 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
2068 */
Roland McGrathfccfb942003-10-01 21:59:44 +00002069 struct tcb *child = NULL;
Roland McGrath09623452003-05-23 02:27:13 +00002070 if (tcp->nzombies > 0 &&
2071 (tcp->u_arg[0] == -1 ||
Roland McGrathfccfb942003-10-01 21:59:44 +00002072 (child = pid2tcb(tcp->u_arg[0])) == NULL))
Roland McGrath09623452003-05-23 02:27:13 +00002073 return 0;
Roland McGrathfccfb942003-10-01 21:59:44 +00002074 if (tcp->u_arg[0] > 0) {
2075 /*
2076 * If the parent waits for a specified child
2077 * PID, then it must get ECHILD right away
2078 * if that PID is not one of its children.
2079 * Make sure that the requested PID matches
2080 * one of the parent's children that we are
2081 * tracing, and don't suspend it otherwise.
2082 */
2083 if (child == NULL)
2084 child = pid2tcb(tcp->u_arg[0]);
2085 if (child == NULL || child->parent != (
2086#ifdef TCB_CLONE_THREAD
2087 (tcp->flags & TCB_CLONE_THREAD)
2088 ? tcp->parent :
2089#endif
Roland McGrathd56a6562005-08-03 11:23:43 +00002090 tcp) ||
2091 (child->flags & TCB_EXITING))
Roland McGrathfccfb942003-10-01 21:59:44 +00002092 return 0;
2093 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002094 tcp->flags |= TCB_SUSPENDED;
2095 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002096#ifdef TCB_CLONE_THREAD
2097 if (tcp->flags & TCB_CLONE_THREAD)
2098 tcp->parent->nclone_waiting++;
2099#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002100 }
2101 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002102 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathc74c0b72004-09-01 19:39:46 +00002103 if (tcp->u_arg[flagarg] & WNOHANG) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00002104 /* We must force a fake result of 0 instead of
2105 the ECHILD error. */
2106 extern int force_result();
2107 return force_result(tcp, 0, 0);
2108 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00002109 }
Roland McGrath09623452003-05-23 02:27:13 +00002110 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2111 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2112 /*
2113 * We just reaped a child we don't know about,
2114 * presumably a zombie we already droptcb'd.
2115 */
2116 tcp->nzombies--;
2117 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002118 return 0;
2119}
2120
2121#ifdef SVR4
2122
2123int
2124sys_wait(tcp)
2125struct tcb *tcp;
2126{
2127 if (exiting(tcp)) {
2128 /* The library wrapper stuffs this into the user variable. */
2129 if (!syserror(tcp))
2130 printstatus(getrval2(tcp));
2131 }
2132 return 0;
2133}
2134
2135#endif /* SVR4 */
2136
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002137#ifdef FREEBSD
2138int
2139sys_wait(tcp)
2140struct tcb *tcp;
2141{
2142 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00002143
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002144 if (exiting(tcp)) {
2145 if (!syserror(tcp)) {
2146 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2147 tprintf("%#lx", tcp->u_arg[0]);
2148 else
2149 printstatus(status);
2150 }
2151 }
2152 return 0;
2153}
2154#endif
2155
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002156int
2157sys_waitpid(tcp)
2158struct tcb *tcp;
2159{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002160 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002161}
2162
2163int
2164sys_wait4(tcp)
2165struct tcb *tcp;
2166{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002167 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002168}
2169
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002170#ifdef ALPHA
2171int
2172sys_osf_wait4(tcp)
2173struct tcb *tcp;
2174{
2175 return printwaitn(tcp, 4, 1);
2176}
2177#endif
2178
Roland McGrathc74c0b72004-09-01 19:39:46 +00002179#if defined SVR4 || defined LINUX
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002180
Roland McGrathd9f816f2004-09-04 03:39:20 +00002181static const struct xlat waitid_types[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002182 { P_PID, "P_PID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002183#ifdef P_PPID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002184 { P_PPID, "P_PPID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002185#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002186 { P_PGID, "P_PGID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002187#ifdef P_SID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002188 { P_SID, "P_SID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002189#endif
2190#ifdef P_CID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002191 { P_CID, "P_CID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002192#endif
2193#ifdef P_UID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002194 { P_UID, "P_UID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002195#endif
2196#ifdef P_GID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002197 { P_GID, "P_GID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002198#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002199 { P_ALL, "P_ALL" },
2200#ifdef P_LWPID
2201 { P_LWPID, "P_LWPID" },
2202#endif
2203 { 0, NULL },
2204};
2205
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002206int
2207sys_waitid(tcp)
2208struct tcb *tcp;
2209{
2210 siginfo_t si;
2211 int exited;
2212
2213 if (entering(tcp)) {
2214 printxval(waitid_types, tcp->u_arg[0], "P_???");
2215 tprintf(", %ld, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002216 }
2217 else {
2218 /* siginfo */
2219 exited = 0;
2220 if (!tcp->u_arg[2])
2221 tprintf("NULL");
2222 else if (syserror(tcp))
2223 tprintf("%#lx", tcp->u_arg[2]);
2224 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2225 tprintf("{???}");
2226 else
John Hughes58265892001-10-18 15:13:53 +00002227 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002228 /* options */
2229 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00002230 printflags(wait4_options, tcp->u_arg[3], "W???");
Roland McGrath39426a32004-10-06 22:02:59 +00002231 if (tcp->u_nargs > 4) {
2232 /* usage */
2233 tprintf(", ");
2234 if (!tcp->u_arg[4])
2235 tprintf("NULL");
2236 else if (tcp->u_error)
2237 tprintf("%#lx", tcp->u_arg[4]);
2238 else
2239 printrusage(tcp, tcp->u_arg[4]);
2240 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002241 }
2242 return 0;
2243}
2244
Roland McGrathc74c0b72004-09-01 19:39:46 +00002245#endif /* SVR4 or LINUX */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002246
2247int
2248sys_alarm(tcp)
2249struct tcb *tcp;
2250{
2251 if (entering(tcp))
2252 tprintf("%lu", tcp->u_arg[0]);
2253 return 0;
2254}
2255
2256int
2257sys_uname(tcp)
2258struct tcb *tcp;
2259{
2260 struct utsname uname;
2261
2262 if (exiting(tcp)) {
2263 if (syserror(tcp) || !verbose(tcp))
2264 tprintf("%#lx", tcp->u_arg[0]);
2265 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2266 tprintf("{...}");
2267 else if (!abbrev(tcp)) {
2268
2269 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2270 uname.sysname, uname.nodename);
2271 tprintf("release=\"%s\", version=\"%s\", ",
2272 uname.release, uname.version);
2273 tprintf("machine=\"%s\"", uname.machine);
2274#ifdef LINUX
2275#ifndef __GLIBC__
2276 tprintf(", domainname=\"%s\"", uname.domainname);
2277#endif /* __GLIBC__ */
2278#endif /* LINUX */
2279 tprintf("}");
2280 }
2281 else
2282 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2283 uname.sysname, uname.nodename);
2284 }
2285 return 0;
2286}
2287
2288#ifndef SVR4
2289
Roland McGrathd9f816f2004-09-04 03:39:20 +00002290static const struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002291#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002292 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2293 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2294 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2295 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2296 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2297 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2298 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2299 { PTRACE_CONT, "PTRACE_CONT" },
2300 { PTRACE_KILL, "PTRACE_KILL" },
2301 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2302 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2303 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002304#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002305 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002306#endif
2307#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002308 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002309#endif
2310#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002311 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002312#endif
2313#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002314 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002315#endif
2316#ifdef PTRACE_GETFPXREGS
2317 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2318#endif
2319#ifdef PTRACE_SETFPXREGS
2320 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2321#endif
Roland McGrathf04bb482005-05-09 07:45:33 +00002322#ifdef PTRACE_GETVRREGS
2323 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2324#endif
2325#ifdef PTRACE_SETVRREGS
2326 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2327#endif
Roland McGrathbf621d42003-01-14 09:46:21 +00002328#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002329 { PTRACE_READDATA, "PTRACE_READDATA" },
2330 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2331 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2332 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2333 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2334 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2335#ifdef SPARC
2336 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2337 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2338#else /* !SPARC */
2339 { PTRACE_22, "PTRACE_PTRACE_22" },
2340 { PTRACE_23, "PTRACE_PTRACE_23" },
2341#endif /* !SPARC */
2342#endif /* SUNOS4 */
2343 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2344#ifdef SUNOS4
2345 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2346#ifdef I386
2347 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2348 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2349 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2350#else /* !I386 */
2351 { PTRACE_26, "PTRACE_26" },
2352 { PTRACE_27, "PTRACE_27" },
2353 { PTRACE_28, "PTRACE_28" },
2354#endif /* !I386 */
2355 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2356#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002357#else /* FREEBSD */
2358 { PT_TRACE_ME, "PT_TRACE_ME" },
2359 { PT_READ_I, "PT_READ_I" },
2360 { PT_READ_D, "PT_READ_D" },
2361 { PT_WRITE_I, "PT_WRITE_I" },
2362 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002363#ifdef PT_READ_U
2364 { PT_READ_U, "PT_READ_U" },
2365#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002366 { PT_CONTINUE, "PT_CONTINUE" },
2367 { PT_KILL, "PT_KILL" },
2368 { PT_STEP, "PT_STEP" },
2369 { PT_ATTACH, "PT_ATTACH" },
2370 { PT_DETACH, "PT_DETACH" },
2371 { PT_GETREGS, "PT_GETREGS" },
2372 { PT_SETREGS, "PT_SETREGS" },
2373 { PT_GETFPREGS, "PT_GETFPREGS" },
2374 { PT_SETFPREGS, "PT_SETFPREGS" },
2375 { PT_GETDBREGS, "PT_GETDBREGS" },
2376 { PT_SETDBREGS, "PT_SETDBREGS" },
2377#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002378 { 0, NULL },
2379};
2380
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002381#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002382#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2383static
2384#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
Roland McGrathd9f816f2004-09-04 03:39:20 +00002385const struct xlat struct_user_offsets[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002386#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002387#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002388 { PT_PSWMASK, "psw_mask" },
2389 { PT_PSWADDR, "psw_addr" },
2390 { PT_GPR0, "gpr0" },
2391 { PT_GPR1, "gpr1" },
2392 { PT_GPR2, "gpr2" },
2393 { PT_GPR3, "gpr3" },
2394 { PT_GPR4, "gpr4" },
2395 { PT_GPR5, "gpr5" },
2396 { PT_GPR6, "gpr6" },
2397 { PT_GPR7, "gpr7" },
2398 { PT_GPR8, "gpr8" },
2399 { PT_GPR9, "gpr9" },
2400 { PT_GPR10, "gpr10" },
2401 { PT_GPR11, "gpr11" },
2402 { PT_GPR12, "gpr12" },
2403 { PT_GPR13, "gpr13" },
2404 { PT_GPR14, "gpr14" },
2405 { PT_GPR15, "gpr15" },
2406 { PT_ACR0, "acr0" },
2407 { PT_ACR1, "acr1" },
2408 { PT_ACR2, "acr2" },
2409 { PT_ACR3, "acr3" },
2410 { PT_ACR4, "acr4" },
2411 { PT_ACR5, "acr5" },
2412 { PT_ACR6, "acr6" },
2413 { PT_ACR7, "acr7" },
2414 { PT_ACR8, "acr8" },
2415 { PT_ACR9, "acr9" },
2416 { PT_ACR10, "acr10" },
2417 { PT_ACR11, "acr11" },
2418 { PT_ACR12, "acr12" },
2419 { PT_ACR13, "acr13" },
2420 { PT_ACR14, "acr14" },
2421 { PT_ACR15, "acr15" },
2422 { PT_ORIGGPR2, "orig_gpr2" },
2423 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002424#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002425 { PT_FPR0_HI, "fpr0.hi" },
2426 { PT_FPR0_LO, "fpr0.lo" },
2427 { PT_FPR1_HI, "fpr1.hi" },
2428 { PT_FPR1_LO, "fpr1.lo" },
2429 { PT_FPR2_HI, "fpr2.hi" },
2430 { PT_FPR2_LO, "fpr2.lo" },
2431 { PT_FPR3_HI, "fpr3.hi" },
2432 { PT_FPR3_LO, "fpr3.lo" },
2433 { PT_FPR4_HI, "fpr4.hi" },
2434 { PT_FPR4_LO, "fpr4.lo" },
2435 { PT_FPR5_HI, "fpr5.hi" },
2436 { PT_FPR5_LO, "fpr5.lo" },
2437 { PT_FPR6_HI, "fpr6.hi" },
2438 { PT_FPR6_LO, "fpr6.lo" },
2439 { PT_FPR7_HI, "fpr7.hi" },
2440 { PT_FPR7_LO, "fpr7.lo" },
2441 { PT_FPR8_HI, "fpr8.hi" },
2442 { PT_FPR8_LO, "fpr8.lo" },
2443 { PT_FPR9_HI, "fpr9.hi" },
2444 { PT_FPR9_LO, "fpr9.lo" },
2445 { PT_FPR10_HI, "fpr10.hi" },
2446 { PT_FPR10_LO, "fpr10.lo" },
2447 { PT_FPR11_HI, "fpr11.hi" },
2448 { PT_FPR11_LO, "fpr11.lo" },
2449 { PT_FPR12_HI, "fpr12.hi" },
2450 { PT_FPR12_LO, "fpr12.lo" },
2451 { PT_FPR13_HI, "fpr13.hi" },
2452 { PT_FPR13_LO, "fpr13.lo" },
2453 { PT_FPR14_HI, "fpr14.hi" },
2454 { PT_FPR14_LO, "fpr14.lo" },
2455 { PT_FPR15_HI, "fpr15.hi" },
2456 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002457#endif
2458#if defined(S390X)
2459 { PT_FPR0, "fpr0" },
2460 { PT_FPR1, "fpr1" },
2461 { PT_FPR2, "fpr2" },
2462 { PT_FPR3, "fpr3" },
2463 { PT_FPR4, "fpr4" },
2464 { PT_FPR5, "fpr5" },
2465 { PT_FPR6, "fpr6" },
2466 { PT_FPR7, "fpr7" },
2467 { PT_FPR8, "fpr8" },
2468 { PT_FPR9, "fpr9" },
2469 { PT_FPR10, "fpr10" },
2470 { PT_FPR11, "fpr11" },
2471 { PT_FPR12, "fpr12" },
2472 { PT_FPR13, "fpr13" },
2473 { PT_FPR14, "fpr14" },
2474 { PT_FPR15, "fpr15" },
2475#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002476 { PT_CR_9, "cr9" },
2477 { PT_CR_10, "cr10" },
2478 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002479 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002480#endif
2481#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002482 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002483#elif defined(HPPA)
2484 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002485#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002486#ifndef PT_ORIG_R3
2487#define PT_ORIG_R3 34
2488#endif
Roland McGratheb285352003-01-14 09:59:00 +00002489#define REGSIZE (sizeof(unsigned long))
2490 { REGSIZE*PT_R0, "r0" },
2491 { REGSIZE*PT_R1, "r1" },
2492 { REGSIZE*PT_R2, "r2" },
2493 { REGSIZE*PT_R3, "r3" },
2494 { REGSIZE*PT_R4, "r4" },
2495 { REGSIZE*PT_R5, "r5" },
2496 { REGSIZE*PT_R6, "r6" },
2497 { REGSIZE*PT_R7, "r7" },
2498 { REGSIZE*PT_R8, "r8" },
2499 { REGSIZE*PT_R9, "r9" },
2500 { REGSIZE*PT_R10, "r10" },
2501 { REGSIZE*PT_R11, "r11" },
2502 { REGSIZE*PT_R12, "r12" },
2503 { REGSIZE*PT_R13, "r13" },
2504 { REGSIZE*PT_R14, "r14" },
2505 { REGSIZE*PT_R15, "r15" },
2506 { REGSIZE*PT_R16, "r16" },
2507 { REGSIZE*PT_R17, "r17" },
2508 { REGSIZE*PT_R18, "r18" },
2509 { REGSIZE*PT_R19, "r19" },
2510 { REGSIZE*PT_R20, "r20" },
2511 { REGSIZE*PT_R21, "r21" },
2512 { REGSIZE*PT_R22, "r22" },
2513 { REGSIZE*PT_R23, "r23" },
2514 { REGSIZE*PT_R24, "r24" },
2515 { REGSIZE*PT_R25, "r25" },
2516 { REGSIZE*PT_R26, "r26" },
2517 { REGSIZE*PT_R27, "r27" },
2518 { REGSIZE*PT_R28, "r28" },
2519 { REGSIZE*PT_R29, "r29" },
2520 { REGSIZE*PT_R30, "r30" },
2521 { REGSIZE*PT_R31, "r31" },
2522 { REGSIZE*PT_NIP, "NIP" },
2523 { REGSIZE*PT_MSR, "MSR" },
2524 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2525 { REGSIZE*PT_CTR, "CTR" },
2526 { REGSIZE*PT_LNK, "LNK" },
2527 { REGSIZE*PT_XER, "XER" },
2528 { REGSIZE*PT_CCR, "CCR" },
2529 { REGSIZE*PT_FPR0, "FPR0" },
2530#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002531#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002532#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002533 { 0, "r0" },
2534 { 1, "r1" },
2535 { 2, "r2" },
2536 { 3, "r3" },
2537 { 4, "r4" },
2538 { 5, "r5" },
2539 { 6, "r6" },
2540 { 7, "r7" },
2541 { 8, "r8" },
2542 { 9, "r9" },
2543 { 10, "r10" },
2544 { 11, "r11" },
2545 { 12, "r12" },
2546 { 13, "r13" },
2547 { 14, "r14" },
2548 { 15, "r15" },
2549 { 16, "r16" },
2550 { 17, "r17" },
2551 { 18, "r18" },
2552 { 19, "r19" },
2553 { 20, "r20" },
2554 { 21, "r21" },
2555 { 22, "r22" },
2556 { 23, "r23" },
2557 { 24, "r24" },
2558 { 25, "r25" },
2559 { 26, "r26" },
2560 { 27, "r27" },
2561 { 28, "r28" },
2562 { 29, "gp" },
2563 { 30, "fp" },
2564 { 31, "zero" },
2565 { 32, "fp0" },
2566 { 33, "fp" },
2567 { 34, "fp2" },
2568 { 35, "fp3" },
2569 { 36, "fp4" },
2570 { 37, "fp5" },
2571 { 38, "fp6" },
2572 { 39, "fp7" },
2573 { 40, "fp8" },
2574 { 41, "fp9" },
2575 { 42, "fp10" },
2576 { 43, "fp11" },
2577 { 44, "fp12" },
2578 { 45, "fp13" },
2579 { 46, "fp14" },
2580 { 47, "fp15" },
2581 { 48, "fp16" },
2582 { 49, "fp17" },
2583 { 50, "fp18" },
2584 { 51, "fp19" },
2585 { 52, "fp20" },
2586 { 53, "fp21" },
2587 { 54, "fp22" },
2588 { 55, "fp23" },
2589 { 56, "fp24" },
2590 { 57, "fp25" },
2591 { 58, "fp26" },
2592 { 59, "fp27" },
2593 { 60, "fp28" },
2594 { 61, "fp29" },
2595 { 62, "fp30" },
2596 { 63, "fp31" },
2597 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002598#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002599#ifdef IA64
2600 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2601 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2602 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2603 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2604 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2605 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2606 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2607 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2608 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2609 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2610 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2611 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2612 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2613 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2614 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2615 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2616 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2617 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2618 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2619 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2620 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2621 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2622 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2623 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2624 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2625 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2626 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2627 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2628 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2629 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2630 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2631 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2632 /* switch stack: */
2633 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2634 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2635 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2636 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2637 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2638 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2639 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2640 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2641 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2642 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002643 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2644 { PT_B4, "b4" }, { PT_B5, "b5" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002645 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002646 /* pt_regs */
Roland McGrathca4e10c2004-01-13 10:13:20 +00002647 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2648 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002649 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2650 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2651 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2652 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2653 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2654 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2655 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2656 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2657 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2658 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2659 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2660 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2661 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2662 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2663 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
Roland McGrathfb1bc072004-03-01 21:29:24 +00002664# ifdef PT_AR_CSD
2665 { PT_AR_CSD, "ar.csd" },
2666# endif
2667# ifdef PT_AR_SSD
2668 { PT_AR_SSD, "ar.ssd" },
2669# endif
Roland McGrathca4e10c2004-01-13 10:13:20 +00002670 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002671#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002672#ifdef I386
2673 { 4*EBX, "4*EBX" },
2674 { 4*ECX, "4*ECX" },
2675 { 4*EDX, "4*EDX" },
2676 { 4*ESI, "4*ESI" },
2677 { 4*EDI, "4*EDI" },
2678 { 4*EBP, "4*EBP" },
2679 { 4*EAX, "4*EAX" },
2680 { 4*DS, "4*DS" },
2681 { 4*ES, "4*ES" },
2682 { 4*FS, "4*FS" },
2683 { 4*GS, "4*GS" },
2684 { 4*ORIG_EAX, "4*ORIG_EAX" },
2685 { 4*EIP, "4*EIP" },
2686 { 4*CS, "4*CS" },
2687 { 4*EFL, "4*EFL" },
2688 { 4*UESP, "4*UESP" },
2689 { 4*SS, "4*SS" },
2690#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002691#ifdef X86_64
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002692 { 8*R15, "8*R15" },
2693 { 8*R14, "8*R14" },
2694 { 8*R13, "8*R13" },
2695 { 8*R12, "8*R12" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002696 { 8*RBP, "8*RBP" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002697 { 8*RBX, "8*RBX" },
2698 { 8*R11, "8*R11" },
2699 { 8*R10, "8*R10" },
2700 { 8*R9, "8*R9" },
2701 { 8*R8, "8*R8" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002702 { 8*RAX, "8*RAX" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002703 { 8*RCX, "8*RCX" },
2704 { 8*RDX, "8*RDX" },
2705 { 8*RSI, "8*RSI" },
2706 { 8*RDI, "8*RDI" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002707#if 0
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002708 { DS, "DS" },
2709 { ES, "ES" },
2710 { FS, "FS" },
2711 { GS, "GS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002712#endif
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002713 { 8*ORIG_RAX, "8*ORIG_RAX" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002714 { 8*RIP, "8*RIP" },
2715 { 8*CS, "8*CS" },
2716 { 8*EFLAGS, "8*EFL" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002717 { 8*RSP, "8*RSP" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002718 { 8*SS, "8*SS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002719#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002720#ifdef M68K
2721 { 4*PT_D1, "4*PT_D1" },
2722 { 4*PT_D2, "4*PT_D2" },
2723 { 4*PT_D3, "4*PT_D3" },
2724 { 4*PT_D4, "4*PT_D4" },
2725 { 4*PT_D5, "4*PT_D5" },
2726 { 4*PT_D6, "4*PT_D6" },
2727 { 4*PT_D7, "4*PT_D7" },
2728 { 4*PT_A0, "4*PT_A0" },
2729 { 4*PT_A1, "4*PT_A1" },
2730 { 4*PT_A2, "4*PT_A2" },
2731 { 4*PT_A3, "4*PT_A3" },
2732 { 4*PT_A4, "4*PT_A4" },
2733 { 4*PT_A5, "4*PT_A5" },
2734 { 4*PT_A6, "4*PT_A6" },
2735 { 4*PT_D0, "4*PT_D0" },
2736 { 4*PT_USP, "4*PT_USP" },
2737 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2738 { 4*PT_SR, "4*PT_SR" },
2739 { 4*PT_PC, "4*PT_PC" },
2740#endif /* M68K */
2741#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002742#ifdef SH
2743 { 4*REG_REG0, "4*REG_REG0" },
2744 { 4*(REG_REG0+1), "4*REG_REG1" },
2745 { 4*(REG_REG0+2), "4*REG_REG2" },
2746 { 4*(REG_REG0+3), "4*REG_REG3" },
2747 { 4*(REG_REG0+4), "4*REG_REG4" },
2748 { 4*(REG_REG0+5), "4*REG_REG5" },
2749 { 4*(REG_REG0+6), "4*REG_REG6" },
2750 { 4*(REG_REG0+7), "4*REG_REG7" },
2751 { 4*(REG_REG0+8), "4*REG_REG8" },
2752 { 4*(REG_REG0+9), "4*REG_REG9" },
2753 { 4*(REG_REG0+10), "4*REG_REG10" },
2754 { 4*(REG_REG0+11), "4*REG_REG11" },
2755 { 4*(REG_REG0+12), "4*REG_REG12" },
2756 { 4*(REG_REG0+13), "4*REG_REG13" },
2757 { 4*(REG_REG0+14), "4*REG_REG14" },
2758 { 4*REG_REG15, "4*REG_REG15" },
2759 { 4*REG_PC, "4*REG_PC" },
2760 { 4*REG_PR, "4*REG_PR" },
2761 { 4*REG_SR, "4*REG_SR" },
2762 { 4*REG_GBR, "4*REG_GBR" },
2763 { 4*REG_MACH, "4*REG_MACH" },
2764 { 4*REG_MACL, "4*REG_MACL" },
2765 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2766 { 4*REG_FPUL, "4*REG_FPUL" },
2767 { 4*REG_FPREG0, "4*REG_FPREG0" },
2768 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2769 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2770 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2771 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2772 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2773 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2774 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2775 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2776 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2777 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2778 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2779 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2780 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2781 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2782 { 4*REG_FPREG15, "4*REG_FPREG15" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002783#ifdef REG_XDREG0
Wichert Akkermanccef6372002-05-01 16:39:22 +00002784 { 4*REG_XDREG0, "4*REG_XDREG0" },
2785 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2786 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2787 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2788 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2789 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2790 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2791 { 4*REG_XDREG14, "4*REG_XDREG14" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002792#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002793 { 4*REG_FPSCR, "4*REG_FPSCR" },
2794#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002795#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002796 { 0, "PC(L)" },
2797 { 4, "PC(U)" },
2798 { 8, "SR(L)" },
2799 { 12, "SR(U)" },
2800 { 16, "syscall no.(L)" },
2801 { 20, "syscall_no.(U)" },
2802 { 24, "R0(L)" },
2803 { 28, "R0(U)" },
2804 { 32, "R1(L)" },
2805 { 36, "R1(U)" },
2806 { 40, "R2(L)" },
2807 { 44, "R2(U)" },
2808 { 48, "R3(L)" },
2809 { 52, "R3(U)" },
2810 { 56, "R4(L)" },
2811 { 60, "R4(U)" },
2812 { 64, "R5(L)" },
2813 { 68, "R5(U)" },
2814 { 72, "R6(L)" },
2815 { 76, "R6(U)" },
2816 { 80, "R7(L)" },
2817 { 84, "R7(U)" },
2818 { 88, "R8(L)" },
2819 { 92, "R8(U)" },
2820 { 96, "R9(L)" },
2821 { 100, "R9(U)" },
2822 { 104, "R10(L)" },
2823 { 108, "R10(U)" },
2824 { 112, "R11(L)" },
2825 { 116, "R11(U)" },
2826 { 120, "R12(L)" },
2827 { 124, "R12(U)" },
2828 { 128, "R13(L)" },
2829 { 132, "R13(U)" },
2830 { 136, "R14(L)" },
2831 { 140, "R14(U)" },
2832 { 144, "R15(L)" },
2833 { 148, "R15(U)" },
2834 { 152, "R16(L)" },
2835 { 156, "R16(U)" },
2836 { 160, "R17(L)" },
2837 { 164, "R17(U)" },
2838 { 168, "R18(L)" },
2839 { 172, "R18(U)" },
2840 { 176, "R19(L)" },
2841 { 180, "R19(U)" },
2842 { 184, "R20(L)" },
2843 { 188, "R20(U)" },
2844 { 192, "R21(L)" },
2845 { 196, "R21(U)" },
2846 { 200, "R22(L)" },
2847 { 204, "R22(U)" },
2848 { 208, "R23(L)" },
2849 { 212, "R23(U)" },
2850 { 216, "R24(L)" },
2851 { 220, "R24(U)" },
2852 { 224, "R25(L)" },
2853 { 228, "R25(U)" },
2854 { 232, "R26(L)" },
2855 { 236, "R26(U)" },
2856 { 240, "R27(L)" },
2857 { 244, "R27(U)" },
2858 { 248, "R28(L)" },
2859 { 252, "R28(U)" },
2860 { 256, "R29(L)" },
2861 { 260, "R29(U)" },
2862 { 264, "R30(L)" },
2863 { 268, "R30(U)" },
2864 { 272, "R31(L)" },
2865 { 276, "R31(U)" },
2866 { 280, "R32(L)" },
2867 { 284, "R32(U)" },
2868 { 288, "R33(L)" },
2869 { 292, "R33(U)" },
2870 { 296, "R34(L)" },
2871 { 300, "R34(U)" },
2872 { 304, "R35(L)" },
2873 { 308, "R35(U)" },
2874 { 312, "R36(L)" },
2875 { 316, "R36(U)" },
2876 { 320, "R37(L)" },
2877 { 324, "R37(U)" },
2878 { 328, "R38(L)" },
2879 { 332, "R38(U)" },
2880 { 336, "R39(L)" },
2881 { 340, "R39(U)" },
2882 { 344, "R40(L)" },
2883 { 348, "R40(U)" },
2884 { 352, "R41(L)" },
2885 { 356, "R41(U)" },
2886 { 360, "R42(L)" },
2887 { 364, "R42(U)" },
2888 { 368, "R43(L)" },
2889 { 372, "R43(U)" },
2890 { 376, "R44(L)" },
2891 { 380, "R44(U)" },
2892 { 384, "R45(L)" },
2893 { 388, "R45(U)" },
2894 { 392, "R46(L)" },
2895 { 396, "R46(U)" },
2896 { 400, "R47(L)" },
2897 { 404, "R47(U)" },
2898 { 408, "R48(L)" },
2899 { 412, "R48(U)" },
2900 { 416, "R49(L)" },
2901 { 420, "R49(U)" },
2902 { 424, "R50(L)" },
2903 { 428, "R50(U)" },
2904 { 432, "R51(L)" },
2905 { 436, "R51(U)" },
2906 { 440, "R52(L)" },
2907 { 444, "R52(U)" },
2908 { 448, "R53(L)" },
2909 { 452, "R53(U)" },
2910 { 456, "R54(L)" },
2911 { 460, "R54(U)" },
2912 { 464, "R55(L)" },
2913 { 468, "R55(U)" },
2914 { 472, "R56(L)" },
2915 { 476, "R56(U)" },
2916 { 480, "R57(L)" },
2917 { 484, "R57(U)" },
2918 { 488, "R58(L)" },
2919 { 492, "R58(U)" },
2920 { 496, "R59(L)" },
2921 { 500, "R59(U)" },
2922 { 504, "R60(L)" },
2923 { 508, "R60(U)" },
2924 { 512, "R61(L)" },
2925 { 516, "R61(U)" },
2926 { 520, "R62(L)" },
2927 { 524, "R62(U)" },
2928 { 528, "TR0(L)" },
2929 { 532, "TR0(U)" },
2930 { 536, "TR1(L)" },
2931 { 540, "TR1(U)" },
2932 { 544, "TR2(L)" },
2933 { 548, "TR2(U)" },
2934 { 552, "TR3(L)" },
2935 { 556, "TR3(U)" },
2936 { 560, "TR4(L)" },
2937 { 564, "TR4(U)" },
2938 { 568, "TR5(L)" },
2939 { 572, "TR5(U)" },
2940 { 576, "TR6(L)" },
2941 { 580, "TR6(U)" },
2942 { 584, "TR7(L)" },
2943 { 588, "TR7(U)" },
2944 /* This entry is in case pt_regs contains dregs (depends on
2945 the kernel build options). */
2946 { uoff(regs), "offsetof(struct user, regs)" },
2947 { uoff(fpu), "offsetof(struct user, fpu)" },
2948#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002949#ifdef ARM
2950 { uoff(regs.ARM_r0), "r0" },
2951 { uoff(regs.ARM_r1), "r1" },
2952 { uoff(regs.ARM_r2), "r2" },
2953 { uoff(regs.ARM_r3), "r3" },
2954 { uoff(regs.ARM_r4), "r4" },
2955 { uoff(regs.ARM_r5), "r5" },
2956 { uoff(regs.ARM_r6), "r6" },
2957 { uoff(regs.ARM_r7), "r7" },
2958 { uoff(regs.ARM_r8), "r8" },
2959 { uoff(regs.ARM_r9), "r9" },
2960 { uoff(regs.ARM_r10), "r10" },
2961 { uoff(regs.ARM_fp), "fp" },
2962 { uoff(regs.ARM_ip), "ip" },
2963 { uoff(regs.ARM_sp), "sp" },
2964 { uoff(regs.ARM_lr), "lr" },
2965 { uoff(regs.ARM_pc), "pc" },
2966 { uoff(regs.ARM_cpsr), "cpsr" },
2967#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002968
Roland McGrath542c2c62008-05-20 01:11:56 +00002969#ifdef MIPS
2970 { 0, "r0" },
2971 { 1, "r1" },
2972 { 2, "r2" },
2973 { 3, "r3" },
2974 { 4, "r4" },
2975 { 5, "r5" },
2976 { 6, "r6" },
2977 { 7, "r7" },
2978 { 8, "r8" },
2979 { 9, "r9" },
2980 { 10, "r10" },
2981 { 11, "r11" },
2982 { 12, "r12" },
2983 { 13, "r13" },
2984 { 14, "r14" },
2985 { 15, "r15" },
2986 { 16, "r16" },
2987 { 17, "r17" },
2988 { 18, "r18" },
2989 { 19, "r19" },
2990 { 20, "r20" },
2991 { 21, "r21" },
2992 { 22, "r22" },
2993 { 23, "r23" },
2994 { 24, "r24" },
2995 { 25, "r25" },
2996 { 26, "r26" },
2997 { 27, "r27" },
2998 { 28, "r28" },
2999 { 29, "r29" },
3000 { 30, "r30" },
3001 { 31, "r31" },
3002 { 32, "f0" },
3003 { 33, "f1" },
3004 { 34, "f2" },
3005 { 35, "f3" },
3006 { 36, "f4" },
3007 { 37, "f5" },
3008 { 38, "f6" },
3009 { 39, "f7" },
3010 { 40, "f8" },
3011 { 41, "f9" },
3012 { 42, "f10" },
3013 { 43, "f11" },
3014 { 44, "f12" },
3015 { 45, "f13" },
3016 { 46, "f14" },
3017 { 47, "f15" },
3018 { 48, "f16" },
3019 { 49, "f17" },
3020 { 50, "f18" },
3021 { 51, "f19" },
3022 { 52, "f20" },
3023 { 53, "f21" },
3024 { 54, "f22" },
3025 { 55, "f23" },
3026 { 56, "f24" },
3027 { 57, "f25" },
3028 { 58, "f26" },
3029 { 59, "f27" },
3030 { 60, "f28" },
3031 { 61, "f29" },
3032 { 62, "f30" },
3033 { 63, "f31" },
3034 { 64, "pc" },
3035 { 65, "cause" },
3036 { 66, "badvaddr" },
3037 { 67, "mmhi" },
3038 { 68, "mmlo" },
3039 { 69, "fpcsr" },
3040 { 70, "fpeir" },
3041#endif
3042
Dmitry V. Levin87ea1f42008-11-10 22:21:41 +00003043#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(BFIN)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003044 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00003045#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00003046#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003047 { uoff(i387), "offsetof(struct user, i387)" },
3048#else /* !I386 */
3049#ifdef M68K
3050 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3051#endif /* M68K */
3052#endif /* !I386 */
3053 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3054 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3055 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003056#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003057 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003058#endif
Roland McGrathf5a47772003-06-26 22:40:42 +00003059#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00003060 { uoff(start_data), "offsetof(struct user, start_data)" },
3061#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003062#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003063 { uoff(start_stack), "offsetof(struct user, start_stack)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003064#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003065 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003066#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003067 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00003068#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003069#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003070 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003071#endif
Dmitry V. Levin87ea1f42008-11-10 22:21:41 +00003072#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003073 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3074#endif
3075 { uoff(magic), "offsetof(struct user, magic)" },
3076 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00003077#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003078 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3079#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00003080#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003081#endif /* !ALPHA */
3082#endif /* !POWERPC/!SPARC */
3083#endif /* LINUX */
3084#ifdef SUNOS4
3085 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3086 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3087 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3088 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3089 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3090 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3091 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3092 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3093 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3094 { uoff(u_error), "offsetof(struct user, u_error)" },
3095 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3096 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3097 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3098 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3099 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3100 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3101 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3102 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3103 { uoff(u_code), "offsetof(struct user, u_code)" },
3104 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3105 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3106 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3107 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3108 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3109 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3110 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3111 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3112 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3113 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3114 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3115 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3116 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3117 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3118 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3119 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3120 { uoff(u_start), "offsetof(struct user, u_start)" },
3121 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3122 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3123 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3124 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3125 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3126 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3127 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3128 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3129 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3130#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00003131#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003132 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00003133#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003134 { 0, NULL },
3135};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003136#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003137
3138int
3139sys_ptrace(tcp)
3140struct tcb *tcp;
3141{
Roland McGrathd9f816f2004-09-04 03:39:20 +00003142 const struct xlat *x;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003143 long addr;
3144
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003145 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00003146 printxval(ptrace_cmds, tcp->u_arg[0],
3147#ifndef FREEBSD
3148 "PTRACE_???"
3149#else
3150 "PT_???"
3151#endif
3152 );
3153 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003154 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003155#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003156 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3157 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3158 for (x = struct_user_offsets; x->str; x++) {
3159 if (x->val >= addr)
3160 break;
3161 }
3162 if (!x->str)
3163 tprintf("%#lx, ", addr);
3164 else if (x->val > addr && x != struct_user_offsets) {
3165 x--;
3166 tprintf("%s + %ld, ", x->str, addr - x->val);
3167 }
3168 else
3169 tprintf("%s, ", x->str);
3170 }
3171 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003172#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003173 tprintf("%#lx, ", tcp->u_arg[2]);
3174#ifdef LINUX
3175 switch (tcp->u_arg[0]) {
Roland McGrath1e868062007-11-19 22:11:45 +00003176#ifndef IA64
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003177 case PTRACE_PEEKDATA:
3178 case PTRACE_PEEKTEXT:
3179 case PTRACE_PEEKUSER:
3180 break;
Roland McGrath1e868062007-11-19 22:11:45 +00003181#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003182 case PTRACE_CONT:
3183 case PTRACE_SINGLESTEP:
3184 case PTRACE_SYSCALL:
3185 case PTRACE_DETACH:
3186 printsignal(tcp->u_arg[3]);
3187 break;
3188 default:
3189 tprintf("%#lx", tcp->u_arg[3]);
3190 break;
3191 }
3192 } else {
3193 switch (tcp->u_arg[0]) {
3194 case PTRACE_PEEKDATA:
3195 case PTRACE_PEEKTEXT:
3196 case PTRACE_PEEKUSER:
Roland McGrath1e868062007-11-19 22:11:45 +00003197#ifdef IA64
3198 return RVAL_HEX;
3199#else
Roland McGratheb285352003-01-14 09:59:00 +00003200 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003201 break;
Roland McGrath1e868062007-11-19 22:11:45 +00003202#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003203 }
3204 }
3205#endif /* LINUX */
3206#ifdef SUNOS4
3207 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3208 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3209 tprintf("%lu, ", tcp->u_arg[3]);
3210 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3211 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3212 tcp->u_arg[0] != PTRACE_READTEXT) {
3213 tprintf("%#lx", tcp->u_arg[3]);
3214 }
3215 } else {
3216 if (tcp->u_arg[0] == PTRACE_READDATA ||
3217 tcp->u_arg[0] == PTRACE_READTEXT) {
3218 tprintf("%lu, ", tcp->u_arg[3]);
3219 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3220 }
3221 }
3222#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003223#ifdef FREEBSD
3224 tprintf("%lu", tcp->u_arg[3]);
3225 }
3226#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003227 return 0;
3228}
3229
3230#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00003231
3232#ifdef LINUX
Roland McGrath51942a92007-07-05 18:59:11 +00003233# ifndef FUTEX_CMP_REQUEUE
3234# define FUTEX_CMP_REQUEUE 4
3235# endif
3236# ifndef FUTEX_WAKE_OP
3237# define FUTEX_WAKE_OP 5
3238# endif
3239# ifndef FUTEX_LOCK_PI
3240# define FUTEX_LOCK_PI 6
3241# define FUTEX_UNLOCK_PI 7
3242# define FUTEX_TRYLOCK_PI 8
3243# endif
Roland McGrath1aeaf742008-07-18 01:27:39 +00003244# ifndef FUTEX_WAIT_BITSET
3245# define FUTEX_WAIT_BITSET 9
3246# endif
3247# ifndef FUTEX_WAKE_BITSET
3248# define FUTEX_WAKE_BITSET 10
Roland McGrath51942a92007-07-05 18:59:11 +00003249# endif
3250# ifndef FUTEX_PRIVATE_FLAG
3251# define FUTEX_PRIVATE_FLAG 128
3252# endif
Roland McGrathd9f816f2004-09-04 03:39:20 +00003253static const struct xlat futexops[] = {
Roland McGrath51942a92007-07-05 18:59:11 +00003254 { FUTEX_WAIT, "FUTEX_WAIT" },
3255 { FUTEX_WAKE, "FUTEX_WAKE" },
3256 { FUTEX_FD, "FUTEX_FD" },
3257 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3258 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3259 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3260 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3261 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3262 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
Roland McGrath1aeaf742008-07-18 01:27:39 +00003263 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3264 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
Roland McGrath51942a92007-07-05 18:59:11 +00003265 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3266 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3267 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3268 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3269 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3270 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3271 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3272 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3273 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
Roland McGrath1aeaf742008-07-18 01:27:39 +00003274 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3275 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
Roland McGrath51942a92007-07-05 18:59:11 +00003276 { 0, NULL }
3277};
3278#ifndef FUTEX_OP_SET
3279# define FUTEX_OP_SET 0
3280# define FUTEX_OP_ADD 1
3281# define FUTEX_OP_OR 2
3282# define FUTEX_OP_ANDN 3
3283# define FUTEX_OP_XOR 4
3284# define FUTEX_OP_CMP_EQ 0
3285# define FUTEX_OP_CMP_NE 1
3286# define FUTEX_OP_CMP_LT 2
3287# define FUTEX_OP_CMP_LE 3
3288# define FUTEX_OP_CMP_GT 4
3289# define FUTEX_OP_CMP_GE 5
3290#endif
3291static const struct xlat futexwakeops[] = {
3292 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3293 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3294 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3295 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3296 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3297 { 0, NULL }
3298};
3299static const struct xlat futexwakecmps[] = {
3300 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3301 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3302 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3303 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3304 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3305 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3306 { 0, NULL }
Roland McGrath5a223472002-12-15 23:58:26 +00003307};
3308
3309int
3310sys_futex(tcp)
3311struct tcb *tcp;
3312{
3313 if (entering(tcp)) {
Roland McGrath1aeaf742008-07-18 01:27:39 +00003314 long int cmd = tcp->u_arg[1] & 127;
Roland McGrath5a223472002-12-15 23:58:26 +00003315 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00003316 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003317 tprintf(", %ld", tcp->u_arg[2]);
Roland McGrath1aeaf742008-07-18 01:27:39 +00003318 if (cmd == FUTEX_WAKE_BITSET)
3319 tprintf(", %lx", tcp->u_arg[5]);
3320 else if (cmd == FUTEX_WAIT) {
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003321 tprintf(", ");
3322 printtv(tcp, tcp->u_arg[3]);
Roland McGrath1aeaf742008-07-18 01:27:39 +00003323 } else if (cmd == FUTEX_WAIT_BITSET) {
3324 tprintf(", ");
3325 printtv(tcp, tcp->u_arg[3]);
3326 tprintf(", %lx", tcp->u_arg[5]);
Roland McGrath51942a92007-07-05 18:59:11 +00003327 } else if (cmd == FUTEX_REQUEUE)
Roland McGrath88812d62003-06-26 22:27:23 +00003328 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath51942a92007-07-05 18:59:11 +00003329 else if (cmd == FUTEX_CMP_REQUEUE)
3330 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3331 else if (cmd == FUTEX_WAKE_OP) {
3332 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3333 if ((tcp->u_arg[5] >> 28) & 8)
3334 tprintf("FUTEX_OP_OPARG_SHIFT|");
3335 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3336 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3337 if ((tcp->u_arg[5] >> 24) & 8)
3338 tprintf("FUTEX_OP_OPARG_SHIFT|");
3339 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3340 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3341 }
Roland McGrath5a223472002-12-15 23:58:26 +00003342 }
3343 return 0;
3344}
3345
3346static void
Roland McGrath79fbda52004-04-14 02:45:55 +00003347print_affinitylist(tcp, list, len)
3348struct tcb *tcp;
3349long list;
Roland McGrath5a223472002-12-15 23:58:26 +00003350unsigned int len;
3351{
3352 int first = 1;
3353 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00003354 while (len >= sizeof (unsigned long)) {
Roland McGrath79fbda52004-04-14 02:45:55 +00003355 unsigned long w;
3356 umove(tcp, list, &w);
3357 tprintf("%s %lx", first ? "" : ",", w);
Roland McGrath5a223472002-12-15 23:58:26 +00003358 first = 0;
3359 len -= sizeof (unsigned long);
Roland McGrath79fbda52004-04-14 02:45:55 +00003360 list += sizeof(unsigned long);
Roland McGrath5a223472002-12-15 23:58:26 +00003361 }
3362 tprintf(" }");
3363}
3364
3365int
3366sys_sched_setaffinity(tcp)
3367struct tcb *tcp;
3368{
3369 if (entering(tcp)) {
3370 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath79fbda52004-04-14 02:45:55 +00003371 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
Roland McGrath5a223472002-12-15 23:58:26 +00003372 }
3373 return 0;
3374}
3375
3376int
3377sys_sched_getaffinity(tcp)
3378struct tcb *tcp;
3379{
3380 if (entering(tcp)) {
3381 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3382 } else {
Roland McGrath79fbda52004-04-14 02:45:55 +00003383 if (tcp->u_rval == -1)
3384 tprintf("%#lx", tcp->u_arg[2]);
3385 else
3386 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
Roland McGrath5a223472002-12-15 23:58:26 +00003387 }
3388 return 0;
3389}
Roland McGrath279d3782004-03-01 20:27:37 +00003390
Roland McGrathd9f816f2004-09-04 03:39:20 +00003391static const struct xlat schedulers[] = {
Roland McGrath279d3782004-03-01 20:27:37 +00003392 { SCHED_OTHER, "SCHED_OTHER" },
3393 { SCHED_RR, "SCHED_RR" },
3394 { SCHED_FIFO, "SCHED_FIFO" },
3395 { 0, NULL }
3396};
3397
3398int
3399sys_sched_getscheduler(tcp)
3400struct tcb *tcp;
3401{
3402 if (entering(tcp)) {
3403 tprintf("%d", (int) tcp->u_arg[0]);
3404 } else if (! syserror(tcp)) {
3405 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3406 if (tcp->auxstr != NULL)
3407 return RVAL_STR;
3408 }
3409 return 0;
3410}
3411
3412int
3413sys_sched_setscheduler(tcp)
3414struct tcb *tcp;
3415{
3416 if (entering(tcp)) {
3417 struct sched_param p;
3418 tprintf("%d, ", (int) tcp->u_arg[0]);
3419 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3420 if (umove(tcp, tcp->u_arg[2], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003421 tprintf(", %#lx", tcp->u_arg[2]);
Roland McGrath279d3782004-03-01 20:27:37 +00003422 else
3423 tprintf(", { %d }", p.__sched_priority);
3424 }
3425 return 0;
3426}
3427
3428int
3429sys_sched_getparam(tcp)
3430struct tcb *tcp;
3431{
3432 if (entering(tcp)) {
3433 tprintf("%d, ", (int) tcp->u_arg[0]);
3434 } else {
3435 struct sched_param p;
3436 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003437 tprintf("%#lx", tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003438 else
3439 tprintf("{ %d }", p.__sched_priority);
3440 }
3441 return 0;
3442}
3443
3444int
3445sys_sched_setparam(tcp)
3446struct tcb *tcp;
3447{
3448 if (entering(tcp)) {
3449 struct sched_param p;
3450 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003451 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003452 else
3453 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3454 }
3455 return 0;
3456}
3457
3458int
3459sys_sched_get_priority_min(tcp)
3460struct tcb *tcp;
3461{
3462 if (entering(tcp)) {
3463 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3464 }
3465 return 0;
3466}
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003467
3468#ifdef X86_64
3469#include <asm/prctl.h>
3470
3471static const struct xlat archvals[] = {
3472 { ARCH_SET_GS, "ARCH_SET_GS" },
3473 { ARCH_SET_FS, "ARCH_SET_FS" },
3474 { ARCH_GET_FS, "ARCH_GET_FS" },
3475 { ARCH_GET_GS, "ARCH_GET_GS" },
3476 { 0, NULL },
3477};
3478
3479int
3480sys_arch_prctl(tcp)
3481struct tcb *tcp;
3482{
3483 if (entering(tcp)) {
3484 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3485 if (tcp->u_arg[0] == ARCH_SET_GS
3486 || tcp->u_arg[0] == ARCH_SET_FS)
3487 tprintf(", %#lx", tcp->u_arg[1]);
3488 } else {
3489 if (tcp->u_arg[0] == ARCH_GET_GS
3490 || tcp->u_arg[0] == ARCH_GET_FS) {
3491 long int v;
3492 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3493 tprintf(", [%#lx]", v);
3494 else
3495 tprintf(", %#lx", tcp->u_arg[1]);
3496 }
3497 }
3498 return 0;
3499}
3500#endif
3501
Roland McGrathdb8319f2007-08-02 01:37:55 +00003502
3503int
3504sys_getcpu(tcp)
3505struct tcb *tcp;
3506{
3507 if (exiting(tcp)) {
3508 unsigned u;
3509 if (tcp->u_arg[0] == 0)
3510 tprintf("NULL, ");
3511 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3512 tprintf("%#lx, ", tcp->u_arg[0]);
3513 else
3514 tprintf("[%u], ", u);
3515 if (tcp->u_arg[1] == 0)
3516 tprintf("NULL, ");
3517 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3518 tprintf("%#lx, ", tcp->u_arg[1]);
3519 else
3520 tprintf("[%u], ", u);
3521 tprintf("%#lx", tcp->u_arg[2]);
3522 }
3523 return 0;
3524}
3525
Roland McGrath5a223472002-12-15 23:58:26 +00003526#endif